diff -Nru armadillo-9.800.4+dfsg/cmake_aux/Modules/ARMA_FindACML.cmake armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindACML.cmake --- armadillo-9.800.4+dfsg/cmake_aux/Modules/ARMA_FindACML.cmake 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindACML.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -# - Find AMD's ACML library (no includes) which provides optimised BLAS and LAPACK functions -# This module defines -# ACML_LIBRARIES, the libraries needed to use ACML. -# ACML_FOUND, If false, do not try to use ACML. -# also defined, but not for general use are -# ACML_LIBRARY, where to find the ACML library. - -SET(ACML_NAMES ${ACML_NAMES} acml) -FIND_LIBRARY(ACML_LIBRARY - NAMES ${ACML_NAMES} - PATHS /usr/lib64 /usr/lib /usr/*/lib64 /usr/*/lib /usr/*/gfortran64/lib/ /usr/*/gfortran32/lib/ /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib /opt/*/lib64 /opt/*/lib /opt/*/gfortran64/lib/ /opt/*/gfortran32/lib/ - ) - -IF (ACML_LIBRARY) - SET(ACML_LIBRARIES ${ACML_LIBRARY}) - SET(ACML_FOUND "YES") -ELSE (ACML_LIBRARY) - SET(ACML_FOUND "NO") -ENDIF (ACML_LIBRARY) - - -IF (ACML_FOUND) - IF (NOT ACML_FIND_QUIETLY) - MESSAGE(STATUS "Found ACML: ${ACML_LIBRARIES}") - ENDIF (NOT ACML_FIND_QUIETLY) -ELSE (ACML_FOUND) - IF (ACML_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find ACML") - ENDIF (ACML_FIND_REQUIRED) -ENDIF (ACML_FOUND) - -# Deprecated declarations. -GET_FILENAME_COMPONENT (NATIVE_ACML_LIB_PATH ${ACML_LIBRARY} PATH) - -MARK_AS_ADVANCED( - ACML_LIBRARY - ) diff -Nru armadillo-9.800.4+dfsg/cmake_aux/Modules/ARMA_FindACMLMP.cmake armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindACMLMP.cmake --- armadillo-9.800.4+dfsg/cmake_aux/Modules/ARMA_FindACMLMP.cmake 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindACMLMP.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -# - Find AMD's ACMLMP library (no includes) which provides optimised and parallelised BLAS and LAPACK functions -# This module defines -# ACMLMP_LIBRARIES, the libraries needed to use ACMLMP. -# ACMLMP_FOUND, If false, do not try to use ACMLMP. -# also defined, but not for general use are -# ACMLMP_LIBRARY, where to find the ACMLMP library. - -SET(ACMLMP_NAMES ${ACMLMP_NAMES} acml_mp) -FIND_LIBRARY(ACMLMP_LIBRARY - NAMES ${ACMLMP_NAMES} - PATHS /usr/lib64 /usr/lib /usr/*/lib64 /usr/*/lib /usr/*/gfortran64_mp/lib/ /usr/*/gfortran32_mp/lib/ /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib /opt/*/lib64 /opt/*/lib /opt/*/gfortran64_mp/lib/ /opt/*/gfortran32_mp/lib/ - ) - -IF (ACMLMP_LIBRARY) - SET(ACMLMP_LIBRARIES ${ACMLMP_LIBRARY}) - SET(ACMLMP_FOUND "YES") -ELSE (ACMLMP_LIBRARY) - SET(ACMLMP_FOUND "NO") -ENDIF (ACMLMP_LIBRARY) - - -IF (ACMLMP_FOUND) - IF (NOT ACMLMP_FIND_QUIETLY) - MESSAGE(STATUS "Found ACMLMP: ${ACMLMP_LIBRARIES}") - ENDIF (NOT ACMLMP_FIND_QUIETLY) -ELSE (ACMLMP_FOUND) - IF (ACMLMP_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find ACMLMP") - ENDIF (ACMLMP_FIND_REQUIRED) -ENDIF (ACMLMP_FOUND) - -# Deprecated declarations. -GET_FILENAME_COMPONENT (NATIVE_ACMLMP_LIB_PATH ${ACMLMP_LIBRARY} PATH) - -MARK_AS_ADVANCED( - ACMLMP_LIBRARY - ) diff -Nru armadillo-9.800.4+dfsg/cmake_aux/Modules/ARMA_FindFlexiBLAS.cmake armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindFlexiBLAS.cmake --- armadillo-9.800.4+dfsg/cmake_aux/Modules/ARMA_FindFlexiBLAS.cmake 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindFlexiBLAS.cmake 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,48 @@ +set(FlexiBLAS_NAMES) +set(FlexiBLAS_NAMES ${FlexiBLAS_NAMES} flexiblas) + +set(FlexiBLAS_TMP_LIBRARY) +set(FlexiBLAS_TMP_LIBRARIES) + + +foreach (FlexiBLAS_NAME ${FlexiBLAS_NAMES}) + find_library(${FlexiBLAS_NAME}_LIBRARY + NAMES ${FlexiBLAS_NAME} + PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} /lib64 /lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/local/lib64 /opt/local/lib + ) + + set(FlexiBLAS_TMP_LIBRARY ${${FlexiBLAS_NAME}_LIBRARY}) + + if(FlexiBLAS_TMP_LIBRARY) + set(FlexiBLAS_TMP_LIBRARIES ${FlexiBLAS_TMP_LIBRARIES} ${FlexiBLAS_TMP_LIBRARY}) + endif() +endforeach() + + +# use only one library + +if(FlexiBLAS_TMP_LIBRARIES) + list(GET FlexiBLAS_TMP_LIBRARIES 0 FlexiBLAS_LIBRARY) +endif() + + +if(FlexiBLAS_LIBRARY) + set(FlexiBLAS_LIBRARIES ${FlexiBLAS_LIBRARY}) + set(FlexiBLAS_FOUND "YES") +else() + set(FlexiBLAS_FOUND "NO") +endif() + + +if(FlexiBLAS_FOUND) + if (NOT FlexiBLAS_FIND_QUIETLY) + message(STATUS "Found FlexiBLAS: ${FlexiBLAS_LIBRARIES}") + endif() +else() + if(FlexiBLAS_FIND_REQUIRED) + message(FATAL_ERROR "Could not find FlexiBLAS") + endif() +endif() + + +# mark_as_advanced(FlexiBLAS_LIBRARY) diff -Nru armadillo-9.800.4+dfsg/CMakeLists.txt armadillo-10.8.2+dfsg/CMakeLists.txt --- armadillo-9.800.4+dfsg/CMakeLists.txt 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/CMakeLists.txt 2016-06-16 16:24:22.000000000 +0000 @@ -1,4 +1,5 @@ - +# SPDX-License-Identifier: Apache-2.0 +# # Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) # Copyright 2008-2016 National ICT Australia (NICTA) # @@ -37,6 +38,13 @@ endif() endif() +if(NOT (CMAKE_VERSION VERSION_LESS "3.1")) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + message(STATUS "CMAKE_CXX_STANDARD = ${CMAKE_CXX_STANDARD}") +endif() + project(armadillo CXX C) include(CheckIncludeFileCXX) include(CheckLibraryExists) @@ -45,24 +53,13 @@ # the settings below will be automatically configured by the rest of this script -set(ARMA_USE_LAPACK false) -set(ARMA_USE_BLAS false) -set(ARMA_USE_ATLAS false) -set(ARMA_USE_HDF5_ALT false) -set(ARMA_USE_ARPACK false) -set(ARMA_USE_EXTERN_CXX11_RNG false) -set(ARMA_USE_SUPERLU false) # Caveat: only SuperLU version 5.x can be used! - -## NOTE: OpenBLAS appears to have its own LAPACK functions, -## NOTE: but on some systems the installed version of OpenBLAS -## NOTE: has been modified not to include LAPACK functions. -## NOTE: As the presence of LAPACK functions in OpenBLAS can't be guaranteed, -## NOTE: this installer script requires LAPACK to be present on the system -## NOTE: in order to enable the use of LAPACK functions by Armadillo. -## NOTE: This installer will link with OpenBLAS first, -## NOTE: so if a full version of OpenBLAS is actually present on the system, -## NOTE: the linker should make use of LAPACK functions from OpenBLAS -## NOTE: instead of standard LAPACK. +set(ARMA_USE_LAPACK false) +set(ARMA_USE_BLAS false) +set(ARMA_USE_ATLAS false) +set(ARMA_USE_HDF5_ALT false) +set(ARMA_USE_ARPACK false) +set(ARMA_USE_EXTERN_RNG false) +set(ARMA_USE_SUPERLU false) # Caveat: only SuperLU version 5.x can be used! ## extract version from sources @@ -80,6 +77,69 @@ message(STATUS "Configuring Armadillo ${ARMA_VERSION_MAJOR}.${ARMA_VERSION_MINOR}.${ARMA_VERSION_PATCH}") +string(COMPARE EQUAL "${CMAKE_CXX_FLAGS}" "" CXX_FLAGS_EMPTY) +if(NOT CXX_FLAGS_EMPTY) + message(STATUS "") + message(STATUS "*** WARNING: variable 'CMAKE_CXX_FLAGS' is not empty; this may cause problems!") + message(STATUS "") +endif() + + +# NOTE: ARMA_USE_EXTERN_RNG requires compiler support for thread_local and C++11 +# NOTE: for Linux, this is available with gcc 4.8.3 onwards +# NOTE: for macOS, thread_local is supoported in Xcode 8 (mid 2016 onwards) in C++11 mode + +# NOTE: thread_local appears broken again on macOS 11 (Big Sur) and/or AppleClang 12.0 +# NOTE: see comments in include/armadillo_bits/arma_rng.hpp + +if(DEFINED CMAKE_CXX_COMPILER_ID AND DEFINED CMAKE_CXX_COMPILER_VERSION) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(NOT (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.8.3)) + set(ARMA_USE_EXTERN_RNG true) + message(STATUS "Detected gcc 4.8.3 or later") + if(NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + message(STATUS "Added '-std=c++11' to compiler flags") + endif() + else() + message(FATAL_ERROR "Compiler too old") + endif() + else() + if(NOT (${CMAKE_MAJOR_VERSION} LESS 3)) + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 6.0) + set(ARMA_USE_EXTERN_RNG true) + message(STATUS "Detected Clang 6.0 or later") + if(NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + message(STATUS "Added '-std=c++14' to compiler flags") + endif() + else() + message(FATAL_ERROR "Compiler too old") + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if(NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 8.0) + set(ARMA_USE_EXTERN_RNG true) + message(STATUS "Detected AppleClang 8.0 or later") + if(NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + message(STATUS "Added '-std=c++14' to compiler flags") + endif() + else() + message(FATAL_ERROR "Compiler too old") + endif() + endif() + endif() + endif() +endif() + +if(MINGW OR MSYS OR CYGWIN OR MSVC) + # MinGW doesn't correctly handle thread_local + set(ARMA_USE_EXTERN_RNG false) +endif() + +message(STATUS "ARMA_USE_EXTERN_RNG = ${ARMA_USE_EXTERN_RNG}") + # As Red Hat Enterprise Linux (and related systems such as Fedora) # does not search /usr/local/lib by default, we need to place the @@ -133,6 +193,20 @@ endif() option(DETECT_HDF5 "Detect HDF5 and include HDF5 support, if found" ON) +# set(DETECT_HDF5 false) +## uncomment the above line to disable the detection of the HDF5 library; +## you can also disable HDF5 detection directly on the command line: +## cmake -D DETECT_HDF5=false . + +option(OPENBLAS_PROVIDES_LAPACK "Assume that OpenBLAS provides LAPACK functions" OFF) +## Example use on the command line: +## cmake -D OPENBLAS_PROVIDES_LAPACK=true . + +option(ALLOW_FLEXIBLAS_LINUX "Allow detection of FlexiBLAS on Linux" ON) +# set(ALLOW_FLEXIBLAS_LINUX false) +## uncomment the above line to disable the detection of FlexiBLAS; +## you can also disable FlexiBLAS detection directly on the command line: +## cmake -D ALLOW_FLEXIBLAS_LINUX=false . option(ALLOW_OPENBLAS_MACOS "Allow detection of OpenBLAS on macOS" OFF) ## Example use on the command line: @@ -142,6 +216,12 @@ ## Example use on the command line: ## cmake -D ALLOW_BLAS_LAPACK_MACOS=true . +option(BUILD_SMOKE_TEST "Build a smoke test" OFF) +## Example use on the command line: +## cmake -D BUILD_SMOKE_TEST=true . +## make +## ctest + if(WIN32) message(STATUS "") @@ -163,11 +243,17 @@ message(STATUS "CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}" ) message(STATUS "CMAKE_CXX_COMPILER_VERSION = ${CMAKE_CXX_COMPILER_VERSION}") message(STATUS "CMAKE_COMPILER_IS_GNUCXX = ${CMAKE_COMPILER_IS_GNUCXX}" ) +message(STATUS "" ) message(STATUS "BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}" ) message(STATUS "DETECT_HDF5 = ${DETECT_HDF5}" ) +message(STATUS "OPENBLAS_PROVIDES_LAPACK = ${OPENBLAS_PROVIDES_LAPACK}" ) +message(STATUS "ALLOW_FLEXIBLAS_LINUX = ${ALLOW_FLEXIBLAS_LINUX}" ) message(STATUS "ALLOW_OPENBLAS_MACOS = ${ALLOW_OPENBLAS_MACOS}" ) message(STATUS "ALLOW_BLAS_LAPACK_MACOS = ${ALLOW_BLAS_LAPACK_MACOS}" ) +message(STATUS "BUILD_SMOKE_TEST = ${BUILD_SMOKE_TEST}" ) +message(STATUS "") +message(STATUS "*** Looking for external libraries") ## ## Find LAPACK and BLAS libraries, or their optimised versions @@ -178,8 +264,6 @@ 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) @@ -240,78 +324,69 @@ else() - set(ARMA_OS unix) - include(ARMA_FindMKL) - include(ARMA_FindACMLMP) - include(ARMA_FindACML) include(ARMA_FindOpenBLAS) include(ARMA_FindATLAS) include(ARMA_FindBLAS) include(ARMA_FindLAPACK) - message(STATUS " MKL_FOUND = ${MKL_FOUND}" ) - message(STATUS " ACMLMP_FOUND = ${ACMLMP_FOUND}" ) - message(STATUS " ACML_FOUND = ${ACML_FOUND}" ) - message(STATUS "OpenBLAS_FOUND = ${OpenBLAS_FOUND}") - message(STATUS " ATLAS_FOUND = ${ATLAS_FOUND}" ) - message(STATUS " BLAS_FOUND = ${BLAS_FOUND}" ) - message(STATUS " LAPACK_FOUND = ${LAPACK_FOUND}" ) + if(ALLOW_FLEXIBLAS_LINUX AND (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) + include(ARMA_FindFlexiBLAS) + endif() + + message(STATUS " MKL_FOUND = ${MKL_FOUND}" ) + message(STATUS " OpenBLAS_FOUND = ${OpenBLAS_FOUND}" ) + message(STATUS " ATLAS_FOUND = ${ATLAS_FOUND}" ) + message(STATUS " BLAS_FOUND = ${BLAS_FOUND}" ) + message(STATUS " LAPACK_FOUND = ${LAPACK_FOUND}" ) - if(MKL_FOUND OR ACMLMP_FOUND OR ACML_FOUND) + if(FlexiBLAS_FOUND) + + message(STATUS "FlexiBLAS_FOUND = ${FlexiBLAS_FOUND}" ) + + set(ARMA_USE_LAPACK true) + set(ARMA_USE_BLAS true) + + set(ARMA_LIBS ${ARMA_LIBS} ${FlexiBLAS_LIBRARIES}) + + message(STATUS "") + message(STATUS "*** Using FlexiBLAS to access BLAS and LAPACK functions.") + message(STATUS "*** https://www.mpi-magdeburg.mpg.de/projects/flexiblas") + message(STATUS "*** WARNING: SuperLU and ARPACK must also link with FlexiBLAS.") + message(STATUS "") + message(STATUS "*** If using FlexiBLAS causes problems, ") + message(STATUS "*** rerun cmake with FlexiBLAS detection disabled:") + message(STATUS "*** cmake -D ALLOW_FLEXIBLAS_LINUX=false .") + message(STATUS "") + + elseif(MKL_FOUND) set(ARMA_USE_LAPACK true) set(ARMA_USE_BLAS true) + set(ARMA_LIBS ${ARMA_LIBS} ${MKL_LIBRARIES}) message(STATUS "") - message(STATUS "*** If the MKL or ACML libraries are installed in non-standard locations such as") + message(STATUS "*** If the MKL libraries are installed in non-standard locations 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 modifying the LD_LIBRARY_PATH environment variable.") message(STATUS "") message(STATUS "*** On systems with SELinux enabled (eg. Fedora, RHEL),") - message(STATUS "*** you may need to change the SELinux type of all MKL/ACML libraries") + message(STATUS "*** you may need to change the SELinux type of all MKL libraries") message(STATUS "*** to fix permission problems that may occur during run-time.") message(STATUS "") - if(MKL_FOUND) - set(ARMA_LIBS ${ARMA_LIBS} ${MKL_LIBRARIES}) - - if(ACMLMP_FOUND OR ACML_FOUND) - message(STATUS "*** Intel MKL as well as AMD ACML libraries were found.") - message(STATUS "*** Using only the MKL library to avoid linking conflicts.") - message(STATUS "*** If you wish to use ACML instead, please link manually with") - message(STATUS "*** acml or acml_mp instead of the armadillo wrapper library.") - message(STATUS "*** Alternatively, remove MKL from your system and rerun") - message(STATUS "*** Armadillo's configuration using ./configure") - endif() - - else() - - if(ACMLMP_FOUND) - set(ARMA_LIBS ${ARMA_LIBS} ${ACMLMP_LIBRARIES}) - - message(STATUS "*** Both single-core and multi-core ACML libraries were found.") - message(STATUS "*** Using only the multi-core library to avoid linking conflicts.") - else() - if(ACML_FOUND) - set(ARMA_LIBS ${ARMA_LIBS} ${ACML_LIBRARIES}) - endif() - endif() - - endif() - else() if(OpenBLAS_FOUND AND ATLAS_FOUND) message(STATUS "") - message(STATUS "*** WARNING: found both OpenBLAS and ATLAS; ATLAS will not be used") + message(STATUS "*** NOTE: found both OpenBLAS and ATLAS; ATLAS will not be used") endif() if(OpenBLAS_FOUND AND BLAS_FOUND) message(STATUS "") - message(STATUS "*** WARNING: found both OpenBLAS and BLAS; BLAS will not be used") + message(STATUS "*** NOTE: found both OpenBLAS and BLAS; BLAS will not be used") endif() if(OpenBLAS_FOUND) @@ -319,6 +394,15 @@ set(ARMA_USE_BLAS true) set(ARMA_LIBS ${ARMA_LIBS} ${OpenBLAS_LIBRARIES}) + if(OPENBLAS_PROVIDES_LAPACK) + set(ARMA_USE_LAPACK true) + else() + message(STATUS "") + message(STATUS "*** NOTE: if OpenBLAS is known to provide LAPACK functions, recommend to") + message(STATUS "*** NOTE: rerun cmake with the OPENBLAS_PROVIDES_LAPACK option enabled:") + message(STATUS "*** NOTE: cmake -D OPENBLAS_PROVIDES_LAPACK=true .") + endif() + message(STATUS "") message(STATUS "*** If the OpenBLAS library is installed in") message(STATUS "*** /usr/local/lib or /usr/local/lib64") @@ -345,10 +429,17 @@ endif() if(LAPACK_FOUND) - set(ARMA_USE_LAPACK true) - set(ARMA_LIBS ${ARMA_LIBS} ${LAPACK_LIBRARIES}) + if(OpenBLAS_FOUND AND OPENBLAS_PROVIDES_LAPACK) + message(STATUS "*** NOTE: found both OpenBLAS and LAPACK;") + message(STATUS "*** NOTE: option OPENBLAS_PROVIDES_LAPACK is enabled,") + message(STATUS "*** NOTE: so will not link with plain LAPACK.") + message(STATUS "") + else() + set(ARMA_USE_LAPACK true) + set(ARMA_LIBS ${ARMA_LIBS} ${LAPACK_LIBRARIES}) + endif() endif() - + endif() endif() @@ -357,12 +448,6 @@ find_package(PkgConfig) -# set(DETECT_HDF5 false) - -## uncomment the above line to disable the detection of the HDF5 library; -## you can also disable HDF5 detection directly on the command line: -## cmake -D DETECT_HDF5=false . - if(DETECT_HDF5) find_package(HDF5 QUIET COMPONENTS C) @@ -425,39 +510,38 @@ set(ARMA_SUPERLU_INCLUDE_DIR ${SuperLU_INCLUDE_DIR}) endif() -message(STATUS "") -message(STATUS "*** Armadillo wrapper library will use the following libraries:") -message(STATUS "*** ARMA_LIBS = ${ARMA_LIBS}") -message(STATUS "") - -# NOTE: ARMA_USE_EXTERN_CXX11_RNG requires compiler support for thread_local and C++11 -# NOTE: for Linux, this is available with gcc 4.8.3 onwards -# NOTE: for macOS, thread_local is supoported in Xcode 8 (mid 2016 onwards) in C++11 mode +if(NOT ARMA_USE_LAPACK) + message(STATUS "") + message(STATUS "*** WARNING: Use of LAPACK is not enabled, as no LAPACK compatible library has been found.") + message(STATUS "*** WARNING: This will materially degrade the available functionality in Armadillo.") -if(DEFINED CMAKE_CXX_COMPILER_ID AND DEFINED CMAKE_CXX_COMPILER_VERSION) - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.8.3) - set(ARMA_USE_EXTERN_CXX11_RNG true) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - message(STATUS "Detected gcc 4.8.3 or later. Added '-std=c++11' to compiler flags") - else() - if(NOT (${CMAKE_MAJOR_VERSION} LESS 3)) - - if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 6.0) - set(ARMA_USE_EXTERN_CXX11_RNG true) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - message(STATUS "Detected Clang 6.0 or later. Added '-std=c++14' to compiler flags") - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 8.0) - set(ARMA_USE_EXTERN_CXX11_RNG true) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - message(STATUS "Detected AppleClang 8.0 or later. Added '-std=c++14' to compiler flags") - endif() - - endif() + if(OpenBLAS_FOUND) + message(STATUS "") + message(STATUS "*** NOTE: OpenBLAS found but LAPACK not found.") + message(STATUS "*** NOTE: OpenBLAS may have been built without LAPACK functions,") + message(STATUS "*** NOTE: so cannot assume that LAPACK functions are available.") + message(STATUS "*** NOTE: To forcefully assume that OpenBLAS provides LAPACK functions,") + message(STATUS "*** NOTE: rerun cmake with the OPENBLAS_PROVIDES_LAPACK option enabled:") + message(STATUS "*** NOTE: cmake -D OPENBLAS_PROVIDES_LAPACK=true .") endif() endif() -message(STATUS "ARMA_USE_EXTERN_CXX11_RNG = ${ARMA_USE_EXTERN_CXX11_RNG}") + +message(STATUS "") +message(STATUS "*** Result of configuration:") +message(STATUS "*** ARMA_USE_WRAPPER = ${ARMA_USE_WRAPPER}") +message(STATUS "*** ARMA_USE_LAPACK = ${ARMA_USE_LAPACK}") +message(STATUS "*** ARMA_USE_BLAS = ${ARMA_USE_BLAS}") +message(STATUS "*** ARMA_USE_ATLAS = ${ARMA_USE_ATLAS}") +message(STATUS "*** ARMA_USE_HDF5_ALT = ${ARMA_USE_HDF5_ALT}") +message(STATUS "*** ARMA_USE_ARPACK = ${ARMA_USE_ARPACK}") +message(STATUS "*** ARMA_USE_EXTERN_RNG = ${ARMA_USE_EXTERN_RNG}") +message(STATUS "*** ARMA_USE_SUPERLU = ${ARMA_USE_SUPERLU}") +message(STATUS "") +message(STATUS "*** Armadillo wrapper library will use the following libraries:") +message(STATUS "*** ARMA_LIBS = ${ARMA_LIBS}") +message(STATUS "") message(STATUS "Copying ${PROJECT_SOURCE_DIR}/include/ to ${PROJECT_BINARY_DIR}/tmp/include/") @@ -466,9 +550,6 @@ message(STATUS "Generating ${PROJECT_BINARY_DIR}/tmp/include/config.hpp") configure_file(${PROJECT_BINARY_DIR}/tmp/include/armadillo_bits/config.hpp.cmake ${PROJECT_BINARY_DIR}/tmp/include/armadillo_bits/config.hpp) -message(STATUS "Generating ${PROJECT_SOURCE_DIR}/examples/Makefile") -configure_file(${PROJECT_SOURCE_DIR}/examples/Makefile.cmake ${PROJECT_SOURCE_DIR}/examples/Makefile) - include_directories(${PROJECT_BINARY_DIR}/tmp/include/ ${CMAKE_REQUIRED_INCLUDES}) @@ -513,7 +594,8 @@ add_library( armadillo ${PROJECT_SOURCE_DIR}/src/wrapper1.cpp ${PROJECT_SOURCE_DIR}/src/wrapper2.cpp ) target_link_libraries( armadillo ${ARMA_LIBS} ) -target_include_directories(armadillo INTERFACE $ $) +# target_include_directories(armadillo INTERFACE $ $) +target_include_directories(armadillo INTERFACE $ $) set_target_properties(armadillo PROPERTIES VERSION ${ARMA_VERSION_MAJOR}.${ARMA_VERSION_MINOR_ALT}.${ARMA_VERSION_PATCH} SOVERSION ${ARMA_VERSION_MAJOR}) @@ -602,3 +684,12 @@ configure_file(${PROJECT_BINARY_DIR}/tmp/misc/armadillo.pc.in "${PROJECT_BINARY_DIR}/tmp/misc/armadillo.pc" @ONLY) install(FILES "${PROJECT_BINARY_DIR}/tmp/misc/armadillo.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + + +# smoke test + +if(BUILD_SMOKE_TEST) + message(STATUS "*** configuring smoke_test") + enable_testing() + add_subdirectory(tests1) +endif() diff -Nru armadillo-9.800.4+dfsg/debian/changelog armadillo-10.8.2+dfsg/debian/changelog --- armadillo-9.800.4+dfsg/debian/changelog 2020-03-23 06:09:58.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/changelog 2022-09-22 05:00:28.000000000 +0000 @@ -1,8 +1,84 @@ -armadillo (1:9.800.4+dfsg-1build1) focal; urgency=medium +armadillo (1:10.8.2+dfsg-1~20.04.sav0) focal; urgency=medium - * No-change rebuild for libgcc-s1 package name change. + * Backport to Focal - -- Matthias Klose Mon, 23 Mar 2020 07:09:58 +0100 + -- Rob Savoury Wed, 21 Sep 2022 22:00:28 -0700 + +armadillo (1:10.8.2+dfsg-1) unstable; urgency=medium + + * New upstream release + + -- Kumar Appaiah Mon, 07 Feb 2022 21:02:29 +0530 + +armadillo (1:10.8.0+dfsg-1) unstable; urgency=medium + + * New upstream release + + -- Kumar Appaiah Wed, 12 Jan 2022 20:59:36 +0530 + +armadillo (1:10.7.4+dfsg-1) unstable; urgency=medium + + * New upstream release + + -- Kumar Appaiah Thu, 25 Nov 2021 22:28:58 +0530 + +armadillo (1:10.6.2+dfsg-1) unstable; urgency=medium + + * New upstream release + * Remove all patches (included upstream) + + -- Kumar Appaiah Tue, 24 Aug 2021 19:47:25 +0530 + +armadillo (1:10.1.2+dfsg-6) unstable; urgency=medium + + * Add patch from upstream for fixing sparse matrix related bug. + + -- Kumar Appaiah Mon, 21 Jun 2021 09:43:00 +0530 + +armadillo (1:10.1.2+dfsg-5) unstable; urgency=medium + + * Add patches from upstream for pinv and rcond bugs + + -- Kumar Appaiah Tue, 09 Mar 2021 20:19:43 +0530 + +armadillo (1:10.1.2+dfsg-4) unstable; urgency=medium + + * Fix issue with princomp function. + + -- Kumar Appaiah Mon, 15 Feb 2021 14:52:17 +0530 + +armadillo (1:10.1.2+dfsg-3) unstable; urgency=medium + + * Add patch to handle sign for NaNs + + -- Kumar Appaiah Wed, 20 Jan 2021 16:19:03 +0530 + +armadillo (1:10.1.2+dfsg-2) unstable; urgency=medium + + * Install cmake and pkg-config files during install. (Closes: #954927) + * Remove generated files during cleanup + * Standards version is now 4.5.1 (no changes needed) + + -- Kumar Appaiah Thu, 17 Dec 2020 07:58:31 +0530 + +armadillo (1:10.1.2+dfsg-1) unstable; urgency=medium + + * New upstream release + + -- Kumar Appaiah Wed, 18 Nov 2020 14:34:07 +0530 + +armadillo (1:10.1.0+dfsg-1) experimental; urgency=medium + + * New upstream release + * Standards version is now 4.5.0 + + -- Kumar Appaiah Fri, 09 Oct 2020 14:59:12 +0530 + +armadillo (1:9.900.1+dfsg-1) unstable; urgency=medium + + * New upstream release + + -- Kumar Appaiah Thu, 11 Jun 2020 14:27:04 +0530 armadillo (1:9.800.4+dfsg-1) unstable; urgency=medium diff -Nru armadillo-9.800.4+dfsg/debian/compat armadillo-10.8.2+dfsg/debian/compat --- armadillo-9.800.4+dfsg/debian/compat 2020-01-22 14:59:32.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/compat 2022-02-07 15:32:21.000000000 +0000 @@ -1 +1 @@ -9 +10 diff -Nru armadillo-9.800.4+dfsg/debian/control armadillo-10.8.2+dfsg/debian/control --- armadillo-9.800.4+dfsg/debian/control 2020-01-22 14:59:32.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/control 2022-02-07 15:32:21.000000000 +0000 @@ -3,7 +3,7 @@ Maintainer: Debian Science Maintainers Uploaders: Kumar Appaiah Build-Depends: debhelper (>= 7), libblas-dev, liblapack-dev, cmake, libarpack2-dev, dpkg-dev (>= 1.16.1~), libsuperlu-dev (>= 5.2), quilt -Standards-Version: 4.4.0 +Standards-Version: 4.5.1 Section: libs Homepage: http://arma.sourceforge.net/ Vcs-Git: https://salsa.debian.org/science-team/armadillo.git @@ -13,7 +13,7 @@ Section: libdevel Architecture: any Suggests: libitpp-dev -Depends: libarmadillo9 (= ${binary:Version}), ${misc:Depends}, libarpack2-dev, libhdf5-dev, libsuperlu-dev (>= 5.2) +Depends: libarmadillo10 (= ${binary:Version}), ${misc:Depends}, libarpack2-dev, libhdf5-dev, libsuperlu-dev (>= 5.2) Replaces: libarmadillo-doc (<= 1.1.2-1) Conflicts: libarmadillo-doc Description: streamlined C++ linear algebra library - Headers @@ -25,7 +25,7 @@ . This package has the development libraries and headers for Armadillo. -Package: libarmadillo9 +Package: libarmadillo10 Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} diff -Nru armadillo-9.800.4+dfsg/debian/libarmadillo10.docs armadillo-10.8.2+dfsg/debian/libarmadillo10.docs --- armadillo-9.800.4+dfsg/debian/libarmadillo10.docs 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/libarmadillo10.docs 2022-02-07 15:32:21.000000000 +0000 @@ -0,0 +1,2 @@ +README.md +docs.html diff -Nru armadillo-9.800.4+dfsg/debian/libarmadillo10.install armadillo-10.8.2+dfsg/debian/libarmadillo10.install --- armadillo-9.800.4+dfsg/debian/libarmadillo10.install 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/libarmadillo10.install 2022-02-07 15:32:21.000000000 +0000 @@ -0,0 +1 @@ +usr/lib/*.so.* usr/lib diff -Nru armadillo-9.800.4+dfsg/debian/libarmadillo9.docs armadillo-10.8.2+dfsg/debian/libarmadillo9.docs --- armadillo-9.800.4+dfsg/debian/libarmadillo9.docs 2020-01-22 14:59:32.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/libarmadillo9.docs 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -README.md -docs.html diff -Nru armadillo-9.800.4+dfsg/debian/libarmadillo9.install armadillo-10.8.2+dfsg/debian/libarmadillo9.install --- armadillo-9.800.4+dfsg/debian/libarmadillo9.install 2020-01-22 14:59:32.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/libarmadillo9.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/*.so.* usr/lib diff -Nru armadillo-9.800.4+dfsg/debian/libarmadillo-dev.install armadillo-10.8.2+dfsg/debian/libarmadillo-dev.install --- armadillo-9.800.4+dfsg/debian/libarmadillo-dev.install 2020-01-22 14:59:32.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/libarmadillo-dev.install 2022-02-07 15:32:21.000000000 +0000 @@ -1,2 +1,3 @@ usr/include/* usr/include usr/lib/lib*.so usr/lib +usr/share/Armadillo/CMake/*.cmake usr/share/doc/libarmadillo-dev diff -Nru armadillo-9.800.4+dfsg/debian/rules armadillo-10.8.2+dfsg/debian/rules --- armadillo-9.800.4+dfsg/debian/rules 2020-01-22 14:59:32.000000000 +0000 +++ armadillo-10.8.2+dfsg/debian/rules 2022-02-07 15:32:21.000000000 +0000 @@ -28,7 +28,7 @@ rm -rf CMakeFiles rm -f install_manifest.txt include/armadillo_bits/config.hpp examples/Makefile rm -f ArmadilloConfig.cmake ArmadilloConfigVersion.cmake - rm -rf InstallFiles + rm -rf InstallFiles tmp *.o a.out dh_clean --exclude ./src/include/armadillo_bits/dgemm_proto.hpp.orig install: build @@ -45,6 +45,8 @@ dh_installdocs -a dh_installexamples -a dh_install -a --sourcedir=debian/tmp + mkdir -p debian/libarmadillo-dev/usr/lib/${DEB_HOST_MULTIARCH}/pkgconfig/ + cp debian/tmp/usr/lib/pkgconfig/armadillo.pc debian/libarmadillo-dev/usr/lib/${DEB_HOST_MULTIARCH}/pkgconfig/ dh_installman -a dh_link -a dh_strip -a diff -Nru armadillo-9.800.4+dfsg/docs.html armadillo-10.8.2+dfsg/docs.html --- armadillo-9.800.4+dfsg/docs.html 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/docs.html 2016-06-16 16:24:22.000000000 +0000 @@ -25,7 +25,8 @@ +
  • If A is not square sized, a std::logic_error exception is thrown
  • +
    +
  • If the matrix power cannot be found: +
      +
    • B = powmat(A) resets B and throws a std::runtime_error exception
    • +
    • powmat(B,A) resets B and returns a bool set to false (exception is not thrown)
    • +
    +
  • +
    +
  • Caveats: +
      +
    • to find the inverse of a matrix, use inv() instead
    • +
    • to solve a system of linear equations, use solve() instead
    • +
    • to find the matrix square root, use sqrtmat() instead
    • +
    • the matrix power operation is generally not the same as applying the pow() function to each element
    • +
    +
    +
  • +Examples: +
      +
      +   mat A(5, 5, fill::randu);
      +
      +   mat B = powmat(A, 4);     //     integer exponent
      +
      +cx_mat C = powmat(A, 4.56);  // non-integer exponent
      +
      +
    +
  • +
    +
  • +See also: + +
  • +
    + + +


    rank( X )
    rank( X, tolerance )
      -
    • Return the rank of matrix X
    • +
    • Return the rank of matrix X, based on on singular value decomposition

    • Any singular values less than tolerance are treated as zero

    • -The tolerance argument is optional; by default tolerance is max(m,n)*max_sv*datum::eps, where: +The tolerance argument is optional; by default tolerance is max(m,n) · max_sv · datum::eps, where:
      • m = number of rows and n = number of columns in X
      • -
      • max_sv = maximal singular value of X
      • +
      • max_sv = maximum singular value of X
      • datum::eps = difference between 1 and the least value greater than 1 that is representable

    • -
    • The computation is based on singular value decomposition; -if the decomposition fails, a std::runtime_error exception is thrown
    • +
    • If the decomposition fails, a std::runtime_error exception is thrown

    • Caveat: to confirm whether a matrix is singular, use rcond() or cond()

    • +Caveat: to distinguish from std::rank, use the arma:: prefix, ie. arma::rank(X) +
    • +
      +
    • Examples:
        -mat   A = randu<mat>(4,5);
        +mat A(4, 5, fill::randu);
         
         uword r = rank(A);
         
        @@ -10153,7 +10572,8 @@ Examples:
          -mat    A = randu<mat>(5,5);
          +mat A(5, 5, fill::randu);
          +
           double r = rcond(A);
           
        @@ -10193,7 +10613,7 @@ Examples:
          -mat A = randu<mat>(2, 3);
          +mat A(2, 3, fill::randu);
           
           mat B = repelem(A, 4, 5);
           
          @@ -10220,8 +10640,8 @@
            - - + +
            n_rows = num_copies_per_row*A.n_rows
            n_cols = num_copies_per_col*A.n_cols
            n_rows = num_copies_per_row×A.n_rows
            n_cols = num_copies_per_col×A.n_cols
          @@ -10229,14 +10649,14 @@
        • Caveat: to apply a vector operation on each row or column of a matrix, -it's generally more efficient to use .each_row() or .each_col() +it is generally more efficient to use .each_row() or .each_col()

        • Examples:
            -mat A = randu<mat>(2, 3);
            +mat A(2, 3, fill::randu);
             
             mat B = repmat(A, 4, 5);
             
            @@ -10286,7 +10706,7 @@ Caveats:
            • -do not use reshape() if you simply want to change the size without preserving data; +do not use reshape() to change the size without preserving data; use .set_size() instead, which is much faster
            • @@ -10303,7 +10723,8 @@ Examples:
                -mat A = randu<mat>(10, 5);
                +mat A(10, 5, fill::randu);
                +
                 mat B = reshape(A, 5, 10);
                 
              @@ -10343,7 +10764,7 @@
            • Caveat: -do not use resize() if you simply want to change the size without preserving data; +do not use resize() to change the size without preserving data; use .set_size() instead, which is much faster

            • @@ -10351,7 +10772,8 @@ Examples:
                -mat A = randu<mat>(4, 5);
                +mat A(4, 5, fill::randu);
                +
                 mat B = resize(A, 7, 6);
                 
              @@ -10385,11 +10807,11 @@
            • -For matrix X, generate a copy of the matrix with the order of elements reversed in each column (dim=0), or each row (dim=1) +For matrix X, generate a copy of the matrix with the order of elements reversed in each column (dim = 0), or each row (dim = 1)

            • -The dim argument is optional; by default dim=0 is used +The dim argument is optional; by default dim = 0 is used

            • @@ -10412,8 +10834,9 @@
            • fliplr() & flipud()
            • shift()
            • sort()
            • -
            • .swap_rows() & .swap_cols()
            • +
            • trans()
            • .t()
            • +
            • .swap_rows() & .swap_cols()

            @@ -10421,8 +10844,8 @@


            -R = roots(P) -
            roots(R, P) +R = roots( P ) +
            roots( R, P )
            • Find the complex roots of a polynomial function represented via vector P and store them in column vector R @@ -10452,7 +10875,7 @@ Examples:

            • @@ -10483,7 +10906,7 @@
            • -For matrix X, generate a copy of the matrix with the elements shifted by N positions in each column (dim=0), or each row (dim=1) +For matrix X, generate a copy of the matrix with the elements shifted by N positions in each column (dim = 0), or each row (dim = 1)

            • @@ -10491,14 +10914,14 @@

            • -The dim argument is optional; by default dim=0 is used +The dim argument is optional; by default dim = 0 is used

            • Examples:
                -mat A = randu<mat>(4,5);
                +mat A(4, 5, fill::randu);
                 mat B = shift(A, -1);
                 mat C = shift(A, +1);
                 
                @@ -10527,18 +10950,18 @@
              • -For matrix X, generate a copy of the matrix with the elements shuffled in each column (dim=0), or each row (dim=1) +For matrix X, generate a copy of the matrix with the elements shuffled in each column (dim = 0), or each row (dim = 1)

              • -The dim argument is optional; by default dim=0 is used +The dim argument is optional; by default dim = 0 is used

              • Examples:
                  -mat A = randu<mat>(4,5);
                  +mat A(4, 5, fill::randu);
                   mat B = shuffle(A);
                   
                @@ -10637,10 +11060,10 @@
                • For vector V, return a vector which is a sorted version of the input vector

                • -
                • For matrix X, return a matrix with the elements of the input matrix sorted in each column (dim=0), or each row (dim=1)
                • +
                • For matrix X, return a matrix with the elements of the input matrix sorted in each column (dim = 0), or each row (dim = 1)

                • -The dim argument is optional; by default dim=0 is used +The dim argument is optional; by default dim = 0 is used

                • The sort_direction argument is optional; sort_direction is either "ascend" or "descend"; by default "ascend" is used
                • @@ -10651,7 +11074,7 @@ Examples:
                    -mat A = randu<mat>(10,10);
                    +mat A(10, 10, fill::randu);
                     mat B = sort(A);
                     
                  @@ -10700,7 +11123,8 @@ Examples:
                    -vec  q       = randu<vec>(10);
                    +vec q(10, fill::randu);
                    +
                     uvec indices = sort_index(q);
                     
                  @@ -10721,8 +11145,8 @@


                  -B = sqrtmat(A) -
                  sqrtmat(B,A) +B = sqrtmat( A ) +
                  sqrtmat( B, A )
                  • Complex square root of general square matrix A

                  • @@ -10740,7 +11164,7 @@ Examples:
                      -   mat A = randu<mat>(5,5);
                      +   mat A(5, 5, fill::randu);
                       
                       cx_mat B = sqrtmat(A);
                       
                      @@ -10751,6 +11175,7 @@ See also:
                      • sqrtmat_sympd()
                      • +
                      • powmat()
                      • expmat()
                      • logmat()
                      • chol()
                      • @@ -10764,8 +11189,8 @@


                        -B = sqrtmat_sympd(A) -
                        sqrtmat_sympd(B,A) +B = sqrtmat_sympd( A ) +
                        sqrtmat_sympd( B, A )
                        • Square root of symmetric/hermitian positive definite matrix A

                        • @@ -10788,7 +11213,7 @@ Examples:
                            -mat A = randu<mat>(5,5);
                            +mat A(5, 5, fill::randu);
                             
                             mat B = A*A.t();   // make symmetric matrix
                             
                            @@ -10827,16 +11252,16 @@
                             
                             
                          • -For matrix M, return the sum of elements in each column (dim=0), or each row (dim=1) +For matrix M, return the sum of elements in each column (dim = 0), or each row (dim = 1)

                          • -For cube Q, return the sums of elements along dimension dim, where dim ∈ { 0, 1, 2 }; -for example, dim=0 indicates the sum of elements in each column within each slice +For cube Q, return the sums of elements along dimension dim, where dim ∈ { 0, 1, 2 }; +for example, dim = 0 indicates the sum of elements in each column within each slice

                          • -The dim argument is optional; by default dim=0 is used +The dim argument is optional; by default dim = 0 is used

                          • @@ -10847,10 +11272,10 @@ Examples:
                              -colvec v = randu<colvec>(10,1);
                              +colvec v(10, fill::randu);
                               double x = sum(v);
                               
                              -mat    M = randu<mat>(10,10);
                              +mat M(10, 10, fill::randu);
                               
                               rowvec a = sum(M);
                               rowvec b = sum(M,0);
                              @@ -10896,12 +11321,12 @@
                               
                               
                            • -For the matrix_of_subscripts argument, the subscripts must be stored in each column of an m x n matrix of type umat; -m=2 for matrix subscripts, while m=3 for cube subscripts +For the matrix_of_subscripts argument, the subscripts must be stored in each column of an m x n matrix of type umat; +m = 2 for matrix subscripts, while m = 3 for cube subscripts

                            • -A std::logic_error exception is thrown if a subscript is out of range +If a subscript is out of range, a std::logic_error exception is thrown

                            • @@ -10956,7 +11381,7 @@ Examples:
                                -mat A = randu<mat>(5,5);
                                +mat A(5, 5, fill::randu);
                                 
                                 mat B = symmatu(A);
                                 mat C = symmatl(A);
                                @@ -10986,14 +11411,14 @@
                                 
                              • If X is an expression, -the function will try to use optimised expression evaluations to calculate only the diagonal elements +the function aims to use optimised expression evaluations to calculate only the diagonal elements

                              • Examples:
                                  -mat    A = randu<mat>(5,5);
                                  +mat A(5, 5, fill::randu);
                                   
                                   double x = trace(A);
                                   
                                  @@ -11022,15 +11447,15 @@ For real (non-complex) matrix:
                                  • trans() provides a transposed copy of the matrix
                                  • -
                                  • strans() not applicable
                                  • +
                                  • strans() is not applicable

                                • For complex matrix:
                                    -
                                  • trans() provides a Hermitian transpose (ie. the conjugate of the elements is taken during the transpose)
                                  • -
                                  • strans() provides a transposed copy without taking the conjugate of the elements
                                  • +
                                  • trans() provides a Hermitian (conjugate) transposed copy (ie. signs of imaginary components are flipped)
                                  • +
                                  • strans() provides a simple transposed copy (ie. signs of imaginary components are not flipped)

                                • @@ -11038,7 +11463,7 @@ Examples:
                                    -mat A = randu<mat>(5,10);
                                    +mat A(5, 10, fill::randu);
                                     
                                     mat B = trans(A);
                                     mat C = A.t();    // equivalent to trans(A), but more compact
                                    @@ -11050,6 +11475,11 @@
                                     
                                     
                                     
                                    @@ -11064,11 +11494,11 @@
                                    trapz( Y, dim )
                                    • -Compute the trapezoidal integral of Y with respect to spacing in X, in each column (dim=0) or each row (dim=1) of Y +Compute the trapezoidal integral of Y with respect to spacing in X, in each column (dim = 0) or each row (dim = 1) of Y

                                    • -X must be a vector; its length must equal either the number of rows in Y (when dim=0), or the number of columns in Y (when dim=1) +X must be a vector; its length must equal either the number of rows in Y (when dim = 0), or the number of columns in Y (when dim = 1)

                                    • @@ -11076,7 +11506,7 @@

                                    • -The dim argument is optional; by default dim=0 +The dim argument is optional; by default dim = 0

                                    • @@ -11124,16 +11554,16 @@ The argument k specifies the diagonal which inclusively delineates the boundary of the triangular part
                                      • -for k > 0, the k-th super-diagonal is used (above main diagonal, towards top-right corner) +for k > 0, the k-th super-diagonal is used (above main diagonal, towards top-right corner)
                                      • -for k < 0, the k-th sub-diagonal is used (below main diagonal, towards bottom-left corner) +for k < 0, the k-th sub-diagonal is used (below main diagonal, towards bottom-left corner)

                                    • -The argument k is optional; by default the main diagonal is used (k=0) +The argument k is optional; by default the main diagonal is used (k = 0)

                                    • @@ -11144,7 +11574,7 @@ Examples:
                                        -mat A = randu<mat>(5,5);
                                        +mat A(5, 5, fill::randu);
                                         
                                         mat U  = trimatu(A);
                                         mat L  = trimatl(A);
                                        @@ -11158,6 +11588,7 @@
                                         
                                      • See also: +


                                        - -unique( A ) + +trimatu_ind( size(A) ) +
                                        trimatu_ind( size(A), k )
                                        +
                                        trimatl_ind( size(A) ) +
                                        trimatl_ind( size(A), k )
                                        • -Return the unique elements of A, sorted in ascending order +Return a column vector containing the indices of elements that form the upper or lower triangle part of matrix A +
                                            +
                                          • trimatu_ind() refers to the upper triangular part
                                          • +
                                          • trimatl_ind() refers to the lower triangular part
                                          • +
                                          +
                                        • +
                                          +
                                        • The output vector must have the type uvec +(ie. the indices are stored as unsigned integers of type uword)

                                        • -If A is a vector, the output is also a vector with the same orientation (row or column) as A; -if A is a matrix, the output is always a column vector +The argument k specifies the diagonal which inclusively delineates the boundary of the triangular part +
                                            +
                                          • +for k > 0, the k-th super-diagonal is used (above main diagonal, towards top-right corner) +
                                          • +
                                          • +for k < 0, the k-th sub-diagonal is used (below main diagonal, towards bottom-left corner) +
                                          • +
                                          +
                                        • +
                                          +
                                        • +The argument k is optional; by default the main diagonal is used (k = 0) +
                                        • +
                                          +
                                        • +The argument size(A) can be replaced with size(n_rows, n_cols)

                                        • Examples:
                                            -mat X;
                                            -X << 1 << 2 << endr
                                            -  << 2 << 3 << endr;
                                            +mat A(5, 5, fill::randu);
                                             
                                            -mat Y = unique(X);
                                            +uvec upper_indices = trimatu_ind( size(A) );
                                            +uvec lower_indices = trimatl_ind( size(A) );
                                            +
                                            +// extract upper/lower triangle into vector
                                            +vec upper_part = A(upper_indices);
                                            +vec lower_part = A(lower_indices);
                                            +
                                            +// obtain indices without the main diagonal
                                            +uvec alt_upper_indices = trimatu_ind( size(A),  1);
                                            +uvec alt_lower_indices = trimatl_ind( size(A), -1);
                                             

                                        • See also:



                                        - -vectorise( X ) -
                                        vectorise( X, dim ) -
                                        vectorise( Q ) + +unique( A ) +
                                        • -Generate a flattened version of matrix X or cube Q +Return the unique elements of A, sorted in ascending order

                                        • -The argument dim is optional; by default dim=0 is used +If A is a vector, the output is also a vector with the same orientation (row or column) as A; +if A is a matrix, the output is always a column vector

                                        • -For dim=0, the elements are copied from X column-wise, resulting in a column vector; equivalent to concatenating all the columns of X -
                                        • +Examples: +
                                            +
                                            +mat X = { { 1, 2 }
                                            +          { 2, 3 } };
                                            +
                                            +mat Y = unique(X);
                                            +
                                            +
                                          + +
                                          +
                                        • See also: + +
                                        • +
                                          +
                                        + +


                                        + +vectorise( X ) +
                                        vectorise( X, dim ) +
                                        vectorise( Q ) +
                                          +
                                        • +Generate a flattened version of matrix X or cube Q +

                                        • -For dim=1, the elements are copied from X row-wise, resulting in a row vector; equivalent to concatenating all the rows of X +The argument dim is optional; by default dim = 0 is used +
                                        • +
                                          +
                                        • +For dim = 0, the elements are copied from X column-wise, resulting in a column vector; equivalent to concatenating all the columns of X +
                                        • +
                                          +
                                        • +For dim = 1, the elements are copied from X row-wise, resulting in a row vector; equivalent to concatenating all the rows of X

                                        • @@ -11242,7 +11743,7 @@ Examples:
                                            -mat X = randu<mat>(4, 5);
                                            +mat X(4, 5, fill::randu);
                                             
                                             vec v = vectorise(X);
                                             
                                            @@ -11268,13 +11769,11 @@ miscellaneous element-wise functions:
                                              - - - - - - - + + + + +
                                              exp    exp2    exp10    trunc_exp   expm1
                                              log    log2    log10    trunc_log   log1p
                                              pow    square   sqrt     
                                              floor    ceil    round    trunc
                                              erf    erfc         
                                              lgamma            
                                              sign             
                                              exp    log    pow    floor    erf    tgamma   sign
                                              exp2    log2    square   ceil    erfc    lgamma    
                                              exp10    log10    sqrt    round             
                                              expm1    log1p        trunc             
                                              trunc_exp   trunc_log                    
                                              @@ -11285,11 +11784,9 @@
                                            • Usage:
                                                -
                                              • B = fn(A)
                                              • -
                                              • A and B must have the same matrix type or cube type, such as mat or cube
                                              • -
                                              • -fn(A) is one of: -
                                                +
                                              • B = fn(A), where fn(A) is one of the functions below
                                              • +
                                              • A and B must have the same matrix type or cube type, such as mat or cube
                                              • +

                                              @@ -11301,7 +11798,7 @@   @@ -11312,7 +11809,7 @@   @@ -11323,30 +11820,30 @@   @@ -11357,7 +11854,7 @@   @@ -11368,7 +11865,7 @@   @@ -11379,63 +11876,63 @@   @@ -11506,13 +12003,24 @@ + + + + + @@ -11540,7 +12048,15 @@
                                              - base-e exponential: e x + base-e exponential: e x
                                              - base-2 exponential: 2 x + base-2 exponential: 2 x
                                              - base-10 exponential: 10 x + base-10 exponential: 10 x
                                              - trunc_exp(A) + expm1(A)   - base-e exponential, - truncated to avoid infinity   (only for float and double elements) + compute exp(A)-1 accurately for values of A close to zero   (only for float and double elements)
                                              - expm1(A) + trunc_exp(A)   - compute exp(A)-1 accurately for values of A close to zero   (only for float and double elements) + base-e exponential, + truncated to avoid infinity   (only for float and double elements)
                                              - natural log: loge x + natural log: loge x
                                              - base-2 log: log2 x + base-2 log: log2 x
                                              - base-10 log: log10 x + base-10 log: log10 x
                                              - trunc_log(A) + log1p(A)   - natural log, - truncated to avoid ±infinity   (only for float and double elements) + compute log(1+A) accurately for values of A close to zero   (only for float and double elements)
                                              - log1p(A) + trunc_log(A)   - compute log(1+A) accurately for values of A close to zero   (only for float and double elements) + natural log, + truncated to avoid ±infinity   (only for float and double elements)
                                              - pow(A, p)  + pow(A, p)   - raise to the power of p: x p + raise to the power of p: x p
                                              - square(A)  + square(A)   - square: x 2 + square: x 2
                                              - sqrt(A)  + sqrt(A)   - square root: x ½ + square root: √x
                                              + tgamma(A) + +   + + gamma function   (only for float and double elements) +
                                              lgamma(A)   - natural log of the gamma function   (only for float and double elements) + natural log of the absolute value of gamma function   (only for float and double elements)
                                            • - +
                                              +
                                            • +Caveats: +
                                                +
                                              • all of the above functions are applied element-wise, where each element is treated independently
                                              • +
                                              • +the element-wise functions exp(), log(), sqrt() and pow() +have the corresponding functions expmat(), logmat(), sqrtmat() and powmat() which take into account matrix structure +

                                            • @@ -11548,7 +12064,7 @@ Examples:
                                                -mat A = randu<mat>(5,5);
                                                +mat A(5, 5, fill::randu);
                                                 mat B = exp(A);
                                                 
                                              @@ -11565,6 +12081,7 @@
                                            • expmat()
                                            • logmat()
                                            • sqrtmat()
                                            • +
                                            • powmat()
                                            • trigonometric functions
                                            • statistics functions
                                            • miscellaneous constants
                                            • @@ -11590,7 +12107,7 @@ tan, atan, tanh, atanh
                                            • -sinc, defined as sinc(x) = sin(πx) / (πx) for x ≠ 0, and sinc(x) = 1 for x = 0 +sinc, defined as sinc(x) = sin(πx) / (πx) for x ≠ 0, and sinc(x) = 1 for x = 0
                                            @@ -11607,7 +12124,7 @@ Examples:
                                              -mat X = randu<mat>(5,5);
                                              +mat X(5, 5, fill::randu);
                                               mat Y = cos(X);
                                               
                                            @@ -11640,32 +12157,54 @@


                                            -R = chol( X ) -
                                            R = chol( X, layout ) -
                                            -
                                            chol( R, X ) -
                                            chol( R, X, layout ) + + + + + + + + + +
                                            R = chol( X )   (form 1)
                                            R = chol( X, layout )   (form 2)
                                               
                                            chol( R, X )   (form 3)
                                            chol( R, X, layout )   (form 4)
                                               
                                            chol( R, P, X, layout, "vector" )   (form 5)
                                            chol( R, P, X, layout, "matrix" )   (form 6)
                                            • -Cholesky decomposition of matrix X +Cholesky decomposition of symmetric/hermitian matrix X into triangular matrix R, with an optional permutation vector/matrix P

                                            • -Matrix X must be symmetric/hermitian and positive-definite +By default, R is upper triangular

                                            • -By default, R is upper triangular, such that R.t()*R = X +The optional argument layout is either "upper" or "lower", which specifies whether R is upper or lower triangular

                                            • -The argument layout is optional; layout is either "upper" or "lower", which specifies whether R is upper or lower triangular +Forms 1 to 4 require X to be positive definite +
                                            • +
                                              +
                                            • +Forms 5 to 6 require X to be positive semi-definite; these forms use pivoted decomposition and provide a permutation vector/matrix P with type uvec or umat +
                                            • +
                                              +
                                            • +The decomposition has the following form: +
                                                +
                                              • forms 1 and 3: X = R.t() * R
                                              • +
                                              • forms 2 and 4 with layout = "upper": X = R.t() * R
                                              • +
                                              • forms 2 and 4 with layout = "lower": X = R * R.t()
                                              • +
                                              • form 5 with layout = "upper": X(P,P) = R.t() * R, where X(P,P) is a non-contiguous view of X
                                              • +
                                              • form 5 with layout = "lower": X(P,P) = R * R.t(), where X(P,P) is a non-contiguous view of X
                                              • +
                                              • form 6 with layout = "upper": X = P * R.t() * R * P.t()
                                              • +
                                              • form 6 with layout = "lower": X = P * R * R.t() * P.t()
                                              • +

                                            • If the decomposition fails:
                                                -
                                              • R = chol(X) resets R and throws a std::runtime_error exception
                                              • -
                                              • chol(R,X) resets R and returns a bool set to false (exception is not thrown)
                                              • +
                                              • the forms R = chol(X) and R = chol(X,layout) reset R and throw a std::runtime_error exception
                                              • +
                                              • the other forms reset R and P, and return a bool set to false (exception is not thrown)

                                            • @@ -11673,11 +12212,19 @@ Examples:
                                                -mat X = randu<mat>(5,5);
                                                -mat Y = X.t()*X;
                                                +mat A(5, 5, fill::randu);
                                                +mat X = A.t()*A;
                                                +
                                                +mat R1 = chol(X);
                                                +mat R2 = chol(X, "lower");
                                                +
                                                 
                                                -mat R1 = chol(Y);
                                                -mat R2 = chol(Y, "lower");
                                                + mat R;
                                                +uvec P_vec;
                                                +umat P_mat;
                                                +
                                                +chol(R, P_vec, X, "upper", "vector");
                                                +chol(R, P_mat, X, "lower", "matrix");
                                                 
                                              @@ -11689,8 +12236,9 @@
                                            • lu()
                                            • qr()
                                            • .is_sympd()
                                            • -
                                            • Cholesky decomposition in MathWorld
                                            • -
                                            • Cholesky decomposition in Wikipedia
                                            • +
                                            • Cholesky decomposition in MathWorld
                                            • +
                                            • Cholesky decomposition in Wikipedia
                                            • +
                                            • Definite matrix in Wikipedia

                                            @@ -11748,7 +12296,7 @@
                                             // for matrices with real elements
                                             
                                            -mat A = randu<mat>(50,50);
                                            +mat A(50, 50, fill::randu);
                                             mat B = A.t()*A;  // generate a symmetric matrix
                                             
                                             vec eigval;
                                            @@ -11759,7 +12307,7 @@
                                             
                                             // for matrices with complex elements
                                             
                                            -cx_mat C = randu<cx_mat>(50,50);
                                            +cx_mat C(50, 50, fill::randu);
                                             cx_mat D = C.t()*C;
                                             
                                                vec eigval2;
                                            @@ -11799,10 +12347,15 @@
                                             

                                            eig_gen( eigval, eigvec, X )
                                            eig_gen( eigval, eigvec, X, bal ) +
                                            +
                                            eig_gen( eigval, leigvec, reigvec, X ) +
                                            eig_gen( eigval, leigvec, reigvec, X, bal )
                                            • Eigen decomposition of dense general (non-symmetric/non-hermitian) square matrix X

                                            • -
                                            • The eigenvalues and corresponding eigenvectors are stored in eigval and eigvec, respectively
                                            • +
                                            • The eigenvalues and corresponding right eigenvectors are stored in eigval and eigvec, respectively
                                            • +
                                              +
                                            • If both left and right eigenvectors are requested they are stored in leigvec and reigvec, respectively

                                            • The eigenvectors are stored as column vectors

                                            • @@ -11825,6 +12378,7 @@
                                            • eigval = eig_gen(X) resets eigval and throws a std::runtime_error exception
                                            • eig_gen(eigval,X) resets eigval and returns a bool set to false (exception is not thrown)
                                            • eig_gen(eigval,eigvec,X) resets eigval & eigvec and returns a bool set to false (exception is not thrown)
                                            • +
                                            • eig_gen(eigval,leigvec,reigvec,X) resets eigval, leigvec & reigvec and returns a bool set to false (exception is not thrown)

                                            @@ -11832,7 +12386,7 @@ Examples:
                                              -mat A = randu<mat>(10,10);
                                              +mat A(10, 10, fill::randu);
                                               
                                               cx_vec eigval;
                                               cx_mat eigvec;
                                              @@ -11866,13 +12420,17 @@
                                               
                                              eig_pair( eigval, A, B )

                                              eig_pair( eigval, eigvec, A, B ) +
                                              +
                                              eig_pair( eigval, leigvec, reigvec, A, B )
                                              • Eigen decomposition for pair of general dense square matrices A and B of the same size, -such that A*eigvec = B*eigvec*diagmat(eigval) +such that A*eigvec = B*eigvec*diagmat(eigval)

                                              • -
                                              • The eigenvalues and corresponding eigenvectors are stored in eigval and eigvec, respectively
                                              • +
                                              • The eigenvalues and corresponding right eigenvectors are stored in eigval and eigvec, respectively
                                              • +
                                                +
                                              • If both left and right eigenvectors are requested they are stored in leigvec and reigvec, respectively

                                              • The eigenvectors are stored as column vectors

                                              • @@ -11883,6 +12441,7 @@
                                              • eigval = eig_pair(A,B) resets eigval and throws a std::runtime_error exception
                                              • eig_pair(eigval,A,B) resets eigval and returns a bool set to false (exception is not thrown)
                                              • eig_pair(eigval,eigvec,A,B) resets eigval & eigvec and returns a bool set to false (exception is not thrown)
                                              • +
                                              • eig_pair(eigval,leigvec,reigvec,A,B) resets eigval, leigvec & reigvec and returns a bool set to false (exception is not thrown)

                                              @@ -11890,8 +12449,8 @@ Examples:
                                                -mat A = randu<mat>(10,10);
                                                -mat B = randu<mat>(10,10);
                                                +mat A(10, 10, fill::randu);
                                                +mat B(10, 10, fill::randu);
                                                 
                                                 cx_vec eigval;
                                                 cx_mat eigvec;
                                                @@ -11992,9 +12551,9 @@
                                                 Caveats:
                                                 
                                                • if matrix A is know to be symmetric positive definite, using inv_sympd() is faster
                                                • -
                                                • if matrix A is know to be diagonal, use inv( diagmat(A) )
                                                • -
                                                • if matrix A is know to be triangular, use inv( trimatu(A) ) or inv( trimatl(A) )
                                                • -
                                                • to solve a system of linear equations, such as Z = inv(X)*Y, using solve() can be faster and/or more accurate
                                                • +
                                                • if matrix A is know to be diagonal, use inv( diagmat(A) )
                                                • +
                                                • if matrix A is know to be triangular, use inv( trimatu(A) ) or inv( trimatl(A) )
                                                • +
                                                • to solve a system of linear equations, such as Z = inv(X)*Y, using solve() can be faster and/or more accurate

                                                @@ -12002,7 +12561,7 @@ Examples: @@ -12061,7 +12621,7 @@ Examples:
                                                  -mat A = randu<mat>(5,5);
                                                  +mat A(5, 5, fill::randu);
                                                   mat B = A.t() * A;
                                                   mat C = inv_sympd(B);
                                                   
                                                  @@ -12120,7 +12680,7 @@ Examples:
                                                    -mat A = randu<mat>(5,5);
                                                    +mat A(5, 5, fill::randu);
                                                     
                                                     mat L, U, P;
                                                     
                                                    @@ -12159,10 +12719,10 @@
                                                     
                                                     
                                                  • -The tolerance argument is optional; by default tolerance is max(m,n)*max_sv*datum::eps, where: +The tolerance argument is optional; by default tolerance is max(m,n) · max_sv · datum::eps, where:
                                                    • m = number of rows and n = number of columns in A
                                                    • -
                                                    • max_sv = maximal singular value of A
                                                    • +
                                                    • max_sv = maximum singular value of A
                                                    • datum::eps = difference between 1 and the least value greater than 1 that is representable
                                                  • @@ -12179,7 +12739,7 @@ Examples:
                                                      -mat A = randu<mat>(5,6);
                                                      +mat A(5, 6, fill::randu);
                                                       
                                                       A.row(0).zeros();
                                                       A.col(0).zeros();
                                                      @@ -12213,7 +12773,7 @@
                                                       
                                                      • Find the orthonormal basis of the range space of matrix A, -so that B.t()*B ≈ eye(r,r), where r = rank(A) +so that B.t()*B ≈ eye(r,r), where r = rank(A)

                                                      • @@ -12221,10 +12781,10 @@

                                                      • -The tolerance argument is optional; by default tolerance is max(m,n)*max_sv*datum::eps, where: +The tolerance argument is optional; by default tolerance is max(m,n) · max_sv · datum::eps, where:
                                                        • m = number of rows and n = number of columns in A
                                                        • -
                                                        • max_sv = maximal singular value of A
                                                        • +
                                                        • max_sv = maximum singular value of A
                                                        • datum::eps = difference between 1 and the least value greater than 1 that is representable
                                                      • @@ -12241,7 +12801,7 @@ Examples:
                                                          -mat A = randu<mat>(5,6);
                                                          +mat A(5, 6, fill::randu);
                                                           
                                                           mat B = orth(A);
                                                           
                                                          @@ -12272,7 +12832,7 @@
                                                          pinv( B, A, tolerance )
                                                          pinv( B, A, tolerance, method )
                                                            -
                                                          • Moore-Penrose pseudo-inverse of matrix A
                                                          • +
                                                          • Moore-Penrose pseudo-inverse (generalised inverse) of matrix A

                                                          • The computation is based on singular value decomposition @@ -12280,10 +12840,10 @@
                                                          • The tolerance argument is optional

                                                          • -
                                                          • The default tolerance is max(m,n)*max_sv*datum::eps, where: +
                                                          • The default tolerance is max(m,n) · max_sv · datum::eps, where:
                                                            • m = number of rows and n = number of columns in A
                                                            • -
                                                            • max_sv = maximal singular value of A
                                                            • +
                                                            • max_sv = maximum singular value of A
                                                            • datum::eps = difference between 1 and the least value greater than 1 that is representable
                                                          • @@ -12313,10 +12873,15 @@
                                                          • +Caveat: to find approximate solutions (eg. minimum norm, least squares) to underdetermined, overdetermined, or rank deficient systems of linear equations, +using solve() can be considerably faster and/or more accurate +
                                                          • +
                                                            +
                                                          • Examples:

                                                          • @@ -12343,24 +12908,47 @@


                                                            -qr( Q, R, X ) + + + + +
                                                            qr( Q, R, X )   (form 1)
                                                            qr( Q, R, P, X, "vector" )   (form 2)
                                                            qr( Q, R, P, X, "matrix" )   (form 3)
                                                            • -Decomposition of X into an orthogonal matrix Q and a right triangular matrix R, such that Q*R = X +Decomposition of X into an orthogonal matrix Q and a right triangular matrix R, +with an optional permutation matrix/vector P +
                                                                +
                                                              • form 1: decomposition has the form Q*R = X
                                                              • +
                                                              • form 2: P is permutation vector with type uvec; decomposition has the form Q*R = X.cols(P)
                                                              • +
                                                              • form 3: P is permutation matrix with type umat; decomposition has the form Q*R = X*P
                                                              • +

                                                            • -If the decomposition fails, Q and R are reset and the function returns a bool set to false (exception is not thrown) +If P is specified, a column pivoting decomposition is used; +the diagonal entries of R are ordered from largest to smallest magnitude +
                                                            • +
                                                              +
                                                            • +If the decomposition fails, Q, R and P are reset and the function returns a bool set to false (exception is not thrown)

                                                            • Examples:
                                                                -mat X = randu<mat>(5,5);
                                                                -mat Q, R;
                                                                +mat X(5, 5, fill::randu);
                                                                +
                                                                +mat Q;
                                                                +mat R;
                                                                +
                                                                +qr(Q, R, X);
                                                                 
                                                                -qr(Q,R,X);
                                                                +uvec P_vec;
                                                                +umat P_mat;
                                                                +
                                                                +qr(Q, R, P_vec, X, "vector");
                                                                +qr(Q, R, P_mat, X, "matrix");
                                                                 
                                                            • @@ -12400,10 +12988,12 @@ Examples:
                                                                -mat X = randu<mat>(6,5);
                                                                -mat Q, R;
                                                                +mat X(6, 5, fill::randu);
                                                                +
                                                                +mat Q;
                                                                +mat R;
                                                                 
                                                                -qr_econ(Q,R,X);
                                                                +qr_econ(Q, R, X);
                                                                 
                                                              @@ -12428,7 +13018,7 @@
                                                              • Generalised Schur decomposition for pair of general square matrices A and B of the same size, -
                                                                such that A = Q.t()*AA*Z.t() and B = Q.t()*BB*Z.t() +
                                                                such that A = Q.t()*AA*Z.t() and B = Q.t()*BB*Z.t()

                                                              • The select argument is optional and specifies the ordering of the top left of the Schur form; it is one of the following: @@ -12458,8 +13048,8 @@ Examples:
                                                                  -mat A = randu<mat>(10,10);
                                                                  -mat B = randu<mat>(10,10);
                                                                  +mat A(10, 10, fill::randu);
                                                                  +mat B(10, 10, fill::randu);
                                                                   
                                                                   mat AA;
                                                                   mat BB;
                                                                  @@ -12547,28 +13137,30 @@
                                                                   
                                                                  solve( X, A, B, settings )
                                                                  • Solve a dense system of linear equations, A*X = B, where X is unknown; -similar functionality to the \ operator in Matlab/Octave, ie. X = A \ B +similar functionality to the \ operator in Matlab/Octave, ie. X = A \ B

                                                                  • -
                                                                  • -By default, matrix A is analysed to automatically determine whether it is a general matrix, band matrix, diagonal matrix, or symmetric/hermitian positive definite (SPD) matrix; -based on the detected matrix structure, a specialised solver is used for faster execution +
                                                                  • A can be square sized (critically determined system), or non-square (under/over-determined system); A can be rank deficient

                                                                  • -If A is known to be a triangular matrix, -the solution can be computed faster by explicitly indicating that A is triangular through trimatu() or trimatl(); see examples below +B can be a vector or matrix

                                                                  • -
                                                                  • A can be square (critically determined system), or non-square (under/over-determined system) +
                                                                  • +The number of rows in A and B must be the same

                                                                  • -B can be a vector or matrix +By default, matrix A is analysed to automatically determine whether it is a general matrix, band matrix, diagonal matrix, or symmetric/hermitian positive definite (SPD) matrix; +based on the detected matrix structure, a specialised solver is used for faster execution; +if no solution is found, an approximate solver is automatically used as a fallback; +see the associated paper for more details

                                                                  • -The number of rows in A and B must be the same +If A is known to be a triangular matrix, +the solution can be computed faster by explicitly indicating that A is triangular through trimatu() or trimatl(); see examples below

                                                                  • The settings argument is optional; it is one of the following, or a combination thereof: @@ -12585,6 +13177,7 @@ solve_opts::no_band   do not use specialised solver for band matrices or diagonal matrices solve_opts::no_trimat   do not use specialised solver for triangular matrices solve_opts::no_sympd   do not use specialised solver for symmetric/hermitian positive definite matrices +solve_opts::force_approx   skip the standard solver and directly use of the approximate solver
                                                                    @@ -12592,11 +13185,19 @@

                                                                  • -Caveat: using solve_opts::fast will speed up finding the solution, but for poorly conditioned systems the solution may have lower quality +If a rank deficient system is detected and the solve_opts::no_approx option is not enabled, a warning is emitted and an approximate solution is attempted; +
                                                                    in Armadillo 10.4 and later versions, this warning can be disabled by setting ARMA_WARN_LEVEL to 1 before including the armadillo header: +
                                                                    #define ARMA_WARN_LEVEL 1 +
                                                                    #include <armadillo>

                                                                  • -Caveat: not all SPD matrices are automatically detected; to skip the analysis step and directly indicate that matrix A is likely SPD, use solve_opts::likely_sympd +Caveats: +
                                                                      +
                                                                    • using solve_opts::fast will speed up finding the solution, but for poorly conditioned systems the solution may have lower quality
                                                                    • +
                                                                    • not all SPD matrices are automatically detected; to skip the analysis step and directly indicate that matrix A is likely SPD, use solve_opts::likely_sympd
                                                                    • +
                                                                    • using solve_opts::force_approx is only advised if the system is known to be rank deficient; the approximate solver is considerably slower
                                                                    • +

                                                                  • @@ -12608,12 +13209,22 @@

                                                                  • +Implementation details are available in the following paper: +
                                                                    + +
                                                                  • +
                                                                    +
                                                                  • Examples:
                                                                      -mat A = randu<mat>(5,5);
                                                                      -vec b = randu<vec>(5);
                                                                      -mat B = randu<mat>(5,5);
                                                                      +mat A(5, 5, fill::randu);
                                                                      +vec b(5,    fill::randu);
                                                                      +mat B(5, 5, fill::randu);
                                                                       
                                                                       vec x1 = solve(A, b);
                                                                       
                                                                      @@ -12637,7 +13248,7 @@
                                                                       
                                                                    • rcond()
                                                                    • roots()
                                                                    • syl()
                                                                    • -
                                                                    • spsolve()
                                                                    • +
                                                                    • spsolve() - solve sparse system of linear equations
                                                                    • linear system of equations in MathWorld
                                                                    • system of linear equations in Wikipedia
                                                                    • band matrix in Wikipedia
                                                                    • @@ -12700,7 +13311,7 @@ Examples:
                                                                        -mat X = randu<mat>(5,5);
                                                                        +mat X(5, 5, fill::randu);
                                                                         
                                                                         mat U;
                                                                         vec s;
                                                                        @@ -12780,7 +13391,7 @@
                                                                         Examples:
                                                                         
                                                                          -mat X = randu<mat>(4,5);
                                                                          +mat X(4, 5, fill::randu);
                                                                           
                                                                           mat U;
                                                                           vec s;
                                                                          @@ -12827,9 +13438,9 @@
                                                                           Examples:
                                                                           
                                                                            -mat A = randu<mat>(5,5);
                                                                            -mat B = randu<mat>(5,5);
                                                                            -mat C = randu<mat>(5,5);
                                                                            +mat A(5, 5, fill::randu);
                                                                            +mat B(5, 5, fill::randu);
                                                                            +mat C(5, 5, fill::randu);
                                                                             
                                                                             mat X1 = syl(A, B, C);
                                                                             
                                                                            @@ -12866,15 +13477,21 @@
                                                                             
                                                                             vec eigval = eigs_sym( X, k )
                                                                             
                                                                            vec eigval = eigs_sym( X, k, form ) -
                                                                            vec eigval = eigs_sym( X, k, form, tol ) +
                                                                            vec eigval = eigs_sym( X, k, form, opts ) +
                                                                            vec eigval = eigs_sym( X, k, sigma ) +
                                                                            vec eigval = eigs_sym( X, k, sigma, opts )

                                                                            eigs_sym( eigval, X, k )
                                                                            eigs_sym( eigval, X, k, form ) -
                                                                            eigs_sym( eigval, X, k, form, tol ) +
                                                                            eigs_sym( eigval, X, k, form, opts ) +
                                                                            eigs_sym( eigval, X, k, sigma ) +
                                                                            eigs_sym( eigval, X, k, sigma, opts )

                                                                            eigs_sym( eigval, eigvec, X, k )
                                                                            eigs_sym( eigval, eigvec, X, k, form ) -
                                                                            eigs_sym( eigval, eigvec, X, k, form, tol ) +
                                                                            eigs_sym( eigval, eigvec, X, k, form, opts ) +
                                                                            eigs_sym( eigval, eigvec, X, k, sigma ) +
                                                                            eigs_sym( eigval, eigvec, X, k, sigma, opts )
                                                                            • Obtain a limited number of eigenvalues and eigenvectors of sparse symmetric real matrix X

                                                                            • @@ -12887,7 +13504,7 @@ - + @@ -12895,8 +13512,27 @@
                                                                              +
                                                                            • The argument sigma is optional; if sigma is given, eigenvalues closest to sigma are found via shift-invert mode +
                                                                              NOTE: to use sigma, both ARMA_USE_ARPACK and ARMA_USE_SUPERLU must be enabled in config.hpp +
                                                                            • +
                                                                            • -The argument tol is optional; it specifies the tolerance for convergence +The opts argument is optional; opts is an instance of the eigs_opts structure: +
                                                                                +
                                                                                +struct eigs_opts
                                                                                +  {
                                                                                +  double       tol;     // default: 0
                                                                                +  unsigned int maxiter; // default: 1000
                                                                                +  unsigned int subdim;  // default: max(2*k+1, 20)
                                                                                +  };
                                                                                +
                                                                                +
                                                                              +
                                                                                +
                                                                              • tol specifies the tolerance for convergence
                                                                              • +
                                                                              • maxiter specifies the maximum number of Arnoldi iterations
                                                                              • +
                                                                              • subdim specifies the dimension of the Krylov subspace, with the constraint k < subdim ≤ X.n_rows; recommended value is subdim ≥ 2*k
                                                                              • +

                                                                            • The eigenvalues and corresponding eigenvectors are stored in eigval and eigvec, respectively
                                                                            • @@ -12915,9 +13551,11 @@
                                                                              • the number of obtained eigenvalues/eigenvectors may be lower than requested, depending on the given data
                                                                              • -it's more difficult to compute the smallest eigenvalues than the largest eigenvalues; -
                                                                                if the decomposition fails, try increasing k (number of eigenvalues) and/or the tolerance +if the decomposition fails, try first increasing opts.subdim (Krylov subspace dimension), +and, as secondary options, try increasing opts.maxiter (maximum number of iterations), +and/or opts.tol (tolerance for convergence), and/or k (number of eigenvalues)
                                                                              • +
                                                                              • for an alternative to the "sm" form, use the shift-invert mode with sigma set to 0.0

                                                                              @@ -12933,6 +13571,11 @@ mat eigvec; eigs_sym(eigval, eigvec, B, 5); // find 5 eigenvalues/eigenvectors + +eigs_opts opts; +opts.maxiter = 10000; // increase max iterations to 10000 + +eigs_sym(eigval, eigvec, B, 5, "lm", opts); @@ -12944,6 +13587,7 @@
                                                                            • eig_sym()
                                                                            • svds()
                                                                            • .is_symmetric()
                                                                            • +
                                                                            • shift-invert mode in ARPACK
                                                                            • eigen decomposition in MathWorld
                                                                            • eigenvalues & eigenvectors in Wikipedia
                                                                            • @@ -12955,15 +13599,21 @@ cx_vec eigval = eigs_gen( X, k )
                                                                              cx_vec eigval = eigs_gen( X, k, form ) -
                                                                              cx_vec eigval = eigs_gen( X, k, form, tol ) +
                                                                              cx_vec eigval = eigs_gen( X, k, sigma ) +
                                                                              cx_vec eigval = eigs_gen( X, k, form, opts ) +
                                                                              cx_vec eigval = eigs_gen( X, k, sigma, opts )

                                                                              eigs_gen( eigval, X, k )
                                                                              eigs_gen( eigval, X, k, form ) -
                                                                              eigs_gen( eigval, X, k, form, tol ) +
                                                                              eigs_gen( eigval, X, k, sigma ) +
                                                                              eigs_gen( eigval, X, k, form, opts ) +
                                                                              eigs_gen( eigval, X, k, sigma, opts )

                                                                              eigs_gen( eigval, eigvec, X, k )
                                                                              eigs_gen( eigval, eigvec, X, k, form ) -
                                                                              eigs_gen( eigval, eigvec, X, k, form, tol ) +
                                                                              eigs_gen( eigval, eigvec, X, k, sigma ) +
                                                                              eigs_gen( eigval, eigvec, X, k, form, opts ) +
                                                                              eigs_gen( eigval, eigvec, X, k, sigma, opts )
                                                                              • Obtain a limited number of eigenvalues and eigenvectors of sparse general (non-symmetric/non-hermitian) square matrix X @@ -12978,7 +13628,7 @@
                                                                              "lm" = obtain eigenvalues with largest magnitude (default operation)
                                                                              "sm" = obtain eigenvalues with smallest magnitude (see caveat below)
                                                                              "sm" = obtain eigenvalues with smallest magnitude (see the caveats below)
                                                                              "la" = obtain eigenvalues with largest algebraic value
                                                                              "sa" = obtain eigenvalues with smallest algebraic value
                                                                              - + @@ -12988,8 +13638,27 @@
                                                                              +
                                                                            • The argument sigma is optional; if sigma is given, eigenvalues closest to sigma are found via shift-invert mode +
                                                                              NOTE: to use sigma, both ARMA_USE_ARPACK and ARMA_USE_SUPERLU must be enabled in config.hpp +
                                                                            • +
                                                                            • -The argument tol is optional; it specifies the tolerance for convergence +The opts argument is optional; opts is an instance of the eigs_opts structure: +
                                                                                +
                                                                                +struct eigs_opts
                                                                                +  {
                                                                                +  double       tol;     // default: 0
                                                                                +  unsigned int maxiter; // default: 1000
                                                                                +  unsigned int subdim;  // default: max(2*k+1, 20)
                                                                                +  };
                                                                                +
                                                                                +
                                                                              +
                                                                                +
                                                                              • tol specifies the tolerance for convergence
                                                                              • +
                                                                              • maxiter specifies the maximum number of Arnoldi iterations
                                                                              • +
                                                                              • subdim specifies the dimension of the Krylov subspace, with the constraint k + 2 < subdim ≤ X.n_rows; recommended value is subdim ≥ 2*k + 1
                                                                              • +

                                                                            • @@ -13012,10 +13681,13 @@
                                                                              • the number of obtained eigenvalues/eigenvectors may be lower than requested, depending on the given data
                                                                              • -it's more difficult to compute the smallest eigenvalues than the largest eigenvalues; -
                                                                                if the decomposition fails, try increasing k (number of eigenvalues) and/or the tolerance +if the decomposition fails, try first increasing opts.subdim (Krylov subspace dimension) +and, as secondary options, try increasing opts.maxiter (maximum number of iterations), +and/or opts.tol (tolerance for convergence), and/or k (number of eigenvalues)
                                                                              • +
                                                                              • for an alternative to the "sm" form, use the shift-invert mode with sigma set to 0.0
                                                                              +

                                                                            • Examples: @@ -13028,6 +13700,11 @@ cx_mat eigvec; eigs_gen(eigval, eigvec, A, 5); // find 5 eigenvalues/eigenvectors + +eigs_opts opts; +opts.maxiter = 10000; // increase max iterations to 10000 + +eigs_gen(eigval, eigvec, A, 5, "lm", opts);
                                                                            • @@ -13038,6 +13715,7 @@
                                                                            • eigs_sym()
                                                                            • eig_gen()
                                                                            • svds()
                                                                            • +
                                                                            • shift-invert mode in ARPACK
                                                                            • eigen decomposition in MathWorld
                                                                            • eigenvalues & eigenvectors in Wikipedia
                                                                            • @@ -13088,7 +13766,7 @@ Notes:
                                                                              • The SuperLU solver is mainly useful for very large and/or very sparse matrices
                                                                              • -
                                                                              • If you have sufficient amount of memory to store a dense version of matrix A, the LAPACK solver can be faster
                                                                              • +
                                                                              • If there is sufficient amount of memory to store a dense version of matrix A, the LAPACK solver can be faster

                                                                              @@ -13159,8 +13837,8 @@
                                                                               sp_mat A = sprandu<sp_mat>(1000, 1000, 0.1);
                                                                               
                                                                              -vec b = randu<vec>(1000);
                                                                              -mat B = randu<mat>(1000, 5);
                                                                              +vec b(1000,    fill::randu);
                                                                              +mat B(1000, 5, fill::randu);
                                                                               
                                                                               vec x = spsolve(A, b);  // solve one system
                                                                               mat X = spsolve(A, B);  // solve several systems
                                                                              @@ -13184,8 +13862,9 @@
                                                                               
                                                                            • See also: @@ -13233,7 +13912,7 @@
                                                                            • The argument tol is optional; it specifies the tolerance for convergence; -it is passed as (tol ÷ √2) to eigs_sym() +it is passed as (tol ÷ √2) to eigs_sym()

                                                                            • @@ -13318,7 +13997,7 @@
                                                                            • "lm" = obtain eigenvalues with largest magnitude (default operation)
                                                                              "sm" = obtain eigenvalues with smallest magnitude (see caveat below)
                                                                              "sm" = obtain eigenvalues with smallest magnitude (see the caveats below)
                                                                              "lr" = obtain eigenvalues with largest real part
                                                                              "sr" = obtain eigenvalues with smallest real part
                                                                              "li" = obtain eigenvalues with largest imaginary part
                                                                              - +
                                                                              "full" = return the full convolution (default setting), with the size equal to A.n_elem + B.n_elem - 1
                                                                              "full" = return the full convolution (default setting), with the size equal to A.n_elem + B.n_elem - 1
                                                                              "same" = return the central part of the convolution, with the same size as vector A
                                                                              @@ -13375,7 +14054,7 @@
                                                                                - +
                                                                                "full" = return the full convolution (default setting), with the size equal to size(A) + size(B) - 1
                                                                                "full" = return the full convolution (default setting), with the size equal to size(A) + size(B) - 1
                                                                                "same" = return the central part of the convolution, with the same size as matrix A
                                                                                @@ -13448,7 +14127,8 @@ Examples:
                                                                                  -   vec X = randu<vec>(100);
                                                                                  +   vec X(100, fill::randu);
                                                                                  +   
                                                                                   cx_vec Y = fft(X, 128);
                                                                                   
                                                                                @@ -13492,7 +14172,8 @@ Examples:
                                                                                  -   mat A = randu<mat>(100,100);
                                                                                  +   mat A(100, 100, fill::randu);
                                                                                  +   
                                                                                   cx_mat B = fft2(A);
                                                                                   cx_mat C = fft2(A, 128, 128);
                                                                                   
                                                                                  @@ -13601,9 +14282,9 @@
                                                                                • -The vector pairs (X, Y) and (XI, YI) define 2D coordinates in a grid; +The vector pairs (X, Y) and (XI, YI) define 2D coordinates in a grid;
                                                                                  for example, X defines the horizontal coordinates and Y defines the corresponding vertical coordinates, -
                                                                                  so that ( X(m)Y(n) ) is the 2D coordinate of element Z(n,m) +
                                                                                  so that ( X(m), Y(n) ) is the 2D coordinate of element Z(n,m)

                                                                                • @@ -13631,7 +14312,7 @@

                                                                                • -If a coordinate in the 2D grid specified by (XI, YI) is outside the domain of the 2D grid specified by (X, Y), +If a coordinate in the 2D grid specified by (XI, YI) is outside the domain of the 2D grid specified by (X, Y),
                                                                                  the corresponding value in ZI is set to extrapolation_value

                                                                                • @@ -13916,26 +14597,26 @@
                                                                                • -For matrix M, find the statistic for each column (dim=0), or each row (dim=1) +For matrix M, find the statistic for each column (dim = 0), or each row (dim = 1)

                                                                                • -For cube Q, find the statistics of elements along dimension dim, where dim ∈ { 0, 1, 2 } +For cube Q, find the statistics of elements along dimension dim, where dim ∈ { 0, 1, 2 }

                                                                                • -The dim argument is optional; by default dim=0 is used +The dim argument is optional; by default dim = 0 is used

                                                                                • -The norm_type argument is optional; by default norm_type=0 is used +The norm_type argument is optional; by default norm_type = 0 is used

                                                                                • For the var() and stddev() functions:
                                                                                    -
                                                                                  • the default norm_type=0 performs normalisation using N-1 (where N is the number of samples), providing the best unbiased estimator
                                                                                  • -
                                                                                  • using norm_type=1 performs normalisation using N, which provides the second moment around the mean
                                                                                  • +
                                                                                  • the default norm_type = 0 performs normalisation using N-1 (where N is the number of samples), providing the best unbiased estimator
                                                                                  • +
                                                                                  • using norm_type = 1 performs normalisation using N, which provides the second moment around the mean

                                                                                • @@ -13949,12 +14630,13 @@ Examples:
                                                                                    -mat A    = randu<mat>(5,5);
                                                                                    +mat A(5, 5, fill::randu);
                                                                                    +
                                                                                     mat B    = mean(A);
                                                                                     mat C    = var(A);
                                                                                     double m = mean(mean(A));
                                                                                     
                                                                                    -vec    v = randu<vec>(5);
                                                                                    +vec v(5, fill::randu);
                                                                                     double x = var(v);
                                                                                     
                                                                                  @@ -13968,10 +14650,11 @@
                                                                                • diff()
                                                                                • hist()
                                                                                • histc()
                                                                                • +
                                                                                • quantile()
                                                                                • min() & max()
                                                                                • running_stat - class for running statistics of scalars
                                                                                • running_stat_vec - class for running statistics of vectors
                                                                                • -
                                                                                • gmm_diag & gmm_full - model and evaluate data using Gaussian Mixture Models (GMMs)
                                                                                • +
                                                                                • gmm_diag / gmm_full - model and evaluate data using Gaussian Mixture Models (GMMs)
                                                                                • kmeans()
                                                                                @@ -14009,17 +14692,17 @@
                                                                              • -The default norm_type=0 performs normalisation using N-1 (where N is the number of observations), +The default norm_type = 0 performs normalisation using N-1 (where N is the number of observations), providing the best unbiased estimation of the covariance matrix (if the observations are from a normal distribution). -Using norm_type=1 causes normalisation to be done using N, which provides the second moment matrix of the observations about their mean +Using norm_type = 1 causes normalisation to be done using N, which provides the second moment matrix of the observations about their mean

                                                                              • Examples:
                                                                                  -mat X = randu<mat>(4,5);
                                                                                  -mat Y = randu<mat>(4,5);
                                                                                  +mat X(4, 5, fill::randu);
                                                                                  +mat Y(4, 5, fill::randu);
                                                                                   
                                                                                   mat C = cov(X,Y);
                                                                                   mat D = cov(X,Y, 1);
                                                                                  @@ -14070,16 +14753,16 @@
                                                                                   
                                                                                   
                                                                                • -The default norm_type=0 performs normalisation of the correlation matrix using N-1 (where N is the number of observations). -Using norm_type=1 causes normalisation to be done using N +The default norm_type = 0 performs normalisation of the correlation matrix using N-1 (where N is the number of observations). +Using norm_type = 1 causes normalisation to be done using N

                                                                                • Examples:
                                                                                    -mat X = randu<mat>(4,5);
                                                                                    -mat Y = randu<mat>(4,5);
                                                                                    +mat X(4, 5, fill::randu);
                                                                                    +mat Y(4, 5, fill::randu);
                                                                                     
                                                                                     mat R = cor(X,Y);
                                                                                     mat S = cor(X,Y, 1);
                                                                                    @@ -14119,9 +14802,9 @@
                                                                                     
                                                                                  • For matrix X, produce a umat matrix containing either -column histogram counts (for dim=0, default), +column histogram counts (for dim = 0, default), or -row histogram counts (for dim=1) +row histogram counts (for dim = 1)

                                                                                  • @@ -14138,7 +14821,7 @@ Examples:
                                                                                      -vec  v  = randn<vec>(1000); // Gaussian distribution
                                                                                      + vec v(1000, fill::randn); // Gaussian distribution
                                                                                       
                                                                                       uvec h1 = hist(v, 11);
                                                                                       uvec h2 = hist(v, linspace<vec>(-2,2,11));
                                                                                      @@ -14149,6 +14832,7 @@
                                                                                       
                                                                                    • See also: @@ -14171,9 +14855,9 @@
                                                                                    • For matrix X, produce a umat matrix containing either -column histogram counts (for dim=0, default), +column histogram counts (for dim = 0, default), or -row histogram counts (for dim=1) +row histogram counts (for dim = 1)

                                                                                    • @@ -14184,7 +14868,7 @@ Examples:
                                                                                        -vec  v = randn<vec>(1000);  // Gaussian distribution
                                                                                        + vec v(1000, fill::randn);  // Gaussian distribution
                                                                                         
                                                                                         uvec h = histc(v, linspace<vec>(-2,2,11));
                                                                                         
                                                                                        @@ -14202,6 +14886,66 @@


                                                                                      + +quantile( V, P ) +
                                                                                      quantile( X, P ) +
                                                                                      quantile( X, P, dim ) +
                                                                                        +
                                                                                      • +For a dataset stored in vector V or matrix X, +calculate the quantiles corresponding to the cumulative probability values in the given P vector +
                                                                                      • +
                                                                                        +
                                                                                      • +For vector V, produce a vector with the same orientation as V and the same length as P +
                                                                                      • +
                                                                                        +
                                                                                      • +For matrix X, produce a matrix with the quantiles for each column vector (dim = 0) or each row vector (dim = 1) +
                                                                                      • +
                                                                                        +
                                                                                      • +The dim argument is optional; by default dim = 0 +
                                                                                      • +
                                                                                        +
                                                                                      • +The P vector must contain values in the [0,1] interval (eg. 0.00, 0.25, 0.50, 0.75, 1.00) +
                                                                                      • +
                                                                                        +
                                                                                      • +The algorithm for calculating the quantiles is based on Definition 5 in: +
                                                                                        +Rob J. Hyndman and Yanan Fan. +Sample Quantiles in Statistical Packages. +The American Statistician, Vol. 50, No. 4, pp. 361-365, 1996. +http://doi.org/10.2307/2684934 +
                                                                                      • +
                                                                                        +
                                                                                      • +Examples: +
                                                                                          +
                                                                                          +vec V(1000, fill::randn);  // Gaussian distribution
                                                                                          +
                                                                                          +vec P = { 0.25, 0.50, 0.75 };
                                                                                          +
                                                                                          +vec Q = quantile(V, P);
                                                                                          +
                                                                                          +
                                                                                        +
                                                                                      • +
                                                                                        +
                                                                                      • See also: + +
                                                                                      • +
                                                                                        +
                                                                                      + +


                                                                                      mat coeff = princomp( mat X )
                                                                                      cx_mat coeff = princomp( cx_mat X )
                                                                                      @@ -14244,7 +14988,7 @@ Examples:
                                                                                        -mat A = randu<mat>(5,4);
                                                                                        +mat A(5, 4, fill::randu);
                                                                                         
                                                                                         mat coeff;
                                                                                         mat score;
                                                                                        @@ -14270,8 +15014,8 @@
                                                                                         
                                                                                         


                                                                                        -normpdf(X) -
                                                                                        normpdf(X, M, S) +normpdf( X ) +
                                                                                        normpdf( X, M, S )
                                                                                        • For each scalar x in X, compute its probability density function according to a Gaussian (normal) distribution using the corresponding mean value m in M and the corresponding standard deviation value s in S: @@ -14303,6 +15047,10 @@
                                                                                        • If M and S are omitted, their values are assumed to be 0 and 1, respectively

                                                                                        • +Caveat: to reduce the incidence of numerical underflows, consider using log_normpdf() +
                                                                                        • +
                                                                                          +
                                                                                        • Examples: + +


                                                                                          + +log_normpdf( X ) +
                                                                                          log_normpdf( X, M, S ) +
                                                                                            +
                                                                                          • +For each scalar x in X, compute the logarithm version of probability density function according to a Gaussian (normal) distribution using the corresponding mean value m in M and the corresponding standard deviation value s in S: +
                                                                                            +
                                                                                            +
                                                                                              + + + + + + + + + + + + + +
                                                                                                   1  (x-m)2
                                                                                              y = log‒‒‒‒‒‒‒ exp−0.5 ‒‒‒‒‒‒ 
                                                                                                s √(2π)    s2
                                                                                              +
                                                                                              + + + + + + + + + + + + +
                                                                                                  (x-m)2
                                                                                                = −log(s √(2π)) + −0.5 ‒‒‒‒‒‒ 
                                                                                                    s2
                                                                                              +
                                                                                              +
                                                                                            +
                                                                                          • +
                                                                                            +
                                                                                          • X can be a scalar, vector, or matrix
                                                                                          • +
                                                                                            +
                                                                                          • M and S can jointly be either scalars, vectors, or matrices
                                                                                          • +
                                                                                            +
                                                                                          • If M and S are omitted, their values are assumed to be 0 and 1, respectively
                                                                                          • +
                                                                                            +
                                                                                          • +Examples: +
                                                                                              +
                                                                                              +vec X(10, fill::randu);
                                                                                              +vec M(10, fill::randu);
                                                                                              +vec S(10, fill::randu);
                                                                                              +
                                                                                              +   vec P1 = log_normpdf(X);
                                                                                              +   vec P2 = log_normpdf(X,    M,    S   );
                                                                                              +   vec P3 = log_normpdf(1.23, M,    S   );
                                                                                              +   vec P4 = log_normpdf(X,    4.56, 7.89);
                                                                                              +double P5 = log_normpdf(1.23, 4.56, 7.89);
                                                                                              +
                                                                                              +
                                                                                            +
                                                                                          • +
                                                                                            +
                                                                                          • +See also: +
                                                                                          • @@ -14333,8 +15158,8 @@


                                                                                            -normcdf(X) -
                                                                                            normcdf(X, M, S) +normcdf( X ) +
                                                                                            normcdf( X, M, S )
                                                                                            • For each scalar x in X, compute its cumulative distribution function according to a Gaussian (normal) distribution using the corresponding mean value m in M and the corresponding standard deviation value s in S @@ -14367,9 +15192,10 @@ See also:

                                                                                            • @@ -14377,12 +15203,12 @@


                                                                                              -X = mvnrnd(M, C) -
                                                                                              X = mvnrnd(M, C, N) +X = mvnrnd( M, C ) +
                                                                                              X = mvnrnd( M, C, N )

                                                                                              -mvnrnd(X, M, C) -
                                                                                              mvnrnd(X, M, C, N) +mvnrnd( X, M, C ) +
                                                                                              mvnrnd( X, M, C, N ) @@ -14501,14 +15327,14 @@


                                                                                              -W = wishrnd(S, df) +W = wishrnd( S, df )
                                                                                              -W = wishrnd(S, df, D) +W = wishrnd( S, df, D )

                                                                                              -wishrnd(W, S, df) +wishrnd( W, S, df )
                                                                                              -wishrnd(W, S, df, D) +wishrnd( W, S, df, D )
                                                                                              • Generate a random matrix sampled from the Wishart distribution with parameters S and df: @@ -14520,7 +15346,7 @@
                                                                                              • D is an optional argument; it specifies the Cholesky decomposition of S; if D is provided, S is ignored; -
                                                                                                using D is more efficient if you need to use wishrnd() many times for the same S matrix +
                                                                                                using D is more efficient if wishrnd() needs to be used many times for the same S matrix

                                                                                              • If generating the random matrix fails: @@ -14561,14 +15387,14 @@


                                                                                                -W = iwishrnd(T, df) +W = iwishrnd( T, df )
                                                                                                -W = iwishrnd(T, df, Dinv) +W = iwishrnd( T, df, Dinv )

                                                                                                -iwishrnd(W, T, df) +iwishrnd( W, T, df )
                                                                                                -iwishrnd(W, T, df, Dinv) +iwishrnd( W, T, df, Dinv )
                                                                                                • Generate a random matrix sampled from the inverse Wishart distribution with parameters T and df: @@ -14580,7 +15406,7 @@
                                                                                                • Dinv is an optional argument; it specifies the Cholesky decomposition of the inverse of T; if Dinv is provided, T is ignored -
                                                                                                  using Dinv is more efficient if you need to use iwishrnd() many times for the same T matrix +
                                                                                                  using Dinv is more efficient if iwishrnd() needs to be used many times for the same T matrix

                                                                                                • If generating the random matrix fails: @@ -14735,14 +15561,14 @@

                                                                                                • -The norm_type argument is optional; by default norm_type=0 is used +The norm_type argument is optional; by default norm_type = 0 is used

                                                                                                • -For the .var() and .stddev() functions, the default norm_type=0 performs normalisation using N-1 +For the .var() and .stddev() functions, the default norm_type = 0 performs normalisation using N-1 (where N is the number of samples so far), providing the best unbiased estimator; -using norm_type=1 causes normalisation to be done using N, which provides the second moment around the mean +using norm_type = 1 causes normalisation to be done using N, which provides the second moment around the mean

                                                                                                • @@ -14773,7 +15599,7 @@

                                                                                                • @@ -14919,14 +15745,14 @@
                                                                                                • -The norm_type argument is optional; by default norm_type=0 is used +The norm_type argument is optional; by default norm_type = 0 is used

                                                                                                • -For the .var() and .stddev() functions, the default norm_type=0 performs normalisation using N-1 +For the .var() and .stddev() functions, the default norm_type = 0 performs normalisation using N-1 (where N is the number of samples so far), providing the best unbiased estimator; -using norm_type=1 causes normalisation to be done using N, which provides the second moment around the mean +using norm_type = 1 causes normalisation to be done using N, which provides the second moment around the mean

                                                                                                • @@ -14983,7 +15809,7 @@
                                                                                                • statistics functions
                                                                                                • cov()
                                                                                                • cor()
                                                                                                • -
                                                                                                • gmm_diag - model and evaluate data using Gaussian Mixture Models (GMMs)
                                                                                                • +
                                                                                                • gmm_diag / gmm_full - model and evaluate data using Gaussian Mixture Models (GMMs)

                                                                                              • @@ -15069,7 +15895,7 @@
                                                                                              • See also:
                                                                                                  -
                                                                                                • gmm_diag - model and evaluate data using Gaussian Mixture Models (GMMs)
                                                                                                • +
                                                                                                • gmm_diag / gmm_full - model and evaluate data using Gaussian Mixture Models (GMMs)
                                                                                                • statistics functions
                                                                                                • running_stat_vec
                                                                                                • k-means clustering in Wikipedia
                                                                                                • @@ -15086,20 +15912,36 @@ gmm_diag
                                                                                                  gmm_full -
                                                                                                  -
                                                                                                  - - - - - + @@ -15120,11 +15962,11 @@
                                                                                                  -
                                                                                                  • Classes for multivariate data modelling and evaluation via Gaussian Mixture Models (GMMs)

                                                                                                  • -Can also be used for probabilistic clustering and vector quantisation (VQ) +The gmm_diag class is tailored for diagonal covariance matrices (ie. in each covariance matrix, all entries outside the main diagonal are assumed to be zero) +
                                                                                                  • +
                                                                                                    +
                                                                                                  • +The gmm_full class is tailored for full covariance matrices +
                                                                                                  • +
                                                                                                    +
                                                                                                  • +The gmm_diag class is typically much faster to train and use than the gmm_full class, +at the potential cost of some reduction in modelling accuracy +
                                                                                                  • +
                                                                                                    +
                                                                                                  • +The gmm_diag and gmm_full classes include dedicated optimisation algorithms for learning (training) the model parameters from data: +
                                                                                                      +
                                                                                                    • k-means clustering, for quick initial estimates
                                                                                                    • +
                                                                                                    • Expectation-Maximisation (EM), for maximum-likelihood estimates
                                                                                                    • +
                                                                                                    +
                                                                                                    +The optimisation algorithms are multi-threaded and can run much quicker on multi-core machines when OpenMP is enabled in your compiler (eg. -fopenmp in GCC and clang) +
                                                                                                  • +
                                                                                                    +
                                                                                                  • +The classes can also be used for probabilistic clustering and vector quantisation (VQ)

                                                                                                  • @@ -15111,7 +15953,7 @@
                                                                                                  p(x) = hg  N( x | mg Cg )hg  N(x|mg, Cg)
                                                                                                    g=0 
                                                                                                  where:
                                                                                                    -
                                                                                                  • n_gaus is the number of Gaussians
                                                                                                  • -
                                                                                                  • N( x | mg Cg ) represents a Gaussian (normal) distribution
                                                                                                  • +
                                                                                                  • n_gaus is the number of Gaussians; n_gaus ≥ 1
                                                                                                  • +
                                                                                                  • N(x|mg, Cg) represents a Gaussian (normal) distribution
                                                                                                  • each Gaussian g has the following parameters:
                                                                                                      -
                                                                                                    • hg is the heft (weight), with constraints hg ≥ 0 and ∑hg = 1
                                                                                                    • +
                                                                                                    • hg is the heft (weight), with constraints hg ≥ 0 and ∑hg = 1
                                                                                                    • mg is the mean vector (centroid) with dimensionality n_dims
                                                                                                    • Cg is the covariance matrix (either diagonal or full)
                                                                                                    @@ -15133,54 +15975,14 @@

                                                                                                  • -The gmm_diag class is tailored for diagonal covariance matrices (ie. in each covariance matrix, all entries outside the main diagonal are assumed to be zero) -
                                                                                                  • -
                                                                                                    -
                                                                                                  • -The gmm_full class is tailored for full covariance matrices -
                                                                                                  • -
                                                                                                    -
                                                                                                  • -The gmm_diag class is typically much faster to train and use than the gmm_full class, -at the potential cost of some reduction in modelling accuracy -
                                                                                                  • -
                                                                                                    -
                                                                                                  • -The gmm_diag and gmm_full classes include dedicated optimisation algorithms for learning (training) the model parameters from data: -
                                                                                                      -
                                                                                                    • k-means clustering, for quick initial estimates
                                                                                                    • -
                                                                                                    • Expectation-Maximisation (EM), for maximum-likelihood estimates
                                                                                                    • -
                                                                                                    -The optimisation algorithms are multi-threaded and run much quicker on multi-core machines when OpenMP is enabled in your compiler (eg. -fopenmp in GCC and clang) -
                                                                                                  • -
                                                                                                  - - - -  - - -
                                                                                                  - - - +Internal implementation details are available in the following paper: - - - - - - - -


                                                                                                  + -logging of warnings and errors +std::ostream& x = get_cout_stream() +
                                                                                                  std::ostream& x = get_cerr_stream()
                                                                                                  -
                                                                                                  set_cerr_stream( user_stream )
                                                                                                  set_cout_stream( user_stream ) -
                                                                                                  -
                                                                                                  std::ostream& x = get_cerr_stream() -
                                                                                                  std::ostream& x = get_cout_stream() +
                                                                                                  set_cerr_stream( user_stream )
                                                                                                    -
                                                                                                  • -In Armadillo 8.x and later versions, warnings and errors are printed by default to the std::cerr stream; -in Armadillo 7.x and earlier, the std::cout stream is used +
                                                                                                  • get_cout_stream():
                                                                                                      -
                                                                                                    • the printing can be disabled by placing #define ARMA_DONT_PRINT_ERRORS before #include <armadillo>
                                                                                                    • -
                                                                                                    • detailed information about errors is always reported via the base std::exception class
                                                                                                    • +
                                                                                                    • get a reference to the stream used for printing matrices and cubes with .print() and .raw_print()
                                                                                                    • +
                                                                                                    • by default this is std::cout
                                                                                                    -

                                                                                                  • -
                                                                                                  • set_cerr_stream(): +
                                                                                                  • get_cerr_stream():
                                                                                                      -
                                                                                                    • change the stream for printing warnings and errors involving out of bounds accesses, failed decompositions and out of memory conditions
                                                                                                    • -
                                                                                                    • the stream can also be changed via the ARMA_CERR_STREAM define; see config.hpp
                                                                                                    • +
                                                                                                    • get a reference to the stream used for printing warnings and errors involving out of bounds accesses, failed decompositions, failed loading/saving, out of memory conditions, etc
                                                                                                    • +
                                                                                                    • by default this is std::cerr
                                                                                                    -

                                                                                                  • -
                                                                                                  • set_cout_stream(): +
                                                                                                  • set_cout_stream( custom_stream ):
                                                                                                      -
                                                                                                    • change the default stream for printing matrices and cubes with .print() and .raw_print()
                                                                                                    • +
                                                                                                    • set the stream used for printing matrices and cubes
                                                                                                    • the stream can also be changed via the ARMA_COUT_STREAM define; see config.hpp

                                                                                                  • -
                                                                                                  • get_cerr_stream(): +
                                                                                                  • set_cerr_stream( custom_stream ):
                                                                                                      -
                                                                                                    • get a reference to the stream for printing warnings and errors
                                                                                                    • +
                                                                                                    • change the stream for printing warnings and errors +
                                                                                                    • the stream can also be changed via the ARMA_CERR_STREAM define; see config.hpp
                                                                                                    +

                                                                                                  • -
                                                                                                  • get_cout_stream(): +
                                                                                                  • +Caveats: +
                                                                                                      +
                                                                                                    • +in Armadillo 10.4 and later versions: +
                                                                                                        +
                                                                                                      • the default degree of emitted warnings about failed decompositions has been considerably reduced compared to earlier versions
                                                                                                      • +
                                                                                                      • the ARMA_WARN_LEVEL option allows fine-grained control over the degree of emitted warnings
                                                                                                      • +
                                                                                                      +
                                                                                                    • +
                                                                                                    • +in Armadillo 10.3 and earlier versions:
                                                                                                        -
                                                                                                      • get a reference to the stream for printing matrices and cubes
                                                                                                      • +
                                                                                                      • all failed decompositions print warnings
                                                                                                      • +
                                                                                                      • a blunt method to disable printing of all warnings and errors is via placing #define ARMA_DONT_PRINT_ERRORS before #include <armadillo> +
                                                                                                      +
                                                                                                    • +
                                                                                                    • +detailed information about errors is always reported via the base std::exception class +
                                                                                                    +

                                                                                                  • +
                                                                                                  • See also:
                                                                                                      @@ -16521,8 +17382,9 @@
                                                                                                    • The minimum width of both uword and sword is either 32 or 64 bits:
                                                                                                        -
                                                                                                      • when using the old C++98 / C++03 standards, the default width is 32 bits
                                                                                                      • -
                                                                                                      • when using the new C++11 / C++14 standards, the default width is 64 bits on 64-bit platforms
                                                                                                      • +
                                                                                                      • the default width is 32 bits on 32-bit platforms
                                                                                                      • +
                                                                                                      • the default width is 64 bits on 64-bit platforms
                                                                                                      • +
                                                                                                      • the default width is 32 bits when using Armadillo in the R environment (via RcppArmadillo) on either 32-bit or 64-bit platforms

                                                                                                    • @@ -16555,7 +17417,7 @@ Example:
                                                                                                        -cx_mat X = randu<cx_mat>(5,5);
                                                                                                        +cx_mat X(5, 5, fill::randu);
                                                                                                         
                                                                                                         X(1,2) = cx_double(2.0, 3.0);
                                                                                                         
                                                                                                        @@ -16616,13 +17478,13 @@ - A(1, 1) + A(1, 1)   - A(0, 0) + A(0, 0)   @@ -16633,13 +17495,13 @@ - A(k, k) + A(k, k)   - A(k-1, k-1) + A(k-1, k-1)   @@ -16667,13 +17529,13 @@ - size(A,1) + size(A,1)   - A.n_rows + A.n_rows   @@ -16684,13 +17546,13 @@ - size(A,2) + size(A,2)   - A.n_cols + A.n_cols   @@ -16701,13 +17563,13 @@ - size(Q,3) + size(Q,3)   - Q.n_slices + Q.n_slices   @@ -16718,13 +17580,13 @@ - numel(A) + numel(A)   - A.n_elem + A.n_elem   @@ -16752,13 +17614,13 @@ - A(:, k) + A(:, k)   - A.col(k) + A.col(k)   @@ -16771,13 +17633,13 @@ - A(k, :) + A(k, :)   - A.row(k) + A.row(k)   @@ -16788,13 +17650,13 @@ - A(:, p:q) + A(:, p:q)   - A.cols(p, q) + A.cols(p, q)   @@ -16805,13 +17667,13 @@ - A(p:q, :) + A(p:q, :)   - A.rows(p, q) + A.rows(p, q)   @@ -16822,13 +17684,13 @@ - A(p:q, r:s) + A(p:q, r:s)   - A( span(p,q), span(r,s) ) + A( span(p,q), span(r,s) )   @@ -16856,13 +17718,13 @@ - Q(:, :, k) + Q(:, :, k)   - Q.slice(k) + Q.slice(k)   @@ -16873,13 +17735,13 @@ - Q(:, :, t:u) + Q(:, :, t:u)   - Q.slices(t, u) + Q.slices(t, u)   @@ -16890,14 +17752,14 @@ - Q(p:q, r:s, t:u) + Q(p:q, r:s, t:u)   - Q( span(p,q), span(r,s), span(t,u) ) + Q( span(p,q), span(r,s), span(t,u) ) @@ -16926,13 +17788,13 @@ - A' + A'   - A.t() or trans(A) + A.t() or trans(A)   @@ -16962,13 +17824,13 @@ - A = zeros(size(A)) + A = zeros(size(A))   - A.zeros() + A.zeros()   @@ -16979,13 +17841,13 @@ - A = ones(size(A)) + A = ones(size(A))   - A.ones() + A.ones()   @@ -16996,13 +17858,13 @@ - A = zeros(k) + A = zeros(k)   - A = zeros<mat>(k,k) + A = zeros<mat>(k,k)   @@ -17013,13 +17875,13 @@ - A = ones(k) + A = ones(k)   - A = ones<mat>(k,k) + A = ones<mat>(k,k)   @@ -17047,13 +17909,13 @@ - C = complex(A,B) + C = complex(A,B)   - cx_mat C = cx_mat(A,B) + cx_mat C = cx_mat(A,B)   @@ -17081,13 +17943,13 @@ - A .* B + A .* B   - A % B + A % B   @@ -17098,13 +17960,13 @@ - A ./ B + A ./ B   - A / B + A / B   @@ -17115,13 +17977,13 @@ - A \ B + A \ B   - solve(A,B) + solve(A,B)   @@ -17132,13 +17994,13 @@ - A = A + 1; + A = A + 1;   - A++ + A++   @@ -17149,13 +18011,13 @@ - A = A - 1; + A = A - 1;   - A-- + A--   @@ -17183,21 +18045,22 @@ - A = [ 1 2; 3 4; ] + A = [ 1 2; 3 4; ]   -A << 1 << 2 << endr
                                                                                                        -   << 3 << 4 << endr; + + A = { { 1, 2 },
                                                                                                        +       { 3, 4 } }; +
                                                                                                          - element initialisation, - with special element endr indicating end of row + element initialisation @@ -17219,13 +18082,13 @@ - X = A(:) + X = A(:)   - X = vectorise(A) + X = vectorise(A)   @@ -17236,13 +18099,13 @@ - X = [ A  B ] + X = [ A  B ]   - X = join_horiz(A,B) + X = join_horiz(A,B)   @@ -17253,13 +18116,13 @@ - X = [ A; B ] + X = [ A; B ]   - X = join_vert(A,B) + X = join_vert(A,B)   @@ -17287,15 +18150,15 @@ - A + A   - cout << A << endl; + cout << A << endl;
                                                                                                        or -
                                                                                                        A.print("A ="); +
                                                                                                        A.print("A =");   @@ -17323,13 +18186,13 @@ - save ‑ascii 'A.dat' A + save ‑ascii 'A.txt' A   - A.save("A.dat", raw_ascii); + A.save("A.txt", raw_ascii);   @@ -17340,13 +18203,13 @@ - load ‑ascii 'A.dat' + load ‑ascii 'A.txt'   - A.load("A.dat", raw_ascii); + A.load("A.txt", raw_ascii);   @@ -17374,19 +18237,19 @@ - A = randn(2,3); + A = randn(2,3);
                                                                                                        B = randn(4,5); -
                                                                                                        F = { A; B } +
                                                                                                        F = { A; B }
                                                                                                          - mat A = randn(2,3); + mat A = randn(2,3);
                                                                                                        mat B = randn(4,5);
                                                                                                        field<mat> F(2,1);
                                                                                                        F(0,0) = A; -
                                                                                                        F(1,0) = B; +
                                                                                                        F(1,0) = B;
                                                                                                          @@ -17414,8 +18277,8 @@ int main() { - mat A = randu<mat>(4,5); - mat B = randu<mat>(4,5); + mat A(4, 5, fill::randu); + mat B(4, 5, fill::randu); cout << A*B.t() << endl; @@ -17423,20 +18286,20 @@ }
                                                                                      • -If you save the above program as example.cpp, -under Linux and Mac OS X it can be compiled using: +If the above program is stored as example.cpp, +under Linux and macOS it can be compiled using:
                                                                                        -g++ example.cpp -o example -O2 -larmadillo +
                                                                                          g++ example.cpp -o example -std=c++11 -O2 -larmadillo

                                                                                      • -As Armadillo is a template library, we strongly recommend to enable optimisation when compiling programs -(eg. when compiling with GCC or clang, use the -O2 or -O3 options) +Armadillo extensively uses template meta-programming, +so it's recommended to enable optimisation when compiling programs (eg. use the -O2 or -O3 options for GCC or clang)

                                                                                      • -
                                                                                      • -See also the example program that comes with the Armadillo archive -
                                                                                      • +
                                                                                      • See the Questions page for more info on compiling and linking
                                                                                      • +
                                                                                        +
                                                                                      • See also the example program that comes with the Armadillo archive

                                                                                      @@ -17483,7 +18346,7 @@   -Enable use of LAPACK, or a high-speed replacement for LAPACK (eg. Intel MKL, AMD ACML or the Accelerate framework). +Enable use of LAPACK, or a high-speed replacement for LAPACK (eg. OpenBLAS, Intel MKL, or the Accelerate framework). Armadillo requires LAPACK for functions such as svd(), inv(), eig_sym(), solve(), etc. @@ -17528,7 +18391,7 @@   -Enable use of BLAS, or a high-speed replacement for BLAS (eg. OpenBLAS, Intel MKL, AMD ACML or the Accelerate framework). +Enable use of BLAS, or a high-speed replacement for BLAS (eg. OpenBLAS, Intel MKL, or the Accelerate framework). BLAS is used for matrix multiplication. Without BLAS, Armadillo will use a built-in matrix multiplication routine, which might be slower for large matrices. @@ -17574,9 +18437,10 @@   -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. eigs_gen(), eigs_sym() and svds(). Requires ARMA_USE_LAPACK to be enabled. +If use of both NEWARP and ARPACK is enabled, NEWARP will be preferred. @@ -17598,7 +18462,7 @@   -Disable use of the built-in reimplementation of ARPACK; overrides ARMA_USE_NEWARP +Disable use of NEWARP (built-in alternative to ARPACK); overrides ARMA_USE_NEWARP @@ -17621,7 +18485,8 @@ Enable use of ARPACK, or a high-speed replacement for ARPACK. -Armadillo requires ARPACK for the eigen decomposition of complex sparse matrices, ie. eigs_gen(), eigs_sym() and svds() +Armadillo requires ARPACK for the eigen decomposition of complex sparse matrices, ie. eigs_gen(), eigs_sym() and svds(). +If use of NEWARP is disabled, ARPACK will also be used for the eigen decomposition of real sparse matrices. @@ -17665,9 +18530,9 @@   -Enable use of SuperLU, which is used by spsolve() for finding the solutions of sparse systems; -you will need to link with the superlu library, for example -lsuperlu -
                                                                                      Caveat: Armadillo 7.x and later versions require SuperLU 5.2, while Armadillo 6.x and earlier versions require SuperLU 4.3 +Enable use of SuperLU, which is used by spsolve() for finding the solutions of sparse systems, +as well as eigs_sym() and eigs_gen() in shift-invert mode. +You will need to link with the superlu library, for example -lsuperlu @@ -17750,82 +18615,13 @@ - -ARMA_USE_CXX11 - - -   - - -Use C++11 features, such as initialiser lists; -automatically enabled when using a compiler in C++11 or C++14 mode, for example: g++ -std=c++11 - - - - -   - - -   - - -   - - - - -ARMA_DONT_USE_CXX11 - - -   - - -Disable use of C++11 features; overrides ARMA_USE_CXX11 - - - - -   - - -   - - -   - - - - -ARMA_OPTIMISE_SOLVE_BAND - - -   - - -Enable optimised handling of band matrices by solve(). -Enabled by default. - - - - -   - - -   - - -   - - - - -ARMA_DONT_OPTIMISE_SOLVE_BAND +ARMA_DONT_USE_STD_MUTEX   -Disable optimised handling of band matrices by solve(); overrides ARMA_OPTIMISE_SOLVE_BAND +Disable use of std::mutex; applicable if your compiler and/or environment doesn't support std::mutex @@ -17841,14 +18637,13 @@ -ARMA_OPTIMISE_SOLVE_SYMPD +ARMA_DONT_OPTIMISE_BAND   -Enable optimised handling of symmetric/hermitian positive definite matrices by solve(). -Enabled by default. +Disable automatically optimised handling of band matrices by solve() and chol() @@ -17864,13 +18659,21 @@ -ARMA_DONT_OPTIMISE_SOLVE_SYMPD +ARMA_DONT_OPTIMISE_SYMPD   -Disable optimised handling of symmetric/hermitian positive definite matrices by solve(); overrides ARMA_OPTIMISE_SOLVE_SYMPD +Disable automatically optimised handling of symmetric/hermitian positive definite matrices by +solve(), +inv(), +pinv(), +expmat(), +logmat(), +sqrtmat(), +powmat(), +rcond() @@ -17894,8 +18697,7 @@ Use OpenMP for parallelisation of computationally expensive element-wise operations (such as exp(), log(), cos(), etc). -Automatically enabled when using a C++11/C++14 compiler which has OpenMP 3.1+ active (eg. the -fopenmp option for gcc and clang). -Caveat: when using gcc, use of -march=native in conjunction with -fopenmp may lead to speed regressions on recent processors. +Automatically enabled when using a compiler which has OpenMP 3.1+ active (eg. the -fopenmp option for gcc and clang). @@ -17939,7 +18741,7 @@   -The minimum number of elements in a matrix to enable OpenMP based parallelisation of computationally expensive element-wise functions; default value is 240 +The minimum number of elements in a matrix to enable OpenMP based parallelisation of computationally expensive element-wise functions; default value is 320 @@ -17961,7 +18763,7 @@   -The maximum number of threads for OpenMP based parallelisation of computationally expensive element-wise functions; default value is 10 +The maximum number of threads for OpenMP based parallelisation of computationally expensive element-wise functions; default value is 8 @@ -18187,10 +18989,9 @@   -Use 64 bit integers. -Automatically enabled when using a C++11 compiler on 64-bit platforms. -Useful if you require matrices/vectors capable of holding more than 4 billion elements. -Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long"). +Use 64 bit integers. Automatically enabled when using a 64-bit platform, except when using Armadillo in the R environment (via RcppArmadillo). +Useful if matrices/vectors capable of holding more than 4 billion elements are required. + This can also be enabled by adding #define ARMA_64BIT_WORD before each instance of #include <armadillo> @@ -18268,7 +19069,7 @@ The number of pre-allocated elements used by matrices and vectors. Must be always enabled and set to an integer that is at least 1. By default set to 16. -If you mainly use lots of very small vectors (eg. ≤ 4 elements), change the number to the size of your vectors. +If you mainly use lots of very small vectors (eg. ≤ 4 elements), change the number to the size of your vectors. @@ -18314,7 +19115,7 @@   -The default stream used for printing error messages and warnings. +The default stream used for printing warnings and errors. Must be always enabled. By default defined to std::cerr @@ -18360,7 +19161,8 @@   -Do not print errors or warnings; overrides ARMA_PRINT_ERRORS +Do not print errors or warnings; overrides ARMA_PRINT_ERRORS. +
                                                                                      Caveat: with Armadillo 10.4 or later versions, consider using ARMA_WARN_LEVEL instead @@ -18374,6 +19176,24 @@   + + +ARMA_WARN_LEVEL + + +   + + +The level of warning messages printed to ARMA_CERR_STREAM. +
                                                                                      Must be an integer ≥ 0. The default value is 2. + + + + + +
                                                                                      0 = no warnings
                                                                                      1 = only critical warnings about arguments and/or data which are likely to lead to incorrect results
                                                                                      2 = as per level 1, and warnings about poorly conditioned systems (low rcond) detected by solve(), spsolve(), etc
                                                                                      3 = as per level 2, and warnings about failed decompositions, failed saving/loading, etc
                                                                                      + +
                                                                                    • @@ -18382,10 +19202,10 @@
                                                                                    • See also:

                                                                                    • @@ -18415,7 +19235,7 @@ int main(int argc, char** argv) { // create a non-invertible matrix - mat A = zeros<mat>(5,5); + mat A(5, 5, fill::zeros); mat B; @@ -18481,7 +19301,7 @@
                                                                                    • Caveat: any function, class, constant or other code not explicitly described in the public API documentation is considered as part of the underlying internal implementation details, -and may change or be removed without notice. +and may be removed or changed without notice. (In other words, don't use internal functionality).
                                                                                    @@ -18510,6 +19330,113 @@ + +
                                                                                  • Version 10.8: + +
                                                                                  • +
                                                                                    + +
                                                                                  • Version 10.7: +
                                                                                      +
                                                                                    • faster handling of submatrix views accessed by X.cols(first_col,last_col)
                                                                                    • +
                                                                                    • faster handling of element-wise min() and max() in compound expressions
                                                                                    • +
                                                                                    • expanded solve() with solve_opts::force_approx option to force use of the approximate solver
                                                                                    • +
                                                                                    +
                                                                                  • +
                                                                                    + +
                                                                                  • Version 10.6: +
                                                                                      +
                                                                                    • expanded chol() to optionally use pivoted decomposition
                                                                                    • +
                                                                                    • expanded vector, matrix and cube constructors to allow element initialisation via fill::value(scalar), eg. mat X(4,5,fill::value(123))
                                                                                    • +
                                                                                    • faster loading of CSV files when using OpenMP +
                                                                                    • added csv_opts::semicolon option to allow saving/loading of CSV files with semicolon (;) instead of comma (,) as the separator
                                                                                    • +
                                                                                    +
                                                                                  • +
                                                                                    + +
                                                                                  • Version 10.5: +
                                                                                      +
                                                                                    • added .clamp() member function
                                                                                    • +
                                                                                    • expanded the standalone clamp() function to handle complex values
                                                                                    • +
                                                                                    • more efficient use of OpenMP
                                                                                    • +
                                                                                    • vector, matrix and cube constructors now initialise elements to zero by default; +
                                                                                      element initialisation can be disabled via the fill::none specifier, eg. mat X(4,5,fill::none) +
                                                                                    • +
                                                                                    +
                                                                                  • +
                                                                                    + +
                                                                                  • Version 10.4: +
                                                                                      +
                                                                                    • faster handling of triangular matrices by log_det()
                                                                                    • +
                                                                                    • added log_det_sympd() for log determinant of symmetric positive matrices
                                                                                    • +
                                                                                    • added ARMA_WARN_LEVEL configuration option, to control the degree of emitted warning messages
                                                                                    • +
                                                                                    • reduced the default degree of warning messages, so that failed decompositions, failed saving/loading, etc, no longer emit warnings
                                                                                    • +
                                                                                    +
                                                                                  • +
                                                                                    + +
                                                                                  • Version 10.3: +
                                                                                      +
                                                                                    • faster handling of symmetric positive definite matrices by pinv()
                                                                                    • +
                                                                                    • expanded .save() / .load() for dense matrices to handle coord_ascii format
                                                                                    • +
                                                                                    • for out of bounds access, element accessors now throw the more nuanced std::out_of_range exception, instead of only std::logic_error +
                                                                                    • improved quality of random numbers
                                                                                    • +
                                                                                    +
                                                                                  • +
                                                                                    + +
                                                                                  • Version 10.2: + +
                                                                                  • +
                                                                                    + +
                                                                                  • Version 10.1: +
                                                                                      +
                                                                                    • C++11 is now the minimum required C++ standard
                                                                                    • +
                                                                                    • faster handling of compound expressions by trimatu() and trimatl()
                                                                                    • +
                                                                                    • faster sparse matrix addition, subtraction and element-wise multiplication
                                                                                    • +
                                                                                    • expanded sparse submatrix views to handle the non-contiguous form of X.cols(vector_of_column_indices)
                                                                                    • +
                                                                                    • expanded eigs_sym() and eigs_gen() with optional fine-grained parameters
                                                                                    • +
                                                                                    +
                                                                                  • +
                                                                                    + +
                                                                                  • Version 9.900: + +
                                                                                  • +
                                                                                  • Version 9.800:
                                                                                      diff -Nru armadillo-9.800.4+dfsg/examples/example1.cpp armadillo-10.8.2+dfsg/examples/example1.cpp --- armadillo-9.800.4+dfsg/examples/example1.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/examples/example1.cpp 2016-06-16 16:24:22.000000000 +0000 @@ -14,12 +14,14 @@ { 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,16 +29,15 @@ 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" - A << 0.165300 << 0.454037 << 0.995795 << 0.124098 << 0.047084 << endr - << 0.688782 << 0.036549 << 0.552848 << 0.937664 << 0.866401 << endr - << 0.348740 << 0.479388 << 0.506228 << 0.145673 << 0.491547 << endr - << 0.148678 << 0.682258 << 0.571154 << 0.874724 << 0.444632 << endr - << 0.245726 << 0.595218 << 0.409327 << 0.367827 << 0.385736 << endr; - + A = { { 0.165300, 0.454037, 0.995795, 0.124098, 0.047084 }, + { 0.688782, 0.036549, 0.552848, 0.937664, 0.866401 }, + { 0.348740, 0.479388, 0.506228, 0.145673, 0.491547 }, + { 0.148678, 0.682258, 0.571154, 0.874724, 0.444632 }, + { 0.245726, 0.595218, 0.409327, 0.367827, 0.385736 } }; + A.print("A:"); // determinant @@ -93,13 +94,11 @@ D.print("D:"); // row vectors are treated like a matrix with one row - rowvec r; - r << 0.59119 << 0.77321 << 0.60275 << 0.35887 << 0.51683; + rowvec r = { 0.59119, 0.77321, 0.60275, 0.35887, 0.51683 }; r.print("r:"); // column vectors are treated like a matrix with one column - vec q; - q << 0.14333 << 0.59478 << 0.14481 << 0.58558 << 0.60809; + vec q = { 0.14333, 0.59478, 0.14481, 0.58558, 0.60809 }; q.print("q:"); // convert matrix to vector; data in matrices is stored column-by-column @@ -120,11 +119,13 @@ B.print("B:"); // imat specifies an integer matrix - imat AA; - imat BB; - - AA << 1 << 2 << 3 << endr << 4 << 5 << 6 << endr << 7 << 8 << 9; - BB << 3 << 2 << 1 << endr << 6 << 5 << 4 << endr << 9 << 8 << 7; + imat AA = { { 1, 2, 3 }, + { 4, 5, 6 }, + { 7, 8, 9 } }; + + imat BB = { { 3, 2, 1 }, + { 6, 5, 4 }, + { 9, 8, 7 } }; // comparison of matrices (element-wise); output of a relational operator is a umat umat ZZ = (AA >= BB); diff -Nru armadillo-9.800.4+dfsg/examples/Makefile armadillo-10.8.2+dfsg/examples/Makefile --- armadillo-9.800.4+dfsg/examples/Makefile 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/examples/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -# You may need to edit this file to reflect the type and capabilities of your system. -# The defaults are for a Linux system and may need to be changed for other systems (eg. Mac OS X). - - -CXX=g++ - -#CXX=CC -## When using the Sun Studio compiler - - -ARMA_INCLUDE_FLAG = -I ../include -## If you've installed Armadillo's headers manually, you may need to tell the compiler where they are. -## For example, change ../include to /usr/local/include - - -LIB_FLAGS = -lblas -llapack -#LIB_FLAGS = -lopenblas -llapack -#LIB_FLAGS = -framework Accelerate -#LIB_FLAGS = -library=sunperf - -## NOTE: on Ubuntu and Debian based systems you may need to add -lgfortran to LIB_FLAGS -## NOTE: if you're using Mac OS, use the line with -framework Accelerate -## NOTE: if you're using the Sun Studio compiler, use the line with -library=sunperf - - -OPT = -O2 -## As the Armadillo library uses recursive templates, compilation times depend on the level of optimisation: -## -## -O0: quick compilation, but the resulting program will be slow -## -O1: good trade-off between compilation time and execution speed -## -O2: produces programs which have almost all possible speedups, but compilation takes longer -## -O3: enables auto vectorisation when using gcc - -#OPT = -xO4 -xannotate=no -## When using the Sun Studio compiler - - -#EXTRA_OPT = -fwhole-program -## Uncomment the above line if you're compiling all source files into one program in a single hit - - -#DEBUG = -DARMA_EXTRA_DEBUG -## Uncomment the above line to enable low-level debugging. -## Lots of debugging information will be printed when a compiled program is run. -## Please enable this option when reporting bugs. - - -#FINAL = -DARMA_NO_DEBUG -## Uncomment the above line to disable Armadillo's checks. -## Not recommended unless your code has been first thoroughly tested! - - -CXXFLAGS = $(ARMA_INCLUDE_FLAG) $(DEBUG) $(FINAL) $(OPT) $(EXTRA_OPT) - -all: example1 - -example1: example1.cpp - $(CXX) $(CXXFLAGS) -o $@ $< $(LIB_FLAGS) - - -.PHONY: clean - -clean: - rm -f example1 - diff -Nru armadillo-9.800.4+dfsg/examples/Makefile.cmake armadillo-10.8.2+dfsg/examples/Makefile.cmake --- armadillo-9.800.4+dfsg/examples/Makefile.cmake 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/examples/Makefile.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -# You may need to edit this file to reflect the type and capabilities of your system. -# The defaults are for a Linux system and may need to be changed for other systems (eg. Mac OS X). - - -CXX=g++ - -#CXX=CC -## When using the Sun Studio compiler - - -# flags configured by CMake -ifeq (${ARMA_OS},macos) - LIB_FLAGS = -larmadillo -framework Accelerate -else - LIB_FLAGS = -larmadillo - ## NOTE: on Ubuntu and Debian based systems you may need to add -lgfortran - - #LIB_FLAGS = -larmadillo -library=sunperf - ## When using the Sun Studio compiler -endif - - - - - -OPT = -O2 -## As the Armadillo library uses recursive templates, compilation times depend on the level of optimisation: -## -## -O0: quick compilation, but the resulting program will be slow -## -O1: good trade-off between compilation time and execution speed -## -O2: produces programs which have almost all possible speedups, but compilation takes longer -## -O3: enables auto vectorisation when using gcc - -#OPT = -xO4 -xannotate=no -## When using the Sun Studio compiler - - -#EXTRA_OPT = -fwhole-program -## Uncomment the above line if you're compiling all source files into one program in a single hit - - -#DEBUG = -DARMA_EXTRA_DEBUG -## Uncomment the above line to enable low-level debugging. -## Lots of debugging information will be printed when a compiled program is run. -## Please enable this option when reporting bugs. - - -#FINAL = -DARMA_NO_DEBUG -## Uncomment the above line to disable Armadillo's checks. -## Not recommended unless your code has been first thoroughly tested! - - -CXXFLAGS = $(DEBUG) $(FINAL) $(OPT) $(EXTRA_OPT) - -all: example1 - -example1: example1.cpp - $(CXX) $(CXXFLAGS) -o $@ $< $(LIB_FLAGS) - - -.PHONY: clean - -clean: - rm -f example1 - diff -Nru armadillo-9.800.4+dfsg/examples/README.txt armadillo-10.8.2+dfsg/examples/README.txt --- armadillo-9.800.4+dfsg/examples/README.txt 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/examples/README.txt 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,24 @@ +How to compile example1.cpp + + +** Linux and macOS ** + +If you have installed Armadillo via the CMake installer: + g++ example1.cpp -o example1 -std=c++11 -O2 -larmadillo + +Otherwise, if you want to use Armadillo without installation: + g++ example1.cpp -o example1 -std=c++11 -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) + +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. diff -Nru armadillo-9.800.4+dfsg/include/armadillo armadillo-10.8.2+dfsg/include/armadillo --- armadillo-9.800.4+dfsg/include/armadillo 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -17,12 +19,15 @@ #ifndef ARMA_INCLUDES #define ARMA_INCLUDES +#include "armadillo_bits/config.hpp" +#include "armadillo_bits/compiler_check.hpp" #include #include #include #include #include +#include #include #include @@ -37,55 +42,30 @@ #include #include #include +#include +#include +#include +#include - -#if ( defined(__unix__) || defined(__unix) || defined(_POSIX_C_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) ) && !defined(_WIN32) - #include -#endif - - -#if (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) - #include -#endif - - -#include "armadillo_bits/compiler_extra.hpp" -#include "armadillo_bits/config.hpp" -#include "armadillo_bits/compiler_setup.hpp" - - -#if defined(ARMA_USE_CXX11) - #include - #include - #include - #include - #include +#if !defined(ARMA_DONT_USE_STD_MUTEX) #include #include #endif - #if defined(ARMA_USE_TBB_ALLOC) #include #endif - #if defined(ARMA_USE_MKL_ALLOC) #include #endif - -#if !defined(ARMA_USE_CXX11) - #if defined(ARMA_HAVE_TR1) - #include - #include - #endif +#if ( defined(__unix__) || defined(__unix) || defined(_POSIX_C_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) ) && !defined(_WIN32) + #include #endif -#include "armadillo_bits/include_atlas.hpp" -#include "armadillo_bits/include_hdf5.hpp" -#include "armadillo_bits/include_superlu.hpp" +#include "armadillo_bits/compiler_setup.hpp" #if defined(ARMA_USE_OPENMP) @@ -93,6 +73,10 @@ #endif +#include "armadillo_bits/include_atlas.hpp" +#include "armadillo_bits/include_hdf5.hpp" +#include "armadillo_bits/include_superlu.hpp" + //! \namespace arma namespace for Armadillo classes and functions namespace arma @@ -119,6 +103,7 @@ #include "armadillo_bits/constants_old.hpp" #include "armadillo_bits/mp_misc.hpp" #include "armadillo_bits/arma_rel_comparators.hpp" + #include "armadillo_bits/fill.hpp" #ifdef ARMA_RNG_ALT #include ARMA_INCFILE_WRAP(ARMA_RNG_ALT) @@ -172,6 +157,7 @@ #include "armadillo_bits/SpCol_bones.hpp" #include "armadillo_bits/SpRow_bones.hpp" #include "armadillo_bits/SpSubview_bones.hpp" + #include "armadillo_bits/SpSubview_col_list_bones.hpp" #include "armadillo_bits/spdiagview_bones.hpp" #include "armadillo_bits/MapMat_bones.hpp" @@ -188,7 +174,8 @@ #include "armadillo_bits/subview_cube_each_bones.hpp" #include "armadillo_bits/subview_cube_slices_bones.hpp" - + #include "armadillo_bits/hdf5_name.hpp" + #include "armadillo_bits/csv_name.hpp" #include "armadillo_bits/diskio_bones.hpp" #include "armadillo_bits/wall_clock_bones.hpp" #include "armadillo_bits/running_stat_bones.hpp" @@ -227,6 +214,8 @@ #include "armadillo_bits/op_diagmat_bones.hpp" #include "armadillo_bits/op_diagvec_bones.hpp" #include "armadillo_bits/op_dot_bones.hpp" + #include "armadillo_bits/op_det_bones.hpp" + #include "armadillo_bits/op_log_det_bones.hpp" #include "armadillo_bits/op_inv_bones.hpp" #include "armadillo_bits/op_htrans_bones.hpp" #include "armadillo_bits/op_max_bones.hpp" @@ -288,6 +277,8 @@ #include "armadillo_bits/op_cond_bones.hpp" #include "armadillo_bits/op_sp_plus_bones.hpp" #include "armadillo_bits/op_sp_minus_bones.hpp" + #include "armadillo_bits/op_powmat_bones.hpp" + #include "armadillo_bits/op_rank_bones.hpp" #include "armadillo_bits/glue_times_bones.hpp" #include "armadillo_bits/glue_mixed_bones.hpp" @@ -312,6 +303,7 @@ #include "armadillo_bits/glue_intersect_bones.hpp" #include "armadillo_bits/glue_affmul_bones.hpp" #include "armadillo_bits/glue_mvnrnd_bones.hpp" + #include "armadillo_bits/glue_quantile_bones.hpp" #include "armadillo_bits/gmm_misc_bones.hpp" #include "armadillo_bits/gmm_diag_bones.hpp" @@ -332,8 +324,8 @@ #include "armadillo_bits/spop_reverse_bones.hpp" #include "armadillo_bits/spop_repmat_bones.hpp" #include "armadillo_bits/spop_vectorise_bones.hpp" + #include "armadillo_bits/spop_norm_bones.hpp" - #include "armadillo_bits/spglue_elem_helper_bones.hpp" #include "armadillo_bits/spglue_plus_bones.hpp" #include "armadillo_bits/spglue_minus_bones.hpp" #include "armadillo_bits/spglue_schur_bones.hpp" @@ -349,9 +341,11 @@ #include "armadillo_bits/newarp_EigsSelect.hpp" #include "armadillo_bits/newarp_DenseGenMatProd_bones.hpp" #include "armadillo_bits/newarp_SparseGenMatProd_bones.hpp" + #include "armadillo_bits/newarp_SparseGenRealShiftSolve_bones.hpp" #include "armadillo_bits/newarp_DoubleShiftQR_bones.hpp" #include "armadillo_bits/newarp_GenEigsSolver_bones.hpp" #include "armadillo_bits/newarp_SymEigsSolver_bones.hpp" + #include "armadillo_bits/newarp_SymEigsShiftSolver_bones.hpp" #include "armadillo_bits/newarp_TridiagEigen_bones.hpp" #include "armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp" #include "armadillo_bits/newarp_UpperHessenbergQR_bones.hpp" @@ -491,10 +485,11 @@ #include "armadillo_bits/fn_trunc_log.hpp" #include "armadillo_bits/fn_toeplitz.hpp" #include "armadillo_bits/fn_trimat.hpp" + #include "armadillo_bits/fn_trimat_ind.hpp" #include "armadillo_bits/fn_cumsum.hpp" #include "armadillo_bits/fn_cumprod.hpp" #include "armadillo_bits/fn_symmat.hpp" - #include "armadillo_bits/fn_syl_lyap.hpp" + #include "armadillo_bits/fn_sylvester.hpp" #include "armadillo_bits/fn_hist.hpp" #include "armadillo_bits/fn_histc.hpp" #include "armadillo_bits/fn_unique.hpp" @@ -528,12 +523,15 @@ #include "armadillo_bits/fn_polyval.hpp" #include "armadillo_bits/fn_intersect.hpp" #include "armadillo_bits/fn_normpdf.hpp" + #include "armadillo_bits/fn_log_normpdf.hpp" #include "armadillo_bits/fn_normcdf.hpp" #include "armadillo_bits/fn_mvnrnd.hpp" #include "armadillo_bits/fn_chi2rnd.hpp" #include "armadillo_bits/fn_wishrnd.hpp" #include "armadillo_bits/fn_roots.hpp" #include "armadillo_bits/fn_randperm.hpp" + #include "armadillo_bits/fn_quantile.hpp" + #include "armadillo_bits/fn_powmat.hpp" #include "armadillo_bits/fn_speye.hpp" #include "armadillo_bits/fn_spones.hpp" @@ -634,6 +632,7 @@ #include "armadillo_bits/SpRow_meat.hpp" #include "armadillo_bits/SpSubview_meat.hpp" #include "armadillo_bits/SpSubview_iterators_meat.hpp" + #include "armadillo_bits/SpSubview_col_list_meat.hpp" #include "armadillo_bits/spdiagview_meat.hpp" #include "armadillo_bits/MapMat_meat.hpp" @@ -645,6 +644,8 @@ #include "armadillo_bits/op_diagmat_meat.hpp" #include "armadillo_bits/op_diagvec_meat.hpp" #include "armadillo_bits/op_dot_meat.hpp" + #include "armadillo_bits/op_det_meat.hpp" + #include "armadillo_bits/op_log_det_meat.hpp" #include "armadillo_bits/op_inv_meat.hpp" #include "armadillo_bits/op_htrans_meat.hpp" #include "armadillo_bits/op_max_meat.hpp" @@ -706,6 +707,8 @@ #include "armadillo_bits/op_cond_meat.hpp" #include "armadillo_bits/op_sp_plus_meat.hpp" #include "armadillo_bits/op_sp_minus_meat.hpp" + #include "armadillo_bits/op_powmat_meat.hpp" + #include "armadillo_bits/op_rank_meat.hpp" #include "armadillo_bits/glue_times_meat.hpp" #include "armadillo_bits/glue_mixed_meat.hpp" @@ -730,6 +733,7 @@ #include "armadillo_bits/glue_intersect_meat.hpp" #include "armadillo_bits/glue_affmul_meat.hpp" #include "armadillo_bits/glue_mvnrnd_meat.hpp" + #include "armadillo_bits/glue_quantile_meat.hpp" #include "armadillo_bits/gmm_misc_meat.hpp" #include "armadillo_bits/gmm_diag_meat.hpp" @@ -750,8 +754,8 @@ #include "armadillo_bits/spop_reverse_meat.hpp" #include "armadillo_bits/spop_repmat_meat.hpp" #include "armadillo_bits/spop_vectorise_meat.hpp" + #include "armadillo_bits/spop_norm_meat.hpp" - #include "armadillo_bits/spglue_elem_helper_meat.hpp" #include "armadillo_bits/spglue_plus_meat.hpp" #include "armadillo_bits/spglue_minus_meat.hpp" #include "armadillo_bits/spglue_schur_meat.hpp" @@ -768,9 +772,11 @@ #include "armadillo_bits/newarp_SortEigenvalue.hpp" #include "armadillo_bits/newarp_DenseGenMatProd_meat.hpp" #include "armadillo_bits/newarp_SparseGenMatProd_meat.hpp" + #include "armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp" #include "armadillo_bits/newarp_DoubleShiftQR_meat.hpp" #include "armadillo_bits/newarp_GenEigsSolver_meat.hpp" #include "armadillo_bits/newarp_SymEigsSolver_meat.hpp" + #include "armadillo_bits/newarp_SymEigsShiftSolver_meat.hpp" #include "armadillo_bits/newarp_TridiagEigen_meat.hpp" #include "armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp" #include "armadillo_bits/newarp_UpperHessenbergQR_meat.hpp" diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/access.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/access.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/access.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/access.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,19 +25,19 @@ public: //! internal function to allow modification of data declared as read-only (use with caution) - template arma_inline static T1& rw (const T1& x) { return const_cast(x); } - template arma_inline static T1*& rwp(const T1* const& x) { return const_cast(x); } + template constexpr static T1& rw (const T1& x) { return const_cast(x); } + template constexpr static T1*& rwp(const T1* const& x) { return const_cast(x); } //! internal function to obtain the real part of either a plain number or a complex number - template arma_inline static const eT& tmp_real(const eT& X) { return X; } - template arma_inline static const T tmp_real(const std::complex& X) { return X.real(); } + template constexpr static const eT& tmp_real(const eT& X) { return X; } + template constexpr static const T tmp_real(const std::complex& X) { return X.real(); } //! internal function to obtain the imag part of either a plain number or a complex number - template arma_inline static const eT tmp_imag(const eT ) { return eT(0); } - template arma_inline static const T tmp_imag(const std::complex& X) { return X.imag(); } + template constexpr static const eT tmp_imag(const eT ) { return eT(0); } + template constexpr static const T tmp_imag(const std::complex& X) { return X.imag(); } //! internal function to work around braindead compilers - template arma_inline static const typename enable_if2::no, const eT&>::result alt_conj(const eT& X) { return X; } + template constexpr static const typename enable_if2::no, const eT&>::result alt_conj(const eT& X) { return X; } template arma_inline static const typename enable_if2::yes, const eT >::result alt_conj(const eT& X) { return std::conj(X); } }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_cmath.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_cmath.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_cmath.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_cmath.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,90 +27,41 @@ template -arma_inline +inline bool -arma_isfinite(eT val) +arma_isfinite(eT) { - arma_ignore(val); - return true; } template<> -arma_inline +inline bool arma_isfinite(float x) { - #if defined(ARMA_USE_CXX11) - { - return std::isfinite(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::isfinite(x); - } - #elif defined(ARMA_HAVE_ISFINITE) - { - return (std::isfinite(x) != 0); - } - #else - { - const float y = (std::numeric_limits::max)(); - - const volatile float xx = x; - - return (xx == xx) && (x >= -y) && (x <= y); - } - #endif + return std::isfinite(x); } template<> -arma_inline +inline bool arma_isfinite(double x) { - #if defined(ARMA_USE_CXX11) - { - return std::isfinite(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::isfinite(x); - } - #elif defined(ARMA_HAVE_ISFINITE) - { - return (std::isfinite(x) != 0); - } - #else - { - const double y = (std::numeric_limits::max)(); - - const volatile double xx = x; - - return (xx == xx) && (x >= -y) && (x <= y); - } - #endif + return std::isfinite(x); } template -arma_inline +inline bool arma_isfinite(const std::complex& x) { - if( (arma_isfinite(x.real()) == false) || (arma_isfinite(x.imag()) == false) ) - { - return false; - } - else - { - return true; - } + return ( arma_isfinite(x.real()) && arma_isfinite(x.imag()) ); } @@ -118,71 +71,37 @@ template -arma_inline +inline bool -arma_isinf(eT val) +arma_isinf(eT) { - arma_ignore(val); - return false; } template<> -arma_inline +inline bool arma_isinf(float x) { - #if defined(ARMA_USE_CXX11) - { - return std::isinf(x); - } - #elif defined(ARMA_HAVE_ISINF) - { - return (std::isinf(x) != 0); - } - #else - { - const float y = (std::numeric_limits::max)(); - - const volatile float xx = x; - - return (xx == xx) && ((x < -y) || (x > y)); - } - #endif + return std::isinf(x); } template<> -arma_inline +inline bool arma_isinf(double x) { - #if defined(ARMA_USE_CXX11) - { - return std::isinf(x); - } - #elif defined(ARMA_HAVE_ISINF) - { - return (std::isinf(x) != 0); - } - #else - { - const double y = (std::numeric_limits::max)(); - - const volatile double xx = x; - - return (xx == xx) && ((x < -y) || (x > y)); - } - #endif + return std::isinf(x); } template -arma_inline +inline bool arma_isinf(const std::complex& x) { @@ -196,7 +115,7 @@ template -arma_inline +inline bool arma_isnan(eT val) { @@ -208,55 +127,27 @@ template<> -arma_inline +inline bool arma_isnan(float x) { - #if defined(ARMA_USE_CXX11) - { - return std::isnan(x); - } - #elif defined(ARMA_HAVE_ISNAN) - { - return (std::isnan(x) != 0); - } - #else - { - const volatile float xx = x; - - return (xx != xx); - } - #endif + return std::isnan(x); } template<> -arma_inline +inline bool arma_isnan(double x) { - #if defined(ARMA_USE_CXX11) - { - return std::isnan(x); - } - #elif defined(ARMA_HAVE_ISNAN) - { - return (std::isnan(x) != 0); - } - #else - { - const volatile double xx = x; - - return (xx != xx); - } - #endif + return std::isnan(x); } template -arma_inline +inline bool arma_isnan(const std::complex& x) { @@ -265,76 +156,12 @@ -// rudimentary wrappers for log1p() - -arma_inline -float -arma_log1p(const float x) - { - #if defined(ARMA_USE_CXX11) - { - return std::log1p(x); - } - #else - { - if((x >= float(0)) && (x < std::numeric_limits::epsilon())) - { - return x; - } - else - if((x < float(0)) && (-x < std::numeric_limits::epsilon())) - { - return x; - } - else - { - return std::log(float(1) + x); - } - } - #endif - } - - - -arma_inline -double -arma_log1p(const double x) - { - #if defined(ARMA_USE_CXX11) - { - return std::log1p(x); - } - #elif defined(ARMA_HAVE_LOG1P) - { - return log1p(x); - } - #else - { - if((x >= double(0)) && (x < std::numeric_limits::epsilon())) - { - return x; - } - else - if((x < double(0)) && (-x < std::numeric_limits::epsilon())) - { - return x; - } - else - { - return std::log(double(1) + x); - } - } - #endif - } - - - // // implementation of arma_sign() template -arma_inline +constexpr typename arma_unsigned_integral_only::result arma_sign(const eT x) { @@ -344,7 +171,7 @@ template -arma_inline +constexpr typename arma_signed_integral_only::result arma_sign(const eT x) { @@ -354,17 +181,17 @@ template -arma_inline +constexpr typename arma_real_only::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) ); } template -arma_inline +inline typename arma_cx_only::result arma_sign(const eT& x) { @@ -378,324 +205,12 @@ // -// wrappers for trigonometric functions -// -// wherever possible, try to use C++11 or TR1 versions of the following functions: -// -// complex acos -// complex asin -// complex atan -// -// real acosh -// real asinh -// real atanh -// -// complex acosh -// complex asinh -// complex atanh -// -// -// if C++11 or TR1 are not available, we have rudimentary versions of: -// -// real acosh -// real asinh -// real atanh - - - -template -arma_inline -std::complex -arma_acos(const std::complex& x) - { - #if defined(ARMA_USE_CXX11) - { - return std::acos(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::acos(x); - } - #else - { - arma_ignore(x); - arma_stop_logic_error("acos(): C++11 compiler required"); - - return std::complex(0); - } - #endif - } - - - -template -arma_inline -std::complex -arma_asin(const std::complex& x) - { - #if defined(ARMA_USE_CXX11) - { - return std::asin(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::asin(x); - } - #else - { - arma_ignore(x); - arma_stop_logic_error("asin(): C++11 compiler required"); - - return std::complex(0); - } - #endif - } - - - -template -arma_inline -std::complex -arma_atan(const std::complex& x) - { - #if defined(ARMA_USE_CXX11) - { - return std::atan(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::atan(x); - } - #else - { - arma_ignore(x); - arma_stop_logic_error("atan(): C++11 compiler required"); - - return std::complex(0); - } - #endif - } - - - -template -arma_inline -eT -arma_acosh(const eT x) - { - #if defined(ARMA_USE_CXX11) - { - return std::acosh(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::acosh(x); - } - #else - { - if(x >= eT(1)) - { - // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/ - return std::log( x + std::sqrt(x*x - eT(1)) ); - } - else - { - if(std::numeric_limits::has_quiet_NaN) - { - return -(std::numeric_limits::quiet_NaN()); - } - else - { - return eT(0); - } - } - } - #endif - } - - - -template -arma_inline -eT -arma_asinh(const eT x) - { - #if defined(ARMA_USE_CXX11) - { - return std::asinh(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::asinh(x); - } - #else - { - // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/ - return std::log( x + std::sqrt(x*x + eT(1)) ); - } - #endif - } - - - -template -arma_inline -eT -arma_atanh(const eT x) - { - #if defined(ARMA_USE_CXX11) - { - return std::atanh(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::atanh(x); - } - #else - { - if( (x >= eT(-1)) && (x <= eT(+1)) ) - { - // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/ - return std::log( ( eT(1)+x ) / ( eT(1)-x ) ) / eT(2); - } - else - { - if(std::numeric_limits::has_quiet_NaN) - { - return -(std::numeric_limits::quiet_NaN()); - } - else - { - return eT(0); - } - } - } - #endif - } - - - -template -arma_inline -std::complex -arma_acosh(const std::complex& x) - { - #if defined(ARMA_USE_CXX11) - { - return std::acosh(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::acosh(x); - } - #else - { - arma_ignore(x); - arma_stop_logic_error("acosh(): C++11 compiler required"); - - return std::complex(0); - } - #endif - } - - - -template -arma_inline -std::complex -arma_asinh(const std::complex& x) - { - #if defined(ARMA_USE_CXX11) - { - return std::asinh(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::asinh(x); - } - #else - { - arma_ignore(x); - arma_stop_logic_error("asinh(): C++11 compiler required"); - - return std::complex(0); - } - #endif - } - - - -template -arma_inline -std::complex -arma_atanh(const std::complex& x) - { - #if defined(ARMA_USE_CXX11) - { - return std::atanh(x); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::atanh(x); - } - #else - { - arma_ignore(x); - arma_stop_logic_error("atanh(): C++11 compiler required"); - - return std::complex(0); - } - #endif - } - - - -// // wrappers for hypot(x, y) = sqrt(x^2 + y^2) template inline eT -arma_hypot_generic(const eT x, const eT y) - { - #if defined(ARMA_USE_CXX11) - { - return std::hypot(x, y); - } - #elif defined(ARMA_HAVE_TR1) - { - return std::tr1::hypot(x, y); - } - #else - { - const eT xabs = std::abs(x); - const eT yabs = std::abs(y); - - eT larger; - eT ratio; - - if(xabs > yabs) - { - larger = xabs; - ratio = yabs / xabs; - } - else - { - larger = yabs; - ratio = xabs / yabs; - } - - return (larger == eT(0)) ? eT(0) : (larger * std::sqrt(eT(1) + ratio * ratio)); - } - #endif - } - - - -template -inline -eT arma_hypot(const eT x, const eT y) { arma_ignore(x); @@ -709,21 +224,21 @@ template<> -arma_inline +inline float arma_hypot(const float x, const float y) { - return arma_hypot_generic(x,y); + return std::hypot(x, y); } template<> -arma_inline +inline double arma_hypot(const double x, const double y) { - return arma_hypot_generic(x,y); + return std::hypot(x, y); } @@ -733,7 +248,7 @@ template -arma_inline +inline eT arma_sinc_generic(const eT x) { @@ -747,7 +262,7 @@ template -arma_inline +inline eT arma_sinc(const eT x) { @@ -757,7 +272,7 @@ template<> -arma_inline +inline float arma_sinc(const float x) { @@ -767,7 +282,7 @@ template<> -arma_inline +inline double arma_sinc(const double x) { @@ -777,7 +292,7 @@ template -arma_inline +inline std::complex arma_sinc(const std::complex& x) { @@ -798,18 +313,7 @@ eT eval(const eT x) { - #if defined(ARMA_USE_CXX11) - { - return eT( std::arg(x) ); - } - #else - { - arma_ignore(x); - arma_stop_logic_error("arg(): C++11 compiler required"); - - return eT(0); - } - #endif + return eT( std::arg(x) ); } }; @@ -819,19 +323,11 @@ struct arma_arg { static - arma_inline + inline float eval(const float x) { - #if defined(ARMA_USE_CXX11) - { - return std::arg(x); - } - #else - { - return std::arg( std::complex( x, float(0) ) ); - } - #endif + return std::arg(x); } }; @@ -841,19 +337,11 @@ struct arma_arg { static - arma_inline + inline double eval(const double x) { - #if defined(ARMA_USE_CXX11) - { - return std::arg(x); - } - #else - { - return std::arg( std::complex( x, double(0) ) ); - } - #endif + return std::arg(x); } }; @@ -863,7 +351,7 @@ struct arma_arg< std::complex > { static - arma_inline + inline float eval(const std::complex& x) { @@ -877,7 +365,7 @@ struct arma_arg< std::complex > { static - arma_inline + inline double eval(const std::complex& x) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_config.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_config.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_config.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_config.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,93 +24,93 @@ struct arma_config { #if defined(ARMA_MAT_PREALLOC) - static const uword mat_prealloc = (sword(ARMA_MAT_PREALLOC) > 0) ? uword(ARMA_MAT_PREALLOC) : 1; + static constexpr uword mat_prealloc = (sword(ARMA_MAT_PREALLOC) > 0) ? uword(ARMA_MAT_PREALLOC) : 1; #else - static const uword mat_prealloc = 16; + static constexpr uword mat_prealloc = 16; #endif #if defined(ARMA_OPENMP_THRESHOLD) - static const uword mp_threshold = (sword(ARMA_OPENMP_THRESHOLD) > 0) ? uword(ARMA_OPENMP_THRESHOLD) : 240; + static constexpr uword mp_threshold = (sword(ARMA_OPENMP_THRESHOLD) > 0) ? uword(ARMA_OPENMP_THRESHOLD) : 320; #else - static const uword mp_threshold = 240; + static constexpr uword mp_threshold = 320; #endif #if defined(ARMA_OPENMP_THREADS) - static const uword mp_threads = (sword(ARMA_OPENMP_THREADS) > 0) ? uword(ARMA_OPENMP_THREADS) : 10; + static constexpr uword mp_threads = (sword(ARMA_OPENMP_THREADS) > 0) ? uword(ARMA_OPENMP_THREADS) : 8; #else - static const uword mp_threads = 10; + static constexpr uword mp_threads = 8; #endif #if defined(ARMA_USE_ATLAS) - static const bool atlas = true; + static constexpr bool atlas = true; #else - static const bool atlas = false; + static constexpr bool atlas = false; #endif #if defined(ARMA_USE_LAPACK) - static const bool lapack = true; + static constexpr bool lapack = true; #else - static const bool lapack = false; + static constexpr bool lapack = false; #endif #if defined(ARMA_USE_BLAS) - static const bool blas = true; + static constexpr bool blas = true; #else - static const bool blas = false; + static constexpr bool blas = false; #endif #if defined(ARMA_USE_NEWARP) - static const bool newarp = true; + static constexpr bool newarp = true; #else - static const bool newarp = false; + static constexpr bool newarp = false; #endif #if defined(ARMA_USE_ARPACK) - static const bool arpack = true; + static constexpr bool arpack = true; #else - static const bool arpack = false; + static constexpr bool arpack = false; #endif #if defined(ARMA_USE_SUPERLU) - static const bool superlu = true; + static constexpr bool superlu = true; #else - static const bool superlu = false; + static constexpr bool superlu = false; #endif #if defined(ARMA_USE_HDF5) - static const bool hdf5 = true; + static constexpr bool hdf5 = true; #else - static const bool hdf5 = false; + static constexpr bool hdf5 = false; #endif #if defined(ARMA_NO_DEBUG) - static const bool debug = false; + static constexpr bool debug = false; #else - static const bool debug = true; + static constexpr bool debug = true; #endif #if defined(ARMA_EXTRA_DEBUG) - static const bool extra_debug = true; + static constexpr bool extra_debug = true; #else - static const bool extra_debug = false; + static constexpr bool extra_debug = false; #endif #if defined(ARMA_GOOD_COMPILER) - static const bool good_comp = true; + static constexpr bool good_comp = true; #else - static const bool good_comp = false; + static constexpr bool good_comp = false; #endif @@ -121,46 +123,65 @@ || defined(ARMA_EXTRA_SPMAT_PROTO) || defined(ARMA_EXTRA_SPMAT_MEAT) \ || defined(ARMA_EXTRA_SPCOL_PROTO) || defined(ARMA_EXTRA_SPCOL_MEAT) \ || defined(ARMA_EXTRA_SPROW_PROTO) || defined(ARMA_EXTRA_SPROW_MEAT) \ + || defined(ARMA_ALIEN_MEM_ALLOC_FUNCTION) \ + || defined(ARMA_ALIEN_MEM_FREE_FUNCTION) \ ) - static const bool extra_code = true; + static constexpr bool extra_code = true; + #else + static constexpr bool extra_code = false; + #endif + + + #if defined(ARMA_HAVE_CXX14) + static constexpr bool cxx14 = true; #else - static const bool extra_code = false; + static constexpr bool cxx14 = false; #endif - #if defined(ARMA_USE_CXX11) - static const bool cxx11 = true; + #if defined(ARMA_HAVE_CXX17) + static constexpr bool cxx17 = true; #else - static const bool cxx11 = false; + static constexpr bool cxx17 = false; + #endif + + + #if (!defined(ARMA_DONT_USE_STD_MUTEX)) + static constexpr bool std_mutex = true; + #else + static constexpr bool std_mutex = false; #endif #if (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) - static const bool posix = true; + static constexpr bool posix = true; #else - static const bool posix = false; + static constexpr bool posix = false; #endif #if defined(ARMA_USE_WRAPPER) - static const bool wrapper = true; + static constexpr bool wrapper = true; #else - static const bool wrapper = false; + static constexpr bool wrapper = false; #endif #if defined(ARMA_USE_OPENMP) - static const bool openmp = true; + static constexpr bool openmp = true; #else - static const bool openmp = false; + static constexpr bool openmp = false; #endif #if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS) - static const bool hidden_args = true; + static constexpr bool hidden_args = true; #else - static const bool hidden_args = false; + static constexpr bool hidden_args = false; #endif + + + static constexpr uword warn_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : 0; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_forward.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_forward.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_forward.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_forward.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,6 +37,7 @@ template class subview; template class subview_col; +template class subview_cols; template class subview_row; template class subview_row_strans; template class subview_row_htrans; @@ -46,6 +49,8 @@ template class SpCol; template class SpRow; template class SpSubview; +template class SpSubview_col; +template class SpSubview_row; template class diagview; template class spdiagview; @@ -65,6 +70,8 @@ template class subview_cube_each2; template class subview_cube_slices; +template class SpSubview_col_list; + class SizeMat; class SizeCube; @@ -142,9 +149,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; }; }; @@ -154,9 +161,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = true; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = true; }; }; @@ -166,9 +173,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; }; }; @@ -178,9 +185,9 @@ template struct traits { - static const bool is_row = true; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; }; }; @@ -190,9 +197,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T1::is_col; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T1::is_col; + static constexpr bool is_xvec = T1::is_xvec; }; }; @@ -202,9 +209,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; }; }; @@ -214,9 +221,9 @@ template struct traits { - static const bool is_row = (T1::is_row || T2::is_row ); - static const bool is_col = (T1::is_col || T2::is_col ); - static const bool is_xvec = (T1::is_xvec || T2::is_xvec); + static constexpr bool is_row = (T1::is_row || T2::is_row ); + static constexpr bool is_col = (T1::is_col || T2::is_col ); + static constexpr bool is_xvec = (T1::is_xvec || T2::is_xvec); }; }; @@ -251,12 +258,13 @@ template class mtGlueCube; -template class Proxy; -template class ProxyCube; +template struct Proxy; +template struct ProxyCube; template class diagmat_proxy; template struct unwrap; +template struct quasi_unwrap; template struct unwrap_cube; template struct unwrap_spmat; @@ -267,7 +275,7 @@ { #if defined(ARMA_USE_OPENMP) int state; - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) std::atomic state; #else int state; @@ -286,7 +294,7 @@ #if defined(ARMA_USE_OPENMP) #pragma omp atomic read out = state; - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) out = state.load(); #else out = state; @@ -302,7 +310,7 @@ #if defined(ARMA_USE_OPENMP) #pragma omp atomic write state = in_state; - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) state.store(in_state); #else state = in_state; @@ -318,7 +326,7 @@ template class mtSpGlue; -template class SpProxy; +template struct SpProxy; @@ -327,6 +335,11 @@ struct arma_reserve_indicator {}; struct arma_layout_indicator {}; +template struct arma_initmode_indicator {}; + +struct arma_zeros_indicator : public arma_initmode_indicator {}; +struct arma_nozeros_indicator : public arma_initmode_indicator {}; + //! \addtogroup injector //! @{ @@ -345,118 +358,42 @@ //! @{ -enum file_type +enum struct file_type : unsigned int { file_type_unknown, - auto_detect, //!< Automatically detect the file type - raw_ascii, //!< ASCII format (text), without any other information. - arma_ascii, //!< Armadillo ASCII format (text), with information about matrix type and size - csv_ascii, //!< comma separated values (CSV), without any other information - raw_binary, //!< raw binary format, without any other information. - arma_binary, //!< Armadillo binary format, with information about matrix type and size + auto_detect, //!< attempt to automatically detect the file type + raw_ascii, //!< raw text (ASCII), without a header + arma_ascii, //!< Armadillo text format, with a header specifying matrix type and size + csv_ascii, //!< comma separated values (CSV), without a header + raw_binary, //!< raw binary format (machine dependent), without a header + arma_binary, //!< Armadillo binary format (machine dependent), with a header specifying matrix type and size pgm_binary, //!< Portable Grey Map (greyscale image) ppm_binary, //!< Portable Pixel Map (colour image), used by the field and cube classes - hdf5_binary, //!< Open binary format, not specific to Armadillo, which can store arbitrary data - hdf5_binary_trans, //!< as per hdf5_binary, but save/load the data with columns transposed to rows - coord_ascii //!< simple co-ordinate format for sparse matrices - }; - - -namespace hdf5_opts - { - typedef unsigned int flag_type; - - struct opts - { - const flag_type flags; - - inline explicit opts(const flag_type in_flags); - - inline const opts operator+(const opts& rhs) const; - }; - - inline - opts::opts(const flag_type in_flags) - : flags(in_flags) - {} - - inline - const opts - opts::operator+(const opts& rhs) const - { - const opts result( flags | rhs.flags ); - - return result; - } - - // The values below (eg. 1u << 0) are for internal Armadillo use only. - // The values can change without notice. - - static const flag_type flag_none = flag_type(0 ); - static const flag_type flag_trans = flag_type(1u << 0); - static const flag_type flag_append = flag_type(1u << 1); - static const flag_type flag_replace = flag_type(1u << 2); - - struct opts_none : public opts { inline opts_none() : opts(flag_none ) {} }; - struct opts_trans : public opts { inline opts_trans() : opts(flag_trans ) {} }; - struct opts_append : public opts { inline opts_append() : opts(flag_append ) {} }; - struct opts_replace : public opts { inline opts_replace() : opts(flag_replace) {} }; - - static const opts_none none; - static const opts_trans trans; - static const opts_append append; - static const opts_replace replace; - } - - -struct hdf5_name - { - const std::string filename; - const std::string dsname; - const hdf5_opts::opts opts; - - inline - hdf5_name(const std::string& in_filename) - : filename(in_filename ) - , dsname (std::string() ) - , opts (hdf5_opts::none) - {} - - inline - hdf5_name(const std::string& in_filename, const std::string& in_dsname, const hdf5_opts::opts& in_opts = hdf5_opts::none) - : filename(in_filename) - , dsname (in_dsname ) - , opts (in_opts ) - {} + hdf5_binary, //!< HDF5: open binary format, not specific to Armadillo, which can store arbitrary data + hdf5_binary_trans, //!< [NOTE: DO NOT USE - deprecated] as per hdf5_binary, but save/load the data with columns transposed to rows + coord_ascii, //!< simple co-ordinate format for sparse matrices (indices start at zero) + ssv_ascii, //!< similar to csv_ascii; uses semicolon (;) instead of comma (,) as the separator }; -//! @} - +static constexpr file_type file_type_unknown = file_type::file_type_unknown; +static constexpr file_type auto_detect = file_type::auto_detect; +static constexpr file_type raw_ascii = file_type::raw_ascii; +static constexpr file_type arma_ascii = file_type::arma_ascii; +static constexpr file_type csv_ascii = file_type::csv_ascii; +static constexpr file_type raw_binary = file_type::raw_binary; +static constexpr file_type arma_binary = file_type::arma_binary; +static constexpr file_type pgm_binary = file_type::pgm_binary; +static constexpr file_type ppm_binary = file_type::ppm_binary; +static constexpr file_type hdf5_binary = file_type::hdf5_binary; +static constexpr file_type hdf5_binary_trans = file_type::hdf5_binary_trans; +static constexpr file_type coord_ascii = file_type::coord_ascii; +static constexpr file_type ssv_ascii = file_type::ssv_ascii; -//! \addtogroup fill -//! @{ +struct hdf5_name; +struct csv_name; -namespace fill - { - struct fill_none {}; - struct fill_zeros {}; - struct fill_ones {}; - struct fill_eye {}; - struct fill_randu {}; - struct fill_randn {}; - - template - struct fill_class { inline fill_class() {} }; - - static const fill_class none; - static const fill_class zeros; - static const fill_class ones; - static const fill_class eye; - static const fill_class randu; - static const fill_class randn; - } //! @} @@ -505,5 +442,28 @@ } }; + +//! @} + + + +//! \ingroup fn_eigs_sym fs_eigs_gen +//! @{ + + +struct eigs_opts + { + double tol; // tolerance + unsigned int maxiter; // max iterations + unsigned int subdim; // subspace dimension + + inline eigs_opts() + { + tol = 0.0; + maxiter = 1000; + subdim = 0; + } + }; + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_ostream_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_ostream_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_ostream_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_ostream_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,15 +24,15 @@ class arma_ostream_state { private: - + const ios::fmtflags orig_flags; const std::streamsize orig_precision; const std::streamsize orig_width; const char orig_fill; - - + + public: - + inline arma_ostream_state(const std::ostream& o); inline void restore(std::ostream& o) const; @@ -44,26 +46,33 @@ template inline static std::streamsize modify_stream(std::ostream& o, const eT* data, const uword n_elem); template inline static std::streamsize modify_stream(std::ostream& o, const std::complex* data, const uword n_elem); - template inline static std::streamsize modify_stream(std::ostream& o, typename SpMat::const_iterator begin, const uword n_elem, const typename arma_not_cx::result* junk = 0); - template inline static std::streamsize modify_stream(std::ostream& o, typename SpMat< T>::const_iterator begin, const uword n_elem, const typename arma_cx_only::result* junk = 0); + template inline static std::streamsize modify_stream(std::ostream& o, typename SpMat::const_iterator begin, const uword n_elem, const typename arma_not_cx::result* junk = nullptr); + template inline static std::streamsize modify_stream(std::ostream& o, typename SpMat::const_iterator begin, const uword n_elem, const typename arma_cx_only::result* junk = nullptr); - template inline static void print_elem_zero(std::ostream& o, const bool modify); + template inline static void print_elem_zero(std::ostream& o, const bool modify); + template inline static void raw_print_elem_zero(std::ostream& o); + + template inline static void print_elem(std::ostream& o, const eT& x, const bool modify); + template inline static void raw_print_elem(std::ostream& o, const eT& x); + + template inline static void print_elem(std::ostream& o, const std::complex& x, const bool modify); + template inline static void raw_print_elem(std::ostream& o, const std::complex& x); - template inline static void print_elem(std::ostream& o, const eT& x, const bool modify); - template inline static void print_elem(std::ostream& o, const std::complex& x, const bool modify); - template arma_cold inline static void print(std::ostream& o, const Mat& m, const bool modify); template arma_cold inline static void print(std::ostream& o, const Cube& m, const bool modify); template arma_cold inline static void print(std::ostream& o, const field& m); template arma_cold inline static void print(std::ostream& o, const subview_field& m); - - + template arma_cold inline static void print_dense(std::ostream& o, const SpMat& m, const bool modify); template arma_cold inline static void print(std::ostream& o, const SpMat& m, const bool modify); arma_cold inline static void print(std::ostream& o, const SizeMat& S); arma_cold inline static void print(std::ostream& o, const SizeCube& S); + + template arma_cold inline static void brief_print(std::ostream& o, const Mat& m, const bool print_size = true); + template arma_cold inline static void brief_print(std::ostream& o, const Cube& m); + template arma_cold inline static void brief_print(std::ostream& o, const SpMat& m); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_ostream_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_ostream_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_ostream_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_ostream_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -190,18 +192,18 @@ { arma_extra_debug_sigprint(); arma_ignore(junk); - + o.unsetf(ios::showbase); o.unsetf(ios::uppercase); o.unsetf(ios::showpos); - + o.fill(' '); - + std::streamsize cell_width; - + bool use_layout_B = false; bool use_layout_C = false; - + for(typename SpMat::const_iterator it = begin; it.pos() < n_elem; ++it) { const eT val = (*it); @@ -218,7 +220,7 @@ use_layout_C = true; break; } - + if( (val >= eT(+10)) || ( (is_signed::value) && (val <= eT(-10)) ) ) @@ -226,7 +228,7 @@ use_layout_B = true; } } - + if(use_layout_C) { o.setf(ios::scientific); @@ -259,10 +261,10 @@ //! "better than nothing" settings for complex numbers -template +template inline std::streamsize -arma_ostream::modify_stream(std::ostream& o, typename SpMat::const_iterator begin, const uword n_elem, const typename arma_cx_only::result* junk) +arma_ostream::modify_stream(std::ostream& o, typename SpMat::const_iterator begin, const uword n_elem, const typename arma_cx_only::result* junk) { arma_ignore(begin); arma_ignore(n_elem); @@ -292,6 +294,8 @@ void arma_ostream::print_elem_zero(std::ostream& o, const bool modify) { + typedef typename promote_type::result promoted_eT; + if(modify) { const ios::fmtflags save_flags = o.flags(); @@ -301,113 +305,124 @@ o.setf(ios::fixed); o.precision(0); - o << eT(0); + o << promoted_eT(0); o.flags(save_flags); o.precision(save_precision); } else { - o << eT(0); + o << promoted_eT(0); } } -//! Print an element to the specified stream template inline void arma_ostream::print_elem(std::ostream& o, const eT& x, const bool modify) { + if(x == eT(0)) + { + arma_ostream::print_elem_zero(o, modify); + } + else + { + arma_ostream::raw_print_elem(o, x); + } + } + + + +template +inline +void +arma_ostream::raw_print_elem(std::ostream& o, const eT& x) + { if(is_signed::value) { typedef typename promote_type::result promoted_eT; - if(x != eT(0)) + if(arma_isfinite(x)) { - if(arma_isfinite(x)) - { - o << promoted_eT(x); - } - else - { - o << ( arma_isinf(x) ? ((x <= eT(0)) ? "-inf" : "inf") : "nan" ); - } + o << promoted_eT(x); } else { - arma_ostream::print_elem_zero(o, modify); + o << ( arma_isinf(x) ? ((x <= eT(0)) ? "-inf" : "inf") : "nan" ); } } else { typedef typename promote_type::result promoted_eT; - if(x != eT(0)) - { - o << promoted_eT(x); - } - else - { - arma_ostream::print_elem_zero(o, modify); - } + o << promoted_eT(x); } } -//! Print a complex element to the specified stream template inline void arma_ostream::print_elem(std::ostream& o, const std::complex& x, const bool modify) { - if( (x.real() != T(0)) || (x.imag() != T(0)) || (modify == false) ) + if( (x.real() == T(0)) && (x.imag() == T(0)) && (modify) ) { - std::ostringstream ss; - ss.flags(o.flags()); - //ss.imbue(o.getloc()); - ss.precision(o.precision()); - - ss << '('; - - const T a = x.real(); - - if(arma_isfinite(a)) - { - ss << a; - } - else - { - ss << ( arma_isinf(a) ? ((a <= T(0)) ? "-inf" : "+inf") : "nan" ); - } - - ss << ','; - - const T b = x.imag(); - - if(arma_isfinite(b)) - { - ss << b; - } - else - { - ss << ( arma_isinf(b) ? ((b <= T(0)) ? "-inf" : "+inf") : "nan" ); - } - - ss << ')'; - - o << ss.str(); + o << "(0,0)"; } else { - o << "(0,0)"; + arma_ostream::raw_print_elem(o, x); } } +template +inline +void +arma_ostream::raw_print_elem(std::ostream& o, const std::complex& x) + { + std::ostringstream ss; + ss.flags(o.flags()); + //ss.imbue(o.getloc()); + ss.precision(o.precision()); + + ss << '('; + + const T a = x.real(); + + if(arma_isfinite(a)) + { + ss << a; + } + else + { + ss << ( arma_isinf(a) ? ((a <= T(0)) ? "-inf" : "+inf") : "nan" ); + } + + ss << ','; + + const T b = x.imag(); + + if(arma_isfinite(b)) + { + ss << b; + } + else + { + ss << ( arma_isinf(b) ? ((b <= T(0)) ? "-inf" : "+inf") : "nan" ); + } + + ss << ')'; + + o << ss.str(); + } + + + //! Print a matrix to the specified stream template arma_cold @@ -461,6 +476,14 @@ } else { + if(modify) + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + } + o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n"; } @@ -487,16 +510,25 @@ { const Mat tmp(const_cast(x.slice_memptr(slice)), x.n_rows, x.n_cols, false); - o << "[cube slice " << slice << ']' << '\n'; + o << "[cube slice: " << slice << ']' << '\n'; arma_ostream::print(o, tmp, modify); - o << '\n'; + + if((slice+1) < x.n_slices) { o << '\n'; } } } else { + if(modify) + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + } + o << "[cube size: " << x.n_rows << 'x' << x.n_cols << 'x' << x.n_slices << "]\n"; } - + stream_state.restore(o); } @@ -504,7 +536,7 @@ //! Print a field to the specified stream -//! Assumes type oT can be printed, i.e. oT has std::ostream& operator<< (std::ostream&, const oT&) +//! Assumes type oT can be printed, ie. oT has std::ostream& operator<< (std::ostream&, const oT&) template arma_cold inline @@ -525,11 +557,11 @@ { if(x_n_slices == 1) { - for(uword col=0; col arma_cold inline @@ -594,9 +631,9 @@ { if(x_n_slices == 1) { - for(uword col=0; col(o, m.begin(), m_n_nonzero) : o.width(); - typename SpMat::const_iterator begin = m.begin(); - typename SpMat::const_iterator m_end = m.end(); + typename SpMat::const_iterator it = m.begin(); + typename SpMat::const_iterator it_end = m.end(); - while(begin != m_end) + while(it != it_end) { - const uword row = begin.row(); + const uword row = it.row(); + const uword col = it.col(); // TODO: change the maximum number of spaces before and after each location to be dependent on n_rows and n_cols - if(row < 10) { o << " "; } - else if(row < 100) { o << " "; } - else if(row < 1000) { o << " "; } - else if(row < 10000) { o << " "; } - else if(row < 100000) { o << ' '; } - - const uword col = begin.col(); + if(row < 10) { o << " "; } + else if(row < 100) { o << " "; } + else if(row < 1000) { o << " "; } + else if(row < 10000) { o << " "; } + else if(row < 100000) { o << " "; } + else if(row < 1000000) { o << ' '; } o << '(' << row << ", " << col << ") "; - if(col < 10) { o << " "; } - else if(col < 100) { o << " "; } - else if(col < 1000) { o << " "; } - else if(col < 10000) { o << " "; } - else if(col < 100000) { o << ' '; } + if(col < 10) { o << " "; } + else if(col < 100) { o << " "; } + else if(col < 1000) { o << " "; } + else if(col < 10000) { o << " "; } + else if(col < 100000) { o << " "; } + else if(col < 1000000) { o << ' '; } if(cell_width > 0) { o.width(cell_width); } - arma_ostream::print_elem(o, eT(*begin), modify); + arma_ostream::print_elem(o, eT(*it), modify); o << '\n'; - ++begin; + ++it; } o << '\n'; @@ -860,6 +911,375 @@ stream_state.restore(o); } + + +template +arma_cold +inline +void +arma_ostream::brief_print(std::ostream& o, const Mat& m, const bool print_size) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + if(print_size) + { + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + + o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "]\n"; + } + + if(m.n_elem == 0) { o.flush(); stream_state.restore(o); return; } + + if((m.n_rows <= 5) && (m.n_cols <= 5)) { arma_ostream::print(o, m, true); return; } + + const bool print_row_ellipsis = (m.n_rows >= 6); + const bool print_col_ellipsis = (m.n_cols >= 6); + + if( (print_row_ellipsis == true) && (print_col_ellipsis == true) ) + { + Mat X(4, 4, arma_nozeros_indicator()); + + X( span(0,2), span(0,2) ) = m( span(0,2), span(0,2) ); // top left submatrix + X( 3, span(0,2) ) = m( m.n_rows-1, span(0,2) ); // truncated last row + X( span(0,2), 3 ) = m( span(0,2), m.n_cols-1 ); // truncated last column + X( 3, 3 ) = m( m.n_rows-1, m.n_cols-1 ); // bottom right element + + const std::streamsize cell_width = arma_ostream::modify_stream(o, X.memptr(), X.n_elem); + + for(uword row=0; row <= 2; ++row) + { + for(uword col=0; col <= 2; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + + o.width(6); + o << "..."; + + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,3), true); + o << '\n'; + } + + for(uword col=0; col <= 2; ++col) + { + o.width(cell_width); + o << ':'; + } + + o.width(6); + o << "..."; + + o.width(cell_width); + o << ':' << '\n'; + + const uword row = 3; + { + for(uword col=0; col <= 2; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + + o.width(6); + o << "..."; + + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,3), true); + o << '\n'; + } + } + + + if( (print_row_ellipsis == true) && (print_col_ellipsis == false) ) + { + Mat X(4, m.n_cols, arma_nozeros_indicator()); + + X( span(0,2), span::all ) = m( span(0,2), span::all ); // top + X( 3, span::all ) = m( m.n_rows-1, span::all ); // bottom + + const std::streamsize cell_width = arma_ostream::modify_stream(o, X.memptr(), X.n_elem); + + for(uword row=0; row <= 2; ++row) // first 3 rows + { + for(uword col=0; col < m.n_cols; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + + o << '\n'; + } + + for(uword col=0; col < m.n_cols; ++col) + { + o.width(cell_width); + o << ':'; + } + + o.width(cell_width); + o << '\n'; + + const uword row = 3; + { + for(uword col=0; col < m.n_cols; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + } + + o << '\n'; + } + + + if( (print_row_ellipsis == false) && (print_col_ellipsis == true) ) + { + Mat X(m.n_rows, 4, arma_nozeros_indicator()); + + X( span::all, span(0,2) ) = m( span::all, span(0,2) ); // left + X( span::all, 3 ) = m( span::all, m.n_cols-1 ); // right + + const std::streamsize cell_width = arma_ostream::modify_stream(o, X.memptr(), X.n_elem); + + for(uword row=0; row < m.n_rows; ++row) + { + for(uword col=0; col <= 2; ++col) + { + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,col), true); + } + + o.width(6); + o << "..."; + + o.width(cell_width); + arma_ostream::print_elem(o, X.at(row,3), true); + o << '\n'; + } + } + + + o.flush(); + stream_state.restore(o); + } + + + +template +arma_cold +inline +void +arma_ostream::brief_print(std::ostream& o, const Cube& x) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(o); + + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.setf(ios::fixed); + + o << "[cube size: " << x.n_rows << 'x' << x.n_cols << 'x' << x.n_slices << "]\n"; + + if(x.n_elem == 0) { o.flush(); stream_state.restore(o); return; } + + if(x.n_slices <= 3) + { + for(uword slice=0; slice < x.n_slices; ++slice) + { + const Mat tmp(const_cast(x.slice_memptr(slice)), x.n_rows, x.n_cols, false); + + o << "[cube slice: " << slice << ']' << '\n'; + arma_ostream::brief_print(o, tmp, false); + + if((slice+1) < x.n_slices) { o << '\n'; } + } + } + else + { + for(uword slice=0; slice <= 1; ++slice) + { + const Mat tmp(const_cast(x.slice_memptr(slice)), x.n_rows, x.n_cols, false); + + o << "[cube slice: " << slice << ']' << '\n'; + arma_ostream::brief_print(o, tmp, false); + o << '\n'; + } + + o << "[cube slice: ...]\n\n"; + + const uword slice = x.n_slices-1; + { + const Mat tmp(const_cast(x.slice_memptr(slice)), x.n_rows, x.n_cols, false); + + o << "[cube slice: " << slice << ']' << '\n'; + arma_ostream::brief_print(o, tmp, false); + } + } + + stream_state.restore(o); + } + + + +template +arma_cold +inline +void +arma_ostream::brief_print(std::ostream& o, const SpMat& m) + { + arma_extra_debug_sigprint(); + + if(m.n_nonzero <= 10) { arma_ostream::print(o, m, true); return; } + + const arma_ostream_state stream_state(o); + + o.unsetf(ios::showbase); + o.unsetf(ios::uppercase); + o.unsetf(ios::showpos); + o.unsetf(ios::scientific); + o.setf(ios::right); + o.setf(ios::fixed); + + const uword m_n_nonzero = m.n_nonzero; + const double density = (m.n_elem > 0) ? (double(m_n_nonzero) / double(m.n_elem) * double(100)) : double(0); + + o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "; n_nonzero: " << m_n_nonzero; + + if(density == double(0)) + { + o.precision(0); + } + else + if(density >= (double(10.0)-std::numeric_limits::epsilon())) + { + o.precision(1); + } + else + if(density > (double(0.01)-std::numeric_limits::epsilon())) + { + o.precision(2); + } + else + if(density > (double(0.001)-std::numeric_limits::epsilon())) + { + o.precision(3); + } + else + if(density > (double(0.0001)-std::numeric_limits::epsilon())) + { + o.precision(4); + } + else + { + o.unsetf(ios::fixed); + o.setf(ios::scientific); + o.precision(2); + } + + o << "; density: " << density << "%]\n\n"; + + // get the first 9 elements and the last element + + typename SpMat::const_iterator it = m.begin(); + typename SpMat::const_iterator it_end = m.end(); + + uvec storage_row(10); + uvec storage_col(10); + Col storage_val(10); + + uword count = 0; + + while( (it != it_end) && (count < 9) ) + { + storage_row(count) = it.row(); + storage_col(count) = it.col(); + storage_val(count) = (*it); + + ++it; + ++count; + } + + it = it_end; + --it; + + storage_row(count) = it.row(); + storage_col(count) = it.col(); + storage_val(count) = (*it); + + const std::streamsize cell_width = arma_ostream::modify_stream(o, storage_val.memptr(), 10); + + for(uword i=0; i < 9; ++i) + { + const uword row = storage_row(i); + const uword col = storage_col(i); + + if(row < 10) { o << " "; } + else if(row < 100) { o << " "; } + else if(row < 1000) { o << " "; } + else if(row < 10000) { o << " "; } + else if(row < 100000) { o << " "; } + else if(row < 1000000) { o << ' '; } + + o << '(' << row << ", " << col << ") "; + + if(col < 10) { o << " "; } + else if(col < 100) { o << " "; } + else if(col < 1000) { o << " "; } + else if(col < 10000) { o << " "; } + else if(col < 100000) { o << " "; } + else if(col < 1000000) { o << ' '; } + + if(cell_width > 0) { o.width(cell_width); } + + arma_ostream::print_elem(o, storage_val(i), true); + o << '\n'; + } + + o << " (:, :) "; + if(cell_width > 0) { o.width(cell_width); } + o << "...\n"; + + + const uword i = 9; + { + const uword row = storage_row(i); + const uword col = storage_col(i); + + if(row < 10) { o << " "; } + else if(row < 100) { o << " "; } + else if(row < 1000) { o << " "; } + else if(row < 10000) { o << " "; } + else if(row < 100000) { o << " "; } + else if(row < 1000000) { o << ' '; } + + o << '(' << row << ", " << col << ") "; + + if(col < 10) { o << " "; } + else if(col < 100) { o << " "; } + else if(col < 1000) { o << " "; } + else if(col < 10000) { o << " "; } + else if(col < 100000) { o << " "; } + else if(col < 1000000) { o << ' '; } + + if(cell_width > 0) { o.width(cell_width); } + + arma_ostream::print_elem(o, storage_val(i), true); + o << '\n'; + } + + o.flush(); + stream_state.restore(o); + } + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_rel_comparators.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rel_comparators.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_rel_comparators.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rel_comparators.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -67,6 +69,33 @@ // // return ( (abs_a != abs_b) ? (abs_a < abs_b) : (std::arg(a) < std::arg(b)) ); // } + + // inline + // bool + // operator() (const eT& a, const eT& b) const + // { + // const T a_real = a.real(); + // const T a_imag = a.imag(); + // + // const T a_mag_squared = a_real*a_real + a_imag*a_imag; + // + // const T b_real = b.real(); + // const T b_imag = b.imag(); + // + // const T b_mag_squared = b_real*b_real + b_imag*b_imag; + // + // if( (a_mag_squared != T(0)) && (b_mag_squared != T(0)) && std::isfinite(a_mag_squared) && std::isfinite(b_mag_squared) ) + // { + // return ( (a_mag_squared != b_mag_squared) ? (a_mag_squared < b_mag_squared) : (std::arg(a) < std::arg(b)) ); + // } + // else + // { + // const T abs_a = std::abs(a); + // const T abs_b = std::abs(b); + // + // return ( (abs_a != abs_b) ? (abs_a < abs_b) : (std::arg(a) < std::arg(b)) ); + // } + // } }; @@ -87,6 +116,33 @@ // // return ( (abs_a != abs_b) ? (abs_a > abs_b) : (std::arg(a) > std::arg(b)) ); // } + + // inline + // bool + // operator() (const eT& a, const eT& b) const + // { + // const T a_real = a.real(); + // const T a_imag = a.imag(); + // + // const T a_mag_squared = a_real*a_real + a_imag*a_imag; + // + // const T b_real = b.real(); + // const T b_imag = b.imag(); + // + // const T b_mag_squared = b_real*b_real + b_imag*b_imag; + // + // if( (a_mag_squared != T(0)) && (b_mag_squared != T(0)) && std::isfinite(a_mag_squared) && std::isfinite(b_mag_squared) ) + // { + // return ( (a_mag_squared != b_mag_squared) ? (a_mag_squared > b_mag_squared) : (std::arg(a) > std::arg(b)) ); + // } + // else + // { + // const T abs_a = std::abs(a); + // const T abs_b = std::abs(b); + // + // return ( (abs_a != abs_b) ? (abs_a > abs_b) : (std::arg(a) > std::arg(b)) ); + // } + // } }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_rng_cxx11.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng_cxx11.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_rng_cxx11.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng_cxx11.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -18,9 +20,6 @@ //! @{ -#if defined(ARMA_USE_CXX11) - - class arma_rng_cxx11 { public: @@ -208,7 +207,4 @@ } -#endif - - //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_rng_cxx98.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng_cxx98.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_rng_cxx98.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng_cxx98.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -104,7 +106,7 @@ w = tmp1*tmp1 + tmp2*tmp2; } - while ( w >= double(1) ); + while( w >= double(1) ); return double( tmp1 * std::sqrt( (double(-2) * std::log(w)) / w) ); } @@ -130,7 +132,7 @@ w = tmp1*tmp1 + tmp2*tmp2; } - while ( w >= eTp(1) ); + while( w >= eTp(1) ); const eTp k = std::sqrt( (eTp(-2) * std::log(w)) / w); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_rng.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_rng.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,39 +21,74 @@ #if defined(ARMA_RNG_ALT) - #undef ARMA_USE_EXTERN_CXX11_RNG + #undef ARMA_USE_EXTERN_RNG #endif -#if !defined(ARMA_USE_CXX11) - #undef ARMA_USE_EXTERN_CXX11_RNG +// NOTE: mt19937_64_instance_warmup is used as a workaround +// NOTE: for thread_local issue on macOS 11 and/or AppleClang 12.0 +// NOTE: see https://gitlab.com/conradsnicta/armadillo-code/-/issues/173 +// NOTE: if this workaround causes problems, please report it and +// NOTE: disable the workaround by uncommenting the code block below: + +// #if defined(__APPLE__) || defined(__apple_build_version__) +// #if !defined(ARMA_DONT_DISABLE_EXTERN_RNG) +// #undef ARMA_USE_EXTERN_RNG +// #endif +// #endif + + +// NOTE: workaround for another thread_local issue on macOS +// NOTE: where GCC (not Clang) may not have support for thread_local + +#if (defined(__APPLE__) && defined(__GNUG__) && !defined(__clang__)) + #if !defined(ARMA_DONT_DISABLE_EXTERN_RNG) + #undef ARMA_USE_EXTERN_RNG + #endif #endif -#if defined(ARMA_USE_EXTERN_CXX11_RNG) - extern thread_local arma_rng_cxx11 arma_rng_cxx11_instance; - // namespace { thread_local arma_rng_cxx11 arma_rng_cxx11_instance; } + +#if defined(ARMA_USE_EXTERN_RNG) + extern thread_local std::mt19937_64 mt19937_64_instance; + + #if defined(__APPLE__) || defined(__apple_build_version__) + namespace + { + struct mt19937_64_instance_warmup + { + inline mt19937_64_instance_warmup() + { + typename std::mt19937_64::result_type junk = mt19937_64_instance(); + arma_ignore(junk); + } + }; + + static mt19937_64_instance_warmup mt19937_64_instance_warmup_run; + } + #endif #endif + class arma_rng { public: #if defined(ARMA_RNG_ALT) - typedef arma_rng_alt::seed_type seed_type; - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) - typedef arma_rng_cxx11::seed_type seed_type; + typedef arma_rng_alt::seed_type seed_type; + #elif defined(ARMA_USE_EXTERN_RNG) + typedef std::mt19937_64::result_type seed_type; #else - typedef arma_rng_cxx98::seed_type seed_type; + typedef arma_rng_cxx98::seed_type seed_type; #endif #if defined(ARMA_RNG_ALT) - static const int rng_method = 2; - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) - static const int rng_method = 1; + static constexpr int rng_method = 2; + #elif defined(ARMA_USE_EXTERN_RNG) + static constexpr int rng_method = 1; #else - static const int rng_method = 0; + static constexpr int rng_method = 0; #endif inline static void set_seed(const seed_type val); @@ -60,6 +97,7 @@ template struct randi; template struct randu; template struct randn; + template struct randg; }; @@ -72,9 +110,9 @@ { arma_rng_alt::set_seed(val); } - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) + #elif defined(ARMA_USE_EXTERN_RNG) { - arma_rng_cxx11_instance.set_seed(val); + mt19937_64_instance.seed(val); } #else { @@ -94,23 +132,18 @@ seed_type seed2 = seed_type(0); seed_type seed3 = seed_type(0); seed_type seed4 = seed_type(0); - seed_type seed5 = seed_type(0); bool have_seed = false; - #if defined(ARMA_USE_CXX11) + try { - try - { - std::random_device rd; - - if(rd.entropy() > double(0)) { seed1 = static_cast( rd() ); } - - if(seed1 != seed_type(0)) { have_seed = true; } - } - catch(...) {} + std::random_device rd; + + if(rd.entropy() > double(0)) { seed1 = static_cast( rd() ); } + + if(seed1 != seed_type(0)) { have_seed = true; } } - #endif + catch(...) {} if(have_seed == false) @@ -144,17 +177,11 @@ { // get better-than-nothing seeds in case reading /dev/urandom failed - #if defined(ARMA_HAVE_GETTIMEOFDAY) - { - struct timeval posix_time; - - gettimeofday(&posix_time, 0); - - seed3 = static_cast(posix_time.tv_usec); - } - #endif + const std::chrono::system_clock::time_point tp_now = std::chrono::system_clock::now(); + + auto since_epoch_usec = std::chrono::duration_cast(tp_now.time_since_epoch()).count(); - seed4 = static_cast( std::time(NULL) & 0xFFFF ); + seed3 = static_cast( since_epoch_usec & 0xFFFF ); union { @@ -164,32 +191,38 @@ tmp.a = (uword*)malloc(sizeof(uword)); - if(tmp.a != NULL) + if(tmp.a != nullptr) { - for(size_t i=0; i struct arma_rng::randi { - arma_inline + inline operator eT () { #if defined(ARMA_RNG_ALT) { return eT( arma_rng_alt::randi_val() ); } - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) + #elif defined(ARMA_USE_EXTERN_RNG) { - return eT( arma_rng_cxx11_instance.randi_val() ); + constexpr double scale = double(std::numeric_limits::max()) / double(std::mt19937_64::max()); + + return eT( double(mt19937_64_instance()) * scale ); } #else { @@ -208,9 +241,9 @@ { return arma_rng_alt::randi_max_val(); } - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) + #elif defined(ARMA_USE_EXTERN_RNG) { - return arma_rng_cxx11::randi_max_val(); + return std::numeric_limits::max(); } #else { @@ -229,13 +262,24 @@ { arma_rng_alt::randi_fill(mem, N, a, b); } - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) + #elif defined(ARMA_USE_EXTERN_RNG) { - arma_rng_cxx11_instance.randi_fill(mem, N, a, b); + std::uniform_int_distribution local_i_distr(a, b); + + for(uword i=0; i local_i_distr(a, b); + + local_engine.seed( local_seed_type(std::rand()) ); + + for(uword i=0; i struct arma_rng::randu { - arma_inline + inline operator eT () { #if defined(ARMA_RNG_ALT) { return eT( arma_rng_alt::randu_val() ); } - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) + #elif defined(ARMA_USE_EXTERN_RNG) { - return eT( arma_rng_cxx11_instance.randu_val() ); + constexpr double scale = double(1.0) / double(std::mt19937_64::max()); + + return eT( double(mt19937_64_instance()) * scale ); } #else { @@ -270,21 +320,30 @@ void fill(eT* mem, const uword N) { - uword j; - - for(j=1; j < N; j+=2) + #if defined(ARMA_RNG_ALT) + { + for(uword i=0; i < N; ++i) { mem[i] = eT( arma_rng_alt::randu_val() ); } + } + #elif defined(ARMA_USE_EXTERN_RNG) { - const eT tmp_i = eT( arma_rng::randu() ); - const eT tmp_j = eT( arma_rng::randu() ); + std::uniform_real_distribution local_u_distr; - (*mem) = tmp_i; mem++; - (*mem) = tmp_j; mem++; + for(uword i=0; i < N; ++i) { mem[i] = eT( local_u_distr(mt19937_64_instance) ); } } - - if((j-1) < N) + #else { - (*mem) = eT( arma_rng::randu() ); + if(N == uword(1)) { mem[0] = eT( arma_rng_cxx98::randu_val() ); return; } + + typedef typename std::mt19937_64::result_type local_seed_type; + + std::mt19937_64 local_engine; + std::uniform_real_distribution local_u_distr; + + local_engine.seed( local_seed_type(std::rand()) ); + + for(uword i=0; i < N; ++i) { mem[i] = eT( local_u_distr(local_engine) ); } } + #endif } }; @@ -296,10 +355,30 @@ arma_inline operator std::complex () { - const T a = T( arma_rng::randu() ); - const T b = T( arma_rng::randu() ); - - return std::complex(a, b); + #if defined(ARMA_RNG_ALT) + { + const T a = T( arma_rng_alt::randu_val() ); + const T b = T( arma_rng_alt::randu_val() ); + + return std::complex(a, b); + } + #elif defined(ARMA_USE_EXTERN_RNG) + { + std::uniform_real_distribution local_u_distr; + + const T a = T( local_u_distr(mt19937_64_instance) ); + const T b = T( local_u_distr(mt19937_64_instance) ); + + return std::complex(a, b); + } + #else + { + const T a = T( arma_rng_cxx98::randu_val() ); + const T b = T( arma_rng_cxx98::randu_val() ); + + return std::complex(a, b); + } + #endif } @@ -308,18 +387,65 @@ void fill(std::complex* mem, const uword N) { - for(uword i=0; i < N; ++i) + #if defined(ARMA_RNG_ALT) { - const T a = T( arma_rng::randu() ); - const T b = T( arma_rng::randu() ); + for(uword i=0; i < N; ++i) + { + const T a = T( arma_rng_alt::randu_val() ); + const T b = T( arma_rng_alt::randu_val() ); + + mem[i] = std::complex(a, b); + } + } + #elif defined(ARMA_USE_EXTERN_RNG) + { + std::uniform_real_distribution local_u_distr; - mem[i] = std::complex(a, b); + for(uword i=0; i < N; ++i) + { + const T a = T( local_u_distr(mt19937_64_instance) ); + const T b = T( local_u_distr(mt19937_64_instance) ); + + mem[i] = std::complex(a, b); + } } + #else + { + if(N == uword(1)) + { + const T a = T( arma_rng_cxx98::randu_val() ); + const T b = T( arma_rng_cxx98::randu_val() ); + + mem[0] = std::complex(a, b); + + return; + } + + typedef typename std::mt19937_64::result_type local_seed_type; + + std::mt19937_64 local_engine; + std::uniform_real_distribution local_u_distr; + + local_engine.seed( local_seed_type(std::rand()) ); + + for(uword i=0; i < N; ++i) + { + const T a = T( local_u_distr(local_engine) ); + const T b = T( local_u_distr(local_engine) ); + + mem[i] = std::complex(a, b); + } + } + #endif } }; +// + + + template struct arma_rng::randn { @@ -330,9 +456,11 @@ { return eT( arma_rng_alt::randn_val() ); } - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) + #elif defined(ARMA_USE_EXTERN_RNG) { - return eT( arma_rng_cxx11_instance.randn_val() ); + std::normal_distribution local_n_distr; + + return eT( local_n_distr(mt19937_64_instance) ); } #else { @@ -342,7 +470,7 @@ } - arma_inline + inline static void dual_val(eT& out1, eT& out2) @@ -351,9 +479,12 @@ { arma_rng_alt::randn_dual_val(out1, out2); } - #elif defined(ARMA_USE_EXTERN_CXX11_RNG) + #elif defined(ARMA_USE_EXTERN_RNG) { - arma_rng_cxx11_instance.randn_dual_val(out1, out2); + std::normal_distribution local_n_distr; + + out1 = eT( local_n_distr(mt19937_64_instance) ); + out2 = eT( local_n_distr(mt19937_64_instance) ); } #else { @@ -368,17 +499,36 @@ void fill_simple(eT* mem, const uword N) { - uword i, j; - - for(i=0, j=1; j < N; i+=2, j+=2) + #if defined(ARMA_RNG_ALT) { - arma_rng::randn::dual_val( mem[i], mem[j] ); + // NOTE: old method to avoid regressions in user code that assumes specific sequence + + uword i, j; + + for(i=0, j=1; j < N; i+=2, j+=2) { arma_rng_alt::randn_dual_val( mem[i], mem[j] ); } + + if(i < N) { mem[i] = eT( arma_rng_alt::randn_val() ); } } - - if(i < N) + #elif defined(ARMA_USE_EXTERN_RNG) + { + std::normal_distribution local_n_distr; + + for(uword i=0; i < N; ++i) { mem[i] = eT( local_n_distr(mt19937_64_instance) ); } + } + #else { - mem[i] = eT( arma_rng::randn() ); + if(N == uword(1)) { mem[0] = eT( arma_rng_cxx98::randn_val() ); return; } + + typedef typename std::mt19937_64::result_type local_seed_type; + + std::mt19937_64 local_engine; + std::normal_distribution local_n_distr; + + local_engine.seed( local_seed_type(std::rand()) ); + + for(uword i=0; i < N; ++i) { mem[i] = eT( local_n_distr(local_engine) ); } } + #endif } @@ -387,11 +537,11 @@ void fill(eT* mem, const uword N) { - #if defined(ARMA_USE_CXX11) && defined(ARMA_USE_OPENMP) + #if defined(ARMA_USE_OPENMP) { if((N < 1024) || omp_in_parallel()) { arma_rng::randn::fill_simple(mem, N); return; } - typedef std::mt19937_64::result_type seed_type; + typedef typename std::mt19937_64::result_type local_seed_type; const uword n_threads = uword( mp_thread_limit::get() ); @@ -402,7 +552,7 @@ { std::mt19937_64& t_engine = engine[t]; - t_engine.seed( seed_type(t) + seed_type(arma_rng::randi()) ); + t_engine.seed( local_seed_type(t) + local_seed_type(arma_rng::randi()) ); } const uword chunk_size = N / n_threads; @@ -460,12 +610,75 @@ inline static void + dual_val(std::complex& out1, std::complex& out2) + { + #if defined(_MSC_VER) + T a; + T b; + #else + T a(0); + T b(0); + #endif + + arma_rng::randn::dual_val(a,b); + out1 = std::complex(a,b); + + arma_rng::randn::dual_val(a,b); + out2 = std::complex(a,b); + } + + + inline + static + void fill_simple(std::complex* mem, const uword N) { - for(uword i=0; i < N; ++i) + #if defined(ARMA_RNG_ALT) { - mem[i] = std::complex( arma_rng::randn< std::complex >() ); + for(uword i=0; i < N; ++i) { mem[i] = std::complex( arma_rng::randn< std::complex >() ); } } + #elif defined(ARMA_USE_EXTERN_RNG) + { + std::normal_distribution local_n_distr; + + for(uword i=0; i < N; ++i) + { + const T a = T( local_n_distr(mt19937_64_instance) ); + const T b = T( local_n_distr(mt19937_64_instance) ); + + mem[i] = std::complex(a,b); + } + } + #else + { + if(N == uword(1)) + { + T a = T(0); + T b = T(0); + + arma_rng_cxx98::randn_dual_val(a,b); + + mem[0] = std::complex(a,b); + + return; + } + + typedef typename std::mt19937_64::result_type local_seed_type; + + std::mt19937_64 local_engine; + std::normal_distribution local_n_distr; + + local_engine.seed( local_seed_type(std::rand()) ); + + for(uword i=0; i < N; ++i) + { + const T a = T( local_n_distr(local_engine) ); + const T b = T( local_n_distr(local_engine) ); + + mem[i] = std::complex(a,b); + } + } + #endif } @@ -474,11 +687,11 @@ void fill(std::complex* mem, const uword N) { - #if defined(ARMA_USE_CXX11) && defined(ARMA_USE_OPENMP) + #if defined(ARMA_USE_OPENMP) { if((N < 512) || omp_in_parallel()) { arma_rng::randn< std::complex >::fill_simple(mem, N); return; } - typedef std::mt19937_64::result_type seed_type; + typedef typename std::mt19937_64::result_type local_seed_type; const uword n_threads = uword( mp_thread_limit::get() ); @@ -489,7 +702,7 @@ { std::mt19937_64& t_engine = engine[t]; - t_engine.seed( seed_type(t) + seed_type(arma_rng::randi()) ); + t_engine.seed( local_seed_type(t) + local_seed_type(arma_rng::randi()) ); } const uword chunk_size = N / n_threads; @@ -532,5 +745,98 @@ }; + +// + + + +template +struct arma_rng::randg + { + inline + static + void + fill_simple(eT* mem, const uword N, const double a, const double b) + { + #if defined(ARMA_USE_EXTERN_RNG) + { + std::gamma_distribution local_g_distr(a,b); + + for(uword i=0; i local_g_distr(a,b); + + local_engine.seed( local_seed_type(arma_rng::randi()) ); + + for(uword i=0; i::fill_simple(mem, N, a, b); return; } + + typedef std::mt19937_64 motor_type; + typedef std::mt19937_64::result_type ovum_type; + typedef std::gamma_distribution distr_type; + + const uword n_threads = uword( mp_thread_limit::get() ); + + std::vector g_motor(n_threads); + std::vector g_distr(n_threads); + + const distr_type g_distr_base(a,b); + + for(uword t=0; t < n_threads; ++t) + { + motor_type& g_motor_t = g_motor[t]; + distr_type& g_distr_t = g_distr[t]; + + g_motor_t.seed( ovum_type(t) + ovum_type(arma_rng::randi()) ); + + g_distr_t.param( g_distr_base.param() ); + } + + const uword chunk_size = N / n_threads; + + #pragma omp parallel for schedule(static) num_threads(int(n_threads)) + for(uword t=0; t < n_threads; ++t) + { + const uword start = (t+0) * chunk_size; + const uword endp1 = (t+1) * chunk_size; + + motor_type& g_motor_t = g_motor[t]; + distr_type& g_distr_t = g_distr[t]; + + for(uword i=start; i < endp1; ++i) { mem[i] = eT( g_distr_t(g_motor_t)); } + } + + motor_type& g_motor_0 = g_motor[0]; + distr_type& g_distr_0 = g_distr[0]; + + for(uword i=(n_threads*chunk_size); i < N; ++i) { mem[i] = eT( g_distr_0(g_motor_0)); } + } + #else + { + arma_rng::randg::fill_simple(mem, N, a, b); + } + #endif + } + + }; + + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_static_check.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_static_check.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_static_check.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_static_check.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -18,49 +20,11 @@ //! @{ +#undef arma_static_check +#define arma_static_check(condition, message) static_assert( !(condition), message ) -template -struct arma_type_check_cxx1998 - { - arma_inline - static - void - apply() - { - static const char - junk[ ERROR___TYPE_MISMATCH_OR_UNSUPPORTED_TYPE ? -1 : +1 ]; - } - }; - - - -template<> -struct arma_type_check_cxx1998 - { - arma_inline - static - void - apply() - { - } - }; - - - -#if defined(ARMA_USE_CXX11) - - #define arma_static_check(condition, message) static_assert( !(condition), #message ) - - #define arma_type_check(condition) static_assert( !(condition), "error: type mismatch or unsupported type" ) - -#else - - #define arma_static_check(condition, message) static const char message[ (condition) ? -1 : +1 ] - - #define arma_type_check(condition) arma_type_check_cxx1998::apply() - -#endif - +#undef arma_type_check +#define arma_type_check(condition) static_assert( !(condition), "error: type mismatch or unsupported type" ) //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_str.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_str.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_str.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_str.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,37 +23,6 @@ namespace arma_str { - #if ( defined(ARMA_USE_CXX11) || defined(ARMA_HAVE_SNPRINTF) ) - - #define arma_snprintf std::snprintf - - #else - - // better-than-nothing emulation of C99 snprintf(), - // with correct return value and null-terminated output string. - // note that _snprintf() provided by MS is not a good substitute for snprintf() - - inline - int - arma_snprintf(char* out, size_t size, const char* fmt, ...) - { - size_t i; - - for(i=0; i 0) - out[size-1] = char(0); - - return int(i); - } - - #endif - class format { public: @@ -66,6 +37,7 @@ { } + // TODO: constructor to handle std::string&& ? const std::string A; @@ -137,7 +109,7 @@ buffer = new char[size_t(buffer_size)]; } - required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B); + required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B); if(required_size < 0) { break; } @@ -191,7 +163,7 @@ buffer = new char[size_t(buffer_size)]; } - required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B); + required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B); if(required_size < 0) { break; } @@ -245,7 +217,7 @@ buffer = new char[size_t(buffer_size)]; } - required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.c_str(), X.A.A.B, X.A.B, X.B); + required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.A.A.c_str(), X.A.A.B, X.A.B, X.B); if(required_size < 0) { break; } @@ -299,7 +271,7 @@ buffer = new char[size_t(buffer_size)]; } - required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B); + required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B); if(required_size < 0) { break; } @@ -353,7 +325,7 @@ buffer = new char[size_t(buffer_size)]; } - required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.c_str(), X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B); + required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.c_str(), X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B); if(required_size < 0) { break; } @@ -407,7 +379,7 @@ buffer = new char[size_t(buffer_size)]; } - required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.A.c_str(), X.A.A.A.A.A.B, X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B); + required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.A.c_str(), X.A.A.A.A.A.B, X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B); if(required_size < 0) { break; } @@ -442,7 +414,7 @@ template struct format_metaprog { - static const uword depth = 0; + static constexpr uword depth = 0; inline static @@ -459,7 +431,7 @@ template struct format_metaprog< basic_format > { - static const uword depth = 1 + format_metaprog::depth; + static constexpr uword depth = 1 + format_metaprog::depth; inline static @@ -511,7 +483,7 @@ inline static const T1& - str_wrapper(const T1& x, const typename string_only::result* junk = 0) + str_wrapper(const T1& x, const typename string_only::result* junk = nullptr) { arma_ignore(junk); @@ -524,7 +496,7 @@ inline static const T1* - str_wrapper(const T1* x, const typename char_only::result* junk = 0) + str_wrapper(const T1* x, const typename char_only::result* junk = nullptr) { arma_ignore(junk); @@ -537,7 +509,7 @@ inline static std::string - str_wrapper(const T1& x, const typename basic_format_only::result* junk = 0) + str_wrapper(const T1& x, const typename basic_format_only::result* junk = nullptr) { arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arma_version.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arma_version.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arma_version.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arma_version.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,18 +21,18 @@ -#define ARMA_VERSION_MAJOR 9 -#define ARMA_VERSION_MINOR 800 -#define ARMA_VERSION_PATCH 4 -#define ARMA_VERSION_NAME "Horizon Scraper" +#define ARMA_VERSION_MAJOR 10 +#define ARMA_VERSION_MINOR 8 +#define ARMA_VERSION_PATCH 2 +#define ARMA_VERSION_NAME "Realm Raider" struct arma_version { - static const unsigned int major = ARMA_VERSION_MAJOR; - static const unsigned int minor = ARMA_VERSION_MINOR; - static const unsigned int patch = ARMA_VERSION_PATCH; + static constexpr unsigned int major = ARMA_VERSION_MAJOR; + static constexpr unsigned int minor = ARMA_VERSION_MINOR; + static constexpr unsigned int patch = ARMA_VERSION_PATCH; static inline diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arrayops_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arrayops_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arrayops_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arrayops_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,48 +25,51 @@ public: template - arma_hot arma_inline static void + arma_inline static void copy(eT* dest, const eT* src, const uword n_elem); - template arma_cold inline static void copy_small(eT* dest, const eT* src, const uword n_elem); - template - arma_hot inline static void + inline static void fill_zeros(eT* dest, const uword n_elem); - template arma_hot inline static void replace(eT* mem, const uword n_elem, const eT old_val, const eT new_val); - template arma_hot inline static void - clean(eT* mem, const uword n_elem, const eT abs_limit, const typename arma_not_cx::result* junk = 0); - + clean(eT* mem, const uword n_elem, const eT abs_limit, const typename arma_not_cx::result* junk = nullptr); template arma_hot inline static void clean(std::complex* mem, const uword n_elem, const T abs_limit); + template + inline static void + clamp(eT* mem, const uword n_elem, const eT min_val, const eT max_val, const typename arma_not_cx::result* junk = nullptr); + + template + inline static void + clamp(std::complex* mem, const uword n_elem, const std::complex& min_val, const std::complex& max_val); + // // array = convert(array) template - arma_hot arma_inline static void - convert_cx_scalar(out_eT& out, const in_eT& in, const typename arma_not_cx::result* junk1 = 0, const typename arma_not_cx< in_eT>::result* junk2 = 0); + arma_inline static void + convert_cx_scalar(out_eT& out, const in_eT& in, const typename arma_not_cx::result* junk1 = nullptr, const typename arma_not_cx< in_eT>::result* junk2 = nullptr); template - arma_hot arma_inline static void - convert_cx_scalar(out_eT& out, const std::complex& in, const typename arma_not_cx::result* junk = 0); + arma_inline static void + convert_cx_scalar(out_eT& out, const std::complex& in, const typename arma_not_cx::result* junk = nullptr); template - arma_hot arma_inline static void + arma_inline static void convert_cx_scalar(std::complex& out, const std::complex< in_T>& in); template @@ -132,6 +137,11 @@ template arma_hot inline static void + inplace_set_simple(eT* dest, const eT val, const uword n_elem); + + template + arma_hot inline static + void inplace_set_base(eT* dest, const eT val, const uword n_elem); template @@ -199,6 +209,16 @@ template arma_hot inline static + bool + is_zero(const eT* mem, const uword n_elem, const eT abs_limit, const typename arma_not_cx::result* junk = nullptr); + + template + arma_hot inline static + bool + is_zero(const std::complex* mem, const uword n_elem, const T abs_limit); + + template + arma_hot inline static bool is_finite(const eT* src, const uword n_elem); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/arrayops_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/arrayops_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/arrayops_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/arrayops_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,11 +22,12 @@ template -arma_hot arma_inline void arrayops::copy(eT* dest, const eT* src, const uword n_elem) { + if( (dest == src) || (n_elem == 0) ) { return; } + if(is_cx::no) { if(n_elem <= 9) @@ -38,7 +41,7 @@ } else { - if(n_elem > 0) { std::memcpy(dest, src, n_elem*sizeof(eT)); } + std::memcpy(dest, src, n_elem*sizeof(eT)); } } @@ -77,12 +80,22 @@ template -arma_hot inline void arrayops::fill_zeros(eT* dest, const uword n_elem) { - arrayops::inplace_set(dest, eT(0), n_elem); + typedef typename get_pod_type::result pod_type; + + if(n_elem == 0) { return; } + + if(std::numeric_limits::is_integer || std::numeric_limits::is_iec559) + { + std::memset((void*)dest, 0, sizeof(eT)*n_elem); + } + else + { + arrayops::inplace_set_simple(dest, eT(0), n_elem); + } } @@ -127,7 +140,7 @@ { eT& val = mem[i]; - val = (std::abs(val) <= abs_limit) ? eT(0) : val; + val = (eop_aux::arma_abs(val) <= abs_limit) ? eT(0) : val; } } @@ -164,8 +177,53 @@ +template +inline +void +arrayops::clamp(eT* mem, const uword n_elem, const eT min_val, const eT max_val, const typename arma_not_cx::result* junk) + { + arma_ignore(junk); + + for(uword i=0; i max_val) ? max_val : val); + } + } + + + +template +inline +void +arrayops::clamp(std::complex* mem, const uword n_elem, const std::complex& min_val, const std::complex& max_val) + { + typedef typename std::complex eT; + + const T min_val_real = std::real(min_val); + const T min_val_imag = std::imag(min_val); + + const T max_val_real = std::real(max_val); + const T max_val_imag = std::imag(max_val); + + for(uword i=0; i max_val_real) ? max_val_real : val_real); + val_imag = (val_imag < min_val_imag) ? min_val_imag : ((val_imag > max_val_imag) ? max_val_imag : val_imag); + + val = std::complex(val_real,val_imag); + } + } + + + template -arma_hot arma_inline void arrayops::convert_cx_scalar @@ -185,7 +243,6 @@ template -arma_hot arma_inline void arrayops::convert_cx_scalar @@ -197,13 +254,16 @@ { arma_ignore(junk); - out = out_eT( in.real() ); + const in_T val = in.real(); + + const bool conversion_ok = (std::is_integral::value && std::is_floating_point::value) ? arma_isfinite(val) : true; + + out = conversion_ok ? out_eT(val) : out_eT(0); } template -arma_hot arma_inline void arrayops::convert_cx_scalar @@ -234,6 +294,7 @@ return; } + const bool check_finite = (std::is_integral::value && std::is_floating_point::value); uword j; @@ -245,15 +306,26 @@ // dest[i] = out_eT( tmp_i ); // dest[j] = out_eT( tmp_j ); - (*dest) = (is_signed::value) - ? out_eT( tmp_i ) - : ( cond_rel< is_signed::value >::lt(tmp_i, in_eT(0)) ? out_eT(0) : out_eT(tmp_i) ); + const bool ok_i = check_finite ? arma_isfinite(tmp_i) : true; + const bool ok_j = check_finite ? arma_isfinite(tmp_j) : true; + + (*dest) = ok_i + ? ( + (is_signed::value) + ? out_eT( tmp_i ) + : ( cond_rel< is_signed::value >::lt(tmp_i, in_eT(0)) ? out_eT(0) : out_eT(tmp_i) ) + ) + : out_eT(0); dest++; - (*dest) = (is_signed::value) - ? out_eT( tmp_j ) - : ( cond_rel< is_signed::value >::lt(tmp_j, in_eT(0)) ? out_eT(0) : out_eT(tmp_j) ); + (*dest) = ok_j + ? ( + (is_signed::value) + ? out_eT( tmp_j ) + : ( cond_rel< is_signed::value >::lt(tmp_j, in_eT(0)) ? out_eT(0) : out_eT(tmp_j) ) + ) + : out_eT(0); dest++; } @@ -263,9 +335,15 @@ // dest[i] = out_eT( tmp_i ); - (*dest) = (is_signed::value) - ? out_eT( tmp_i ) - : ( cond_rel< is_signed::value >::lt(tmp_i, in_eT(0)) ? out_eT(0) : out_eT(tmp_i) ); + const bool ok_i = check_finite ? arma_isfinite(tmp_i) : true; + + (*dest) = ok_i + ? ( + (is_signed::value) + ? out_eT( tmp_i ) + : ( cond_rel< is_signed::value >::lt(tmp_i, in_eT(0)) ? out_eT(0) : out_eT(tmp_i) ) + ) + : out_eT(0); } } @@ -595,30 +673,19 @@ void arrayops::inplace_set(eT* dest, const eT val, const uword n_elem) { - typedef typename get_pod_type::result pod_type; - - if( (n_elem <= 9) && (is_cx::no) ) + if(val == eT(0)) { - arrayops::inplace_set_small(dest, val, n_elem); + arrayops::fill_zeros(dest, n_elem); } else { - if( (val == eT(0)) && (std::numeric_limits::is_integer || (std::numeric_limits::is_iec559 && is_real::value)) ) + if( (n_elem <= 9) && (is_cx::no) ) { - if(n_elem > 0) { std::memset((void*)dest, 0, sizeof(eT)*n_elem); } + arrayops::inplace_set_small(dest, val, n_elem); } else { - if(memory::is_aligned(dest)) - { - memory::mark_as_aligned(dest); - - arrayops::inplace_set_base(dest, val, n_elem); - } - else - { - arrayops::inplace_set_base(dest, val, n_elem); - } + arrayops::inplace_set_simple(dest, val, n_elem); } } } @@ -629,6 +696,26 @@ arma_hot inline void +arrayops::inplace_set_simple(eT* dest, const eT val, const uword n_elem) + { + if(memory::is_aligned(dest)) + { + memory::mark_as_aligned(dest); + + arrayops::inplace_set_base(dest, val, n_elem); + } + else + { + arrayops::inplace_set_base(dest, val, n_elem); + } + } + + + +template +arma_hot +inline +void arrayops::inplace_set_base(eT* dest, const eT val, const uword n_elem) { #if defined(ARMA_SIMPLE_LOOPS) @@ -989,6 +1076,72 @@ } + +template +arma_hot +inline +bool +arrayops::is_zero(const eT* mem, const uword n_elem, const eT abs_limit, const typename arma_not_cx::result* junk) + { + arma_ignore(junk); + + if(n_elem == 0) { return false; } + + if(abs_limit == eT(0)) + { + for(uword i=0; i abs_limit) { return false; } + } + } + + return true; + } + + + +template +arma_hot +inline +bool +arrayops::is_zero(const std::complex* mem, const uword n_elem, const T abs_limit) + { + typedef typename std::complex eT; + + if(n_elem == 0) { return false; } + + if(abs_limit == T(0)) + { + for(uword i=0; i abs_limit) { return false; } + if(std::abs(std::imag(val)) > abs_limit) { return false; } + } + } + + return true; + } + + template arma_hot diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/auxlib_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/auxlib_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/auxlib_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/auxlib_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,54 +25,42 @@ { public: - - template - struct pos - { - static const uword n2 = row + col*2; - static const uword n3 = row + col*3; - static const uword n4 = row + col*4; - }; - - // // inv template - inline static bool inv(Mat& out, const Mat& A); + inline static bool inv(Mat& A); template - arma_cold inline static bool inv_tiny(Mat& out, const Mat& X); + inline static bool inv(Mat& out, const Mat& X); - template - inline static bool inv_tr(Mat& out, const Base& X, const uword layout); + template + inline static bool inv_tr(Mat& A, const uword layout); - template - inline static bool inv_sympd(Mat& out, const Base& X); + template + inline static bool inv_sympd(Mat& A); + + template + inline static bool inv_sympd(Mat& out, const Mat& X); template - arma_cold inline static bool inv_sympd_tiny(Mat& out, const Mat& X); + inline static bool inv_sympd_rcond(Mat& A, const eT rcond_threshold); + template + inline static bool inv_sympd_rcond(Mat< std::complex >& A, const T rcond_threshold); // - // det - - template - inline static eT det(const Base& X); + // det and log_det template - arma_cold inline static eT det_tinymat(const Mat& X, const uword N); + inline static bool det(eT& out_val, Mat& A); template - inline static eT det_lapack(const Mat& X, const bool make_copy); - - - // - // log_det + inline static bool log_det(eT& out_val, typename get_pod_type::result& out_sign, Mat& A); - template - inline static bool log_det(eT& out_val, typename get_pod_type::result& out_sign, const Base& X); + template + inline static bool log_det_sympd(typename get_pod_type::result& out_val, Mat& A); // @@ -107,6 +97,26 @@ // + // eig_gen_twosided + + template + inline static bool eig_gen_twosided(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base& expr); + + template + inline static bool eig_gen_twosided(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base< std::complex, T1 >& expr); + + + // + // eig_gen_twosided_balance + + template + inline static bool eig_gen_twosided_balance(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base& expr); + + template + inline static bool eig_gen_twosided_balance(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base< std::complex, T1 >& expr); + + + // // eig_pair template @@ -117,13 +127,23 @@ // + // eig_pair_twosided + + template + inline static bool eig_pair_twosided(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base& A_expr, const Base& B_expr); + + template + inline static bool eig_pair_twosided(Mat< std::complex >& vals, Mat< std::complex >& lvecs, Mat< std::complex >& rvecs, const Base< std::complex, T1 >& A_expr, const Base< std::complex, T2 >& B_expr); + + + // // eig_sym - template - inline static bool eig_sym(Col& eigval, const Base& X); + template + inline static bool eig_sym(Col& eigval, Mat& A); - template - inline static bool eig_sym(Col& eigval, const Base,T1>& X); + template + inline static bool eig_sym(Col& eigval, Mat< std::complex >& A); template inline static bool eig_sym(Col& eigval, Mat& eigvec, const Mat& X); @@ -156,14 +176,17 @@ template inline static bool chol_band_common(Mat& X, const uword KD, const uword layout); - + template + inline static bool chol_pivot(Mat& X, Mat& P, const uword layout); + + // // hessenberg decomposition - + template inline static bool hess(Mat& H, const Base& X, Col& tao); - - + + // // qr @@ -173,59 +196,54 @@ template inline static bool qr_econ(Mat& Q, Mat& R, const Base& X); - - // - // svd - template - inline static bool svd(Col& S, const Base& X, uword& n_rows, uword& n_cols); + inline static bool qr_pivot(Mat& Q, Mat& R, Mat& P, const Base& X); - template - inline static bool svd(Col& S, const Base, T1>& X, uword& n_rows, uword& n_cols); + template + inline static bool qr_pivot(Mat< std::complex >& Q, Mat< std::complex >& R, Mat& P, const Base,T1>& X); - template - inline static bool svd(Col& S, const Base& X); - template - inline static bool svd(Col& S, const Base, T1>& X); + // + // svd - template - inline static bool svd(Mat& U, Col& S, Mat& V, const Base& X); + template + inline static bool svd(Col& S, Mat& A); + + template + inline static bool svd(Col& S, Mat< std::complex >& A); - template - inline static bool svd(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, const Base< std::complex, T1>& X); - template - inline static bool svd_econ(Mat& U, Col& S, Mat& V, const Base& X, const char mode); + template + inline static bool svd(Mat& U, Col& S, Mat& V, Mat& A); - template - inline static bool svd_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, const Base< std::complex, T1>& X, const char mode); + template + inline static bool svd(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A); + template + inline static bool svd_econ(Mat& U, Col& S, Mat& V, Mat& A, const char mode); - template - inline static bool svd_dc(Col& S, const Base& X, uword& n_rows, uword& n_cols); + template + inline static bool svd_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A, const char mode); - template - inline static bool svd_dc(Col& S, const Base, T1>& X, uword& n_rows, uword& n_cols); - template - inline static bool svd_dc(Col& S, const Base& X); + template + inline static bool svd_dc(Col& S, Mat& A); - template - inline static bool svd_dc(Col& S, const Base, T1>& X); + template + inline static bool svd_dc(Col& S, Mat< std::complex >& A); - template - inline static bool svd_dc(Mat& U, Col& S, Mat& V, const Base& X); + template + inline static bool svd_dc(Mat& U, Col& S, Mat& V, Mat& A); - template - inline static bool svd_dc(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, const Base< std::complex, T1>& X); + template + inline static bool svd_dc(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A); - template - inline static bool svd_dc_econ(Mat& U, Col& S, Mat& V, const Base& X); + template + inline static bool svd_dc_econ(Mat& U, Col& S, Mat& V, Mat& A); - template - inline static bool svd_dc_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, const Base< std::complex, T1>& X); + template + inline static bool svd_dc_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A); // @@ -269,7 +287,12 @@ // template - inline static bool solve_approx_fast(Mat& out, Mat& A, const Base& B_expr); + inline static bool solve_rect_fast(Mat& out, Mat& A, const Base& B_expr); + + template + inline static bool solve_rect_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool allow_ugly); + + // template inline static bool solve_approx_svd(Mat& out, Mat& A, const Base& B_expr); @@ -330,13 +353,13 @@ inline static bool schur(Mat& U, Mat& S, const Base& X, const bool calc_U = true); template - inline static bool schur(Mat >& U, Mat >& S, const Base,T1>& X, const bool calc_U = true); + inline static bool schur(Mat< std::complex >& U, Mat< std::complex >& S, const Base,T1>& X, const bool calc_U = true); template - inline static bool schur(Mat >& U, Mat >& S, const bool calc_U = true); + inline static bool schur(Mat< std::complex >& U, Mat< std::complex >& S, const bool calc_U = true); // - // syl (solution of the Sylvester equation AX + XB = C) + // solve the Sylvester equation AX + XB = C template inline static bool syl(Mat& X, const Mat& A, const Mat& B, const Mat& C); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/auxlib_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/auxlib_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/auxlib_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/auxlib_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,49 +24,48 @@ template inline bool -auxlib::inv(Mat& out, const Mat& A) +auxlib::inv(Mat& A) { arma_extra_debug_sigprint(); - out = A; - - if(out.is_empty()) { return true; } + if(A.is_empty()) { return true; } #if defined(ARMA_USE_ATLAS) { - arma_debug_assert_atlas_size(out); + arma_debug_assert_atlas_size(A); - podarray ipiv(out.n_rows); + podarray ipiv(A.n_rows); int info = 0; arma_extra_debug_print("atlas::clapack_getrf()"); - info = atlas::clapack_getrf(atlas::CblasColMajor, out.n_rows, out.n_cols, out.memptr(), out.n_rows, ipiv.memptr()); + info = atlas::clapack_getrf(atlas::CblasColMajor, A.n_rows, A.n_cols, A.memptr(), A.n_rows, ipiv.memptr()); if(info != 0) { return false; } arma_extra_debug_print("atlas::clapack_getri()"); - info = atlas::clapack_getri(atlas::CblasColMajor, out.n_rows, out.memptr(), out.n_rows, ipiv.memptr()); + info = atlas::clapack_getri(atlas::CblasColMajor, A.n_rows, A.memptr(), A.n_rows, ipiv.memptr()); return (info == 0); } #elif defined(ARMA_USE_LAPACK) { - arma_debug_assert_blas_size(out); + arma_debug_assert_blas_size(A); - blas_int n_rows = blas_int(out.n_rows); - blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), n_rows); - blas_int info = 0; + blas_int n = blas_int(A.n_rows); + blas_int lda = blas_int(A.n_rows); + blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), n); + blas_int info = 0; - podarray ipiv(out.n_rows); + podarray ipiv(A.n_rows); - if(n_rows > 16) + if(n > 16) { eT work_query[2]; blas_int lwork_query = -1; arma_extra_debug_print("lapack::getri()"); - lapack::getri(&n_rows, out.memptr(), &n_rows, ipiv.memptr(), &work_query[0], &lwork_query, &info); + lapack::getri(&n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info); if(info != 0) { return false; } @@ -76,18 +77,18 @@ podarray work( static_cast(lwork) ); arma_extra_debug_print("lapack::getrf()"); - lapack::getrf(&n_rows, &n_rows, out.memptr(), &n_rows, ipiv.memptr(), &info); + lapack::getrf(&n, &n, A.memptr(), &lda, ipiv.memptr(), &info); if(info != 0) { return false; } arma_extra_debug_print("lapack::getri()"); - lapack::getri(&n_rows, out.memptr(), &n_rows, ipiv.memptr(), work.memptr(), &lwork, &info); + lapack::getri(&n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info); return (info == 0); } #else { - out.soft_reset(); + arma_ignore(A); arma_stop_logic_error("inv(): use of ATLAS or LAPACK must be enabled"); return false; } @@ -97,174 +98,56 @@ template -arma_cold inline bool -auxlib::inv_tiny(Mat& out, const Mat& X) +auxlib::inv(Mat& out, const Mat& X) { arma_extra_debug_sigprint(); - const uword N = X.n_rows; - - out.set_size(N,N); - - typedef typename get_pod_type::result T; - - const T det_min = std::numeric_limits::epsilon(); - - bool calc_ok = false; - - const eT* Xm = X.memptr(); - eT* outm = out.memptr(); - - switch(N) - { - case 0: - calc_ok = true; - break; - - case 1: - { - outm[0] = eT(1) / Xm[0]; - - calc_ok = true; - }; - break; - - case 2: - { - const eT a = Xm[pos<0,0>::n2]; - const eT b = Xm[pos<0,1>::n2]; - const eT c = Xm[pos<1,0>::n2]; - const eT d = Xm[pos<1,1>::n2]; - - const eT det_val = (a*d - b*c); - - if(std::abs(det_val) >= det_min) - { - outm[pos<0,0>::n2] = d / det_val; - outm[pos<0,1>::n2] = -b / det_val; - outm[pos<1,0>::n2] = -c / det_val; - outm[pos<1,1>::n2] = a / det_val; - - calc_ok = true; - } - }; - break; - - case 3: - { - const eT det_val = auxlib::det_tinymat(X,3); - - if(std::abs(det_val) >= det_min) - { - outm[pos<0,0>::n3] = (Xm[pos<2,2>::n3]*Xm[pos<1,1>::n3] - Xm[pos<2,1>::n3]*Xm[pos<1,2>::n3]) / det_val; - outm[pos<1,0>::n3] = -(Xm[pos<2,2>::n3]*Xm[pos<1,0>::n3] - Xm[pos<2,0>::n3]*Xm[pos<1,2>::n3]) / det_val; - outm[pos<2,0>::n3] = (Xm[pos<2,1>::n3]*Xm[pos<1,0>::n3] - Xm[pos<2,0>::n3]*Xm[pos<1,1>::n3]) / det_val; - - outm[pos<0,1>::n3] = -(Xm[pos<2,2>::n3]*Xm[pos<0,1>::n3] - Xm[pos<2,1>::n3]*Xm[pos<0,2>::n3]) / det_val; - outm[pos<1,1>::n3] = (Xm[pos<2,2>::n3]*Xm[pos<0,0>::n3] - Xm[pos<2,0>::n3]*Xm[pos<0,2>::n3]) / det_val; - outm[pos<2,1>::n3] = -(Xm[pos<2,1>::n3]*Xm[pos<0,0>::n3] - Xm[pos<2,0>::n3]*Xm[pos<0,1>::n3]) / det_val; - - outm[pos<0,2>::n3] = (Xm[pos<1,2>::n3]*Xm[pos<0,1>::n3] - Xm[pos<1,1>::n3]*Xm[pos<0,2>::n3]) / det_val; - outm[pos<1,2>::n3] = -(Xm[pos<1,2>::n3]*Xm[pos<0,0>::n3] - Xm[pos<1,0>::n3]*Xm[pos<0,2>::n3]) / det_val; - outm[pos<2,2>::n3] = (Xm[pos<1,1>::n3]*Xm[pos<0,0>::n3] - Xm[pos<1,0>::n3]*Xm[pos<0,1>::n3]) / det_val; - - const eT check_val = Xm[pos<0,0>::n3]*outm[pos<0,0>::n3] + Xm[pos<0,1>::n3]*outm[pos<1,0>::n3] + Xm[pos<0,2>::n3]*outm[pos<2,0>::n3]; - - const T max_diff = (is_float::value) ? T(1e-4) : T(1e-10); // empirically determined; may need tuning - - if(std::abs(T(1) - check_val) < max_diff) { calc_ok = true; } - } - }; - break; - - case 4: - { - const eT det_val = auxlib::det_tinymat(X,4); - - if(std::abs(det_val) >= det_min) - { - outm[pos<0,0>::n4] = ( Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] + Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<1,0>::n4] = ( Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<2,0>::n4] = ( Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<3,0>::n4] = ( Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] ) / det_val; - - outm[pos<0,1>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<1,1>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<2,1>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<3,1>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] ) / det_val; - - outm[pos<0,2>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<1,2>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<2,2>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,3>::n4] ) / det_val; - outm[pos<3,2>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,2>::n4] ) / det_val; - - outm[pos<0,3>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4] ) / det_val; - outm[pos<1,3>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4] ) / det_val; - outm[pos<2,3>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4] ) / det_val; - outm[pos<3,3>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4] ) / det_val; - - const eT check_val = Xm[pos<0,0>::n4]*outm[pos<0,0>::n4] + Xm[pos<0,1>::n4]*outm[pos<1,0>::n4] + Xm[pos<0,2>::n4]*outm[pos<2,0>::n4] + Xm[pos<0,3>::n4]*outm[pos<3,0>::n4]; - - const T max_diff = (is_float::value) ? T(1e-4) : T(1e-10); // empirically determined; may need tuning - - if(std::abs(T(1) - check_val) < max_diff) { calc_ok = true; } - } - }; - break; - - default: - ; - } + out = X; - return calc_ok; + return auxlib::inv(out); } -template +template inline bool -auxlib::inv_tr(Mat& out, const Base& X, const uword layout) +auxlib::inv_tr(Mat& A, const uword layout) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_LAPACK) { - out = X.get_ref(); - - arma_debug_check( (out.is_square() == false), "inv(): given matrix must be square sized" ); - - if(out.is_empty()) { return true; } + if(A.is_empty()) { return true; } - arma_debug_assert_blas_size(out); + arma_debug_assert_blas_size(A); char uplo = (layout == 0) ? 'U' : 'L'; char diag = 'N'; - blas_int n = blas_int(out.n_rows); + blas_int n = blas_int(A.n_rows); blas_int info = 0; arma_extra_debug_print("lapack::trtri()"); - lapack::trtri(&uplo, &diag, &n, out.memptr(), &n, &info); + lapack::trtri(&uplo, &diag, &n, A.memptr(), &n, &info); if(info != 0) { return false; } if(layout == 0) { - out = trimatu(out); // upper triangular + A = trimatu(A); // upper triangular } else { - out = trimatl(out); // lower triangular + A = trimatl(A); // lower triangular } return true; } #else { - arma_ignore(out); - arma_ignore(X); + arma_ignore(A); arma_ignore(layout); arma_stop_logic_error("inv(): use of LAPACK must be enabled"); return false; @@ -274,89 +157,62 @@ -template +template inline bool -auxlib::inv_sympd(Mat& out, const Base& X) +auxlib::inv_sympd(Mat& A) { arma_extra_debug_sigprint(); - out = X.get_ref(); - - arma_debug_check( (out.is_square() == false), "inv_sympd(): given matrix must be square sized" ); - - if(out.is_empty()) { return true; } - - // if(auxlib::rudimentary_sym_check(out) == false) - // { - // if(is_cx::no ) { arma_debug_warn("inv_sympd(): given matrix is not symmetric"); } - // if(is_cx::yes) { arma_debug_warn("inv_sympd(): given matrix is not hermitian"); } - // return false; - // } - - if((arma_config::debug) && (auxlib::rudimentary_sym_check(out) == false)) - { - if(is_cx::no ) { arma_debug_warn("inv_sympd(): given matrix is not symmetric"); } - if(is_cx::yes) { arma_debug_warn("inv_sympd(): given matrix is not hermitian"); } - } - - if(out.n_rows <= 4) - { - Mat tmp; - - const bool status = auxlib::inv_sympd_tiny(tmp, out); - - if(status == true) { out = tmp; return true; } - } + if(A.is_empty()) { return true; } #if defined(ARMA_USE_ATLAS) { - arma_debug_assert_atlas_size(out); + arma_debug_assert_atlas_size(A); int info = 0; arma_extra_debug_print("atlas::clapack_potrf()"); - info = atlas::clapack_potrf(atlas::CblasColMajor, atlas::CblasLower, out.n_rows, out.memptr(), out.n_rows); + info = atlas::clapack_potrf(atlas::CblasColMajor, atlas::CblasLower, A.n_rows, A.memptr(), A.n_rows); if(info != 0) { return false; } arma_extra_debug_print("atlas::clapack_potri()"); - info = atlas::clapack_potri(atlas::CblasColMajor, atlas::CblasLower, out.n_rows, out.memptr(), out.n_rows); + info = atlas::clapack_potri(atlas::CblasColMajor, atlas::CblasLower, A.n_rows, A.memptr(), A.n_rows); if(info != 0) { return false; } - out = symmatl(out); + A = symmatl(A); return true; } #elif defined(ARMA_USE_LAPACK) { - arma_debug_assert_blas_size(out); + arma_debug_assert_blas_size(A); char uplo = 'L'; - blas_int n = blas_int(out.n_rows); + blas_int n = blas_int(A.n_rows); blas_int info = 0; // NOTE: for complex matrices, zpotrf() assumes the matrix is hermitian (not simply symmetric) arma_extra_debug_print("lapack::potrf()"); - lapack::potrf(&uplo, &n, out.memptr(), &n, &info); + lapack::potrf(&uplo, &n, A.memptr(), &n, &info); if(info != 0) { return false; } arma_extra_debug_print("lapack::potri()"); - lapack::potri(&uplo, &n, out.memptr(), &n, &info); + lapack::potri(&uplo, &n, A.memptr(), &n, &info); if(info != 0) { return false; } - out = symmatl(out); + A = symmatl(A); return true; } #else { - arma_ignore(out); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("inv_sympd(): use of ATLAS or LAPACK must be enabled"); return false; } @@ -366,133 +222,131 @@ template -arma_cold inline bool -auxlib::inv_sympd_tiny(Mat& out, const Mat& X) +auxlib::inv_sympd(Mat& out, const Mat& X) { arma_extra_debug_sigprint(); - // if(sympd_helper::guess_sympd(X) == false) { return false; } + out = X; - return auxlib::inv_tiny(out, X); + return auxlib::inv_sympd(out); } -template +template inline -eT -auxlib::det(const Base& X) +bool +auxlib::inv_sympd_rcond(Mat& A, const eT rcond_threshold) { arma_extra_debug_sigprint(); - typedef typename get_pod_type::result T; - - const bool make_copy = (is_Mat::value) ? true : false; - - const unwrap tmp(X.get_ref()); - const Mat& A = tmp.M; - - arma_debug_check( (A.is_square() == false), "det(): given matrix must be square sized" ); - - const uword N = A.n_rows; + if(A.is_empty()) { return true; } - if(N <= 4) + #if defined(ARMA_USE_LAPACK) { - const eT det_val = auxlib::det_tinymat(A, N); + typedef typename get_pod_type::result T; + + arma_debug_assert_blas_size(A); + + char norm_id = '1'; + char uplo = 'L'; + blas_int n = blas_int(A.n_rows); + blas_int info = 0; + T norm_val = T(0); + + podarray work(A.n_rows); + + arma_extra_debug_print("lapack::lansy()"); + norm_val = lapack::lansy(&norm_id, &uplo, &n, A.memptr(), &n, work.memptr()); + + arma_extra_debug_print("lapack::potrf()"); + lapack::potrf(&uplo, &n, A.memptr(), &n, &info); + + if(info != 0) { return false; } + + const T rcond = auxlib::lu_rcond_sympd(A, norm_val); + + if(rcond < rcond_threshold) { return false; } + + arma_extra_debug_print("lapack::potri()"); + lapack::potri(&uplo, &n, A.memptr(), &n, &info); - const T det_min = std::numeric_limits::epsilon(); + if(info != 0) { return false; } + + A = symmatl(A); - if(std::abs(det_val) >= det_min) { return det_val; } + return true; } - - return auxlib::det_lapack(A, make_copy); + #else + { + arma_ignore(A); + arma_ignore(rcond_threshold); + arma_stop_logic_error("inv_sympd_rcond(): use LAPACK must be enabled"); + return false; + } + #endif } -template -arma_cold +template inline -eT -auxlib::det_tinymat(const Mat& X, const uword N) +bool +auxlib::inv_sympd_rcond(Mat< std::complex >& A, const T rcond_threshold) { arma_extra_debug_sigprint(); - const eT* Xm = X.memptr(); + if(A.is_empty()) { return true; } - switch(N) + #if defined(ARMA_CRIPPLED_LAPACK) + { + arma_ignore(A); + arma_ignore(rcond_threshold); + return false; + } + #elif defined(ARMA_USE_LAPACK) + { + arma_debug_assert_blas_size(A); + + char norm_id = '1'; + char uplo = 'L'; + blas_int n = blas_int(A.n_rows); + blas_int info = 0; + T norm_val = T(0); + + podarray work(A.n_rows); + + arma_extra_debug_print("lapack::lanhe()"); + norm_val = lapack::lanhe(&norm_id, &uplo, &n, A.memptr(), &n, work.memptr()); + + arma_extra_debug_print("lapack::potrf()"); + lapack::potrf(&uplo, &n, A.memptr(), &n, &info); + + if(info != 0) { return false; } + + const T rcond = auxlib::lu_rcond_sympd(A, norm_val); + + if(rcond < rcond_threshold) { return false; } + + arma_extra_debug_print("lapack::potri()"); + lapack::potri(&uplo, &n, A.memptr(), &n, &info); + + if(info != 0) { return false; } + + A = symmatl(A); + + return true; + } + #else { - case 0: - return eT(1); - break; - - case 1: - return Xm[0]; - break; - - case 2: - { - return ( Xm[pos<0,0>::n2]*Xm[pos<1,1>::n2] - Xm[pos<0,1>::n2]*Xm[pos<1,0>::n2] ); - } - break; - - case 3: - { - // const double tmp1 = X.at(0,0) * X.at(1,1) * X.at(2,2); - // const double tmp2 = X.at(0,1) * X.at(1,2) * X.at(2,0); - // const double tmp3 = X.at(0,2) * X.at(1,0) * X.at(2,1); - // const double tmp4 = X.at(2,0) * X.at(1,1) * X.at(0,2); - // const double tmp5 = X.at(2,1) * X.at(1,2) * X.at(0,0); - // const double tmp6 = X.at(2,2) * X.at(1,0) * X.at(0,1); - // return (tmp1+tmp2+tmp3) - (tmp4+tmp5+tmp6); - - const eT val1 = Xm[pos<0,0>::n3]*(Xm[pos<2,2>::n3]*Xm[pos<1,1>::n3] - Xm[pos<2,1>::n3]*Xm[pos<1,2>::n3]); - const eT val2 = Xm[pos<1,0>::n3]*(Xm[pos<2,2>::n3]*Xm[pos<0,1>::n3] - Xm[pos<2,1>::n3]*Xm[pos<0,2>::n3]); - const eT val3 = Xm[pos<2,0>::n3]*(Xm[pos<1,2>::n3]*Xm[pos<0,1>::n3] - Xm[pos<1,1>::n3]*Xm[pos<0,2>::n3]); - - return ( val1 - val2 + val3 ); - } - break; - - case 4: - { - const eT val = \ - Xm[pos<0,3>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,0>::n4] \ - - Xm[pos<0,2>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,0>::n4] \ - - Xm[pos<0,3>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,0>::n4] \ - + Xm[pos<0,1>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,0>::n4] \ - + Xm[pos<0,2>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,0>::n4] \ - - Xm[pos<0,1>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,0>::n4] \ - - Xm[pos<0,3>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,1>::n4] \ - + Xm[pos<0,2>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,1>::n4] \ - + Xm[pos<0,3>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,1>::n4] \ - - Xm[pos<0,0>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,1>::n4] \ - - Xm[pos<0,2>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,1>::n4] \ - + Xm[pos<0,0>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,1>::n4] \ - + Xm[pos<0,3>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,2>::n4] \ - - Xm[pos<0,1>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,2>::n4] \ - - Xm[pos<0,3>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,2>::n4] \ - + Xm[pos<0,0>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,2>::n4] \ - + Xm[pos<0,1>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,2>::n4] \ - - Xm[pos<0,0>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,2>::n4] \ - - Xm[pos<0,2>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,3>::n4] \ - + Xm[pos<0,1>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,3>::n4] \ - + Xm[pos<0,2>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,3>::n4] \ - - Xm[pos<0,0>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,3>::n4] \ - - Xm[pos<0,1>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,3>::n4] \ - + Xm[pos<0,0>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,3>::n4] \ - ; - - return val; - } - break; - - default: - return eT(0); - ; + arma_ignore(A); + arma_ignore(rcond_threshold); + arma_stop_logic_error("inv_sympd_rcond(): use LAPACK must be enabled"); + return false; } + #endif } @@ -500,82 +354,75 @@ //! determinant of a matrix template inline -eT -auxlib::det_lapack(const Mat& X, const bool make_copy) +bool +auxlib::det(eT& out_val, Mat& A) { arma_extra_debug_sigprint(); - Mat X_copy; - - if(make_copy) { X_copy = X; } - - Mat& tmp = (make_copy) ? X_copy : const_cast< Mat& >(X); - - if(tmp.is_empty()) { return eT(1); } + if(A.is_empty()) { out_val = eT(1); return true; } #if defined(ARMA_USE_ATLAS) { - arma_debug_assert_atlas_size(tmp); + arma_debug_assert_atlas_size(A); - podarray ipiv(tmp.n_rows); + podarray ipiv(A.n_rows); arma_extra_debug_print("atlas::clapack_getrf()"); - //const int info = - atlas::clapack_getrf(atlas::CblasColMajor, tmp.n_rows, tmp.n_cols, tmp.memptr(), tmp.n_rows, ipiv.memptr()); + const int info = atlas::clapack_getrf(atlas::CblasColMajor, A.n_rows, A.n_cols, A.memptr(), A.n_rows, ipiv.memptr()); - // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero - eT val = tmp.at(0,0); - for(uword i=1; i < tmp.n_rows; ++i) - { - val *= tmp.at(i,i); - } + if(info < 0) { return false; } + + // on output A appears to be L+U_alt, where U_alt is U with the main diagonal set to zero + eT val = A.at(0,0); + for(uword i=1; i < A.n_rows; ++i) { val *= A.at(i,i); } int sign = +1; - for(uword i=0; i < tmp.n_rows; ++i) + for(uword i=0; i < A.n_rows; ++i) { - if( int(i) != ipiv.mem[i] ) // NOTE: no adjustment required, as the clapack version of getrf() assumes counting from 0 - { - sign *= -1; - } + // NOTE: no adjustment required, as the clapack version of getrf() assumes counting from 0 + if( int(i) != ipiv.mem[i] ) { sign *= -1; } } - return ( (sign < 0) ? -val : val ); + out_val = (sign < 0) ? eT(-val) : eT(val); + + return true; } #elif defined(ARMA_USE_LAPACK) { - arma_debug_assert_blas_size(tmp); + arma_debug_assert_blas_size(A); - podarray ipiv(tmp.n_rows); + podarray ipiv(A.n_rows); blas_int info = 0; - blas_int n_rows = blas_int(tmp.n_rows); - blas_int n_cols = blas_int(tmp.n_cols); + blas_int n_rows = blas_int(A.n_rows); + blas_int n_cols = blas_int(A.n_cols); arma_extra_debug_print("lapack::getrf()"); - lapack::getrf(&n_rows, &n_cols, tmp.memptr(), &n_rows, ipiv.memptr(), &info); + lapack::getrf(&n_rows, &n_cols, A.memptr(), &n_rows, ipiv.memptr(), &info); - // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero - eT val = tmp.at(0,0); - for(uword i=1; i < tmp.n_rows; ++i) - { - val *= tmp.at(i,i); - } + if(info < 0) { return false; } + + // on output A appears to be L+U_alt, where U_alt is U with the main diagonal set to zero + eT val = A.at(0,0); + for(uword i=1; i < A.n_rows; ++i) { val *= A.at(i,i); } blas_int sign = +1; - for(uword i=0; i < tmp.n_rows; ++i) + for(uword i=0; i < A.n_rows; ++i) { - if( blas_int(i) != (ipiv.mem[i] - 1) ) // NOTE: adjustment of -1 is required as Fortran counts from 1 - { - sign *= -1; - } + // NOTE: adjustment of -1 is required as Fortran counts from 1 + if( blas_int(i) != (ipiv.mem[i] - 1) ) { sign *= -1; } } - return ( (sign < 0) ? -val : val ); + out_val = (sign < 0) ? eT(-val) : eT(val); + + return true; } #else { + arma_ignore(out_val); + arma_ignore(A); arma_stop_logic_error("det(): use of ATLAS or LAPACK must be enabled"); - return eT(0); + return false; } #endif } @@ -583,50 +430,47 @@ //! log determinant of a matrix -template +template inline bool -auxlib::log_det(eT& out_val, typename get_pod_type::result& out_sign, const Base& X) +auxlib::log_det(eT& out_val, typename get_pod_type::result& out_sign, Mat& A) { arma_extra_debug_sigprint(); typedef typename get_pod_type::result T; - #if defined(ARMA_USE_ATLAS) + if(A.is_empty()) { - Mat tmp(X.get_ref()); - arma_debug_check( (tmp.is_square() == false), "log_det(): given matrix must be square sized" ); - - if(tmp.is_empty()) - { - out_val = eT(0); - out_sign = T(1); - return true; - } + out_val = eT(0); + out_sign = T(1); + return true; + } - arma_debug_assert_atlas_size(tmp); + #if defined(ARMA_USE_ATLAS) + { + arma_debug_assert_atlas_size(A); - podarray ipiv(tmp.n_rows); + podarray ipiv(A.n_rows); arma_extra_debug_print("atlas::clapack_getrf()"); - const int info = atlas::clapack_getrf(atlas::CblasColMajor, tmp.n_rows, tmp.n_cols, tmp.memptr(), tmp.n_rows, ipiv.memptr()); + const int info = atlas::clapack_getrf(atlas::CblasColMajor, A.n_rows, A.n_cols, A.memptr(), A.n_rows, ipiv.memptr()); if(info < 0) { return false; } - // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero + // on output A appears to be L+U_alt, where U_alt is U with the main diagonal set to zero - sword sign = (is_cx::no) ? ( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? -1 : +1 ) : +1; - eT val = (is_cx::no) ? std::log( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? tmp.at(0,0)*T(-1) : tmp.at(0,0) ) : std::log( tmp.at(0,0) ); + sword sign = (is_cx::no) ? ( (access::tmp_real( A.at(0,0) ) < T(0)) ? -1 : +1 ) : +1; + eT val = (is_cx::no) ? std::log( (access::tmp_real( A.at(0,0) ) < T(0)) ? A.at(0,0)*T(-1) : A.at(0,0) ) : std::log( A.at(0,0) ); - for(uword i=1; i < tmp.n_rows; ++i) + for(uword i=1; i < A.n_rows; ++i) { - const eT x = tmp.at(i,i); + const eT x = A.at(i,i); sign *= (is_cx::no) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1; val += (is_cx::no) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x); } - for(uword i=0; i < tmp.n_rows; ++i) + for(uword i=0; i < A.n_rows; ++i) { if( int(i) != ipiv.mem[i] ) // NOTE: no adjustment required, as the clapack version of getrf() assumes counting from 0 { @@ -641,43 +485,33 @@ } #elif defined(ARMA_USE_LAPACK) { - Mat tmp(X.get_ref()); - arma_debug_check( (tmp.is_square() == false), "log_det(): given matrix must be square sized" ); - - if(tmp.is_empty()) - { - out_val = eT(0); - out_sign = T(1); - return true; - } - - arma_debug_assert_blas_size(tmp); + arma_debug_assert_blas_size(A); - podarray ipiv(tmp.n_rows); + podarray ipiv(A.n_rows); blas_int info = 0; - blas_int n_rows = blas_int(tmp.n_rows); - blas_int n_cols = blas_int(tmp.n_cols); + blas_int n_rows = blas_int(A.n_rows); + blas_int n_cols = blas_int(A.n_cols); arma_extra_debug_print("lapack::getrf()"); - lapack::getrf(&n_rows, &n_cols, tmp.memptr(), &n_rows, ipiv.memptr(), &info); + lapack::getrf(&n_rows, &n_cols, A.memptr(), &n_rows, ipiv.memptr(), &info); if(info < 0) { return false; } - // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero + // on output A appears to be L+U_alt, where U_alt is U with the main diagonal set to zero - sword sign = (is_cx::no) ? ( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? -1 : +1 ) : +1; - eT val = (is_cx::no) ? std::log( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? tmp.at(0,0)*T(-1) : tmp.at(0,0) ) : std::log( tmp.at(0,0) ); + sword sign = (is_cx::no) ? ( (access::tmp_real( A.at(0,0) ) < T(0)) ? -1 : +1 ) : +1; + eT val = (is_cx::no) ? std::log( (access::tmp_real( A.at(0,0) ) < T(0)) ? A.at(0,0)*T(-1) : A.at(0,0) ) : std::log( A.at(0,0) ); - for(uword i=1; i < tmp.n_rows; ++i) + for(uword i=1; i < A.n_rows; ++i) { - const eT x = tmp.at(i,i); + const eT x = A.at(i,i); sign *= (is_cx::no) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1; val += (is_cx::no) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x); } - for(uword i=0; i < tmp.n_rows; ++i) + for(uword i=0; i < A.n_rows; ++i) { if( blas_int(i) != (ipiv.mem[i] - 1) ) // NOTE: adjustment of -1 is required as Fortran counts from 1 { @@ -692,13 +526,73 @@ } #else { - arma_ignore(X); + arma_ignore(A); + arma_ignore(out_val); + arma_ignore(out_sign); + arma_stop_logic_error("log_det(): use of ATLAS or LAPACK must be enabled"); + return false; + } + #endif + } + + + +template +inline +bool +auxlib::log_det_sympd(typename get_pod_type::result& out_val, Mat& A) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + if(A.is_empty()) { out_val = T(0); return true; } + + #if defined(ARMA_USE_ATLAS) + { + arma_debug_assert_atlas_size(A); - out_val = eT(0); - out_sign = T(0); + int info = 0; - arma_stop_logic_error("log_det(): use of ATLAS or LAPACK must be enabled"); + arma_extra_debug_print("atlas::clapack_potrf()"); + info = atlas::clapack_potrf(atlas::CblasColMajor, atlas::CblasLower, A.n_rows, A.memptr(), A.n_rows); + + if(info != 0) { return false; } + + T val = std::log( access::tmp_real(A.at(0,0)) ); + for(uword i=1; i < A.n_rows; ++i) { val += std::log( access::tmp_real(A.at(i,i)) ); } + + out_val = T(2) * val; + + return true; + } + #elif defined(ARMA_USE_LAPACK) + { + arma_debug_assert_blas_size(A); + + char uplo = 'L'; + blas_int n = blas_int(A.n_rows); + blas_int info = 0; + + arma_extra_debug_print("lapack::potrf()"); + lapack::potrf(&uplo, &n, A.memptr(), &n, &info); + + if(info != 0) { return false; } + + T val = std::log( access::tmp_real(A.at(0,0)) ); + + for(uword i=1; i < A.n_rows; ++i) { val += std::log( access::tmp_real(A.at(i,i)) ); } + + out_val = T(2) * val; + + return true; + } + #else + { + arma_ignore(out_val); + arma_ignore(A); + arma_stop_logic_error("det(): use of ATLAS or LAPACK must be enabled"); return false; } #endif @@ -770,7 +664,7 @@ L.at(row,col) = eT(0); } - if( L.in_range(col,col) == true ) + if( L.in_range(col,col) ) { L.at(col,col) = eT(1); } @@ -950,7 +844,7 @@ vals.set_size(X.n_rows, 1); - Mat tmp(1,1); + Mat tmp(1, 1, arma_nozeros_indicator()); if(vecs_on) { @@ -967,7 +861,7 @@ T* vr = (vecs_on) ? tmp.memptr() : junk.memptr(); blas_int ldvl = blas_int(1); blas_int ldvr = (vecs_on) ? blas_int(tmp.n_rows) : blas_int(1); - blas_int lwork = (vecs_on) ? (3 * ((std::max)(blas_int(1), 4*N)) ) : (3 * ((std::max)(blas_int(1), 3*N)) ); + blas_int lwork = 64*N; // lwork_min = (vecs_on) ? (std::max)(blas_int(1), 4*N) : (std::max)(blas_int(1), 3*N) blas_int info = 0; podarray work( static_cast(lwork) ); @@ -1074,7 +968,7 @@ eT* vr = (vecs_on) ? vecs.memptr() : junk.memptr(); blas_int ldvl = blas_int(1); blas_int ldvr = (vecs_on) ? blas_int(vecs.n_rows) : blas_int(1); - blas_int lwork = 3 * ((std::max)(blas_int(1), 2*N)); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1), 2*N) blas_int info = 0; podarray work( static_cast(lwork) ); @@ -1135,7 +1029,7 @@ vals.set_size(X.n_rows, 1); - Mat tmp(1,1); + Mat tmp(1, 1, arma_nozeros_indicator()); if(vecs_on) { @@ -1157,7 +1051,7 @@ blas_int ilo = blas_int(0); blas_int ihi = blas_int(0); T abnrm = T(0); - blas_int lwork = 3 * ((std::max)(blas_int(1), blas_int(2*N))); + blas_int lwork = 64*N; // lwork_min = (vecs_on) ? (std::max)(blas_int(1), 2*N) : (std::max)(blas_int(1), 3*N) blas_int info = blas_int(0); podarray scale(X.n_rows); @@ -1280,7 +1174,7 @@ blas_int ilo = blas_int(0); blas_int ihi = blas_int(0); T abnrm = T(0); - blas_int lwork = 3 * ((std::max)(blas_int(1), blas_int(2*N))); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1), blas_int(2*N)) blas_int info = blas_int(0); podarray scale(X.n_rows); @@ -1310,16 +1204,395 @@ -//! eigendecomposition of general square real matrix pair (real) -template +//! two-sided eigen decomposition of general square matrix (real) +template inline bool -auxlib::eig_pair +auxlib::eig_gen_twosided ( - Mat< std::complex >& vals, - Mat< std::complex >& vecs, - const bool vecs_on, - const Base& A_expr, + Mat< std::complex >& vals, + Mat< std::complex >& lvecs, + Mat< std::complex >& rvecs, + const Base& expr + ) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + typedef typename T1::pod_type T; + + Mat X = expr.get_ref(); + + arma_debug_check( (X.is_square() == false), "eig_gen(): given matrix must be square sized" ); + + arma_debug_assert_blas_size(X); + + if(X.is_empty()) + { + vals.reset(); + lvecs.reset(); + rvecs.reset(); + return true; + } + + if(X.is_finite() == false) { return false; } + + vals.set_size(X.n_rows, 1); + + lvecs.set_size(X.n_rows, X.n_rows); + rvecs.set_size(X.n_rows, X.n_rows); + + Mat ltmp(X.n_rows, X.n_rows, arma_nozeros_indicator()); + Mat rtmp(X.n_rows, X.n_rows, arma_nozeros_indicator()); + + char jobvl = 'V'; + char jobvr = 'V'; + blas_int N = blas_int(X.n_rows); + blas_int ldvl = blas_int(ltmp.n_rows); + blas_int ldvr = blas_int(rtmp.n_rows); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1), 4*N) + blas_int info = 0; + + podarray work( static_cast(lwork) ); + + podarray vals_real(X.n_rows); + podarray vals_imag(X.n_rows); + + arma_extra_debug_print("lapack::geev() -- START"); + lapack::geev(&jobvl, &jobvr, &N, X.memptr(), &N, vals_real.memptr(), vals_imag.memptr(), ltmp.memptr(), &ldvl, rtmp.memptr(), &ldvr, work.memptr(), &lwork, &info); + arma_extra_debug_print("lapack::geev() -- END"); + + if(info != 0) { return false; } + + arma_extra_debug_print("reformatting eigenvalues and eigenvectors"); + + std::complex* vals_mem = vals.memptr(); + + for(uword i=0; i < X.n_rows; ++i) { vals_mem[i] = std::complex(vals_real[i], vals_imag[i]); } + + for(uword j=0; j < X.n_rows; ++j) + { + if( (j < (X.n_rows-1)) && (vals_mem[j] == std::conj(vals_mem[j+1])) ) + { + for(uword i=0; i < X.n_rows; ++i) + { + lvecs.at(i,j) = std::complex( ltmp.at(i,j), ltmp.at(i,j+1) ); + lvecs.at(i,j+1) = std::complex( ltmp.at(i,j), -ltmp.at(i,j+1) ); + rvecs.at(i,j) = std::complex( rtmp.at(i,j), rtmp.at(i,j+1) ); + rvecs.at(i,j+1) = std::complex( rtmp.at(i,j), -rtmp.at(i,j+1) ); + } + ++j; + } + else + { + for(uword i=0; i(ltmp.at(i,j), T(0)); + rvecs.at(i,j) = std::complex(rtmp.at(i,j), T(0)); + } + } + } + + return true; + } + #else + { + arma_ignore(vals); + arma_ignore(lvecs); + arma_ignore(rvecs); + arma_ignore(expr); + arma_stop_logic_error("eig_gen(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +//! two-sided eigen decomposition of general square matrix (complex) +template +inline +bool +auxlib::eig_gen_twosided + ( + Mat< std::complex >& vals, + Mat< std::complex >& lvecs, + Mat< std::complex >& rvecs, + const Base< std::complex, T1 >& expr + ) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + typedef typename T1::pod_type T; + typedef typename std::complex eT; + + Mat X = expr.get_ref(); + + arma_debug_check( (X.is_square() == false), "eig_gen(): given matrix must be square sized" ); + + arma_debug_assert_blas_size(X); + + if(X.is_empty()) + { + vals.reset(); + lvecs.reset(); + rvecs.reset(); + return true; + } + + if(X.is_finite() == false) { return false; } + + vals.set_size(X.n_rows, 1); + + lvecs.set_size(X.n_rows, X.n_rows); + rvecs.set_size(X.n_rows, X.n_rows); + + char jobvl = 'V'; + char jobvr = 'V'; + blas_int N = blas_int(X.n_rows); + blas_int ldvl = blas_int(lvecs.n_rows); + blas_int ldvr = blas_int(rvecs.n_rows); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1), 2*N) + blas_int info = 0; + + podarray work( static_cast(lwork) ); + podarray< T> rwork( static_cast(2*N) ); + + arma_extra_debug_print("lapack::cx_geev() -- START"); + lapack::cx_geev(&jobvl, &jobvr, &N, X.memptr(), &N, vals.memptr(), lvecs.memptr(), &ldvl, rvecs.memptr(), &ldvr, work.memptr(), &lwork, rwork.memptr(), &info); + arma_extra_debug_print("lapack::cx_geev() -- END"); + + return (info == 0); + } + #else + { + arma_ignore(vals); + arma_ignore(lvecs); + arma_ignore(rvecs); + arma_ignore(expr); + arma_stop_logic_error("eig_gen(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +//! two-sided eigen decomposition of general square matrix (real, balance given matrix) +template +inline +bool +auxlib::eig_gen_twosided_balance + ( + Mat< std::complex >& vals, + Mat< std::complex >& lvecs, + Mat< std::complex >& rvecs, + const Base& expr + ) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + typedef typename T1::pod_type T; + + Mat X = expr.get_ref(); + + arma_debug_check( (X.is_square() == false), "eig_gen(): given matrix must be square sized" ); + + arma_debug_assert_blas_size(X); + + if(X.is_empty()) + { + vals.reset(); + lvecs.reset(); + rvecs.reset(); + return true; + } + + if(X.is_finite() == false) { return false; } + + vals.set_size(X.n_rows, 1); + + lvecs.set_size(X.n_rows, X.n_rows); + rvecs.set_size(X.n_rows, X.n_rows); + + Mat ltmp(X.n_rows, X.n_rows, arma_nozeros_indicator()); + Mat rtmp(X.n_rows, X.n_rows, arma_nozeros_indicator()); + + char bal = 'B'; + char jobvl = 'V'; + char jobvr = 'V'; + char sense = 'N'; + blas_int N = blas_int(X.n_rows); + blas_int ldvl = blas_int(ltmp.n_rows); + blas_int ldvr = blas_int(rtmp.n_rows); + blas_int ilo = blas_int(0); + blas_int ihi = blas_int(0); + T abnrm = T(0); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1), blas_int(3*N)) + blas_int info = blas_int(0); + + podarray scale(X.n_rows); + podarray rconde(X.n_rows); + podarray rcondv(X.n_rows); + + podarray work( static_cast(lwork) ); + podarray iwork( uword(1) ); // iwork not used by lapack::geevx() as sense = 'N' + + podarray vals_real(X.n_rows); + podarray vals_imag(X.n_rows); + + arma_extra_debug_print("lapack::geevx() -- START"); + lapack::geevx(&bal, &jobvl, &jobvr, &sense, &N, X.memptr(), &N, vals_real.memptr(), vals_imag.memptr(), ltmp.memptr(), &ldvl, rtmp.memptr(), &ldvr, &ilo, &ihi, scale.memptr(), &abnrm, rconde.memptr(), rcondv.memptr(), work.memptr(), &lwork, iwork.memptr(), &info); + arma_extra_debug_print("lapack::geevx() -- END"); + + if(info != 0) { return false; } + + arma_extra_debug_print("reformatting eigenvalues and eigenvectors"); + + std::complex* vals_mem = vals.memptr(); + + for(uword i=0; i < X.n_rows; ++i) { vals_mem[i] = std::complex(vals_real[i], vals_imag[i]); } + + for(uword j=0; j < X.n_rows; ++j) + { + if( (j < (X.n_rows-1)) && (vals_mem[j] == std::conj(vals_mem[j+1])) ) + { + for(uword i=0; i < X.n_rows; ++i) + { + lvecs.at(i,j) = std::complex( ltmp.at(i,j), ltmp.at(i,j+1) ); + lvecs.at(i,j+1) = std::complex( ltmp.at(i,j), -ltmp.at(i,j+1) ); + rvecs.at(i,j) = std::complex( rtmp.at(i,j), rtmp.at(i,j+1) ); + rvecs.at(i,j+1) = std::complex( rtmp.at(i,j), -rtmp.at(i,j+1) ); + } + ++j; + } + else + { + for(uword i=0; i(ltmp.at(i,j), T(0)); + rvecs.at(i,j) = std::complex(rtmp.at(i,j), T(0)); + } + } + } + + return true; + } + #else + { + arma_ignore(vals); + arma_ignore(lvecs); + arma_ignore(rvecs); + arma_ignore(expr); + arma_stop_logic_error("eig_gen(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +//! two-sided eigen decomposition of general square matrix (complex, balance given matrix) +template +inline +bool +auxlib::eig_gen_twosided_balance + ( + Mat< std::complex >& vals, + Mat< std::complex >& lvecs, + Mat< std::complex >& rvecs, + const Base< std::complex, T1 >& expr + ) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_CRIPPLED_LAPACK) + { + arma_extra_debug_print("auxlib::eig_gen_twosided_balance(): redirecting to auxlib::eig_gen() due to crippled LAPACK"); + + return auxlib::eig_gen(vals, lvecs, rvecs, expr); + } + #elif defined(ARMA_USE_LAPACK) + { + typedef typename T1::pod_type T; + typedef typename std::complex eT; + + Mat X = expr.get_ref(); + + arma_debug_check( (X.is_square() == false), "eig_gen(): given matrix must be square sized" ); + + arma_debug_assert_blas_size(X); + + if(X.is_empty()) + { + vals.reset(); + lvecs.reset(); + rvecs.reset(); + return true; + } + + if(X.is_finite() == false) { return false; } + + vals.set_size(X.n_rows, 1); + + lvecs.set_size(X.n_rows, X.n_rows); + rvecs.set_size(X.n_rows, X.n_rows); + + char bal = 'B'; + char jobvl = 'V'; + char jobvr = 'V'; + char sense = 'N'; + blas_int N = blas_int(X.n_rows); + blas_int ldvl = blas_int(lvecs.n_rows); + blas_int ldvr = blas_int(rvecs.n_rows); + blas_int ilo = blas_int(0); + blas_int ihi = blas_int(0); + T abnrm = T(0); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1), blas_int(2*N)) + blas_int info = blas_int(0); + + podarray scale(X.n_rows); + podarray rconde(X.n_rows); + podarray rcondv(X.n_rows); + + podarray work( static_cast(lwork) ); + podarray< T> rwork( static_cast(2*N) ); + + arma_extra_debug_print("lapack::cx_geevx() -- START"); + lapack::cx_geevx(&bal, &jobvl, &jobvr, &sense, &N, X.memptr(), &N, vals.memptr(), lvecs.memptr(), &ldvl, rvecs.memptr(), &ldvr, &ilo, &ihi, scale.memptr(), &abnrm, rconde.memptr(), rcondv.memptr(), work.memptr(), &lwork, rwork.memptr(), &info); + arma_extra_debug_print("lapack::cx_geevx() -- END"); + + return (info == 0); + } + #else + { + arma_ignore(vals); + arma_ignore(lvecs); + arma_ignore(rvecs); + arma_ignore(expr); + arma_stop_logic_error("eig_gen(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +//! eigendecomposition of general square matrix pair (real) +template +inline +bool +auxlib::eig_pair + ( + Mat< std::complex >& vals, + Mat< std::complex >& vecs, + const bool vecs_on, + const Base& A_expr, const Base& B_expr ) { @@ -1351,7 +1624,7 @@ vals.set_size(A.n_rows, 1); - Mat tmp(1,1); + Mat tmp(1, 1, arma_nozeros_indicator()); if(vecs_on) { @@ -1368,7 +1641,7 @@ T* vr = (vecs_on) ? tmp.memptr() : junk.memptr(); blas_int ldvl = blas_int(1); blas_int ldvr = (vecs_on) ? blas_int(tmp.n_rows) : blas_int(1); - blas_int lwork = 3 * ((std::max)(blas_int(1), 8*N)); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1), 8*N) blas_int info = 0; podarray alphar(A.n_rows); @@ -1410,7 +1683,7 @@ } } - if(beta_has_zero) { arma_debug_warn("eig_pair(): given matrices appear ill-conditioned"); } + if(beta_has_zero) { arma_debug_warn_level(1, "eig_pair(): given matrices appear ill-conditioned"); } if(vecs_on) { @@ -1453,7 +1726,7 @@ -//! eigendecomposition of general square real matrix pair (complex) +//! eigendecomposition of general square matrix pair (complex) template inline bool @@ -1496,16 +1769,253 @@ if(vecs_on) { vecs.set_size(A.n_rows, A.n_rows); } - podarray junk(1); + podarray junk(1); + + char jobvl = 'N'; + char jobvr = (vecs_on) ? 'V' : 'N'; + blas_int N = blas_int(A.n_rows); + eT* vl = junk.memptr(); + eT* vr = (vecs_on) ? vecs.memptr() : junk.memptr(); + blas_int ldvl = blas_int(1); + blas_int ldvr = (vecs_on) ? blas_int(vecs.n_rows) : blas_int(1); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1),2*N) + blas_int info = 0; + + podarray alpha(A.n_rows); + podarray beta(A.n_rows); + + podarray work( static_cast(lwork) ); + podarray rwork( static_cast(8*N) ); + + arma_extra_debug_print("lapack::cx_ggev()"); + lapack::cx_ggev(&jobvl, &jobvr, &N, A.memptr(), &N, B.memptr(), &N, alpha.memptr(), beta.memptr(), vl, &ldvl, vr, &ldvr, work.memptr(), &lwork, rwork.memptr(), &info); + + if(info != 0) { return false; } + + eT* vals_mem = vals.memptr(); + const eT* alpha_mem = alpha.memptr(); + const eT* beta_mem = beta.memptr(); + + const std::complex zero(T(0), T(0)); + + bool beta_has_zero = false; + + for(uword i=0; i +inline +bool +auxlib::eig_pair_twosided + ( + Mat< std::complex >& vals, + Mat< std::complex >& lvecs, + Mat< std::complex >& rvecs, + const Base& A_expr, + const Base& B_expr + ) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + typedef typename T1::pod_type T; + typedef std::complex eT; + + Mat A(A_expr.get_ref()); + Mat B(B_expr.get_ref()); + + arma_debug_check( ((A.is_square() == false) || (B.is_square() == false)), "eig_pair(): given matrices must be square sized" ); + + arma_debug_check( (A.n_rows != B.n_rows), "eig_pair(): given matrices must have the same size" ); + + arma_debug_assert_blas_size(A); + + if(A.is_empty()) + { + vals.reset(); + lvecs.reset(); + rvecs.reset(); + return true; + } + + if(A.is_finite() == false) { return false; } + if(B.is_finite() == false) { return false; } + + vals.set_size(A.n_rows, 1); + + lvecs.set_size(A.n_rows, A.n_rows); + rvecs.set_size(A.n_rows, A.n_rows); + + Mat ltmp(A.n_rows, A.n_rows, arma_nozeros_indicator()); + Mat rtmp(A.n_rows, A.n_rows, arma_nozeros_indicator()); + + char jobvl = 'V'; + char jobvr = 'V'; + blas_int N = blas_int(A.n_rows); + blas_int ldvl = blas_int(ltmp.n_rows); + blas_int ldvr = blas_int(rtmp.n_rows); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1), 8*N) + blas_int info = 0; + + podarray alphar(A.n_rows); + podarray alphai(A.n_rows); + podarray beta(A.n_rows); + + podarray work( static_cast(lwork) ); + + arma_extra_debug_print("lapack::ggev()"); + lapack::ggev(&jobvl, &jobvr, &N, A.memptr(), &N, B.memptr(), &N, alphar.memptr(), alphai.memptr(), beta.memptr(), ltmp.memptr(), &ldvl, rtmp.memptr(), &ldvr, work.memptr(), &lwork, &info); + + if(info != 0) { return false; } + + arma_extra_debug_print("reformatting eigenvalues and eigenvectors"); + + eT* vals_mem = vals.memptr(); + const T* alphar_mem = alphar.memptr(); + const T* alphai_mem = alphai.memptr(); + const T* beta_mem = beta.memptr(); + + bool beta_has_zero = false; + + for(uword j=0; j(re, im); + + if( (alphai_val > T(0)) && (j < (A.n_rows-1)) ) + { + ++j; + vals_mem[j] = std::complex(re,-im); // force exact conjugate + } + } + + if(beta_has_zero) { arma_debug_warn_level(1, "eig_pair(): given matrices appear ill-conditioned"); } + + for(uword j=0; j < A.n_rows; ++j) + { + if( (j < (A.n_rows-1)) && (vals_mem[j] == std::conj(vals_mem[j+1])) ) + { + for(uword i=0; i < A.n_rows; ++i) + { + lvecs.at(i,j) = std::complex( ltmp.at(i,j), ltmp.at(i,j+1) ); + lvecs.at(i,j+1) = std::complex( ltmp.at(i,j), -ltmp.at(i,j+1) ); + rvecs.at(i,j) = std::complex( rtmp.at(i,j), rtmp.at(i,j+1) ); + rvecs.at(i,j+1) = std::complex( rtmp.at(i,j), -rtmp.at(i,j+1) ); + } + ++j; + } + else + { + for(uword i=0; i(ltmp.at(i,j), T(0)); + rvecs.at(i,j) = std::complex(rtmp.at(i,j), T(0)); + } + } + } + + return true; + } + #else + { + arma_ignore(vals); + arma_ignore(lvecs); + arma_ignore(rvecs); + arma_ignore(A_expr); + arma_ignore(B_expr); + arma_stop_logic_error("eig_pair(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +//! two-sided eigendecomposition of general square matrix pair (complex) +template +inline +bool +auxlib::eig_pair_twosided + ( + Mat< std::complex >& vals, + Mat< std::complex >& lvecs, + Mat< std::complex >& rvecs, + const Base< std::complex, T1 >& A_expr, + const Base< std::complex, T2 >& B_expr + ) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + typedef typename T1::pod_type T; + typedef typename std::complex eT; + + Mat A(A_expr.get_ref()); + Mat B(B_expr.get_ref()); + + arma_debug_check( ((A.is_square() == false) || (B.is_square() == false)), "eig_pair(): given matrices must be square sized" ); + + arma_debug_check( (A.n_rows != B.n_rows), "eig_pair(): given matrices must have the same size" ); + + arma_debug_assert_blas_size(A); + + if(A.is_empty()) + { + vals.reset(); + lvecs.reset(); + rvecs.reset(); + return true; + } + + if(A.is_finite() == false) { return false; } + if(B.is_finite() == false) { return false; } + + vals.set_size(A.n_rows, 1); + + lvecs.set_size(A.n_rows, A.n_rows); + rvecs.set_size(A.n_rows, A.n_rows); - char jobvl = 'N'; - char jobvr = (vecs_on) ? 'V' : 'N'; + char jobvl = 'V'; + char jobvr = 'V'; blas_int N = blas_int(A.n_rows); - eT* vl = junk.memptr(); - eT* vr = (vecs_on) ? vecs.memptr() : junk.memptr(); - blas_int ldvl = blas_int(1); - blas_int ldvr = (vecs_on) ? blas_int(vecs.n_rows) : blas_int(1); - blas_int lwork = 3 * ((std::max)(blas_int(1),2*N)); + blas_int ldvl = blas_int(lvecs.n_rows); + blas_int ldvr = blas_int(rvecs.n_rows); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1),2*N) blas_int info = 0; podarray alpha(A.n_rows); @@ -1515,7 +2025,7 @@ podarray rwork( static_cast(8*N) ); arma_extra_debug_print("lapack::cx_ggev()"); - lapack::cx_ggev(&jobvl, &jobvr, &N, A.memptr(), &N, B.memptr(), &N, alpha.memptr(), beta.memptr(), vl, &ldvl, vr, &ldvr, work.memptr(), &lwork, rwork.memptr(), &info); + lapack::cx_ggev(&jobvl, &jobvr, &N, A.memptr(), &N, B.memptr(), &N, alpha.memptr(), beta.memptr(), lvecs.memptr(), &ldvl, rvecs.memptr(), &ldvr, work.memptr(), &lwork, rwork.memptr(), &info); if(info != 0) { return false; } @@ -1536,15 +2046,15 @@ beta_has_zero = (beta_has_zero || (beta_val == zero)); } - if(beta_has_zero) { arma_debug_warn("eig_pair(): given matrices appear ill-conditioned"); } + if(beta_has_zero) { arma_debug_warn_level(1, "eig_pair(): given matrices appear ill-conditioned"); } return true; } #else { arma_ignore(vals); - arma_ignore(vecs); - arma_ignore(vecs_on); + arma_ignore(lvecs); + arma_ignore(rvecs); arma_ignore(A_expr); arma_ignore(B_expr); arma_stop_logic_error("eig_pair(): use of LAPACK must be enabled"); @@ -1556,34 +2066,28 @@ //! eigenvalues of a symmetric real matrix -template +template inline bool -auxlib::eig_sym(Col& eigval, const Base& X) +auxlib::eig_sym(Col& eigval, Mat& A) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_LAPACK) { - Mat A(X.get_ref()); - arma_debug_check( (A.is_square() == false), "eig_sym(): given matrix must be square sized" ); - if(A.is_empty()) - { - eigval.reset(); - return true; - } + if(A.is_empty()) { eigval.reset(); return true; } // if(auxlib::rudimentary_sym_check(A) == false) // { - // arma_debug_warn("eig_sym(): given matrix is not symmetric"); + // arma_debug_warn_level(1, "eig_sym(): given matrix is not symmetric"); // return false; // } if((arma_config::debug) && (auxlib::rudimentary_sym_check(A) == false)) { - arma_debug_warn("eig_sym(): given matrix is not symmetric"); + arma_debug_warn_level(1, "eig_sym(): given matrix is not symmetric"); } arma_debug_assert_blas_size(A); @@ -1594,7 +2098,7 @@ char uplo = 'U'; blas_int N = blas_int(A.n_rows); - blas_int lwork = 3 * ( (std::max)(blas_int(1), 3*N-1) ); + blas_int lwork = (64+2)*N; // lwork_min = (std::max)(blas_int(1), 3*N-1) blas_int info = 0; podarray work( static_cast(lwork) ); @@ -1607,7 +2111,7 @@ #else { arma_ignore(eigval); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("eig_sym(): use of LAPACK must be enabled"); return false; } @@ -1617,10 +2121,10 @@ //! eigenvalues of a hermitian complex matrix -template +template inline bool -auxlib::eig_sym(Col& eigval, const Base,T1>& X) +auxlib::eig_sym(Col& eigval, Mat< std::complex >& A) { arma_extra_debug_sigprint(); @@ -1628,25 +2132,19 @@ { typedef typename std::complex eT; - Mat A(X.get_ref()); - arma_debug_check( (A.is_square() == false), "eig_sym(): given matrix must be square sized" ); - if(A.is_empty()) - { - eigval.reset(); - return true; - } + if(A.is_empty()) { eigval.reset(); return true; } // if(auxlib::rudimentary_sym_check(A) == false) // { - // arma_debug_warn("eig_sym(): given matrix is not hermitian"); + // arma_debug_warn_level(1, "eig_sym(): given matrix is not hermitian"); // return false; // } if((arma_config::debug) && (auxlib::rudimentary_sym_check(A) == false)) { - arma_debug_warn("eig_sym(): given matrix is not hermitian"); + arma_debug_warn_level(1, "eig_sym(): given matrix is not hermitian"); } arma_debug_assert_blas_size(A); @@ -1657,11 +2155,11 @@ char uplo = 'U'; blas_int N = blas_int(A.n_rows); - blas_int lwork = 3 * ( (std::max)(blas_int(1), 2*N-1) ); + blas_int lwork = (64+1)*N; // lwork_min = (std::max)(blas_int(1), 2*N-1) blas_int info = 0; podarray work( static_cast(lwork) ); - podarray rwork( static_cast( (std::max)(blas_int(1), 3*N-2) ) ); + podarray rwork( static_cast( (std::max)(blas_int(1), 3*N) ) ); arma_extra_debug_print("lapack::heev()"); lapack::heev(&jobz, &uplo, &N, A.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, rwork.memptr(), &info); @@ -1671,7 +2169,7 @@ #else { arma_ignore(eigval); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("eig_sym(): use of LAPACK must be enabled"); return false; } @@ -1690,9 +2188,9 @@ #if defined(ARMA_USE_LAPACK) { - eigvec = X; + arma_debug_check( (X.is_square() == false), "eig_sym(): given matrix must be square sized" ); - arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix must be square sized" ); + eigvec = X; if(eigvec.is_empty()) { @@ -1709,7 +2207,7 @@ char uplo = 'U'; blas_int N = blas_int(eigvec.n_rows); - blas_int lwork = 3 * ( (std::max)(blas_int(1), 3*N-1) ); + blas_int lwork = (64+2)*N; // lwork_min = (std::max)(blas_int(1), 3*N-1) blas_int info = 0; podarray work( static_cast(lwork) ); @@ -1744,9 +2242,9 @@ { typedef typename std::complex eT; - eigvec = X; + arma_debug_check( (X.is_square() == false), "eig_sym(): given matrix must be square sized" ); - arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix must be square sized" ); + eigvec = X; if(eigvec.is_empty()) { @@ -1763,11 +2261,11 @@ char uplo = 'U'; blas_int N = blas_int(eigvec.n_rows); - blas_int lwork = 3 * ( (std::max)(blas_int(1), 2*N-1) ); + blas_int lwork = (64+1)*N; // lwork_min = (std::max)(blas_int(1), 2*N-1) blas_int info = 0; podarray work( static_cast(lwork) ); - podarray rwork( static_cast((std::max)(blas_int(1), 3*N-2)) ); + podarray rwork( static_cast((std::max)(blas_int(1), 3*N)) ); arma_extra_debug_print("lapack::heev()"); lapack::heev(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, rwork.memptr(), &info); @@ -1797,9 +2295,9 @@ #if defined(ARMA_USE_LAPACK) { - eigvec = X; + arma_debug_check( (X.is_square() == false), "eig_sym(): given matrix must be square sized" ); - arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix must be square sized" ); + eigvec = X; if(eigvec.is_empty()) { @@ -1815,16 +2313,39 @@ char jobz = 'V'; char uplo = 'U'; - blas_int N = blas_int(eigvec.n_rows); - blas_int lwork = 2 * (1 + 6*N + 2*(N*N)); - blas_int liwork = 3 * (3 + 5*N); - blas_int info = 0; + blas_int N = blas_int(eigvec.n_rows); + blas_int lwork_min = 1 + 6*N + 2*(N*N); + blas_int liwork_min = 3 + 5*N; + blas_int info = 0; + + blas_int lwork_proposed = 0; + blas_int liwork_proposed = 0; + + if(N >= 32) + { + eT work_query[2]; + blas_int iwork_query[2]; + + blas_int lwork_query = -1; + blas_int liwork_query = -1; + + arma_extra_debug_print("lapack::syevd()"); + lapack::syevd(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), &work_query[0], &lwork_query, &iwork_query[0], &liwork_query, &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( work_query[0] ); + liwork_proposed = iwork_query[0]; + } + + blas_int lwork_final = (std::max)( lwork_proposed, lwork_min); + blas_int liwork_final = (std::max)(liwork_proposed, liwork_min); - podarray work( static_cast( lwork) ); - podarray iwork( static_cast(liwork) ); + podarray work( static_cast( lwork_final) ); + podarray iwork( static_cast(liwork_final) ); arma_extra_debug_print("lapack::syevd()"); - lapack::syevd(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, iwork.memptr(), &liwork, &info); + lapack::syevd(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork_final, iwork.memptr(), &liwork_final, &info); return (info == 0); } @@ -1853,9 +2374,9 @@ { typedef typename std::complex eT; - eigvec = X; + arma_debug_check( (X.is_square() == false), "eig_sym(): given matrix must be square sized" ); - arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix must be square sized" ); + eigvec = X; if(eigvec.is_empty()) { @@ -1871,18 +2392,46 @@ char jobz = 'V'; char uplo = 'U'; - blas_int N = blas_int(eigvec.n_rows); - blas_int lwork = 2 * (2*N + N*N); - blas_int lrwork = 2 * (1 + 5*N + 2*(N*N)); - blas_int liwork = 3 * (3 + 5*N); - blas_int info = 0; + blas_int N = blas_int(eigvec.n_rows); + blas_int lwork_min = 2*N + N*N; + blas_int lrwork_min = 1 + 5*N + 2*(N*N); + blas_int liwork_min = 3 + 5*N; + blas_int info = 0; + + blas_int lwork_proposed = 0; + blas_int lrwork_proposed = 0; + blas_int liwork_proposed = 0; - podarray work( static_cast(lwork) ); - podarray rwork( static_cast(lrwork) ); - podarray iwork( static_cast(liwork) ); + if(N >= 32) + { + eT work_query[2]; + T rwork_query[2]; + blas_int iwork_query[2]; + + blas_int lwork_query = -1; + blas_int lrwork_query = -1; + blas_int liwork_query = -1; + + arma_extra_debug_print("lapack::heevd()"); + lapack::heevd(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), &work_query[0], &lwork_query, &rwork_query[0], &lrwork_query, &iwork_query[0], &liwork_query, &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + lrwork_proposed = static_cast( rwork_query[0] ); + liwork_proposed = iwork_query[0]; + } + + blas_int lwork_final = (std::max)( lwork_proposed, lwork_min); + blas_int lrwork_final = (std::max)(lrwork_proposed, lrwork_min); + blas_int liwork_final = (std::max)(liwork_proposed, liwork_min); + + podarray work( static_cast( lwork_final) ); + podarray< T> rwork( static_cast(lrwork_final) ); + podarray iwork( static_cast(liwork_final) ); arma_extra_debug_print("lapack::heevd()"); - lapack::heevd(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, rwork.memptr(), &lrwork, iwork.memptr(), &liwork, &info); + lapack::heevd(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork_final, rwork.memptr(), &lrwork_final, iwork.memptr(), &liwork_final, &info); return (info == 0); } @@ -2077,6 +2626,61 @@ } + +template +inline +bool +auxlib::chol_pivot(Mat& X, Mat& P, const uword layout) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + typedef typename get_pod_type::result T; + + arma_debug_assert_blas_size(X); + + char uplo = (layout == 0) ? 'U' : 'L'; + blas_int n = blas_int(X.n_rows); + blas_int rank = 0; + T tol = T(-1); + blas_int info = 0; + + podarray ipiv( X.n_rows); + podarray work(2*X.n_rows); + + ipiv.zeros(); + + arma_extra_debug_print("lapack::pstrf()"); + lapack::pstrf(&uplo, &n, X.memptr(), &n, ipiv.memptr(), &rank, &tol, work.memptr(), &info); + + if(info != 0) { return false; } + + X = (layout == 0) ? trimatu(X) : trimatl(X); // trimatu() and trimatl() return the same type + + P.set_size(X.n_rows, 1); + + for(uword i=0; i < X.n_rows; ++i) + { + P[i] = uword(ipiv[i] - 1); // take into account that Fortran counts from 1 + } + + return true; + } + #else + { + arma_ignore(X); + arma_ignore(P); + arma_ignore(layout); + + arma_stop_logic_error("chol(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + // // hessenberg decomposition template @@ -2157,7 +2761,6 @@ blas_int m = static_cast(R_n_rows); blas_int n = static_cast(R_n_cols); - blas_int lwork = 0; blas_int lwork_min = (std::max)(blas_int(1), (std::max)(m,n)); // take into account requirements of geqrf() _and_ orgqr()/ungqr() blas_int k = (std::min)(m,n); blas_int info = 0; @@ -2173,13 +2776,12 @@ if(info != 0) { return false; } blas_int lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); - lwork = (std::max)(lwork_proposed, lwork_min); - - podarray work( static_cast(lwork) ); + podarray work( static_cast(lwork_final) ); arma_extra_debug_print("lapack::geqrf()"); - lapack::geqrf(&m, &n, R.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info); + lapack::geqrf(&m, &n, R.memptr(), &m, tau.memptr(), work.memptr(), &lwork_final, &info); if(info != 0) { return false; } @@ -2202,13 +2804,13 @@ if( (is_float::value) || (is_double::value) ) { arma_extra_debug_print("lapack::orgqr()"); - lapack::orgqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info); + lapack::orgqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork_final, &info); } else if( (is_cx_float::value) || (is_cx_double::value) ) { arma_extra_debug_print("lapack::ungqr()"); - lapack::ungqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info); + lapack::ungqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork_final, &info); } return (info == 0); @@ -2248,80 +2850,257 @@ Q = X.get_ref(); - const uword Q_n_rows = Q.n_rows; - const uword Q_n_cols = Q.n_cols; + const uword Q_n_rows = Q.n_rows; + const uword Q_n_cols = Q.n_cols; + + if( Q_n_rows <= Q_n_cols ) + { + return auxlib::qr(Q, R, Q); + } + + if(Q.is_empty()) + { + Q.set_size(Q_n_rows, 0 ); + R.set_size(0, Q_n_cols); + return true; + } + + arma_debug_assert_blas_size(Q); + + blas_int m = static_cast(Q_n_rows); + blas_int n = static_cast(Q_n_cols); + blas_int lwork_min = (std::max)(blas_int(1), (std::max)(m,n)); // take into account requirements of geqrf() _and_ orgqr()/ungqr() + blas_int k = (std::min)(m,n); + blas_int info = 0; + + podarray tau( static_cast(k) ); + + eT work_query[2]; + blas_int lwork_query = -1; + + arma_extra_debug_print("lapack::geqrf()"); + lapack::geqrf(&m, &n, Q.memptr(), &m, tau.memptr(), &work_query[0], &lwork_query, &info); + + if(info != 0) { return false; } + + blas_int lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + + arma_extra_debug_print("lapack::geqrf()"); + lapack::geqrf(&m, &n, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork_final, &info); + + if(info != 0) { return false; } + + R.zeros(Q_n_cols, Q_n_cols); + + // + // construct R + + for(uword col=0; col < Q_n_cols; ++col) + { + for(uword row=0; row <= col; ++row) + { + R.at(row,col) = Q.at(row,col); + } + } + + if( (is_float::value) || (is_double::value) ) + { + arma_extra_debug_print("lapack::orgqr()"); + lapack::orgqr(&m, &n, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork_final, &info); + } + else + if( (is_cx_float::value) || (is_cx_double::value) ) + { + arma_extra_debug_print("lapack::ungqr()"); + lapack::ungqr(&m, &n, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork_final, &info); + } + + return (info == 0); + } + #else + { + arma_ignore(Q); + arma_ignore(R); + arma_ignore(X); + arma_stop_logic_error("qr_econ(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +template +inline +bool +auxlib::qr_pivot(Mat& Q, Mat& R, Mat& P, const Base& X) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + R = X.get_ref(); + + const uword R_n_rows = R.n_rows; + const uword R_n_cols = R.n_cols; + + if(R.is_empty()) + { + Q.eye(R_n_rows, R_n_rows); + + P.set_size(R_n_cols, 1); + + for(uword col=0; col < R_n_cols; ++col) { P.at(col) = col; } + + return true; + } + + arma_debug_assert_blas_size(R); + + blas_int m = static_cast(R_n_rows); + blas_int n = static_cast(R_n_cols); + blas_int lwork_min = (std::max)(blas_int(3*n + 1), (std::max)(m,n)); // take into account requirements of geqp3() and orgqr() + blas_int k = (std::min)(m,n); + blas_int info = 0; + + podarray tau( static_cast(k) ); + podarray jpvt( R_n_cols ); + + jpvt.zeros(); + + eT work_query[2]; + blas_int lwork_query = -1; + + arma_extra_debug_print("lapack::geqp3()"); + lapack::geqp3(&m, &n, R.memptr(), &m, jpvt.memptr(), tau.memptr(), &work_query[0], &lwork_query, &info); + + if(info != 0) { return false; } + + blas_int lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + + arma_extra_debug_print("lapack::geqp3()"); + lapack::geqp3(&m, &n, R.memptr(), &m, jpvt.memptr(), tau.memptr(), work.memptr(), &lwork_final, &info); + + if(info != 0) { return false; } + + Q.set_size(R_n_rows, R_n_rows); + + arrayops::copy( Q.memptr(), R.memptr(), (std::min)(Q.n_elem, R.n_elem) ); + + // + // construct R and P + + P.set_size(R_n_cols, 1); + + for(uword col=0; col < R_n_cols; ++col) + { + for(uword row=(col+1); row < R_n_rows; ++row) { R.at(row,col) = eT(0); } + + P.at(col) = jpvt[col] - 1; // take into account that Fortran counts from 1 + } + + arma_extra_debug_print("lapack::orgqr()"); + lapack::orgqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork_final, &info); + + return (info == 0); + } + #else + { + arma_ignore(Q); + arma_ignore(R); + arma_ignore(P); + arma_ignore(X); + arma_stop_logic_error("qr(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +template +inline +bool +auxlib::qr_pivot(Mat< std::complex >& Q, Mat< std::complex >& R, Mat& P, const Base,T1>& X) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + typedef typename std::complex eT; + + R = X.get_ref(); - if( Q_n_rows <= Q_n_cols ) - { - return auxlib::qr(Q, R, Q); - } + const uword R_n_rows = R.n_rows; + const uword R_n_cols = R.n_cols; - if(Q.is_empty()) + if(R.is_empty()) { - Q.set_size(Q_n_rows, 0 ); - R.set_size(0, Q_n_cols); + Q.eye(R_n_rows, R_n_rows); + + P.set_size(R_n_cols, 1); + + for(uword col=0; col < R_n_cols; ++col) { P.at(col) = col; } + return true; } - arma_debug_assert_blas_size(Q); + arma_debug_assert_blas_size(R); - blas_int m = static_cast(Q_n_rows); - blas_int n = static_cast(Q_n_cols); - blas_int lwork = 0; - blas_int lwork_min = (std::max)(blas_int(1), (std::max)(m,n)); // take into account requirements of geqrf() _and_ orgqr()/ungqr() + blas_int m = static_cast(R_n_rows); + blas_int n = static_cast(R_n_cols); + blas_int lwork_min = (std::max)(blas_int(3*n + 1), (std::max)(m,n)); // take into account requirements of geqp3() and ungqr() blas_int k = (std::min)(m,n); blas_int info = 0; - podarray tau( static_cast(k) ); + podarray tau( static_cast(k) ); + podarray< T> rwork( 2*R_n_cols ); + podarray jpvt( R_n_cols ); + + jpvt.zeros(); eT work_query[2]; blas_int lwork_query = -1; - arma_extra_debug_print("lapack::geqrf()"); - lapack::geqrf(&m, &n, Q.memptr(), &m, tau.memptr(), &work_query[0], &lwork_query, &info); + arma_extra_debug_print("lapack::geqp3()"); + lapack::cx_geqp3(&m, &n, R.memptr(), &m, jpvt.memptr(), tau.memptr(), &work_query[0], &lwork_query, rwork.memptr(), &info); if(info != 0) { return false; } blas_int lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); - lwork = (std::max)(lwork_proposed, lwork_min); - - podarray work( static_cast(lwork) ); + podarray work( static_cast(lwork_final) ); - arma_extra_debug_print("lapack::geqrf()"); - lapack::geqrf(&m, &n, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info); + arma_extra_debug_print("lapack::geqp3()"); + lapack::cx_geqp3(&m, &n, R.memptr(), &m, jpvt.memptr(), tau.memptr(), work.memptr(), &lwork_final, rwork.memptr(), &info); if(info != 0) { return false; } - R.set_size(Q_n_cols, Q_n_cols); + Q.set_size(R_n_rows, R_n_rows); + + arrayops::copy( Q.memptr(), R.memptr(), (std::min)(Q.n_elem, R.n_elem) ); // - // construct R + // construct R and P - for(uword col=0; col < Q_n_cols; ++col) + P.set_size(R_n_cols, 1); + + for(uword col=0; col < R_n_cols; ++col) { - for(uword row=0; row <= col; ++row) - { - R.at(row,col) = Q.at(row,col); - } + for(uword row=(col+1); row < R_n_rows; ++row) { R.at(row,col) = eT(0); } - for(uword row=(col+1); row < Q_n_cols; ++row) - { - R.at(row,col) = eT(0); - } + P.at(col) = jpvt[col] - 1; // take into account that Fortran counts from 1 } - if( (is_float::value) || (is_double::value) ) - { - arma_extra_debug_print("lapack::orgqr()"); - lapack::orgqr(&m, &n, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info); - } - else - if( (is_cx_float::value) || (is_cx_double::value) ) - { - arma_extra_debug_print("lapack::ungqr()"); - lapack::ungqr(&m, &n, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info); - } + arma_extra_debug_print("lapack::ungqr()"); + lapack::ungqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork_final, &info); return (info == 0); } @@ -2329,8 +3108,9 @@ { arma_ignore(Q); arma_ignore(R); + arma_ignore(P); arma_ignore(X); - arma_stop_logic_error("qr_econ(): use of LAPACK must be enabled"); + arma_stop_logic_error("qr(): use of LAPACK must be enabled"); return false; } #endif @@ -2338,71 +3118,64 @@ -template +template inline bool -auxlib::svd(Col& S, const Base& X, uword& X_n_rows, uword& X_n_cols) +auxlib::svd(Col& S, Mat& A) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_LAPACK) { - Mat A(X.get_ref()); - - X_n_rows = A.n_rows; - X_n_cols = A.n_cols; - - if(A.is_empty()) - { - S.reset(); - return true; - } + if(A.is_empty()) { S.reset(); return true; } arma_debug_assert_blas_size(A); - Mat U(1, 1); - Mat V(1, A.n_cols); + Mat U(1, 1, arma_nozeros_indicator()); + Mat V(1, A.n_cols, arma_nozeros_indicator()); char jobu = 'N'; char jobvt = 'N'; - blas_int m = A.n_rows; - blas_int n = A.n_cols; - blas_int min_mn = (std::min)(m,n); - blas_int lda = A.n_rows; - blas_int ldu = U.n_rows; - blas_int ldvt = V.n_rows; - blas_int lwork = 0; - blas_int lwork_min = (std::max)( blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ); - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = blas_int(U.n_rows); + blas_int ldvt = blas_int(V.n_rows); + blas_int lwork_min = (std::max)( blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ); + blas_int info = 0; S.set_size( static_cast(min_mn) ); - eT work_query[2]; - blas_int lwork_query = -1; - - arma_extra_debug_print("lapack::gesvd()"); - lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, &info); - - if(info != 0) { return false; } + blas_int lwork_proposed = 0; - blas_int lwork_proposed = static_cast( work_query[0] ); + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = -1; + + arma_extra_debug_print("lapack::gesvd()"); + lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( work_query[0] ); + } - lwork = (std::max)(lwork_proposed, lwork_min); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); - podarray work( static_cast(lwork) ); + podarray work( static_cast(lwork_final) ); arma_extra_debug_print("lapack::gesvd()"); - lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, &info); + lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, &info); return (info == 0); } #else { arma_ignore(S); - arma_ignore(X); - arma_ignore(X_n_rows); - arma_ignore(X_n_cols); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -2411,10 +3184,10 @@ -template +template inline bool -auxlib::svd(Col& S, const Base, T1>& X, uword& X_n_rows, uword& X_n_cols) +auxlib::svd(Col& S, Mat< std::complex >& A) { arma_extra_debug_sigprint(); @@ -2422,66 +3195,57 @@ { typedef std::complex eT; - Mat A(X.get_ref()); - - X_n_rows = A.n_rows; - X_n_cols = A.n_cols; - - if(A.is_empty()) - { - S.reset(); - return true; - } + if(A.is_empty()) { S.reset(); return true; } arma_debug_assert_blas_size(A); - Mat U(1, 1); - Mat V(1, A.n_cols); + Mat U(1, 1, arma_nozeros_indicator()); + Mat V(1, A.n_cols, arma_nozeros_indicator()); char jobu = 'N'; char jobvt = 'N'; - blas_int m = A.n_rows; - blas_int n = A.n_cols; - blas_int min_mn = (std::min)(m,n); - blas_int lda = A.n_rows; - blas_int ldu = U.n_rows; - blas_int ldvt = V.n_rows; - blas_int lwork = 3 * ( (std::max)(blas_int(1), 2*min_mn+(std::max)(m,n) ) ); - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = blas_int(U.n_rows); + blas_int ldvt = blas_int(V.n_rows); + blas_int lwork_min = (std::max)( blas_int(1), 2*min_mn+(std::max)(m,n) ); + blas_int info = 0; S.set_size( static_cast(min_mn) ); - podarray work( static_cast(lwork ) ); - podarray< T> rwork( static_cast(5*min_mn) ); - - blas_int lwork_tmp = -1; // let gesvd_() calculate the optimum size of the workspace - - arma_extra_debug_print("lapack::cx_gesvd()"); - lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_tmp, rwork.memptr(), &info); - - if(info != 0) { return false; } + podarray rwork( static_cast(5*min_mn) ); - blas_int proposed_lwork = static_cast(real(work[0])); + blas_int lwork_proposed = 0; - if(proposed_lwork > lwork) + if((m*n) >= 1024) { - lwork = proposed_lwork; - work.set_size( static_cast(lwork) ); + eT work_query[2]; + blas_int lwork_query = -1; // query to find optimum size of workspace + + arma_extra_debug_print("lapack::cx_gesvd()"); + lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, rwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); } + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::cx_gesvd()"); - lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, rwork.memptr(), &info); + lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, rwork.memptr(), &info); return (info == 0); } #else { arma_ignore(S); - arma_ignore(X); - arma_ignore(X_n_rows); - arma_ignore(X_n_cols); - + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -2490,43 +3254,15 @@ -template -inline -bool -auxlib::svd(Col& S, const Base& X) - { - arma_extra_debug_sigprint(); - - uword junk; - return auxlib::svd(S, X, junk, junk); - } - - - -template -inline -bool -auxlib::svd(Col& S, const Base, T1>& X) - { - arma_extra_debug_sigprint(); - - uword junk; - return auxlib::svd(S, X, junk, junk); - } - - - -template +template inline bool -auxlib::svd(Mat& U, Col& S, Mat& V, const Base& X) +auxlib::svd(Mat& U, Col& S, Mat& V, Mat& A) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_LAPACK) { - Mat A(X.get_ref()); - if(A.is_empty()) { U.eye(A.n_rows, A.n_rows); @@ -2543,35 +3279,39 @@ char jobu = 'A'; char jobvt = 'A'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int min_mn = (std::min)(m,n); - blas_int lda = blas_int(A.n_rows); - blas_int ldu = blas_int(U.n_rows); - blas_int ldvt = blas_int(V.n_rows); - blas_int lwork_min = (std::max)( blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ); - blas_int lwork = 0; - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = blas_int(U.n_rows); + blas_int ldvt = blas_int(V.n_rows); + blas_int lwork_min = (std::max)( blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ); + blas_int info = 0; S.set_size( static_cast(min_mn) ); - // let gesvd_() calculate the optimum size of the workspace - eT work_query[2]; - blas_int lwork_query = -1; - - arma_extra_debug_print("lapack::gesvd()"); - lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, &info); - - if(info != 0) { return false; } + blas_int lwork_proposed = 0; - blas_int lwork_proposed = static_cast( work_query[0] ); + if((m*n) >= 1024) + { + // query to find optimum size of workspace + eT work_query[2]; + blas_int lwork_query = -1; + + arma_extra_debug_print("lapack::gesvd()"); + lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( work_query[0] ); + } - lwork = (std::max)(lwork_proposed, lwork_min); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); - podarray work( static_cast(lwork) ); + podarray work( static_cast(lwork_final) ); arma_extra_debug_print("lapack::gesvd()"); - lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, &info); + lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, &info); if(info != 0) { return false; } @@ -2584,7 +3324,7 @@ arma_ignore(U); arma_ignore(S); arma_ignore(V); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -2593,10 +3333,10 @@ -template +template inline bool -auxlib::svd(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, const Base< std::complex, T1>& X) +auxlib::svd(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A) { arma_extra_debug_sigprint(); @@ -2604,8 +3344,6 @@ { typedef std::complex eT; - Mat A(X.get_ref()); - if(A.is_empty()) { U.eye(A.n_rows, A.n_rows); @@ -2622,37 +3360,40 @@ char jobu = 'A'; char jobvt = 'A'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int min_mn = (std::min)(m,n); - blas_int lda = blas_int(A.n_rows); - blas_int ldu = blas_int(U.n_rows); - blas_int ldvt = blas_int(V.n_rows); - blas_int lwork = 3 * ( (std::max)(blas_int(1), 2*min_mn + (std::max)(m,n) ) ); - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = blas_int(U.n_rows); + blas_int ldvt = blas_int(V.n_rows); + blas_int lwork_min = (std::max)( blas_int(1), 2*min_mn + (std::max)(m,n) ); + blas_int info = 0; S.set_size( static_cast(min_mn) ); - podarray work( static_cast(lwork ) ); - podarray rwork( static_cast(5*min_mn) ); - - blas_int lwork_tmp = -1; // let gesvd_() calculate the optimum size of the workspace + podarray rwork( static_cast(5*min_mn) ); - arma_extra_debug_print("lapack::cx_gesvd()"); - lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_tmp, rwork.memptr(), &info); - - if(info != 0) { return false; } - - blas_int proposed_lwork = static_cast(real(work[0])); + blas_int lwork_proposed = 0; - if(proposed_lwork > lwork) + if((m*n) >= 1024) { - lwork = proposed_lwork; - work.set_size( static_cast(lwork) ); + eT work_query[2]; + blas_int lwork_query = -1; // query to find optimum size of workspace + + arma_extra_debug_print("lapack::cx_gesvd()"); + lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, rwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); } + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::cx_gesvd()"); - lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, rwork.memptr(), &info); + lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, rwork.memptr(), &info); if(info != 0) { return false; } @@ -2665,7 +3406,7 @@ arma_ignore(U); arma_ignore(S); arma_ignore(V); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -2674,17 +3415,15 @@ -template +template inline bool -auxlib::svd_econ(Mat& U, Col& S, Mat& V, const Base& X, const char mode) +auxlib::svd_econ(Mat& U, Col& S, Mat& V, Mat& A, const char mode) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_LAPACK) { - Mat A(X.get_ref()); - if(A.is_empty()) { U.eye(); @@ -2745,29 +3484,30 @@ } - blas_int lwork = 3 * ( (std::max)(blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ) ); - blas_int info = 0; - - - podarray work( static_cast(lwork) ); - - blas_int lwork_tmp = -1; // let gesvd_() calculate the optimum size of the workspace - - arma_extra_debug_print("lapack::gesvd()"); - lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_tmp, &info); - - if(info != 0) { return false; } + blas_int lwork_min = (std::max)( blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ); + blas_int info = 0; - blas_int proposed_lwork = static_cast(work[0]); + blas_int lwork_proposed = 0; - if(proposed_lwork > lwork) + if((m*n) >= 1024) { - lwork = proposed_lwork; - work.set_size( static_cast(lwork) ); + eT work_query[2]; + blas_int lwork_query = -1; // query to find optimum size of workspace + + arma_extra_debug_print("lapack::gesvd()"); + lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast(work_query[0]); } + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::gesvd()"); - lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, &info); + lapack::gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, &info); if(info != 0) { return false; } @@ -2780,7 +3520,7 @@ arma_ignore(U); arma_ignore(S); arma_ignore(V); - arma_ignore(X); + arma_ignore(A); arma_ignore(mode); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; @@ -2790,10 +3530,10 @@ -template +template inline bool -auxlib::svd_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, const Base< std::complex, T1>& X, const char mode) +auxlib::svd_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A, const char mode) { arma_extra_debug_sigprint(); @@ -2801,8 +3541,6 @@ { typedef std::complex eT; - Mat A(X.get_ref()); - if(A.is_empty()) { U.eye(); @@ -2862,30 +3600,32 @@ V.set_size( static_cast(ldvt), static_cast(n) ); } - blas_int lwork = 3 * ( (std::max)(blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ) ); - blas_int info = 0; - - - podarray work( static_cast(lwork ) ); - podarray rwork( static_cast(5*min_mn) ); - - blas_int lwork_tmp = -1; // let gesvd_() calculate the optimum size of the workspace - - arma_extra_debug_print("lapack::cx_gesvd()"); - lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_tmp, rwork.memptr(), &info); + blas_int lwork_min = (std::max)( blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ); + blas_int info = 0; - if(info != 0) { return false; } + podarray rwork( static_cast(5*min_mn) ); - blas_int proposed_lwork = static_cast(real(work[0])); + blas_int lwork_proposed = 0; - if(proposed_lwork > lwork) + if((m*n) >= 1024) { - lwork = proposed_lwork; - work.set_size( static_cast(lwork) ); + eT work_query[2]; + blas_int lwork_query = -1; // query to find optimum size of workspace + + arma_extra_debug_print("lapack::cx_gesvd()"); + lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, rwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); } + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::cx_gesvd()"); - lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, rwork.memptr(), &info); + lapack::cx_gesvd(&jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, rwork.memptr(), &info); if(info != 0) { return false; } @@ -2898,7 +3638,7 @@ arma_ignore(U); arma_ignore(S); arma_ignore(V); - arma_ignore(X); + arma_ignore(A); arma_ignore(mode); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; @@ -2908,58 +3648,66 @@ -template +template inline bool -auxlib::svd_dc(Col& S, const Base& X, uword& X_n_rows, uword& X_n_cols) +auxlib::svd_dc(Col& S, Mat& A) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_LAPACK) { - Mat A(X.get_ref()); - - X_n_rows = A.n_rows; - X_n_cols = A.n_cols; - - if(A.is_empty()) - { - S.reset(); - return true; - } + if(A.is_empty()) { S.reset(); return true; } arma_debug_assert_blas_size(A); - Mat U(1, 1); - Mat V(1, 1); + Mat U(1, 1, arma_nozeros_indicator()); + Mat V(1, 1, arma_nozeros_indicator()); char jobz = 'N'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int min_mn = (std::min)(m,n); - blas_int lda = blas_int(A.n_rows); - blas_int ldu = blas_int(U.n_rows); - blas_int ldvt = blas_int(V.n_rows); - blas_int lwork = 3 * ( 3*min_mn + std::max( std::max(m,n), 7*min_mn ) ); - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int max_mn = (std::max)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = blas_int(U.n_rows); + blas_int ldvt = blas_int(V.n_rows); + blas_int lwork_min = 3*min_mn + (std::max)( max_mn, 7*min_mn ); + blas_int info = 0; S.set_size( static_cast(min_mn) ); - podarray work( static_cast(lwork ) ); podarray iwork( static_cast(8*min_mn) ); + blas_int lwork_proposed = 0; + + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = blas_int(-1); + + arma_extra_debug_print("lapack::gesdd()"); + lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, iwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( work_query[0] ); + } + + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::gesdd()"); - lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, iwork.memptr(), &info); + lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, iwork.memptr(), &info); return (info == 0); } #else { arma_ignore(S); - arma_ignore(X); - arma_ignore(X_n_rows); - arma_ignore(X_n_cols); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -2968,10 +3716,10 @@ -template +template inline bool -auxlib::svd_dc(Col& S, const Base, T1>& X, uword& X_n_rows, uword& X_n_cols) +auxlib::svd_dc(Col& S, Mat< std::complex >& A) { arma_extra_debug_sigprint(); @@ -2979,50 +3727,58 @@ { typedef std::complex eT; - Mat A(X.get_ref()); - - X_n_rows = A.n_rows; - X_n_cols = A.n_cols; - - if(A.is_empty()) - { - S.reset(); - return true; - } + if(A.is_empty()) { S.reset(); return true; } arma_debug_assert_blas_size(A); - Mat U(1, 1); - Mat V(1, 1); + Mat U(1, 1, arma_nozeros_indicator()); + Mat V(1, 1, arma_nozeros_indicator()); char jobz = 'N'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int min_mn = (std::min)(m,n); - blas_int lda = blas_int(A.n_rows); - blas_int ldu = blas_int(U.n_rows); - blas_int ldvt = blas_int(V.n_rows); - blas_int lwork = 3 * (2*min_mn + std::max(m,n)); - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int max_mn = (std::max)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = blas_int(U.n_rows); + blas_int ldvt = blas_int(V.n_rows); + blas_int lwork_min = 2*min_mn + max_mn; + blas_int info = 0; + + S.set_size( static_cast(min_mn) ); + + podarray rwork( static_cast(7*min_mn) ); // from LAPACK 3.8 docs: LAPACK <= v3.6 needs 7*mn + podarray iwork( static_cast(8*min_mn) ); + + blas_int lwork_proposed = 0; + + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = blas_int(-1); + + arma_extra_debug_print("lapack::cx_gesdd()"); + lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, rwork.memptr(), iwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + } - S.set_size( static_cast(min_mn) ); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); - podarray work( static_cast(lwork ) ); - podarray rwork( static_cast(7*min_mn) ); // LAPACK 3.4.2 docs state 5*min(m,n), while zgesdd() seems to write past the end - podarray iwork( static_cast(8*min_mn) ); + podarray work( static_cast(lwork_final) ); arma_extra_debug_print("lapack::cx_gesdd()"); - lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, rwork.memptr(), iwork.memptr(), &info); + lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, rwork.memptr(), iwork.memptr(), &info); return (info == 0); } #else { arma_ignore(S); - arma_ignore(X); - arma_ignore(X_n_rows); - arma_ignore(X_n_cols); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -3031,43 +3787,15 @@ -template -inline -bool -auxlib::svd_dc(Col& S, const Base& X) - { - arma_extra_debug_sigprint(); - - uword junk; - return auxlib::svd_dc(S, X, junk, junk); - } - - - -template -inline -bool -auxlib::svd_dc(Col& S, const Base, T1>& X) - { - arma_extra_debug_sigprint(); - - uword junk; - return auxlib::svd_dc(S, X, junk, junk); - } - - - -template +template inline bool -auxlib::svd_dc(Mat& U, Col& S, Mat& V, const Base& X) +auxlib::svd_dc(Mat& U, Col& S, Mat& V, Mat& A) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_LAPACK) { - Mat A(X.get_ref()); - if(A.is_empty()) { U.eye(A.n_rows, A.n_rows); @@ -3083,25 +3811,43 @@ char jobz = 'A'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int min_mn = (std::min)(m,n); - blas_int max_mn = (std::max)(m,n); - blas_int lda = blas_int(A.n_rows); - blas_int ldu = blas_int(U.n_rows); - blas_int ldvt = blas_int(V.n_rows); - blas_int lwork1 = 3*min_mn*min_mn + (std::max)( max_mn, 4*min_mn*min_mn + 4*min_mn ); - blas_int lwork2 = 3*min_mn + (std::max)( max_mn, 4*min_mn*min_mn + 3*min_mn + max_mn ); - blas_int lwork = 2 * ((std::max)(lwork1, lwork2)); // due to differences between lapack 3.1 and 3.4 - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int max_mn = (std::max)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = blas_int(U.n_rows); + blas_int ldvt = blas_int(V.n_rows); + blas_int lwork1 = 3*min_mn*min_mn + (std::max)(max_mn, 4*min_mn*min_mn + 4*min_mn); // as per LAPACK 3.2 docs + blas_int lwork2 = 4*min_mn*min_mn + 6*min_mn + max_mn; // as per LAPACK 3.8 docs; consistent with LAPACK 3.4 docs + blas_int lwork_min = (std::max)(lwork1, lwork2); // due to differences between LAPACK 3.2 and 3.8 + blas_int info = 0; S.set_size( static_cast(min_mn) ); - podarray work( static_cast(lwork ) ); podarray iwork( static_cast(8*min_mn) ); + blas_int lwork_proposed = 0; + + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = blas_int(-1); + + arma_extra_debug_print("lapack::gesdd()"); + lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, iwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast(work_query[0]); + } + + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::gesdd()"); - lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, iwork.memptr(), &info); + lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, iwork.memptr(), &info); if(info != 0) { return false; } @@ -3114,7 +3860,7 @@ arma_ignore(U); arma_ignore(S); arma_ignore(V); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -3123,10 +3869,10 @@ -template +template inline bool -auxlib::svd_dc(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, const Base< std::complex, T1>& X) +auxlib::svd_dc(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A) { arma_extra_debug_sigprint(); @@ -3134,8 +3880,6 @@ { typedef std::complex eT; - Mat A(X.get_ref()); - if(A.is_empty()) { U.eye(A.n_rows, A.n_rows); @@ -3151,27 +3895,43 @@ char jobz = 'A'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int min_mn = (std::min)(m,n); - blas_int max_mn = (std::max)(m,n); - blas_int lda = blas_int(A.n_rows); - blas_int ldu = blas_int(U.n_rows); - blas_int ldvt = blas_int(V.n_rows); - blas_int lwork = 2 * (min_mn*min_mn + 2*min_mn + max_mn); - blas_int lrwork1 = 5*min_mn*min_mn + 7*min_mn; - blas_int lrwork2 = min_mn * ((std::max)(5*min_mn+7, 2*max_mn + 2*min_mn+1)); - blas_int lrwork = (std::max)(lrwork1, lrwork2); // due to differences between lapack 3.1 and 3.4 - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int max_mn = (std::max)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = blas_int(U.n_rows); + blas_int ldvt = blas_int(V.n_rows); + blas_int lwork_min = min_mn*min_mn + 2*min_mn + max_mn; // as per LAPACK 3.2, 3.4, 3.8 docs + blas_int lrwork = min_mn * ((std::max)(5*min_mn+7, 2*max_mn + 2*min_mn+1)); // as per LAPACK 3.4 docs; LAPACK 3.8 uses 5*min_mn+5 instead of 5*min_mn+7 + blas_int info = 0; S.set_size( static_cast(min_mn) ); - podarray work( static_cast(lwork ) ); podarray rwork( static_cast(lrwork ) ); podarray iwork( static_cast(8*min_mn) ); + blas_int lwork_proposed = 0; + + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = blas_int(-1); + + arma_extra_debug_print("lapack::cx_gesdd()"); + lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, rwork.memptr(), iwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + } + + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::cx_gesdd()"); - lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, rwork.memptr(), iwork.memptr(), &info); + lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, rwork.memptr(), iwork.memptr(), &info); if(info != 0) { return false; } @@ -3184,7 +3944,7 @@ arma_ignore(U); arma_ignore(S); arma_ignore(V); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -3193,32 +3953,30 @@ -template +template inline bool -auxlib::svd_dc_econ(Mat& U, Col& S, Mat& V, const Base& X) +auxlib::svd_dc_econ(Mat& U, Col& S, Mat& V, Mat& A) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_LAPACK) { - Mat A(X.get_ref()); - arma_debug_assert_blas_size(A); char jobz = 'S'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int min_mn = (std::min)(m,n); - blas_int max_mn = (std::max)(m,n); - blas_int lda = blas_int(A.n_rows); - blas_int ldu = m; - blas_int ldvt = min_mn; - blas_int lwork1 = 3*min_mn*min_mn + (std::max)( max_mn, 4*min_mn*min_mn + 4*min_mn ); - blas_int lwork2 = 3*min_mn + (std::max)( max_mn, 4*min_mn*min_mn + 3*min_mn + max_mn ); - blas_int lwork = 2 * ((std::max)(lwork1, lwork2)); // due to differences between lapack 3.1 and 3.4 - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int max_mn = (std::max)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = m; + blas_int ldvt = min_mn; + blas_int lwork1 = 3*min_mn*min_mn + (std::max)( max_mn, 4*min_mn*min_mn + 4*min_mn ); // as per LAPACK 3.2 docs + blas_int lwork2 = 4*min_mn*min_mn + 6*min_mn + max_mn; // as per LAPACK 3.4 docs; LAPACK 3.8 requires 4*min_mn*min_mn + 7*min_mn + blas_int lwork_min = (std::max)(lwork1, lwork2); // due to differences between LAPACK 3.2 and 3.4 + blas_int info = 0; if(A.is_empty()) { @@ -3234,11 +3992,29 @@ V.set_size( static_cast(min_mn), static_cast(n) ); - podarray work( static_cast(lwork ) ); podarray iwork( static_cast(8*min_mn) ); + blas_int lwork_proposed = 0; + + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = blas_int(-1); + + arma_extra_debug_print("lapack::gesdd()"); + lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, iwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast(work_query[0]); + } + + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::gesdd()"); - lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, iwork.memptr(), &info); + lapack::gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, iwork.memptr(), &info); if(info != 0) { return false; } @@ -3251,7 +4027,7 @@ arma_ignore(U); arma_ignore(S); arma_ignore(V); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -3260,10 +4036,10 @@ -template +template inline bool -auxlib::svd_dc_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, const Base< std::complex, T1>& X) +auxlib::svd_dc_econ(Mat< std::complex >& U, Col& S, Mat< std::complex >& V, Mat< std::complex >& A) { arma_extra_debug_sigprint(); @@ -3271,24 +4047,20 @@ { typedef std::complex eT; - Mat A(X.get_ref()); - arma_debug_assert_blas_size(A); char jobz = 'S'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int min_mn = (std::min)(m,n); - blas_int max_mn = (std::max)(m,n); - blas_int lda = blas_int(A.n_rows); - blas_int ldu = m; - blas_int ldvt = min_mn; - blas_int lwork = 2 * (min_mn*min_mn + 2*min_mn + max_mn); - blas_int lrwork1 = 5*min_mn*min_mn + 7*min_mn; - blas_int lrwork2 = min_mn * ((std::max)(5*min_mn+7, 2*max_mn + 2*min_mn+1)); - blas_int lrwork = (std::max)(lrwork1, lrwork2); // due to differences between lapack 3.1 and 3.4 - blas_int info = 0; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int max_mn = (std::max)(m,n); + blas_int lda = blas_int(A.n_rows); + blas_int ldu = m; + blas_int ldvt = min_mn; + blas_int lwork_min = min_mn*min_mn + 2*min_mn + max_mn; // as per LAPACK 3.2 docs + blas_int lrwork = min_mn * ((std::max)(5*min_mn+7, 2*max_mn + 2*min_mn+1)); // LAPACK 3.8 uses 5*min_mn+5 instead of 5*min_mn+7 + blas_int info = 0; if(A.is_empty()) { @@ -3304,12 +4076,30 @@ V.set_size( static_cast(min_mn), static_cast(n) ); - podarray work( static_cast(lwork ) ); podarray rwork( static_cast(lrwork ) ); podarray iwork( static_cast(8*min_mn) ); + blas_int lwork_proposed = 0; + + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = blas_int(-1); + + arma_extra_debug_print("lapack::cx_gesdd()"); + lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, rwork.memptr(), iwork.memptr(), &info); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + } + + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + arma_extra_debug_print("lapack::cx_gesdd()"); - lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, rwork.memptr(), iwork.memptr(), &info); + lapack::cx_gesdd(&jobz, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork_final, rwork.memptr(), iwork.memptr(), &info); if(info != 0) { return false; } @@ -3322,7 +4112,7 @@ arma_ignore(U); arma_ignore(S); arma_ignore(V); - arma_ignore(X); + arma_ignore(A); arma_stop_logic_error("svd(): use of LAPACK must be enabled"); return false; } @@ -3340,15 +4130,15 @@ { arma_extra_debug_sigprint(); - // NOTE: assuming A has a size <= 4x4 + // NOTE: assuming A has size <= 4x4 typedef typename T1::elem_type eT; const uword A_n_rows = A.n_rows; - Mat A_inv(A_n_rows, A_n_rows); + Mat A_inv(A_n_rows, A_n_rows, arma_nozeros_indicator()); - const bool status = auxlib::inv_tiny(A_inv, A); + const bool status = op_inv::apply_tiny_noalias(A_inv, A); if(status == false) { return false; } @@ -3368,7 +4158,7 @@ if(UB.is_alias(out)) { - Mat tmp(A_n_rows, B_n_cols); + Mat tmp(A_n_rows, B_n_cols, arma_nozeros_indicator()); gemm_emul::apply(tmp, A_inv, B); @@ -3398,11 +4188,11 @@ const uword A_n_rows = A.n_rows; - if(A_n_rows <= 4) + if((A_n_rows <= 4) && is_cx::no) { const bool status = auxlib::solve_square_tiny(out, A, B_expr.get_ref()); - if(status == true) { return true; } + if(status) { return true; } } out = B_expr.get_ref(); @@ -3580,7 +4370,7 @@ blas_int info = blas_int(0); eT rcond = eT(0); - Mat AF(A.n_rows, A.n_rows); + Mat AF(A.n_rows, A.n_rows, arma_nozeros_indicator()); podarray IPIV( A.n_rows); podarray R( A.n_rows); @@ -3682,7 +4472,7 @@ blas_int info = blas_int(0); T rcond = T(0); - Mat AF(A.n_rows, A.n_rows); + Mat AF(A.n_rows, A.n_rows, arma_nozeros_indicator()); podarray IPIV( A.n_rows); podarray< T> R( A.n_rows); @@ -3764,13 +4554,15 @@ { arma_extra_debug_sigprint(); + typedef typename T1::elem_type eT; + const uword A_n_rows = A.n_rows; - if(A_n_rows <= 4) + if((A_n_rows <= 4) && is_cx::no) { const bool status = auxlib::solve_square_tiny(out, A, B_expr.get_ref()); - if(status == true) { return true; } + if(status) { return true; } } out = B_expr.get_ref(); @@ -3788,8 +4580,6 @@ #if defined(ARMA_USE_ATLAS) { - typedef typename T1::elem_type eT; - arma_debug_assert_atlas_size(A, out); int info = 0; @@ -3801,8 +4591,6 @@ } #elif defined(ARMA_USE_LAPACK) { - typedef typename T1::elem_type eT; - arma_debug_assert_blas_size(A, out); char uplo = 'L'; @@ -4030,7 +4818,7 @@ blas_int info = blas_int(0); eT rcond = eT(0); - Mat AF(A.n_rows, A.n_rows); + Mat AF(A.n_rows, A.n_rows, arma_nozeros_indicator()); podarray S( A.n_rows); podarray FERR( B.n_cols); @@ -4119,7 +4907,7 @@ blas_int info = blas_int(0); T rcond = T(0); - Mat AF(A.n_rows, A.n_rows); + Mat AF(A.n_rows, A.n_rows, arma_nozeros_indicator()); podarray< T> S( A.n_rows); podarray< T> FERR( B.n_cols); @@ -4157,7 +4945,7 @@ template inline bool -auxlib::solve_approx_fast(Mat& out, Mat& A, const Base& B_expr) +auxlib::solve_rect_fast(Mat& out, Mat& A, const Base& B_expr) { arma_extra_debug_sigprint(); @@ -4178,7 +4966,7 @@ arma_debug_assert_blas_size(A,B); - Mat tmp( (std::max)(A.n_rows, A.n_cols), B.n_cols ); + Mat tmp( (std::max)(A.n_rows, A.n_cols), B.n_cols, arma_nozeros_indicator() ); if(arma::size(tmp) == arma::size(B)) { @@ -4190,23 +4978,184 @@ tmp(0,0, arma::size(B)) = B; } - char trans = 'N'; - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int lda = blas_int(A.n_rows); - blas_int ldb = blas_int(tmp.n_rows); - blas_int nrhs = blas_int(B.n_cols); - blas_int mn = (std::min)(m,n); - blas_int lwork = 3 * ( (std::max)(blas_int(1), mn + (std::max)(mn, nrhs)) ); - blas_int info = 0; + char trans = 'N'; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int lda = blas_int(A.n_rows); + blas_int ldb = blas_int(tmp.n_rows); + blas_int nrhs = blas_int(B.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int lwork_min = (std::max)(blas_int(1), min_mn + (std::max)(min_mn, nrhs)); + blas_int info = 0; - podarray work( static_cast(lwork) ); + blas_int lwork_proposed = 0; + + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = -1; + + arma_extra_debug_print("lapack::gels()"); + lapack::gels( &trans, &m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, &work_query[0], &lwork_query, &info ); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + } + + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); + + arma_extra_debug_print("lapack::gels()"); + lapack::gels( &trans, &m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, work.memptr(), &lwork_final, &info ); + + if(info != 0) { return false; } + + if(tmp.n_rows == A.n_cols) + { + out.steal_mem(tmp); + } + else + { + out = tmp.head_rows(A.n_cols); + } + + return true; + } + #else + { + arma_ignore(out); + arma_ignore(A); + arma_ignore(B_expr); + arma_stop_logic_error("solve(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +//! solve a non-square full-rank system via QR or LQ decomposition with rcond estimate (experimental) +template +inline +bool +auxlib::solve_rect_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool allow_ugly) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_LAPACK) + { + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + out_rcond = T(0); + + const unwrap U(B_expr.get_ref()); + const Mat& B = U.M; + + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in the given matrices must be the same" ); + + if(A.is_empty() || B.is_empty()) + { + out.zeros(A.n_cols, B.n_cols); + return true; + } + + arma_debug_assert_blas_size(A,B); + + Mat tmp( (std::max)(A.n_rows, A.n_cols), B.n_cols, arma_nozeros_indicator() ); + + if(arma::size(tmp) == arma::size(B)) + { + tmp = B; + } + else + { + tmp.zeros(); + tmp(0,0, arma::size(B)) = B; + } + + char trans = 'N'; + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int lda = blas_int(A.n_rows); + blas_int ldb = blas_int(tmp.n_rows); + blas_int nrhs = blas_int(B.n_cols); + blas_int min_mn = (std::min)(m,n); + blas_int lwork_min = (std::max)(blas_int(1), min_mn + (std::max)(min_mn, nrhs)); + blas_int info = 0; + + blas_int lwork_proposed = 0; + + if((m*n) >= 1024) + { + eT work_query[2]; + blas_int lwork_query = -1; + + arma_extra_debug_print("lapack::gels()"); + lapack::gels( &trans, &m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, &work_query[0], &lwork_query, &info ); + + if(info != 0) { return false; } + + lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + } + + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); + + podarray work( static_cast(lwork_final) ); arma_extra_debug_print("lapack::gels()"); - lapack::gels( &trans, &m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, work.memptr(), &lwork, &info ); + lapack::gels( &trans, &m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, work.memptr(), &lwork_final, &info ); if(info != 0) { return false; } + if(A.n_rows >= A.n_cols) + { + arma_extra_debug_print("estimating rcond via R"); + + // xGELS docs: for M >= N, A contains details of its QR decomposition as returned by xGEQRF + // xGEQRF docs: elements on and above the diagonal contain the min(M,N)-by-N upper trapezoidal matrix R + + Mat R(A.n_cols, A.n_cols, arma_zeros_indicator()); + + for(uword col=0; col < A.n_cols; ++col) + { + for(uword row=0; row <= col; ++row) + { + R.at(row,col) = A.at(row,col); + } + } + + // determine quality of solution + out_rcond = auxlib::rcond_trimat(R, 0); // 0: upper triangular; 1: lower triangular + + if( (allow_ugly == false) && (out_rcond < auxlib::epsilon_lapack(A)) ) { return false; } + } + else + if(A.n_rows < A.n_cols) + { + arma_extra_debug_print("estimating rcond via L"); + + // xGELS docs: for M < N, A contains details of its LQ decomposition as returned by xGELQF + // xGELQF docs: elements on and below the diagonal contain the M-by-min(M,N) lower trapezoidal matrix L + + Mat L(A.n_rows, A.n_rows, arma_zeros_indicator()); + + for(uword col=0; col < A.n_rows; ++col) + { + for(uword row=col; row < A.n_rows; ++row) + { + L.at(row,col) = A.at(row,col); + } + } + + // determine quality of solution + out_rcond = auxlib::rcond_trimat(L, 1); // 0: upper triangular; 1: lower triangular + + if( (allow_ugly == false) && (out_rcond < auxlib::epsilon_lapack(A)) ) { return false; } + } + if(tmp.n_rows == A.n_cols) { out.steal_mem(tmp); @@ -4221,8 +5170,10 @@ #else { arma_ignore(out); + arma_ignore(out_rcond); arma_ignore(A); arma_ignore(B_expr); + arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -4255,7 +5206,7 @@ arma_debug_assert_blas_size(A,B); - Mat tmp( (std::max)(A.n_rows, A.n_cols), B.n_cols ); + Mat tmp( (std::max)(A.n_rows, A.n_cols), B.n_cols, arma_nozeros_indicator() ); if(arma::size(tmp) == arma::size(B)) { @@ -4267,18 +5218,17 @@ tmp(0,0, arma::size(B)) = B; } - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int nrhs = blas_int(B.n_cols); - blas_int lda = blas_int(A.n_rows); - blas_int ldb = blas_int(tmp.n_rows); - eT rcond = eT(-1); // -1 means "use machine precision" - blas_int rank = blas_int(0); - blas_int info = blas_int(0); - - const uword min_mn = (std::min)(A.n_rows, A.n_cols); + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m, n); + blas_int nrhs = blas_int(B.n_cols); + blas_int lda = blas_int(A.n_rows); + blas_int ldb = blas_int(tmp.n_rows); + eT rcond = eT(-1); // -1 means "use machine precision" + blas_int rank = blas_int(0); + blas_int info = blas_int(0); - podarray S(min_mn); + podarray S( static_cast(min_mn) ); // NOTE: with LAPACK 3.8, can use the workspace query to also obtain liwork, // NOTE: which makes the call to lapack::laenv() redundant @@ -4302,10 +5252,12 @@ blas_int smlsiz_p1 = blas_int(1) + smlsiz; blas_int nlvl = (std::max)( blas_int(0), blas_int(1) + blas_int( std::log(double(min_mn) / double(smlsiz_p1))/double(0.69314718055994530942) ) ); - blas_int liwork = (std::max)( blas_int(1), (blas_int(3)*blas_int(min_mn)*nlvl + blas_int(11)*blas_int(min_mn)) ); + blas_int liwork = (std::max)( blas_int(1), (blas_int(3)*min_mn*nlvl + blas_int(11)*min_mn) ); podarray iwork( static_cast(liwork) ); + blas_int lwork_min = blas_int(12)*min_mn + blas_int(2)*min_mn*smlsiz + blas_int(8)*min_mn*nlvl + min_mn*nrhs + smlsiz_p1*smlsiz_p1; + eT work_query[2]; blas_int lwork_query = blas_int(-1); @@ -4316,12 +5268,13 @@ // NOTE: in LAPACK 3.8, iwork[0] returns the minimum liwork - blas_int lwork = static_cast( access::tmp_real(work_query[0]) ); + blas_int lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); - podarray work( static_cast(lwork) ); + podarray work( static_cast(lwork_final) ); arma_extra_debug_print("lapack::gelsd()"); - lapack::gelsd(&m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, S.memptr(), &rcond, &rank, work.memptr(), &lwork, iwork.memptr(), &info); + lapack::gelsd(&m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, S.memptr(), &rcond, &rank, work.memptr(), &lwork_final, iwork.memptr(), &info); if(info != 0) { return false; } @@ -4374,7 +5327,7 @@ arma_debug_assert_blas_size(A,B); - Mat tmp( (std::max)(A.n_rows, A.n_cols), B.n_cols ); + Mat tmp( (std::max)(A.n_rows, A.n_cols), B.n_cols, arma_nozeros_indicator() ); if(arma::size(tmp) == arma::size(B)) { @@ -4386,18 +5339,17 @@ tmp(0,0, arma::size(B)) = B; } - blas_int m = blas_int(A.n_rows); - blas_int n = blas_int(A.n_cols); - blas_int nrhs = blas_int(B.n_cols); - blas_int lda = blas_int(A.n_rows); - blas_int ldb = blas_int(tmp.n_rows); - T rcond = T(-1); // -1 means "use machine precision" - blas_int rank = blas_int(0); - blas_int info = blas_int(0); - - const uword min_mn = (std::min)(A.n_rows, A.n_cols); + blas_int m = blas_int(A.n_rows); + blas_int n = blas_int(A.n_cols); + blas_int min_mn = (std::min)(m, n); + blas_int nrhs = blas_int(B.n_cols); + blas_int lda = blas_int(A.n_rows); + blas_int ldb = blas_int(tmp.n_rows); + T rcond = T(-1); // -1 means "use machine precision" + blas_int rank = blas_int(0); + blas_int info = blas_int(0); - podarray S(min_mn); + podarray S( static_cast(min_mn) ); blas_int ispec = blas_int(9); @@ -4414,7 +5366,7 @@ blas_int laenv_result = (arma_config::hidden_args) ? blas_int(lapack::laenv(&ispec, name, opts, &n1, &n2, &n3, &n4, 6, 1)) : blas_int(0); - blas_int smlsiz = (std::max)( blas_int(25), laenv_result ); + blas_int smlsiz = (std::max)( blas_int(25), laenv_result ); blas_int smlsiz_p1 = blas_int(1) + smlsiz; blas_int nlvl = (std::max)( blas_int(0), blas_int(1) + blas_int( std::log(double(min_mn) / double(smlsiz_p1))/double(0.69314718055994530942) ) ); @@ -4428,6 +5380,8 @@ podarray rwork( static_cast(lrwork) ); podarray iwork( static_cast(liwork) ); + blas_int lwork_min = 2*min_mn + min_mn*nrhs; + eT work_query[2]; blas_int lwork_query = blas_int(-1); @@ -4436,12 +5390,13 @@ if(info != 0) { return false; } - blas_int lwork = static_cast( access::tmp_real( work_query[0]) ); + blas_int lwork_proposed = static_cast( access::tmp_real( work_query[0]) ); + blas_int lwork_final = (std::max)(lwork_proposed, lwork_min); - podarray work( static_cast(lwork) ); + podarray work( static_cast(lwork_final) ); arma_extra_debug_print("lapack::cx_gelsd()"); - lapack::cx_gelsd(&m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, S.memptr(), &rcond, &rank, work.memptr(), &lwork, rwork.memptr(), iwork.memptr(), &info); + lapack::cx_gelsd(&m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, S.memptr(), &rcond, &rank, work.memptr(), &lwork_final, rwork.memptr(), iwork.memptr(), &info); if(info != 0) { return false; } @@ -4846,7 +5801,7 @@ out.set_size(N, B.n_cols); - Mat AFB(2*KL+KU+1, N); + Mat AFB(2*KL+KU+1, N, arma_nozeros_indicator()); char fact = (equilibrate) ? 'E' : 'N'; char trans = 'N'; @@ -4955,7 +5910,7 @@ out.set_size(N, B.n_cols); - Mat AFB(2*KL+KU+1, N); + Mat AFB(2*KL+KU+1, N, arma_nozeros_indicator()); char fact = (equilibrate) ? 'E' : 'N'; char trans = 'N'; @@ -5145,7 +6100,7 @@ blas_int n = blas_int(S_n_rows); blas_int sdim = 0; blas_int ldvs = calc_U ? n : blas_int(1); - blas_int lwork = 3 * ((std::max)(blas_int(1), 3*n)); + blas_int lwork = 64*n; // lwork_min = (std::max)(blas_int(1), 3*n) blas_int info = 0; podarray wr(S_n_rows); @@ -5176,7 +6131,7 @@ template inline bool -auxlib::schur(Mat >& U, Mat >& S, const Base,T1>& X, const bool calc_U) +auxlib::schur(Mat< std::complex >& U, Mat< std::complex >& S, const Base,T1>& X, const bool calc_U) { arma_extra_debug_sigprint(); @@ -5192,7 +6147,7 @@ template inline bool -auxlib::schur(Mat >& U, Mat >& S, const bool calc_U) +auxlib::schur(Mat< std::complex >& U, Mat< std::complex >& S, const bool calc_U) { arma_extra_debug_sigprint(); @@ -5219,7 +6174,7 @@ blas_int n = blas_int(S_n_rows); blas_int sdim = 0; blas_int ldvs = calc_U ? n : blas_int(1); - blas_int lwork = 3 * ((std::max)(blas_int(1), 2*n)); + blas_int lwork = 64*n; // lwork_min = (std::max)(blas_int(1), 2*n) blas_int info = 0; podarray w(S_n_rows); @@ -5246,7 +6201,7 @@ // -// syl (solution of the Sylvester equation AX + XB = C) +// solve the Sylvester equation AX + XB = C template inline @@ -5261,21 +6216,14 @@ arma_debug_check( (C.n_rows != A.n_rows) || (C.n_cols != B.n_cols), "syl(): matrices are not conformant" ); - if(A.is_empty() || B.is_empty() || C.is_empty()) - { - X.reset(); - return true; - } - + if(A.is_empty() || B.is_empty() || C.is_empty()) { X.reset(); return true; } + Mat Z1, Z2, T1, T2; const bool status_sd1 = auxlib::schur(Z1, T1, A); const bool status_sd2 = auxlib::schur(Z2, T2, B); - if( (status_sd1 == false) || (status_sd2 == false) ) - { - return false; - } + if( (status_sd1 == false) || (status_sd2 == false) ) { return false; } char trana = 'N'; char tranb = 'N'; @@ -5353,7 +6301,7 @@ void* selctg = 0; blas_int N = blas_int(A.n_rows); blas_int sdim = 0; - blas_int lwork = 3 * ((std::max)(blas_int(1),8*N+16)); + blas_int lwork = 64*N+16; // lwork_min = (std::max)(blas_int(1),8*N+16) blas_int info = 0; if(mode == 'l') { eigsort = 'S'; selctg = qz_helper::ptr_cast(&(qz_helper::select_lhp)); } @@ -5444,7 +6392,7 @@ void* selctg = 0; blas_int N = blas_int(A.n_rows); blas_int sdim = 0; - blas_int lwork = 3 * ((std::max)(blas_int(1),2*N)); + blas_int lwork = 64*N; // lwork_min = (std::max)(blas_int(1),2*N) blas_int info = 0; if(mode == 'l') { eigsort = 'S'; selctg = qz_helper::ptr_cast(&(qz_helper::cx_select_lhp)); } @@ -6151,7 +7099,8 @@ const T tol = T(10000)*std::numeric_limits::epsilon(); // allow some leeway - if(std::abs(X_mem[0].imag()) > tol) { return false; } + if(std::abs(X_mem[0 ].imag()) > tol) { return false; } // check top-left + if(std::abs(X_mem[X.n_elem-1].imag()) > tol) { return false; } // check bottom-right const eT& A = X_mem[Nm1 ]; // bottom-left corner (ie. last value in first column) const eT& B = X_mem[Nm1*N]; // top-right corner (ie. first value in last column) diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/band_helper.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/band_helper.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/band_helper.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/band_helper.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -37,7 +39,7 @@ if(N < N_min) { return false; } - // first, quickly check bottom-right and top-left corners + // first, quickly check bottom-left and top-right corners const eT eT_zero = eT(0); @@ -115,7 +117,7 @@ if(N < N_min) { return false; } - // first, quickly check bottom-right corner + // first, quickly check bottom-left corner const eT eT_zero = eT(0); @@ -178,7 +180,7 @@ if(N < N_min) { return false; } - // first, quickly check top-left corner + // first, quickly check top-right corner const eT eT_zero = eT(0); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Base_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Base_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Base_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Base_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,10 +24,7 @@ template struct Base_extra_yes { - arma_inline const Op i() const; //!< matrix inverse - - arma_deprecated inline const Op i(const bool ) const; //!< kept only for compatibility with old user code - arma_deprecated inline const Op i(const char*) const; //!< kept only for compatibility with old user code + inline arma_warn_unused const Op i() const; //!< matrix inverse inline arma_warn_unused bool is_sympd() const; inline arma_warn_unused bool is_sympd(typename get_pod_type::result tol) const; @@ -52,14 +51,14 @@ template struct Base_eval_Mat { - arma_inline const derived& eval() const; + arma_inline arma_warn_unused const derived& eval() const; }; template struct Base_eval_expr { - arma_inline Mat eval() const; //!< force the immediate evaluation of a delayed expression + inline arma_warn_unused Mat eval() const; //!< force the immediate evaluation of a delayed expression }; @@ -77,18 +76,18 @@ template struct Base_trans_cx { - arma_inline const Op t() const; - arma_inline const Op ht() const; - arma_inline const Op st() const; // simple transpose: no complex conjugates + arma_inline arma_warn_unused const Op t() const; + arma_inline arma_warn_unused const Op ht() const; + arma_inline arma_warn_unused const Op st() const; // simple transpose: no complex conjugates }; template struct Base_trans_default { - arma_inline const Op t() const; - arma_inline const Op ht() const; - arma_inline const Op st() const; // return op_htrans instead of op_strans, as it's handled better by matrix multiplication code + arma_inline arma_warn_unused const Op t() const; + arma_inline arma_warn_unused const Op ht() const; + arma_inline arma_warn_unused const Op st() const; // return op_htrans instead of op_strans, as it's handled better by matrix multiplication code }; @@ -105,7 +104,7 @@ //! Class for static polymorphism, modelled after the "Curiously Recurring Template Pattern" (CRTP). //! Used for type-safe downcasting in functions that restrict their input(s) to be classes that are -//! derived from Base (e.g. Mat, Op, Glue, diagview, subview). +//! derived from Base (eg. Mat, Op, Glue, diagview, subview). //! A Base object can be converted to a Mat object by the unwrap class. template @@ -122,6 +121,9 @@ arma_cold inline void raw_print( const std::string extra_text = "") const; arma_cold inline void raw_print(std::ostream& user_stream, const std::string extra_text = "") const; + arma_cold inline void brief_print( const std::string extra_text = "") const; + arma_cold inline void brief_print(std::ostream& user_stream, const std::string extra_text = "") const; + inline arma_warn_unused elem_type min() const; inline arma_warn_unused elem_type max() const; @@ -140,6 +142,8 @@ inline arma_warn_unused bool is_hermitian() const; inline arma_warn_unused bool is_hermitian(const typename get_pod_type::result tol) const; + inline arma_warn_unused bool is_zero(const typename get_pod_type::result tol = 0) const; + inline arma_warn_unused bool is_trimatu() const; inline arma_warn_unused bool is_trimatl() const; inline arma_warn_unused bool is_diagmat() const; @@ -152,8 +156,8 @@ inline arma_warn_unused bool has_inf() const; inline arma_warn_unused bool has_nan() const; - arma_inline const Op as_col() const; - arma_inline const Op as_row() const; + inline arma_warn_unused const Op as_col() const; + inline arma_warn_unused const Op as_row() const; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/BaseCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/BaseCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/BaseCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/BaseCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,14 +24,14 @@ template struct BaseCube_eval_Cube { - arma_inline const derived& eval() const; + arma_inline arma_warn_unused const derived& eval() const; }; template struct BaseCube_eval_expr { - arma_inline Cube eval() const; //!< force the immediate evaluation of a delayed expression + inline arma_warn_unused Cube eval() const; //!< force the immediate evaluation of a delayed expression }; @@ -57,12 +59,17 @@ arma_cold inline void raw_print( const std::string extra_text = "") const; arma_cold inline void raw_print(std::ostream& user_stream, const std::string extra_text = "") const; + arma_cold inline void brief_print( const std::string extra_text = "") const; + arma_cold inline void brief_print(std::ostream& user_stream, const std::string extra_text = "") const; + inline arma_warn_unused elem_type min() const; inline arma_warn_unused elem_type max() const; inline arma_warn_unused uword index_min() const; inline arma_warn_unused uword index_max() const; + inline arma_warn_unused bool is_zero(const typename get_pod_type::result tol = 0) const; + inline arma_warn_unused bool is_empty() const; inline arma_warn_unused bool is_finite() const; inline arma_warn_unused bool has_inf() const; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/BaseCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/BaseCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/BaseCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/BaseCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,9 +37,20 @@ void BaseCube::print(const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_cube tmp( (*this).get_ref() ); - tmp.M.impl_print(extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::print(get_cout_stream(), tmp.M, true); } @@ -48,9 +61,20 @@ void BaseCube::print(std::ostream& user_stream, const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_cube tmp( (*this).get_ref() ); - tmp.M.impl_print(user_stream, extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::print(user_stream, tmp.M, true); } @@ -61,9 +85,20 @@ void BaseCube::raw_print(const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_cube tmp( (*this).get_ref() ); - tmp.M.impl_raw_print(extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::print(get_cout_stream(), tmp.M, false); } @@ -74,9 +109,68 @@ void BaseCube::raw_print(std::ostream& user_stream, const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_cube tmp( (*this).get_ref() ); - tmp.M.impl_raw_print(user_stream, extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::print(user_stream, tmp.M, false); + } + + + +template +arma_cold +inline +void +BaseCube::brief_print(const std::string extra_text) const + { + arma_extra_debug_sigprint(); + + const unwrap_cube tmp( (*this).get_ref() ); + + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::brief_print(get_cout_stream(), tmp.M); + } + + + +template +arma_cold +inline +void +BaseCube::brief_print(std::ostream& user_stream, const std::string extra_text) const + { + arma_extra_debug_sigprint(); + + const unwrap_cube tmp( (*this).get_ref() ); + + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::brief_print(user_stream, tmp.M); } @@ -155,6 +249,59 @@ inline arma_warn_unused bool +BaseCube::is_zero(const typename get_pod_type::result tol) const + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + arma_debug_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" ); + + if(ProxyCube::use_at || is_Cube::stored_type>::value) + { + const unwrap_cube U( (*this).get_ref() ); + + return arrayops::is_zero( U.M.memptr(), U.M.n_elem, tol ); + } + + const ProxyCube P( (*this).get_ref() ); + + const uword n_elem = P.get_n_elem(); + + if(n_elem == 0) { return false; } + + const typename ProxyCube::ea_type Pea = P.get_ea(); + + if(is_cx::yes) + { + for(uword i=0; i 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(eop_aux::arma_abs(Pea[i]) > tol) { return false; } + } + } + + return true; + } + + + +template +inline +arma_warn_unused +bool BaseCube::is_empty() const { arma_extra_debug_sigprint(); @@ -270,6 +417,7 @@ template arma_inline +arma_warn_unused const derived& BaseCube_eval_Cube::eval() const { @@ -284,7 +432,8 @@ // extra functions defined in BaseCube_eval_expr template -arma_inline +inline +arma_warn_unused Cube BaseCube_eval_expr::eval() const { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Base_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Base_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Base_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Base_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,9 +37,20 @@ void Base::print(const std::string extra_text) const { + arma_extra_debug_sigprint(); + const quasi_unwrap tmp( (*this).get_ref() ); - tmp.M.impl_print(extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::print(get_cout_stream(), tmp.M, true); } @@ -48,9 +61,20 @@ void Base::print(std::ostream& user_stream, const std::string extra_text) const { + arma_extra_debug_sigprint(); + const quasi_unwrap tmp( (*this).get_ref() ); - tmp.M.impl_print(user_stream, extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::print(user_stream, tmp.M, true); } @@ -61,9 +85,20 @@ void Base::raw_print(const std::string extra_text) const { + arma_extra_debug_sigprint(); + const quasi_unwrap tmp( (*this).get_ref() ); - tmp.M.impl_raw_print(extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::print(get_cout_stream(), tmp.M, false); } @@ -74,9 +109,68 @@ void Base::raw_print(std::ostream& user_stream, const std::string extra_text) const { + arma_extra_debug_sigprint(); + + const quasi_unwrap tmp( (*this).get_ref() ); + + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::print(user_stream, tmp.M, false); + } + + + +template +arma_cold +inline +void +Base::brief_print(const std::string extra_text) const + { + arma_extra_debug_sigprint(); + + const quasi_unwrap tmp( (*this).get_ref() ); + + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::brief_print(get_cout_stream(), tmp.M); + } + + + +template +arma_cold +inline +void +Base::brief_print(std::ostream& user_stream, const std::string extra_text) const + { + arma_extra_debug_sigprint(); + const quasi_unwrap tmp( (*this).get_ref() ); - tmp.M.impl_raw_print(user_stream, extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::brief_print(user_stream, tmp.M); } @@ -379,6 +473,59 @@ inline arma_warn_unused bool +Base::is_zero(const typename get_pod_type::result tol) const + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + arma_debug_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" ); + + if(Proxy::use_at || is_Mat::stored_type>::value) + { + const quasi_unwrap U( (*this).get_ref() ); + + return arrayops::is_zero( U.M.memptr(), U.M.n_elem, tol ); + } + + const Proxy P( (*this).get_ref() ); + + const uword n_elem = P.get_n_elem(); + + if(n_elem == 0) { return false; } + + const typename Proxy::ea_type Pea = P.get_ea(); + + if(is_cx::yes) + { + for(uword i=0; i tol) { return false; } + if(eop_aux::arma_abs(val_imag) > tol) { return false; } + } + } + else // not complex + { + for(uword i=0; i tol) { return false; } + } + } + + return true; + } + + + +template +inline +arma_warn_unused +bool Base::is_trimatu() const { arma_extra_debug_sigprint(); @@ -427,19 +574,25 @@ if(A.n_elem <= 1) { return true; } + // NOTE: we're NOT assuming the matrix has a square size + const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; - const elem_type* A_colmem = A.memptr(); + const elem_type* A_mem = A.memptr(); + + if(A_mem[1] != elem_type(0)) { return false; } + + // if we got to this point, do a thorough check for(uword A_col=0; A_col < A_n_cols; ++A_col) { for(uword A_row=0; A_row < A_n_rows; ++A_row) { - if( (A_colmem[A_row] != elem_type(0)) && (A_row != A_col) ) { return false; } + if( (A_mem[A_row] != elem_type(0)) && (A_row != A_col) ) { return false; } } - A_colmem += A_n_rows; + A_mem += A_n_rows; } return true; @@ -664,7 +817,8 @@ template -arma_inline +inline +arma_warn_unused const Op Base::as_col() const { @@ -674,7 +828,8 @@ template -arma_inline +inline +arma_warn_unused const Op Base::as_row() const { @@ -687,36 +842,11 @@ // extra functions defined in Base_extra_yes template -arma_inline -const Op -Base_extra_yes::i() const - { - return Op(static_cast(*this)); - } - - - -template -arma_deprecated -inline -const Op -Base_extra_yes::i(const bool) const // argument kept only for compatibility with old user code - { - // arma_debug_warn(".i(bool) is deprecated and will be removed; change to .i()"); - - return Op(static_cast(*this)); - } - - - -template -arma_deprecated inline +arma_warn_unused const Op -Base_extra_yes::i(const char*) const // argument kept only for compatibility with old user code +Base_extra_yes::i() const { - // arma_debug_warn(".i(char*) is deprecated and will be removed; change to .i()"); - return Op(static_cast(*this)); } @@ -778,6 +908,7 @@ template arma_inline +arma_warn_unused const derived& Base_eval_Mat::eval() const { @@ -792,7 +923,8 @@ // extra functions defined in Base_eval_expr template -arma_inline +inline +arma_warn_unused Mat Base_eval_expr::eval() const { @@ -808,6 +940,7 @@ template arma_inline +arma_warn_unused const Op Base_trans_cx::t() const { @@ -818,6 +951,7 @@ template arma_inline +arma_warn_unused const Op Base_trans_cx::ht() const { @@ -828,6 +962,7 @@ template arma_inline +arma_warn_unused const Op Base_trans_cx::st() const { @@ -841,6 +976,7 @@ template arma_inline +arma_warn_unused const Op Base_trans_default::t() const { @@ -851,6 +987,7 @@ template arma_inline +arma_warn_unused const Op Base_trans_default::ht() const { @@ -861,6 +998,7 @@ template arma_inline +arma_warn_unused const Op Base_trans_default::st() const { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Col_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Col_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Col_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Col_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,20 +29,29 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_col = true; - static const bool is_row = false; - static const bool is_xvec = false; + static constexpr bool is_col = true; + static constexpr bool is_row = false; + static constexpr bool is_xvec = false; + + inline Col(); + inline Col(const Col& X); - inline Col(); - inline Col(const Col& X); inline explicit Col(const uword n_elem); inline explicit Col(const uword in_rows, const uword in_cols); inline explicit Col(const SizeMat& s); + template inline explicit Col(const uword n_elem, const arma_initmode_indicator&); + template inline explicit Col(const uword in_rows, const uword in_cols, const arma_initmode_indicator&); + template inline explicit Col(const SizeMat& s, const arma_initmode_indicator&); + template inline Col(const uword n_elem, const fill::fill_class& f); template inline Col(const uword in_rows, const uword in_cols, const fill::fill_class& f); template inline Col(const SizeMat& s, const fill::fill_class& f); + inline Col(const uword N, const fill::scalar_holder f); + inline Col(const uword in_rows, const uword in_cols, const fill::scalar_holder f); + inline Col(const SizeMat& s, const fill::scalar_holder f); + inline Col(const char* text); inline Col& operator=(const char* text); @@ -50,13 +61,11 @@ inline Col(const std::vector& x); inline Col& operator=(const std::vector& x); - #if defined(ARMA_USE_CXX11) inline Col(const std::initializer_list& list); inline Col& operator=(const std::initializer_list& list); inline Col(Col&& m); inline Col& operator=(Col&& m); - #endif inline Col& operator=(const eT val); inline Col& operator=(const Col& m); @@ -79,13 +88,13 @@ inline Col(const subview_cube& X); inline Col& operator=(const subview_cube& X); - inline mat_injector operator<<(const eT val); + arma_cold inline mat_injector operator<<(const eT val); - arma_inline const Op,op_htrans> t() const; - arma_inline const Op,op_htrans> ht() const; - arma_inline const Op,op_strans> st() const; + arma_inline arma_warn_unused const Op,op_htrans> t() const; + arma_inline arma_warn_unused const Op,op_htrans> ht() const; + arma_inline arma_warn_unused const Op,op_strans> st() const; - arma_inline const Op,op_strans> as_row() const; + arma_inline arma_warn_unused const Op,op_strans> as_row() const; arma_inline subview_col row(const uword row_num); arma_inline const subview_col row(const uword row_num) const; @@ -173,7 +182,7 @@ { private: - static const bool use_extra = (fixed_n_elem > arma_config::mat_prealloc); + static constexpr bool use_extra = (fixed_n_elem > arma_config::mat_prealloc); arma_align_mem eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ]; @@ -185,9 +194,9 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_col = true; - static const bool is_row = false; - static const bool is_xvec = false; + static constexpr bool is_col = true; + static constexpr bool is_row = false; + static constexpr bool is_xvec = false; static const uword n_rows; // value provided below the class definition static const uword n_cols; // value provided below the class definition @@ -197,6 +206,7 @@ arma_inline fixed(const fixed& X); inline fixed(const subview_cube& X); + inline fixed(const fill::scalar_holder f); template inline fixed(const fill::fill_class& f); template inline fixed(const Base& A); template inline fixed(const Base& A, const Base& B); @@ -215,10 +225,8 @@ using Col::operator(); - #if defined(ARMA_USE_CXX11) - inline fixed(const std::initializer_list& list); - inline Col& operator=(const std::initializer_list& list); - #endif + inline fixed(const std::initializer_list& list); + inline Col& operator=(const std::initializer_list& list); arma_inline Col& operator=(const fixed& X); @@ -227,9 +235,9 @@ template inline Col& operator=(const eGlue& X); #endif - arma_inline const Op< Col_fixed_type, op_htrans > t() const; - arma_inline const Op< Col_fixed_type, op_htrans > ht() const; - arma_inline const Op< Col_fixed_type, op_strans > st() const; + arma_inline arma_warn_unused const Op< Col_fixed_type, op_htrans > t() const; + arma_inline arma_warn_unused const Op< Col_fixed_type, op_htrans > ht() const; + arma_inline arma_warn_unused const Op< Col_fixed_type, op_strans > st() const; arma_inline arma_warn_unused const eT& at_alt (const uword i) const; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Col_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Col_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Col_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Col_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -48,6 +50,13 @@ : Mat(arma_vec_indicator(), in_n_elem, 1, 1) { arma_extra_debug_sigprint(); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Col::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + #endif } @@ -60,6 +69,13 @@ arma_extra_debug_sigprint(); Mat::init_warm(in_n_rows, in_n_cols); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Col::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + #endif } @@ -72,6 +88,71 @@ arma_extra_debug_sigprint(); Mat::init_warm(s.n_rows, s.n_cols); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Col::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + #endif + } + + + +//! internal use only +template +template +inline +Col::Col(const uword in_n_elem, const arma_initmode_indicator&) + : Mat(arma_vec_indicator(), in_n_elem, 1, 1) + { + arma_extra_debug_sigprint(); + + if(do_zeros) + { + arma_extra_debug_print("Col::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + } + + + +//! internal use only +template +template +inline +Col::Col(const uword in_n_rows, const uword in_n_cols, const arma_initmode_indicator&) + : Mat(arma_vec_indicator(), 0, 0, 1) + { + arma_extra_debug_sigprint(); + + Mat::init_warm(in_n_rows, in_n_cols); + + if(do_zeros) + { + arma_extra_debug_print("Col::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + } + + + +//! internal use only +template +template +inline +Col::Col(const SizeMat& s, const arma_initmode_indicator&) + : Mat(arma_vec_indicator(), 0, 0, 1) + { + arma_extra_debug_sigprint(); + + Mat::init_warm(s.n_rows, s.n_cols); + + if(do_zeros) + { + arma_extra_debug_print("Col::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } } @@ -121,6 +202,46 @@ template inline +Col::Col(const uword in_n_elem, const fill::scalar_holder f) + : Mat(arma_vec_indicator(), in_n_elem, 1, 1) + { + arma_extra_debug_sigprint(); + + (*this).fill(f.scalar); + } + + + +template +inline +Col::Col(const uword in_n_rows, const uword in_n_cols, const fill::scalar_holder f) + : Mat(arma_vec_indicator(), 0, 0, 1) + { + arma_extra_debug_sigprint(); + + Mat::init_warm(in_n_rows, in_n_cols); + + (*this).fill(f.scalar); + } + + + +template +inline +Col::Col(const SizeMat& s, const fill::scalar_holder f) + : Mat(arma_vec_indicator(), 0, 0, 1) + { + arma_extra_debug_sigprint(); + + Mat::init_warm(s.n_rows, s.n_cols); + + (*this).fill(f.scalar); + } + + + +template +inline Col::Col(const char* text) : Mat(arma_vec_indicator(), 1) { @@ -221,102 +342,100 @@ -#if defined(ARMA_USE_CXX11) +template +inline +Col::Col(const std::initializer_list& list) + : Mat(arma_vec_indicator(), 1) + { + arma_extra_debug_sigprint(); - template - inline - Col::Col(const std::initializer_list& list) - : Mat(arma_vec_indicator(), 1) - { - arma_extra_debug_sigprint(); - - (*this).operator=(list); - } + (*this).operator=(list); + } + + + +template +inline +Col& +Col::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + Mat tmp(list); + arma_debug_check( ((tmp.n_elem > 0) && (tmp.is_vec() == false)), "Mat::init(): requested size is not compatible with column vector layout" ); - template - inline - Col& - Col::operator=(const std::initializer_list& list) - { - arma_extra_debug_sigprint(); - - Mat tmp(list); - - arma_debug_check( ((tmp.n_elem > 0) && (tmp.is_vec() == false)), "Mat::init(): requested size is not compatible with column vector layout" ); - - access::rw(tmp.n_rows) = tmp.n_elem; - access::rw(tmp.n_cols) = 1; - - (*this).steal_mem(tmp); - - return *this; - } + access::rw(tmp.n_rows) = tmp.n_elem; + access::rw(tmp.n_cols) = 1; + (*this).steal_mem(tmp); + return *this; + } + + + +template +inline +Col::Col(Col&& X) + : Mat(arma_vec_indicator(), 1) + { + arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - template - inline - Col::Col(Col&& X) - : Mat(arma_vec_indicator(), 1) + access::rw(Mat::n_rows) = X.n_rows; + access::rw(Mat::n_cols) = 1; + access::rw(Mat::n_elem) = X.n_elem; + access::rw(Mat::n_alloc) = X.n_alloc; + + if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) ) + { + access::rw(Mat::mem_state) = X.mem_state; + access::rw(Mat::mem) = X.mem; + + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 1; + 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) { - arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); + (*this).init_cold(); - access::rw(Mat::n_rows) = X.n_rows; - access::rw(Mat::n_cols) = 1; - access::rw(Mat::n_elem) = X.n_elem; + arrayops::copy( (*this).memptr(), X.mem, X.n_elem ); - if( ((X.mem_state == 0) && (X.n_elem > arma_config::mat_prealloc)) || (X.mem_state == 1) || (X.mem_state == 2) ) + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) { - access::rw(Mat::mem_state) = X.mem_state; - access::rw(Mat::mem) = X.mem; - - access::rw(X.n_rows) = 0; - access::rw(X.n_cols) = 1; - access::rw(X.n_elem) = 0; - access::rw(X.mem_state) = 0; - access::rw(X.mem) = 0; - } - else - { - (*this).init_cold(); - - arrayops::copy( (*this).memptr(), X.mem, X.n_elem ); - - if( (X.mem_state == 0) && (X.n_elem <= arma_config::mat_prealloc) ) - { - access::rw(X.n_rows) = 0; - access::rw(X.n_cols) = 1; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = 0; - } + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 1; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; } } + } + + + +template +inline +Col& +Col::operator=(Col&& X) + { + arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); + (*this).steal_mem(X); - - template - inline - Col& - Col::operator=(Col&& X) + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) && (this != &X) ) { - arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - - (*this).steal_mem(X); - - if( (X.mem_state == 0) && (X.n_elem <= arma_config::mat_prealloc) && (this != &X) ) - { - access::rw(X.n_rows) = 0; - access::rw(X.n_cols) = 1; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = 0; - } - - return *this; + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 1; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; } -#endif + return *this; + } @@ -506,6 +625,7 @@ template inline +arma_cold mat_injector< Col > Col::operator<<(const eT val) { @@ -516,6 +636,7 @@ template arma_inline +arma_warn_unused const Op,op_htrans> Col::t() const { @@ -526,6 +647,7 @@ template arma_inline +arma_warn_unused const Op,op_htrans> Col::ht() const { @@ -536,6 +658,7 @@ template arma_inline +arma_warn_unused const Op,op_strans> Col::st() const { @@ -546,6 +669,7 @@ template arma_inline +arma_warn_unused const Op,op_strans> Col::as_row() const { @@ -561,7 +685,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_row1 >= Mat::n_rows), "Col::row(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( (in_row1 >= Mat::n_rows), "Col::row(): indices out of bounds or incorrectly used" ); return subview_col(*this, 0, in_row1, 1); } @@ -575,7 +699,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_row1 >= Mat::n_rows), "Col::row(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( (in_row1 >= Mat::n_rows), "Col::row(): indices out of bounds or incorrectly used" ); return subview_col(*this, 0, in_row1, 1); } @@ -589,7 +713,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used" ); const uword subview_n_rows = in_row2 - in_row1 + 1; @@ -605,7 +729,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used" ); const uword subview_n_rows = in_row2 - in_row1 + 1; @@ -621,7 +745,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used" ); const uword subview_n_rows = in_row2 - in_row1 + 1; @@ -637,7 +761,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used" ); const uword subview_n_rows = in_row2 - in_row1 + 1; @@ -685,7 +809,7 @@ const uword in_row2 = row_span.b; const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; - arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used" ); return subview_col(*this, 0, in_row1, subvec_n_rows); } @@ -707,7 +831,7 @@ const uword in_row2 = row_span.b; const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; - arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used" ); return subview_col(*this, 0, in_row1, subvec_n_rows); } @@ -747,7 +871,7 @@ arma_debug_check( (s.n_cols != 1), "Col::subvec(): given size does not specify a column vector" ); - arma_debug_check( ( (start_row >= Mat::n_rows) || ((start_row + s.n_rows) > Mat::n_rows) ), "Col::subvec(): size out of bounds" ); + arma_debug_check_bounds( ( (start_row >= Mat::n_rows) || ((start_row + s.n_rows) > Mat::n_rows) ), "Col::subvec(): size out of bounds" ); return subview_col(*this, 0, start_row, s.n_rows); } @@ -763,7 +887,7 @@ arma_debug_check( (s.n_cols != 1), "Col::subvec(): given size does not specify a column vector" ); - arma_debug_check( ( (start_row >= Mat::n_rows) || ((start_row + s.n_rows) > Mat::n_rows) ), "Col::subvec(): size out of bounds" ); + arma_debug_check_bounds( ( (start_row >= Mat::n_rows) || ((start_row + s.n_rows) > Mat::n_rows) ), "Col::subvec(): size out of bounds" ); return subview_col(*this, 0, start_row, s.n_rows); } @@ -777,7 +901,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > Mat::n_rows), "Col::head(): size out of bounds"); + arma_debug_check_bounds( (N > Mat::n_rows), "Col::head(): size out of bounds" ); return subview_col(*this, 0, 0, N); } @@ -791,7 +915,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > Mat::n_rows), "Col::head(): size out of bounds"); + arma_debug_check_bounds( (N > Mat::n_rows), "Col::head(): size out of bounds" ); return subview_col(*this, 0, 0, N); } @@ -805,7 +929,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > Mat::n_rows), "Col::tail(): size out of bounds"); + arma_debug_check_bounds( (N > Mat::n_rows), "Col::tail(): size out of bounds" ); const uword start_row = Mat::n_rows - N; @@ -821,7 +945,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > Mat::n_rows), "Col::tail(): size out of bounds"); + arma_debug_check_bounds( (N > Mat::n_rows), "Col::tail(): size out of bounds" ); const uword start_row = Mat::n_rows - N; @@ -886,7 +1010,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( row_num >= Mat::n_rows, "Col::shed_row(): index out of bounds"); + arma_debug_check_bounds( row_num >= Mat::n_rows, "Col::shed_row(): index out of bounds" ); shed_rows(row_num, row_num); } @@ -901,7 +1025,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= Mat::n_rows), "Col::shed_rows(): indices out of bounds or incorrectly used" @@ -910,7 +1034,7 @@ const uword n_keep_front = in_row1; const uword n_keep_back = Mat::n_rows - (in_row2 + 1); - Col X(n_keep_front + n_keep_back); + Col X(n_keep_front + n_keep_back, arma_nozeros_indicator()); eT* X_mem = X.memptr(); const eT* t_mem = (*this).memptr(); @@ -959,11 +1083,11 @@ const uword B_n_rows = t_n_rows - row_num; // insertion at row_num == n_rows is in effect an append operation - arma_debug_check( (row_num > t_n_rows), "Col::insert_rows(): index out of bounds"); + arma_debug_check_bounds( (row_num > t_n_rows), "Col::insert_rows(): index out of bounds" ); if(N > 0) { - Col out(t_n_rows + N); + Col out(t_n_rows + N, arma_nozeros_indicator()); eT* out_mem = out.memptr(); const eT* t_mem = (*this).memptr(); @@ -1055,7 +1179,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= Mat::n_rows), "Col::begin_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= Mat::n_rows), "Col::begin_row(): index out of bounds" ); return Mat::memptr() + row_num; } @@ -1069,7 +1193,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= Mat::n_rows), "Col::begin_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= Mat::n_rows), "Col::begin_row(): index out of bounds" ); return Mat::memptr() + row_num; } @@ -1083,7 +1207,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= Mat::n_rows), "Col::end_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= Mat::n_rows), "Col::end_row(): index out of bounds" ); return Mat::memptr() + row_num + 1; } @@ -1097,7 +1221,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= Mat::n_rows), "Col::end_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= Mat::n_rows), "Col::end_row(): index out of bounds" ); return Mat::memptr() + row_num + 1; } @@ -1111,6 +1235,16 @@ : Col( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat::mem_local) ) { arma_extra_debug_sigprint_this(this); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Col::fixed::constructor: zeroing memory"); + + eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(Mat::mem_local[0]); + + arrayops::inplace_set_fixed( mem_use, eT(0) ); + } + #endif } @@ -1146,6 +1280,19 @@ template template +inline +Col::fixed::fixed(const fill::scalar_holder f) + : Col( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat::mem_local) ) + { + arma_extra_debug_sigprint_this(this); + + (*this).fill(f.scalar); + } + + + +template +template template inline Col::fixed::fixed(const fill::fill_class&) @@ -1153,11 +1300,11 @@ { arma_extra_debug_sigprint_this(this); - if(is_same_type::yes) (*this).zeros(); - if(is_same_type::yes) (*this).ones(); - if(is_same_type::yes) (*this).eye(); - if(is_same_type::yes) (*this).randu(); - if(is_same_type::yes) (*this).randn(); + if(is_same_type::yes) { (*this).zeros(); } + if(is_same_type::yes) { (*this).ones(); } + if(is_same_type::yes) { (*this).eye(); } + if(is_same_type::yes) { (*this).randu(); } + if(is_same_type::yes) { (*this).randn(); } } @@ -1302,43 +1449,39 @@ -#if defined(ARMA_USE_CXX11) +template +template +inline +Col::fixed::fixed(const std::initializer_list& list) + : Col( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat::mem_local) ) + { + arma_extra_debug_sigprint_this(this); - template - template - inline - Col::fixed::fixed(const std::initializer_list& list) - : Col( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat::mem_local) ) - { - arma_extra_debug_sigprint_this(this); - - (*this).operator=(list); - } + (*this).operator=(list); + } + + + +template +template +inline +Col& +Col::fixed::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + const uword N = uword(list.size()); + arma_debug_check( (N > fixed_n_elem), "Col::fixed: initialiser list is too long" ); - template - template - inline - Col& - Col::fixed::operator=(const std::initializer_list& list) - { - arma_extra_debug_sigprint(); - - const uword N = uword(list.size()); - - arma_debug_check( (N > fixed_n_elem), "Col::fixed: initialiser list is too long" ); - - eT* this_mem = (*this).memptr(); - - arrayops::copy( this_mem, list.begin(), N ); - - for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); } - - return *this; - } + eT* this_mem = (*this).memptr(); -#endif + arrayops::copy( this_mem, list.begin(), N ); + + for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); } + + return *this; + } @@ -1442,6 +1585,7 @@ template template arma_inline +arma_warn_unused const Op< typename Col::template fixed::Col_fixed_type, op_htrans > Col::fixed::t() const { @@ -1453,6 +1597,7 @@ template template arma_inline +arma_warn_unused const Op< typename Col::template fixed::Col_fixed_type, op_htrans > Col::fixed::ht() const { @@ -1464,6 +1609,7 @@ template template arma_inline +arma_warn_unused const Op< typename Col::template fixed::Col_fixed_type, op_strans > Col::fixed::st() const { @@ -1549,7 +1695,7 @@ eT& Col::fixed::operator() (const uword ii) { - arma_debug_check( (ii >= fixed_n_elem), "Col::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= fixed_n_elem), "Col::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[ii] : Mat::mem_local[ii]; } @@ -1563,7 +1709,7 @@ const eT& Col::fixed::operator() (const uword ii) const { - arma_debug_check( (ii >= fixed_n_elem), "Col::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= fixed_n_elem), "Col::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[ii] : Mat::mem_local[ii]; } @@ -1601,7 +1747,7 @@ eT& Col::fixed::operator() (const uword in_row, const uword in_col) { - arma_debug_check( ((in_row >= fixed_n_elem) || (in_col > 0)), "Col::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= fixed_n_elem) || (in_col > 0)), "Col::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[in_row] : Mat::mem_local[in_row]; } @@ -1615,7 +1761,7 @@ const eT& Col::fixed::operator() (const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row >= fixed_n_elem) || (in_col > 0)), "Col::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= fixed_n_elem) || (in_col > 0)), "Col::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[in_row] : Mat::mem_local[in_row]; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/compiler_check.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_check.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/compiler_check.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_check.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +#undef ARMA_HAVE_CXX11 +#undef ARMA_HAVE_CXX14 +#undef ARMA_HAVE_CXX17 +#undef ARMA_HAVE_CXX20 + +#if (__cplusplus >= 201103L) + #define ARMA_HAVE_CXX11 +#endif + +#if (__cplusplus >= 201402L) + #define ARMA_HAVE_CXX14 +#endif + +#if (__cplusplus >= 201703L) + #define ARMA_HAVE_CXX17 +#endif + +#if (__cplusplus >= 202002L) + #define ARMA_HAVE_CXX20 +#endif + + +// MS really can't get its proverbial shit together +#if defined(_MSVC_LANG) + + #if (_MSVC_LANG >= 201402L) + #undef ARMA_HAVE_CXX11 + #undef ARMA_HAVE_CXX14 + + #define ARMA_HAVE_CXX11 + #define ARMA_HAVE_CXX14 + #endif + + #if (_MSVC_LANG >= 201703L) + #undef ARMA_HAVE_CXX17 + #define ARMA_HAVE_CXX17 + #endif + + #if (_MSVC_LANG >= 202002L) + #undef ARMA_HAVE_CXX20 + #define ARMA_HAVE_CXX20 + #endif + +#endif + + +// warn about ignored option used in old versions of Armadillo +#if defined(ARMA_DONT_USE_CXX11) + #pragma message ("WARNING: option ARMA_DONT_USE_CXX11 ignored") +#endif + + +#if !defined(ARMA_HAVE_CXX11) + #error "*** C++11 compiler required; enable C++11 mode in your compiler, or use an earlier version of Armadillo" +#endif + + +// for compatibility with earlier versions of Armadillo +#undef ARMA_USE_CXX11 +#define ARMA_USE_CXX11 diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/compiler_extra.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_extra.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/compiler_extra.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_extra.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2008-2016 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - - -#if (__cplusplus >= 201103L) - #undef ARMA_USE_CXX11 - #define ARMA_USE_CXX11 -#endif - - -// MS really can't get its proverbial shit together -#if (defined(_MSVC_LANG) && (_MSVC_LANG >= 201402L)) - #undef ARMA_USE_CXX11 - #define ARMA_USE_CXX11 - #undef ARMA_DONT_PRINT_CXX11_WARNING - #define ARMA_DONT_PRINT_CXX11_WARNING -#endif - - -#if (defined(_OPENMP) && (_OPENMP >= 201107)) - #undef ARMA_USE_OPENMP - #define ARMA_USE_OPENMP -#endif diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/compiler_setup.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_setup.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/compiler_setup.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_setup.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -78,29 +80,17 @@ #undef ARMA_INCFILE_WRAP #define ARMA_INCFILE_WRAP(x) -#if defined(ARMA_USE_CXX11) - - #undef ARMA_USE_U64S64 - #define ARMA_USE_U64S64 - - #if !defined(ARMA_32BIT_WORD) - #undef ARMA_64BIT_WORD - #define ARMA_64BIT_WORD - #endif - - #if defined(ARMA_64BIT_WORD) && defined(SIZE_MAX) - #if (SIZE_MAX < 0xFFFFFFFFFFFFFFFFull) - // #pragma message ("WARNING: disabled use of 64 bit integers, as std::size_t is smaller than 64 bits") - #undef ARMA_64BIT_WORD - #endif - #endif - -#endif +#if !defined(ARMA_32BIT_WORD) + #undef ARMA_64BIT_WORD + #define ARMA_64BIT_WORD +#endif -#if defined(ARMA_64BIT_WORD) - #undef ARMA_USE_U64S64 - #define ARMA_USE_U64S64 +#if defined(ARMA_64BIT_WORD) && defined(SIZE_MAX) + #if (SIZE_MAX < 0xFFFFFFFFFFFFFFFFull) + // #pragma message ("WARNING: disabled use of 64 bit integers, as std::size_t is smaller than 64 bits") + #undef ARMA_64BIT_WORD + #endif #endif @@ -111,20 +101,6 @@ #undef ARMA_GOOD_COMPILER -#undef ARMA_HAVE_TR1 -#undef ARMA_HAVE_GETTIMEOFDAY -#undef ARMA_HAVE_SNPRINTF -#undef ARMA_HAVE_ISFINITE -#undef ARMA_HAVE_LOG1P -#undef ARMA_HAVE_ISINF -#undef ARMA_HAVE_ISNAN - - -#if (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) - #define ARMA_HAVE_GETTIMEOFDAY -#endif - - // posix_memalign() is part of IEEE standard 1003.1 // http://pubs.opengroup.org/onlinepubs/009696899/functions/posix_memalign.html // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html @@ -141,10 +117,6 @@ // #undef ARMA_HAVE_POSIX_MEMALIGN // NOTE: posix_memalign() is available since macOS 10.6 (late 2009 onwards) - - // #undef ARMA_USE_EXTERN_CXX11_RNG - // NOTE: thread_local seems to work in Apple clang since Xcode 8 (mid 2016 onwards) - // NOTE: https://stackoverflow.com/questions/28094794/why-does-apple-clang-disallow-c11-thread-local-when-official-clang-supports #endif @@ -161,13 +133,16 @@ #define ARMA_FNSIG __FUNCSIG__ #elif defined(__INTEL_COMPILER) #define ARMA_FNSIG __FUNCTION__ -#elif defined(ARMA_USE_CXX11) - #define ARMA_FNSIG __func__ #else - #define ARMA_FNSIG "(unknown)" + #define ARMA_FNSIG __func__ #endif +// #if defined(ARMA_HAVE_CXX17) +// #define arma_warn_unused [[nodiscard]] +// #endif + + #if !defined(ARMA_ALLOW_FAKE_GCC) #if (defined(__GNUG__) || defined(__GNUC__)) && (defined(__INTEL_COMPILER) || defined(__NVCC__) || defined(__CUDACC__) || defined(__PGI) || defined(__PATHSCALE__) || defined(__ARMCC_VERSION) || defined(__IBMCPP__)) #undef ARMA_DETECTED_FAKE_GCC @@ -187,18 +162,8 @@ #undef ARMA_GCC_VERSION #define ARMA_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) - #if (ARMA_GCC_VERSION < 40400) - #error "*** newer compiler required ***" - #endif - #if (ARMA_GCC_VERSION < 40800) - #undef ARMA_PRINT_CXX98_WARNING - #define ARMA_PRINT_CXX98_WARNING - #endif - - #if ( (ARMA_GCC_VERSION >= 40700) && (ARMA_GCC_VERSION <= 40701) ) - #error "gcc versions 4.7.0 and 4.7.1 are unsupported; use 4.7.2 or later" - // due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53549 + #error "*** newer compiler required; need gcc 4.8 or later ***" #endif #define ARMA_GOOD_COMPILER @@ -226,22 +191,8 @@ #undef ARMA_HAVE_ALIGNED_ATTRIBUTE #define ARMA_HAVE_ALIGNED_ATTRIBUTE - #if defined(ARMA_USE_CXX11) - #if (ARMA_GCC_VERSION < 40800) - #undef ARMA_PRINT_CXX11_WARNING - #define ARMA_PRINT_CXX11_WARNING - #endif - #endif - - #if !defined(ARMA_USE_CXX11) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && (__cplusplus < 201103L) && !defined(ARMA_DONT_USE_TR1) - #if defined(_GLIBCXX_USE_C99_MATH_TR1) && defined(_GLIBCXX_USE_C99_COMPLEX_TR1) - #define ARMA_HAVE_TR1 - #endif - #endif - - #if (ARMA_GCC_VERSION >= 40700) - #define ARMA_HAVE_GCC_ASSUME_ALIGNED - #endif + #undef ARMA_HAVE_GCC_ASSUME_ALIGNED + #define ARMA_HAVE_GCC_ASSUME_ALIGNED // gcc's vectoriser can handle elaborate loops #undef ARMA_SIMPLE_LOOPS @@ -250,14 +201,6 @@ #define ARMA_SIMPLE_LOOPS #endif - #if !defined(ARMA_USE_CXX11) && (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) - #define ARMA_HAVE_SNPRINTF - #define ARMA_HAVE_ISFINITE - #define ARMA_HAVE_LOG1P - #define ARMA_HAVE_ISINF - #define ARMA_HAVE_ISNAN - #endif - #endif @@ -337,14 +280,6 @@ #define ARMA_HAVE_GCC_ASSUME_ALIGNED #endif - #if !defined(ARMA_USE_CXX11) && (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) - #define ARMA_HAVE_SNPRINTF - #define ARMA_HAVE_ISFINITE - #define ARMA_HAVE_LOG1P - #define ARMA_HAVE_ISINF - #define ARMA_HAVE_ISNAN - #endif - #endif @@ -354,7 +289,7 @@ #error "*** newer compiler required ***" #endif - #if (__INTEL_COMPILER < 1300) + #if (__INTEL_COMPILER < 1500) #error "*** newer compiler required ***" #endif @@ -362,34 +297,15 @@ #undef ARMA_HAVE_ICC_ASSUME_ALIGNED #define ARMA_HAVE_ICC_ASSUME_ALIGNED - #if defined(ARMA_USE_CXX11) - #if (__INTEL_COMPILER < 1500) - #undef ARMA_PRINT_CXX11_WARNING - #define ARMA_PRINT_CXX11_WARNING - #endif - #endif - #endif #if defined(_MSC_VER) - #if (_MSC_VER < 1700) + #if (_MSC_VER < 1900) #error "*** newer compiler required ***" #endif - #if (_MSC_VER < 1800) - #undef ARMA_PRINT_CXX98_WARNING - #define ARMA_PRINT_CXX98_WARNING - #endif - - #if defined(ARMA_USE_CXX11) - #if (_MSC_VER < 1900) - #undef ARMA_PRINT_CXX11_WARNING - #define ARMA_PRINT_CXX11_WARNING - #endif - #endif - #undef arma_deprecated #define arma_deprecated __declspec(deprecated) // #undef arma_inline @@ -415,10 +331,7 @@ #pragma warning(disable: 4711) // call was inlined #pragma warning(disable: 4714) // __forceinline can't be inlined #pragma warning(disable: 4800) // value forced to bool - - #if defined(ARMA_USE_CXX11) - #pragma warning(disable: 4519) // default template args are only allowed on a class template - #endif + #pragma warning(disable: 4519) // C++11: default template args are only allowed on a class template // #if (_MANAGED == 1) || (_M_CEE == 1) @@ -451,49 +364,29 @@ // http://www.oracle.com/technetwork/server-storage/solarisstudio/training/index-jsp-141991.html // http://www.oracle.com/technetwork/server-storage/solarisstudio/documentation/cplusplus-faq-355066.html - #if (__SUNPRO_CC < 0x5100) + #if (__SUNPRO_CC < 0x5140) #error "*** newer compiler required ***" #endif - #if defined(ARMA_USE_CXX11) - #if (__SUNPRO_CC < 0x5130) - #undef ARMA_PRINT_CXX11_WARNING - #define ARMA_PRINT_CXX11_WARNING - #endif - #endif - #endif -#if defined(ARMA_USE_CXX11) && defined(__CYGWIN__) && !defined(ARMA_DONT_PRINT_CXX11_WARNING) +#if defined(__CYGWIN__) && !defined(ARMA_DONT_PRINT_CXX11_WARNING) #pragma message ("WARNING: Cygwin may have incomplete support for C++11 features.") #endif -#if defined(ARMA_USE_CXX11) && (__cplusplus < 201103L) - #undef ARMA_PRINT_CXX11_WARNING - #define ARMA_PRINT_CXX11_WARNING -#endif - - -#if defined(ARMA_PRINT_CXX98_WARNING) && !defined(ARMA_DONT_PRINT_CXX98_WARNING) - #pragma message ("WARNING: this compiler is OUTDATED and has INCOMPLETE support for the C++ standard;") - #pragma message ("WARNING: if something breaks, you get to keep all the pieces.") -#endif - - -#if defined(ARMA_PRINT_CXX11_WARNING) && !defined(ARMA_DONT_PRINT_CXX11_WARNING) - #pragma message ("WARNING: use of C++11 features has been enabled,") - #pragma message ("WARNING: but this compiler has INCOMPLETE support for C++11;") - #pragma message ("WARNING: if something breaks, you get to keep all the pieces.") - #pragma message ("WARNING: to forcefully prevent Armadillo from using C++11 features,") - #pragma message ("WARNING: #define ARMA_DONT_USE_CXX11 before #include ") +#if !defined(ARMA_DONT_USE_OPENMP) + #if (defined(_OPENMP) && (_OPENMP >= 201107)) + #undef ARMA_USE_OPENMP + #define ARMA_USE_OPENMP + #endif #endif #if ( defined(ARMA_USE_OPENMP) && (!defined(_OPENMP) || (defined(_OPENMP) && (_OPENMP < 201107))) ) - // OpenMP 3.1 required for atomic read and atomic write // OpenMP 3.0 required for parallelisation of loops with unsigned integers + // OpenMP 3.1 required for atomic read and atomic write #undef ARMA_USE_OPENMP #undef ARMA_PRINT_OPENMP_WARNING #define ARMA_PRINT_OPENMP_WARNING @@ -510,22 +403,10 @@ #endif -#if defined(ARMA_USE_OPENMP) && !defined(ARMA_USE_CXX11) - #if (defined(ARMA_GCC_VERSION) && (ARMA_GCC_VERSION >= 50400)) || (defined(__clang__) && !defined(ARMA_FAKE_CLANG)) - #undef ARMA_PRINT_OPENMP_CXX11_WARNING - #define ARMA_PRINT_OPENMP_CXX11_WARNING - #endif -#endif - - -#if defined(ARMA_PRINT_OPENMP_CXX11_WARNING) && !defined(ARMA_DONT_PRINT_OPENMP_WARNING) - #pragma message ("WARNING: support for OpenMP requires C++11/C++14; add -std=c++11 or -std=c++14 to compiler flags") -#endif - - -#if defined(ARMA_USE_OPENMP) && defined(ARMA_USE_CXX11) +#if defined(ARMA_USE_OPENMP) #if (defined(ARMA_GCC_VERSION) && (ARMA_GCC_VERSION < 50400)) // due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57580 + // TODO: gcc 4.9.4 is also fixed, so use a more fine-grained gcc version check? #undef ARMA_USE_OPENMP #if !defined(ARMA_DONT_PRINT_OPENMP_WARNING) #pragma message ("WARNING: use of OpenMP disabled due to compiler bug in gcc <= 5.3") @@ -534,23 +415,24 @@ #endif -#if defined(ARMA_GCC_VERSION) && (ARMA_GCC_VERSION >= 50400) && !defined(ARMA_USE_CXX11) - #if !defined(ARMA_PRINT_CXX11_WARNING) && !defined(ARMA_PRINT_OPENMP_CXX11_WARNING) && !defined(ARMA_DONT_PRINT_CXX11_WARNING) - #pragma message ("NOTE: suggest to enable C++14 mode for faster code; add -std=c++14 to compiler flags") - #endif +#if ( defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) ) + #undef ARMA_PRINT_EXCEPTIONS + #define ARMA_PRINT_EXCEPTIONS +#endif + + +#if (defined(ARMA_ALIEN_MEM_ALLOC_FUNCTION) && !defined(ARMA_ALIEN_MEM_FREE_FUNCTION)) || (!defined(ARMA_ALIEN_MEM_ALLOC_FUNCTION) && defined(ARMA_ALIEN_MEM_FREE_FUNCTION)) + #error "*** both ARMA_ALIEN_MEM_ALLOC_FUNCTION and ARMA_ALIEN_MEM_FREE_FUNCTION must be defined ***" #endif // cleanup -#undef ARMA_FAKE_GCC -#undef ARMA_FAKE_CLANG +#undef ARMA_DETECTED_FAKE_GCC +#undef ARMA_DETECTED_FAKE_CLANG #undef ARMA_GCC_VERSION -#undef ARMA_PRINT_CXX98_WARNING -#undef ARMA_PRINT_CXX11_WARNING #undef ARMA_PRINT_OPENMP_WARNING -#undef ARMA_PRINT_OPENMP_CXX11_WARNING diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/compiler_setup_post.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_setup_post.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/compiler_setup_post.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_setup_post.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/cond_rel_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/cond_rel_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/cond_rel_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/cond_rel_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/cond_rel_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/cond_rel_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/cond_rel_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/cond_rel_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/config.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/config.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/config.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/config.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -15,17 +17,27 @@ +#if !defined(ARMA_WARN_LEVEL) + #define ARMA_WARN_LEVEL 2 +#endif +//// The level of warning messages printed to ARMA_CERR_STREAM. +//// Must be an integer >= 0. The default value is 2. +//// 0 = no warnings +//// 1 = only critical warnings about arguments and/or data which are likely to lead to incorrect results +//// 2 = as per level 1, and warnings about poorly conditioned systems (low rcond) detected by solve(), spsolve(), etc +//// 3 = as per level 2, and warnings about failed decompositions, failed saving/loading, etc + #if !defined(ARMA_USE_LAPACK) #define ARMA_USE_LAPACK //// Comment out the above line if you don't have LAPACK or a high-speed replacement for LAPACK, -//// such as Intel MKL, AMD ACML, or the Accelerate framework. +//// such as OpenBLAS, Intel MKL, or the Accelerate framework. //// LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse. #endif #if !defined(ARMA_USE_BLAS) #define ARMA_USE_BLAS //// Comment out the above line if you don't have BLAS or a high-speed replacement for BLAS, -//// such as OpenBLAS, GotoBLAS, Intel MKL, AMD ACML, or the Accelerate framework. +//// such as OpenBLAS, Intel MKL, or the Accelerate framework. //// BLAS is used for matrix multiplication. //// Without BLAS, matrix multiplication will still work, but might be slower. #endif @@ -62,7 +74,7 @@ //// You will then need to link your programs directly with -llapack -lblas instead of -larmadillo // #define ARMA_BLAS_CAPITALS -//// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names (eg. ACML on 64-bit Windows) +//// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names #define ARMA_BLAS_UNDERSCORE //// Uncomment the above line if your BLAS and LAPACK libraries have function names with a trailing underscore. @@ -74,6 +86,12 @@ // #define ARMA_BLAS_LONG_LONG //// Uncomment the above line if your BLAS and LAPACK libraries use "long long" instead of "int" +// #define ARMA_BLAS_NOEXCEPT +//// Uncomment the above line if you require BLAS functions to have the 'noexcept' specification + +// #define ARMA_LAPACK_NOEXCEPT +//// Uncomment the above line if you require LAPACK functions to have the 'noexcept' specification + #define ARMA_USE_FORTRAN_HIDDEN_ARGS //// Comment out the above line to call BLAS and LAPACK functions without using so-called "hidden" arguments. //// Fortran functions (compiled without a BIND(C) declaration) that have char arguments @@ -99,12 +117,6 @@ //// uncomment the above define and specify the appropriate include directory. //// Make sure the directory has a trailing / -#if !defined(ARMA_USE_CXX11) -// #define ARMA_USE_CXX11 -//// Uncomment the above line to forcefully enable use of C++11 features (eg. initialiser lists). -//// Note that ARMA_USE_CXX11 is automatically enabled when a C++11 compiler is detected. -#endif - #if !defined(ARMA_USE_OPENMP) // #define ARMA_USE_OPENMP //// Uncomment the above line to forcefully enable use of OpenMP for parallelisation. @@ -114,8 +126,7 @@ #if !defined(ARMA_64BIT_WORD) // #define ARMA_64BIT_WORD //// Uncomment the above line if you require matrices/vectors capable of holding more than 4 billion elements. -//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long"). -//// Note that ARMA_64BIT_WORD is automatically enabled when a C++11 compiler is detected and std::size_t has 64 bits. +//// Note that ARMA_64BIT_WORD is automatically enabled when std::size_t has 64 bits and ARMA_32BIT_WORD is not defined. #endif #if !defined(ARMA_USE_HDF5) @@ -125,14 +136,17 @@ //// and you will need to link with the hdf5 library (eg. -lhdf5) #endif -#if !defined(ARMA_OPTIMISE_SOLVE_BAND) - #define ARMA_OPTIMISE_SOLVE_BAND - //// Comment out the above line if you don't want optimised handling of band matrices by solve() +#if !defined(ARMA_OPTIMISE_BAND) + #define ARMA_OPTIMISE_BAND + //// Comment out the above line if you don't want automatically optimised handling + //// of band matrices by solve() and chol() #endif -#if !defined(ARMA_OPTIMISE_SOLVE_SYMPD) - #define ARMA_OPTIMISE_SOLVE_SYMPD - //// Comment out the above line if you don't want optimised handling of symmetric/hermitian positive definite matrices by solve() +#if !defined(ARMA_OPTIMISE_SYMPD) + #define ARMA_OPTIMISE_SYMPD + //// Comment out the above line if you don't want automatically optimised handling + //// of symmetric/hermitian positive definite matrices by various functions: + //// solve(), inv(), pinv(), expmat(), logmat(), sqrtmat(), rcond() #endif // #define ARMA_USE_HDF5_ALT @@ -152,13 +166,13 @@ //// change the number to the size of your vectors. #if !defined(ARMA_OPENMP_THRESHOLD) - #define ARMA_OPENMP_THRESHOLD 240 + #define ARMA_OPENMP_THRESHOLD 320 #endif //// The minimum number of elements in a matrix to allow OpenMP based parallelisation; //// it must be an integer that is at least 1. #if !defined(ARMA_OPENMP_THREADS) - #define ARMA_OPENMP_THREADS 10 + #define ARMA_OPENMP_THREADS 8 #endif //// The maximum number of threads to use for OpenMP based parallelisation; //// it must be an integer that is at least 1. @@ -205,6 +219,11 @@ //// Comment out the above line if you don't want errors and warnings printed (eg. failed decompositions) #endif +#if !defined(ARMA_PRINT_EXCEPTIONS) +// #define ARMA_PRINT_EXCEPTIONS +//// see also compiler_setup.hpp +#endif + #if !defined(ARMA_PRINT_HDF5_ERRORS) // #define ARMA_PRINT_HDF5_ERRORS #endif @@ -244,9 +263,17 @@ #undef ARMA_USE_FORTRAN_HIDDEN_ARGS #endif -#if defined(ARMA_DONT_USE_CXX11) - #undef ARMA_USE_CXX11 - #undef ARMA_USE_EXTERN_CXX11_RNG +#if !defined(ARMA_DONT_USE_STD_MUTEX) + // #define ARMA_DONT_USE_STD_MUTEX + //// Uncomment the above line to disable use of std::mutex +#endif + +// for compatibility with earlier versions of Armadillo +#if defined(ARMA_DONT_USE_CXX11_MUTEX) + #pragma message ("WARNING: support for ARMA_DONT_USE_CXX11_MUTEX is deprecated and will be removed;") + #pragma message ("WARNING: use ARMA_DONT_USE_STD_MUTEX instead") + #undef ARMA_DONT_USE_STD_MUTEX + #define ARMA_DONT_USE_STD_MUTEX #endif #if defined(ARMA_DONT_USE_OPENMP) @@ -254,15 +281,20 @@ #endif #if defined(ARMA_USE_WRAPPER) - #if defined(ARMA_USE_CXX11) - #if !defined(ARMA_USE_EXTERN_CXX11_RNG) - // #define ARMA_USE_EXTERN_CXX11_RNG - #endif + #if !defined(ARMA_USE_EXTERN_RNG) + // #define ARMA_USE_EXTERN_RNG #endif #endif +#if defined(ARMA_DONT_USE_EXTERN_RNG) + #undef ARMA_USE_EXTERN_RNG +#endif + +// for compatibility with earlier versions of Armadillo #if defined(ARMA_DONT_USE_EXTERN_CXX11_RNG) - #undef ARMA_USE_EXTERN_CXX11_RNG + #pragma message ("WARNING: support for ARMA_DONT_USE_EXTERN_CXX11_RNG is deprecated and will be removed;") + #pragma message ("WARNING: use ARMA_DONT_USE_EXTERN_RNG instead") + #undef ARMA_USE_EXTERN_RNG #endif #if defined(ARMA_32BIT_WORD) @@ -274,22 +306,35 @@ #undef ARMA_USE_HDF5_ALT #endif -#if defined(ARMA_DONT_OPTIMISE_SOLVE_BAND) - #undef ARMA_OPTIMISE_SOLVE_BAND +#if defined(ARMA_DONT_OPTIMISE_BAND) || defined(ARMA_DONT_OPTIMISE_SOLVE_BAND) + #undef ARMA_OPTIMISE_BAND #endif -#if defined(ARMA_DONT_OPTIMISE_SOLVE_SYMPD) - #undef ARMA_OPTIMISE_SOLVE_SYMPD +#if defined(ARMA_DONT_OPTIMISE_SYMPD) || defined(ARMA_DONT_OPTIMISE_SOLVE_SYMPD) + #undef ARMA_OPTIMISE_SYMPD #endif #if defined(ARMA_DONT_PRINT_ERRORS) #undef ARMA_PRINT_ERRORS #endif +#if defined(ARMA_DONT_PRINT_EXCEPTIONS) + #undef ARMA_PRINT_EXCEPTIONS +#endif + +#if !defined(ARMA_DONT_ZERO_INIT) + // #define ARMA_DONT_ZERO_INIT + //// Uncomment the above line to disable initialising elements to zero during construction of dense matrices and cubes +#endif + #if defined(ARMA_DONT_PRINT_HDF5_ERRORS) #undef ARMA_PRINT_HDF5_ERRORS #endif +#if defined(ARMA_NO_CRIPPLED_LAPACK) + #undef ARMA_CRIPPLED_LAPACK +#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 diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/config.hpp.cmake armadillo-10.8.2+dfsg/include/armadillo_bits/config.hpp.cmake --- armadillo-9.800.4+dfsg/include/armadillo_bits/config.hpp.cmake 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/config.hpp.cmake 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -15,17 +17,27 @@ +#if !defined(ARMA_WARN_LEVEL) + #define ARMA_WARN_LEVEL 2 +#endif +//// The level of warning messages printed to ARMA_CERR_STREAM. +//// Must be an integer >= 0. The default value is 2. +//// 0 = no warnings +//// 1 = only critical warnings about arguments and/or data which are likely to lead to incorrect results +//// 2 = as per level 1, and warnings about poorly conditioned systems (low rcond) detected by solve(), spsolve(), etc +//// 3 = as per level 2, and warnings about failed decompositions, failed saving/loading, etc + #if !defined(ARMA_USE_LAPACK) #cmakedefine ARMA_USE_LAPACK //// Comment out the above line if you don't have LAPACK or a high-speed replacement for LAPACK, -//// such as Intel MKL, AMD ACML, or the Accelerate framework. +//// such as OpenBLAS, Intel MKL, or the Accelerate framework. //// LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse. #endif #if !defined(ARMA_USE_BLAS) #cmakedefine ARMA_USE_BLAS //// Comment out the above line if you don't have BLAS or a high-speed replacement for BLAS, -//// such as OpenBLAS, GotoBLAS, Intel MKL, AMD ACML, or the Accelerate framework. +//// such as OpenBLAS, Intel MKL, or the Accelerate framework. //// BLAS is used for matrix multiplication. //// Without BLAS, matrix multiplication will still work, but might be slower. #endif @@ -62,7 +74,7 @@ //// You will then need to link your programs directly with -llapack -lblas instead of -larmadillo // #define ARMA_BLAS_CAPITALS -//// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names (eg. ACML on 64-bit Windows) +//// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names #define ARMA_BLAS_UNDERSCORE //// Uncomment the above line if your BLAS and LAPACK libraries have function names with a trailing underscore. @@ -74,6 +86,12 @@ // #define ARMA_BLAS_LONG_LONG //// Uncomment the above line if your BLAS and LAPACK libraries use "long long" instead of "int" +// #define ARMA_BLAS_NOEXCEPT +//// Uncomment the above line if you require BLAS functions to have the 'noexcept' specification + +// #define ARMA_LAPACK_NOEXCEPT +//// Uncomment the above line if you require LAPACK functions to have the 'noexcept' specification + #define ARMA_USE_FORTRAN_HIDDEN_ARGS //// Comment out the above line to call BLAS and LAPACK functions without using so-called "hidden" arguments. //// Fortran functions (compiled without a BIND(C) declaration) that have char arguments @@ -99,12 +117,6 @@ //// uncomment the above define and specify the appropriate include directory. //// Make sure the directory has a trailing / -#if !defined(ARMA_USE_CXX11) -// #define ARMA_USE_CXX11 -//// Uncomment the above line to forcefully enable use of C++11 features (eg. initialiser lists). -//// Note that ARMA_USE_CXX11 is automatically enabled when a C++11 compiler is detected. -#endif - #if !defined(ARMA_USE_OPENMP) // #define ARMA_USE_OPENMP //// Uncomment the above line to forcefully enable use of OpenMP for parallelisation. @@ -114,8 +126,7 @@ #if !defined(ARMA_64BIT_WORD) // #define ARMA_64BIT_WORD //// Uncomment the above line if you require matrices/vectors capable of holding more than 4 billion elements. -//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long"). -//// Note that ARMA_64BIT_WORD is automatically enabled when a C++11 compiler is detected and std::size_t has 64 bits. +//// Note that ARMA_64BIT_WORD is automatically enabled when std::size_t has 64 bits and ARMA_32BIT_WORD is not defined. #endif #if !defined(ARMA_USE_HDF5) @@ -125,14 +136,17 @@ //// and you will need to link with the hdf5 library (eg. -lhdf5) #endif -#if !defined(ARMA_OPTIMISE_SOLVE_BAND) - #define ARMA_OPTIMISE_SOLVE_BAND - //// Comment out the above line if you don't want optimised handling of band matrices by solve() +#if !defined(ARMA_OPTIMISE_BAND) + #define ARMA_OPTIMISE_BAND + //// Comment out the above line if you don't want automatically optimised handling + //// of band matrices by solve() and chol() #endif -#if !defined(ARMA_OPTIMISE_SOLVE_SYMPD) - #define ARMA_OPTIMISE_SOLVE_SYMPD - //// Comment out the above line if you don't want optimised handling of symmetric/hermitian positive definite matrices by solve() +#if !defined(ARMA_OPTIMISE_SYMPD) + #define ARMA_OPTIMISE_SYMPD + //// Comment out the above line if you don't want automatically optimised handling + //// of symmetric/hermitian positive definite matrices by various functions: + //// solve(), inv(), pinv(), expmat(), logmat(), sqrtmat(), rcond() #endif #cmakedefine ARMA_USE_HDF5_ALT @@ -152,13 +166,13 @@ //// change the number to the size of your vectors. #if !defined(ARMA_OPENMP_THRESHOLD) - #define ARMA_OPENMP_THRESHOLD 240 + #define ARMA_OPENMP_THRESHOLD 320 #endif //// The minimum number of elements in a matrix to allow OpenMP based parallelisation; //// it must be an integer that is at least 1. #if !defined(ARMA_OPENMP_THREADS) - #define ARMA_OPENMP_THREADS 10 + #define ARMA_OPENMP_THREADS 8 #endif //// The maximum number of threads to use for OpenMP based parallelisation; //// it must be an integer that is at least 1. @@ -205,6 +219,11 @@ //// Comment out the above line if you don't want errors and warnings printed (eg. failed decompositions) #endif +#if !defined(ARMA_PRINT_EXCEPTIONS) +// #define ARMA_PRINT_EXCEPTIONS +//// see also compiler_setup.hpp +#endif + #if !defined(ARMA_PRINT_HDF5_ERRORS) // #define ARMA_PRINT_HDF5_ERRORS #endif @@ -244,9 +263,17 @@ #undef ARMA_USE_FORTRAN_HIDDEN_ARGS #endif -#if defined(ARMA_DONT_USE_CXX11) - #undef ARMA_USE_CXX11 - #undef ARMA_USE_EXTERN_CXX11_RNG +#if !defined(ARMA_DONT_USE_STD_MUTEX) + // #define ARMA_DONT_USE_STD_MUTEX + //// Uncomment the above line to disable use of std::mutex +#endif + +// for compatibility with earlier versions of Armadillo +#if defined(ARMA_DONT_USE_CXX11_MUTEX) + #pragma message ("WARNING: support for ARMA_DONT_USE_CXX11_MUTEX is deprecated and will be removed;") + #pragma message ("WARNING: use ARMA_DONT_USE_STD_MUTEX instead") + #undef ARMA_DONT_USE_STD_MUTEX + #define ARMA_DONT_USE_STD_MUTEX #endif #if defined(ARMA_DONT_USE_OPENMP) @@ -254,15 +281,20 @@ #endif #if defined(ARMA_USE_WRAPPER) - #if defined(ARMA_USE_CXX11) - #if !defined(ARMA_USE_EXTERN_CXX11_RNG) - #cmakedefine ARMA_USE_EXTERN_CXX11_RNG - #endif + #if !defined(ARMA_USE_EXTERN_RNG) + #cmakedefine ARMA_USE_EXTERN_RNG #endif #endif +#if defined(ARMA_DONT_USE_EXTERN_RNG) + #undef ARMA_USE_EXTERN_RNG +#endif + +// for compatibility with earlier versions of Armadillo #if defined(ARMA_DONT_USE_EXTERN_CXX11_RNG) - #undef ARMA_USE_EXTERN_CXX11_RNG + #pragma message ("WARNING: support for ARMA_DONT_USE_EXTERN_CXX11_RNG is deprecated and will be removed;") + #pragma message ("WARNING: use ARMA_DONT_USE_EXTERN_RNG instead") + #undef ARMA_USE_EXTERN_RNG #endif #if defined(ARMA_32BIT_WORD) @@ -274,22 +306,35 @@ #undef ARMA_USE_HDF5_ALT #endif -#if defined(ARMA_DONT_OPTIMISE_SOLVE_BAND) - #undef ARMA_OPTIMISE_SOLVE_BAND +#if defined(ARMA_DONT_OPTIMISE_BAND) || defined(ARMA_DONT_OPTIMISE_SOLVE_BAND) + #undef ARMA_OPTIMISE_BAND #endif -#if defined(ARMA_DONT_OPTIMISE_SOLVE_SYMPD) - #undef ARMA_OPTIMISE_SOLVE_SYMPD +#if defined(ARMA_DONT_OPTIMISE_SYMPD) || defined(ARMA_DONT_OPTIMISE_SOLVE_SYMPD) + #undef ARMA_OPTIMISE_SYMPD #endif #if defined(ARMA_DONT_PRINT_ERRORS) #undef ARMA_PRINT_ERRORS #endif +#if defined(ARMA_DONT_PRINT_EXCEPTIONS) + #undef ARMA_PRINT_EXCEPTIONS +#endif + +#if !defined(ARMA_DONT_ZERO_INIT) + // #define ARMA_DONT_ZERO_INIT + //// Uncomment the above line to disable initialising elements to zero during construction of dense matrices and cubes +#endif + #if defined(ARMA_DONT_PRINT_HDF5_ERRORS) #undef ARMA_PRINT_HDF5_ERRORS #endif +#if defined(ARMA_NO_CRIPPLED_LAPACK) + #undef ARMA_CRIPPLED_LAPACK +#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 diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/constants.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/constants.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/constants.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/constants.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,7 +29,7 @@ template static typename arma_real_only::result - nan(typename arma_real_only::result* junk = 0) + nan(typename arma_real_only::result* junk = nullptr) { arma_ignore(junk); @@ -45,7 +47,7 @@ template static typename arma_cx_only::result - nan(typename arma_cx_only::result* junk = 0) + nan(typename arma_cx_only::result* junk = nullptr) { arma_ignore(junk); @@ -58,7 +60,7 @@ template static typename arma_integral_only::result - nan(typename arma_integral_only::result* junk = 0) + nan(typename arma_integral_only::result* junk = nullptr) { arma_ignore(junk); @@ -69,7 +71,7 @@ template static typename arma_real_only::result - inf(typename arma_real_only::result* junk = 0) + inf(typename arma_real_only::result* junk = nullptr) { arma_ignore(junk); @@ -87,7 +89,7 @@ template static typename arma_cx_only::result - inf(typename arma_cx_only::result* junk = 0) + inf(typename arma_cx_only::result* junk = nullptr) { arma_ignore(junk); @@ -100,7 +102,7 @@ template static typename arma_integral_only::result - inf(typename arma_integral_only::result* junk = 0) + inf(typename arma_integral_only::result* junk = nullptr) { arma_ignore(junk); @@ -113,7 +115,7 @@ //! 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 @@ -124,17 +126,19 @@ { public: - static const eT pi; //!< ratio of any circle's circumference to its diameter - static const eT e; //!< base of the natural logarithm - static const eT euler; //!< Euler's constant, aka Euler-Mascheroni constant - static const eT gratio; //!< golden ratio - static const eT sqrt2; //!< square root of 2 - static const eT sqrt2pi; //!< square root of 2*pi - static const eT eps; //!< the difference between 1 and the least value greater than 1 that is representable - 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 pi; //!< ratio of any circle's circumference to its diameter + static const eT tau; //!< ratio of any circle's circumference to its radius (replacement of 2*pi) + static const eT e; //!< base of the natural logarithm + static const eT euler; //!< Euler's constant, aka Euler-Mascheroni constant + static const eT gratio; //!< golden ratio + static const eT sqrt2; //!< square root of 2 + static const eT sqrt2pi; //!< square root of 2*pi + static const eT log_sqrt2pi; //!< log of square root of 2*pi + static const eT eps; //!< the difference between 1 and the least value greater than 1 that is representable + 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 // @@ -173,47 +177,49 @@ // the long lengths of the constants are for future support of "long double" // and any smart compiler that does high-precision computation at compile-time -template const eT Datum::pi = eT(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679); -template const eT Datum::e = eT(2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274); -template const eT Datum::euler = eT(0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495); -template const eT Datum::gratio = eT(1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374); -template const eT Datum::sqrt2 = eT(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727); -template const eT Datum::sqrt2pi = eT(2.5066282746310005024157652848110452530069867406099383166299235763422936546078419749465958383780572661); -template const eT Datum::eps = std::numeric_limits::epsilon(); -template const eT Datum::log_min = std::log(std::numeric_limits::min()); -template const eT Datum::log_max = std::log(std::numeric_limits::max()); -template const eT Datum::nan = priv::Datum_helper::nan(); -template const eT Datum::inf = priv::Datum_helper::inf(); - -template const eT Datum::m_u = eT(1.660539040e-27); -template const eT Datum::N_A = eT(6.022140857e23); -template const eT Datum::k = eT(1.38064852e-23); -template const eT Datum::k_evk = eT(8.6173303e-5); -template const eT Datum::a_0 = eT(0.52917721067e-10); -template const eT Datum::mu_B = eT(927.4009994e-26); -template const eT Datum::Z_0 = eT(376.730313461771); -template const eT Datum::G_0 = eT(7.7480917310e-5); -template const eT Datum::k_e = eT(8.9875517873681764e9); -template const eT Datum::eps_0 = eT(8.85418781762039e-12); -template const eT Datum::m_e = eT(9.10938356e-31); -template const eT Datum::eV = eT(1.6021766208e-19); -template const eT Datum::ec = eT(1.6021766208e-19); -template const eT Datum::F = eT(96485.33289); -template const eT Datum::alpha = eT(7.2973525664e-3); -template const eT Datum::alpha_inv = eT(137.035999139); -template const eT Datum::K_J = eT(483597.8525e9); -template const eT Datum::mu_0 = eT(1.25663706143592e-06); -template const eT Datum::phi_0 = eT(2.067833667e-15); -template const eT Datum::R = eT(8.3144598); -template const eT Datum::G = eT(6.67408e-11); -template const eT Datum::h = eT(6.626070040e-34); -template const eT Datum::h_bar = eT(1.054571800e-34); -template const eT Datum::m_p = eT(1.672621898e-27); -template const eT Datum::R_inf = eT(10973731.568508); +template const eT Datum::pi = eT(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679); +template const eT Datum::tau = eT(6.2831853071795864769252867665590057683943387987502116419498891846156328125724179972560696506842341359); +template const eT Datum::e = eT(2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274); +template const eT Datum::euler = eT(0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495); +template const eT Datum::gratio = eT(1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374); +template const eT Datum::sqrt2 = eT(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727); +template const eT Datum::sqrt2pi = eT(2.5066282746310005024157652848110452530069867406099383166299235763422936546078419749465958383780572661); +template const eT Datum::log_sqrt2pi = eT(0.9189385332046727417803297364056176398613974736377834128171515404827656959272603976947432986359541976); +template const eT Datum::eps = std::numeric_limits::epsilon(); +template const eT Datum::log_min = std::log(std::numeric_limits::min()); +template const eT Datum::log_max = std::log(std::numeric_limits::max()); +template const eT Datum::nan = priv::Datum_helper::nan(); +template const eT Datum::inf = priv::Datum_helper::inf(); + +template const eT Datum::m_u = eT(1.66053906660e-27); +template const eT Datum::N_A = eT(6.02214076e23); +template const eT Datum::k = eT(1.380649e-23); +template const eT Datum::k_evk = eT(8.617333262e-5); +template const eT Datum::a_0 = eT(5.29177210903e-11); +template const eT Datum::mu_B = eT(9.2740100783e-24); +template const eT Datum::Z_0 = eT(376.730313668); +template const eT Datum::G_0 = eT(7.748091729e-5); +template const eT Datum::k_e = eT(8.9875517923e9); +template const eT Datum::eps_0 = eT(8.8541878128e-12); +template const eT Datum::m_e = eT(9.1093837015e-31); +template const eT Datum::eV = eT(1.602176634e-19); +template const eT Datum::ec = eT(1.602176634e-19); +template const eT Datum::F = eT(96485.33212); +template const eT Datum::alpha = eT(7.2973525693e-3); +template const eT Datum::alpha_inv = eT(137.035999084); +template const eT Datum::K_J = eT(483597.8484e9); +template const eT Datum::mu_0 = eT(1.25663706212e-6); +template const eT Datum::phi_0 = eT(2.067833848e-15); +template const eT Datum::R = eT(8.314462618); +template const eT Datum::G = eT(6.67430e-11); +template const eT Datum::h = eT(6.62607015e-34); +template const eT Datum::h_bar = eT(1.054571817e-34); +template const eT Datum::m_p = eT(1.67262192369e-27); +template const eT Datum::R_inf = eT(10973731.568160); template const eT Datum::c_0 = eT(299792458.0); -template const eT Datum::sigma = eT(5.670367e-8); -template const eT Datum::R_k = eT(25812.8074555); -template const eT Datum::b = eT(2.8977729e-3); +template const eT Datum::sigma = eT(5.670374419e-8); +template const eT Datum::R_k = eT(25812.80745); +template const eT Datum::b = eT(2.897771955e-3); @@ -228,62 +234,40 @@ template static - arma_inline + constexpr typename arma_real_only::result - most_neg(typename arma_real_only::result* junk = 0) + most_neg() { - arma_ignore(junk); - - if(std::numeric_limits::has_infinity) - { - return -(std::numeric_limits::infinity()); - } - else - { - return -(std::numeric_limits::max()); - } + return (std::numeric_limits::has_infinity) ? -(std::numeric_limits::infinity()) : std::numeric_limits::lowest(); } template static - arma_inline + constexpr typename arma_integral_only::result - most_neg(typename arma_integral_only::result* junk = 0) + most_neg() { - arma_ignore(junk); - - return std::numeric_limits::min(); + return std::numeric_limits::lowest(); } template static - arma_inline + constexpr typename arma_real_only::result - most_pos(typename arma_real_only::result* junk = 0) + most_pos() { - arma_ignore(junk); - - if(std::numeric_limits::has_infinity) - { - return std::numeric_limits::infinity(); - } - else - { - return std::numeric_limits::max(); - } + return (std::numeric_limits::has_infinity) ? std::numeric_limits::infinity() : std::numeric_limits::max(); } template static - arma_inline + constexpr typename arma_integral_only::result - most_pos(typename arma_integral_only::result* junk = 0) + most_pos() { - arma_ignore(junk); - return std::numeric_limits::max(); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/constants_old.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/constants_old.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/constants_old.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/constants_old.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -32,34 +34,34 @@ // and any smart compiler that does high-precision computation at compile-time //! ratio of any circle's circumference to its diameter - arma_deprecated static eT pi() { return eT(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679); } // use datum::pi instead + arma_deprecated static eT pi() { return eT(Datum::pi); } // use datum::pi instead //! base of the natural logarithm - arma_deprecated static eT e() { return eT(2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274); } // use datum::e instead + arma_deprecated static eT e() { return eT(Datum::e); } // use datum::e instead //! Euler's constant, aka Euler-Mascheroni constant - arma_deprecated static eT euler() { return eT(0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495); } // use datum::euler instead + arma_deprecated static eT euler() { return eT(Datum::euler); } // use datum::euler instead //! golden ratio - arma_deprecated static eT gratio() { return eT(1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374); } // use datum::gratio instead + arma_deprecated static eT gratio() { return eT(Datum::gratio); } // use datum::gratio instead //! square root of 2 - arma_deprecated static eT sqrt2() { return eT(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727); } // use datum::sqrt2 instead + arma_deprecated static eT sqrt2() { return eT(Datum::sqrt2); } // use datum::sqrt2 instead //! the difference between 1 and the least value greater than 1 that is representable - arma_deprecated static eT eps() { return std::numeric_limits::epsilon(); } // use datum::eps instead + arma_deprecated static eT eps() { return eT(Datum::eps); } // use datum::eps instead //! log of the minimum representable value - arma_deprecated static eT log_min() { static const eT out = std::log(std::numeric_limits::min()); return out; } // use datum::log_min instead + arma_deprecated static eT log_min() { return eT(Datum::log_min); } // use datum::log_min instead //! log of the maximum representable value - arma_deprecated static eT log_max() { static const eT out = std::log(std::numeric_limits::max()); return out; } // use datum::log_max instead + arma_deprecated static eT log_max() { return eT(Datum::log_max); } // use datum::log_max instead //! "not a number" - arma_deprecated static eT nan() { return priv::Datum_helper::nan(); } // use datum::nan instead + arma_deprecated static eT nan() { return eT(Datum::nan); } // use datum::nan instead //! infinity - arma_deprecated static eT inf() { return priv::Datum_helper::inf(); } // use datum::inf instead + arma_deprecated static eT inf() { return eT(Datum::inf); } // use datum::inf instead }; @@ -74,91 +76,91 @@ public: //! atomic mass constant (in kg) - arma_deprecated static eT m_u() { return eT(1.660539040e-27); } + arma_deprecated static eT m_u() { return eT(Datum::m_u); } //! Avogadro constant - arma_deprecated static eT N_A() { return eT(6.022140857e23); } + arma_deprecated static eT N_A() { return eT(Datum::N_A); } //! Boltzmann constant (in joules per kelvin) - arma_deprecated static eT k() { return eT(1.38064852e-23); } + arma_deprecated static eT k() { return eT(Datum::k); } //! Boltzmann constant (in eV/K) - arma_deprecated static eT k_evk() { return eT(8.6173303e-5); } + arma_deprecated static eT k_evk() { return eT(Datum::k_evk); } //! Bohr radius (in meters) - arma_deprecated static eT a_0() { return eT(0.52917721067e-10); } + arma_deprecated static eT a_0() { return eT(Datum::a_0); } //! Bohr magneton - arma_deprecated static eT mu_B() { return eT(927.4009994e-26); } + arma_deprecated static eT mu_B() { return eT(Datum::mu_B); } //! characteristic impedance of vacuum (in ohms) - arma_deprecated static eT Z_0() { return eT(376.730313461771); } + arma_deprecated static eT Z_0() { return eT(Datum::Z_0); } //! conductance quantum (in siemens) - arma_deprecated static eT G_0() { return eT(7.7480917310e-5); } + arma_deprecated static eT G_0() { return eT(Datum::G_0); } //! Coulomb's constant (in meters per farad) - arma_deprecated static eT k_e() { return eT(8.9875517873681764e9); } + arma_deprecated static eT k_e() { return eT(Datum::k_e); } //! electric constant (in farads per meter) - arma_deprecated static eT eps_0() { return eT(8.85418781762039e-12); } + arma_deprecated static eT eps_0() { return eT(Datum::eps_0); } //! electron mass (in kg) - arma_deprecated static eT m_e() { return eT(9.10938356e-31); } + arma_deprecated static eT m_e() { return eT(Datum::m_e); } //! electron volt (in joules) - arma_deprecated static eT eV() { return eT(1.6021766208e-19); } + arma_deprecated static eT eV() { return eT(Datum::eV); } //! elementary charge (in coulombs) - arma_deprecated static eT e() { return eT(1.6021766208e-19); } + arma_deprecated static eT e() { return eT(Datum::ec); } //! Faraday constant (in coulombs) - arma_deprecated static eT F() { return eT(96485.33289); } + arma_deprecated static eT F() { return eT(Datum::F); } //! fine-structure constant - arma_deprecated static eT alpha() { return eT(7.2973525664e-3); } + arma_deprecated static eT alpha() { return eT(Datum::alpha); } //! inverse fine-structure constant - arma_deprecated static eT alpha_inv() { return eT(137.035999139); } + arma_deprecated static eT alpha_inv() { return eT(Datum::alpha_inv); } //! Josephson constant - arma_deprecated static eT K_J() { return eT(483597.8525e9); } + arma_deprecated static eT K_J() { return eT(Datum::K_J); } //! magnetic constant (in henries per meter) - arma_deprecated static eT mu_0() { return eT(1.25663706143592e-06); } + arma_deprecated static eT mu_0() { return eT(Datum::mu_0); } //! magnetic flux quantum (in webers) - arma_deprecated static eT phi_0() { return eT(2.067833667e-15); } + arma_deprecated static eT phi_0() { return eT(Datum::phi_0); } //! molar gas constant (in joules per mole kelvin) - arma_deprecated static eT R() { return eT(8.3144598); } + arma_deprecated static eT R() { return eT(Datum::R); } //! Newtonian constant of gravitation (in newton square meters per kilogram squared) - arma_deprecated static eT G() { return eT(6.67408e-11); } + arma_deprecated static eT G() { return eT(Datum::G); } //! Planck constant (in joule seconds) - arma_deprecated static eT h() { return eT(6.626070040e-34); } + arma_deprecated static eT h() { return eT(Datum::h); } //! Planck constant over 2 pi, aka reduced Planck constant (in joule seconds) - arma_deprecated static eT h_bar() { return eT(1.054571800e-34); } + arma_deprecated static eT h_bar() { return eT(Datum::h_bar); } //! proton mass (in kg) - arma_deprecated static eT m_p() { return eT(1.672621898e-27); } + arma_deprecated static eT m_p() { return eT(Datum::m_p); } //! Rydberg constant (in reciprocal meters) - arma_deprecated static eT R_inf() { return eT(10973731.568508); } + arma_deprecated static eT R_inf() { return eT(Datum::R_inf); } //! speed of light in vacuum (in meters per second) - arma_deprecated static eT c_0() { return eT(299792458.0); } + arma_deprecated static eT c_0() { return eT(Datum::c_0); } //! Stefan-Boltzmann constant - arma_deprecated static eT sigma() { return eT(5.670367e-8); } + arma_deprecated static eT sigma() { return eT(Datum::sigma); } //! von Klitzing constant (in ohms) - arma_deprecated static eT R_k() { return eT(25812.8074555); } + arma_deprecated static eT R_k() { return eT(Datum::R_k); } //! Wien wavelength displacement law constant - arma_deprecated static eT b() { return eT(2.8977729e-3); } + arma_deprecated static eT b() { return eT(Datum::b); } }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/csv_name.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/csv_name.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/csv_name.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/csv_name.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup diskio +//! @{ + + +namespace csv_opts + { + typedef unsigned int flag_type; + + struct opts + { + const flag_type flags; + + inline explicit opts(const flag_type in_flags); + + inline const opts operator+(const opts& rhs) const; + }; + + inline + opts::opts(const flag_type in_flags) + : flags(in_flags) + {} + + inline + const opts + opts::operator+(const opts& rhs) const + { + const opts result( flags | rhs.flags ); + + return result; + } + + // The values below (eg. 1u << 0) are for internal Armadillo use only. + // The values can change without notice. + + static const flag_type flag_none = flag_type(0 ); + static const flag_type flag_trans = flag_type(1u << 0); + static const flag_type flag_no_header = flag_type(1u << 1); + static const flag_type flag_with_header = flag_type(1u << 2); + static const flag_type flag_semicolon = flag_type(1u << 3); + + struct opts_none : public opts { inline opts_none() : opts(flag_none ) {} }; + struct opts_trans : public opts { inline opts_trans() : opts(flag_trans ) {} }; + struct opts_no_header : public opts { inline opts_no_header() : opts(flag_no_header ) {} }; + struct opts_with_header : public opts { inline opts_with_header() : opts(flag_with_header) {} }; + struct opts_semicolon : public opts { inline opts_semicolon() : opts(flag_semicolon ) {} }; + + static const opts_none none; + static const opts_trans trans; + static const opts_no_header no_header; + static const opts_with_header with_header; + static const opts_semicolon semicolon; + } + + +struct csv_name + { + typedef field header_type; + + const std::string filename; + const csv_opts::opts opts; + + header_type header_junk; + const header_type& header_ro; + header_type& header_rw; + + inline + csv_name(const std::string& in_filename, const csv_opts::opts& in_opts = csv_opts::no_header) + : filename (in_filename) + , opts (in_opts ) + , header_ro(header_junk) + , header_rw(header_junk) + {} + + inline + csv_name(const std::string& in_filename, field& in_header) + : filename (in_filename ) + , opts (csv_opts::with_header) + , header_ro(in_header ) + , header_rw(in_header ) + {} + + inline + csv_name(const std::string& in_filename, const field& in_header) + : filename (in_filename ) + , opts (csv_opts::with_header) + , header_ro(in_header ) + , header_rw(header_junk ) + {} + + inline + csv_name(const std::string& in_filename, field& in_header, const csv_opts::opts& in_opts) + : filename (in_filename ) + , opts (csv_opts::with_header + in_opts) + , header_ro(in_header ) + , header_rw(in_header ) + {} + + inline + csv_name(const std::string& in_filename, const field& in_header, const csv_opts::opts& in_opts) + : filename (in_filename ) + , opts (csv_opts::with_header + in_opts) + , header_ro(in_header ) + , header_rw(header_junk ) + {} + }; + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Cube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Cube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Cube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Cube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,8 +23,8 @@ struct Cube_prealloc { - static const uword mat_ptrs_size = 4; - static const uword mem_n_elem = 64; + static constexpr uword mat_ptrs_size = 4; + static constexpr uword mem_n_elem = 64; }; @@ -42,6 +44,7 @@ const uword n_elem_slice; //!< number of elements in each slice (read-only) const uword n_slices; //!< number of slices in the cube (read-only) const uword n_elem; //!< number of elements in the cube (read-only) + const uword n_alloc; //!< number of allocated elements (read-only); NOTE: n_alloc can be 0, even if n_elem > 0 const uword mem_state; // mem_state = 0: normal cube which manages its own memory @@ -65,28 +68,32 @@ inline ~Cube(); inline Cube(); - inline explicit Cube(const uword in_rows, const uword in_cols, const uword in_slices); + inline explicit Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices); inline explicit Cube(const SizeCube& s); - template inline Cube(const uword in_rows, const uword in_cols, const uword in_slices, const fill::fill_class& f); - template inline Cube(const SizeCube& s, const fill::fill_class& f); + template inline explicit Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const arma_initmode_indicator&); + template inline explicit Cube(const SizeCube& s, const arma_initmode_indicator&); + + template inline Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const fill::fill_class& f); + template inline Cube(const SizeCube& s, const fill::fill_class& f); + + inline Cube(const uword in_rows, const uword in_cols, const uword in_slices, const fill::scalar_holder f); + inline Cube(const SizeCube& s, const fill::scalar_holder f); - #if defined(ARMA_USE_CXX11) inline Cube(Cube&& m); inline Cube& operator=(Cube&& m); - #endif inline Cube( eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices, const bool copy_aux_mem = true, const bool strict = false, const bool prealloc_mat = false); inline Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices); - inline Cube& operator=(const eT val); + inline Cube& operator= (const eT val); inline Cube& operator+=(const eT val); inline Cube& operator-=(const eT val); inline Cube& operator*=(const eT val); inline Cube& operator/=(const eT val); inline Cube(const Cube& m); - inline Cube& operator=(const Cube& m); + inline Cube& operator= (const Cube& m); inline Cube& operator+=(const Cube& m); inline Cube& operator-=(const Cube& m); inline Cube& operator%=(const Cube& m); @@ -96,14 +103,14 @@ inline explicit Cube(const BaseCube& A, const BaseCube& B); inline Cube(const subview_cube& X); - inline Cube& operator=(const subview_cube& X); + inline Cube& operator= (const subview_cube& X); inline Cube& operator+=(const subview_cube& X); inline Cube& operator-=(const subview_cube& X); inline Cube& operator%=(const subview_cube& X); inline Cube& operator/=(const subview_cube& X); template inline Cube(const subview_cube_slices& X); - template inline Cube& operator=(const subview_cube_slices& X); + template inline Cube& operator= (const subview_cube_slices& X); template inline Cube& operator+=(const subview_cube_slices& X); template inline Cube& operator-=(const subview_cube_slices& X); template inline Cube& operator%=(const subview_cube_slices& X); @@ -173,13 +180,11 @@ template inline subview_cube_each2 each_slice(const Base& indices); template inline const subview_cube_each2 each_slice(const Base& indices) const; - #if defined(ARMA_USE_CXX11) inline const Cube& each_slice(const std::function< void( Mat&) >& F); inline const Cube& each_slice(const std::function< void(const Mat&) >& F) const; inline const Cube& each_slice(const std::function< void( Mat&) >& F, const bool use_mp); inline const Cube& each_slice(const std::function< void(const Mat&) >& F, const bool use_mp) const; - #endif template arma_inline subview_cube_slices slices(const Base& indices); @@ -206,49 +211,49 @@ template inline Cube(const GenCube& X); - template inline Cube& operator=(const GenCube& X); + template inline Cube& operator= (const GenCube& X); template inline Cube& operator+=(const GenCube& X); template inline Cube& operator-=(const GenCube& X); template inline Cube& operator%=(const GenCube& X); template inline Cube& operator/=(const GenCube& X); template inline Cube(const OpCube& X); - template inline Cube& operator=(const OpCube& X); + template inline Cube& operator= (const OpCube& X); template inline Cube& operator+=(const OpCube& X); template inline Cube& operator-=(const OpCube& X); template inline Cube& operator%=(const OpCube& X); template inline Cube& operator/=(const OpCube& X); template inline Cube(const eOpCube& X); - template inline Cube& operator=(const eOpCube& X); + template inline Cube& operator= (const eOpCube& X); template inline Cube& operator+=(const eOpCube& X); template inline Cube& operator-=(const eOpCube& X); template inline Cube& operator%=(const eOpCube& X); template inline Cube& operator/=(const eOpCube& X); template inline Cube(const mtOpCube& X); - template inline Cube& operator=(const mtOpCube& X); + template inline Cube& operator= (const mtOpCube& X); template inline Cube& operator+=(const mtOpCube& X); template inline Cube& operator-=(const mtOpCube& X); template inline Cube& operator%=(const mtOpCube& X); template inline Cube& operator/=(const mtOpCube& X); template inline Cube(const GlueCube& X); - template inline Cube& operator=(const GlueCube& X); + template inline Cube& operator= (const GlueCube& X); template inline Cube& operator+=(const GlueCube& X); template inline Cube& operator-=(const GlueCube& X); template inline Cube& operator%=(const GlueCube& X); template inline Cube& operator/=(const GlueCube& X); template inline Cube(const eGlueCube& X); - template inline Cube& operator=(const eGlueCube& X); + template inline Cube& operator= (const eGlueCube& X); template inline Cube& operator+=(const eGlueCube& X); template inline Cube& operator-=(const eGlueCube& X); template inline Cube& operator%=(const eGlueCube& X); template inline Cube& operator/=(const eGlueCube& X); template inline Cube(const mtGlueCube& X); - template inline Cube& operator=(const mtGlueCube& X); + template inline Cube& operator= (const mtGlueCube& X); template inline Cube& operator+=(const mtGlueCube& X); template inline Cube& operator-=(const mtGlueCube& X); template inline Cube& operator%=(const mtGlueCube& X); @@ -301,23 +306,15 @@ arma_inline arma_warn_unused eT* slice_colptr(const uword in_slice, const uword in_col); arma_inline arma_warn_unused const eT* slice_colptr(const uword in_slice, const uword in_col) const; - arma_cold inline void impl_print( const std::string& extra_text) const; - arma_cold inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const; - - arma_cold inline void impl_raw_print( const std::string& extra_text) const; - arma_cold inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const; - - inline void set_size(const uword in_rows, const uword in_cols, const uword in_slices); + inline void set_size(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); inline void set_size(const SizeCube& s); - inline void reshape(const uword in_rows, const uword in_cols, const uword in_slices); + inline void reshape(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); inline void reshape(const SizeCube& s); - inline void resize(const uword in_rows, const uword in_cols, const uword in_slices); + inline void resize(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); inline void resize(const SizeCube& s); - arma_deprecated inline void reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim); //!< NOTE: don't use this form: it will be removed - template inline void copy_size(const Cube& m); @@ -331,22 +328,24 @@ inline const Cube& clean(const pod_type threshold); + inline const Cube& clamp(const eT min_val, const eT max_val); + inline const Cube& fill(const eT val); inline const Cube& zeros(); - inline const Cube& zeros(const uword in_rows, const uword in_cols, const uword in_slices); + inline const Cube& zeros(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); inline const Cube& zeros(const SizeCube& s); inline const Cube& ones(); - inline const Cube& ones(const uword in_rows, const uword in_cols, const uword in_slices); + inline const Cube& ones(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); inline const Cube& ones(const SizeCube& s); inline const Cube& randu(); - inline const Cube& randu(const uword in_rows, const uword in_cols, const uword in_slices); + inline const Cube& randu(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); inline const Cube& randu(const SizeCube& s); inline const Cube& randn(); - inline const Cube& randn(const uword in_rows, const uword in_cols, const uword in_slices); + inline const Cube& randn(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); inline const Cube& randn(const SizeCube& s); inline void reset(); @@ -367,13 +366,13 @@ inline eT max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const; - inline arma_cold bool save(const std::string name, const file_type type = arma_binary, const bool print_status = true) const; - inline arma_cold bool save(const hdf5_name& spec, const file_type type = hdf5_binary, const bool print_status = true) const; - inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary, const bool print_status = true) const; - - inline arma_cold bool load(const std::string name, const file_type type = auto_detect, const bool print_status = true); - inline arma_cold bool load(const hdf5_name& spec, const file_type type = hdf5_binary, const bool print_status = true); - inline arma_cold bool load( std::istream& is, const file_type type = auto_detect, const bool print_status = true); + inline arma_cold bool save(const std::string name, const file_type type = arma_binary) const; + inline arma_cold bool save(const hdf5_name& spec, const file_type type = hdf5_binary) const; + inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary) const; + + inline arma_cold bool load(const std::string name, const file_type type = auto_detect); + inline arma_cold bool load(const hdf5_name& spec, const file_type type = hdf5_binary); + inline arma_cold bool load( std::istream& is, const file_type type = auto_detect); inline arma_cold bool quiet_save(const std::string name, const file_type type = arma_binary) const; inline arma_cold bool quiet_save(const hdf5_name& spec, const file_type type = hdf5_binary) const; @@ -410,6 +409,12 @@ inline bool empty() const; inline uword size() const; + inline arma_warn_unused eT& front(); + inline arma_warn_unused const eT& front() const; + + inline arma_warn_unused eT& back(); + inline arma_warn_unused const eT& back() const; + inline void swap(Cube& B); inline void steal_mem(Cube& X); //!< don't use this unless you're writing code internal to Armadillo @@ -420,7 +425,7 @@ protected: inline void init_cold(); - inline void init_warm(const uword in_rows, const uword in_cols, const uword in_slices); + inline void init_warm(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices); template inline void init(const BaseCube& A, const BaseCube& B); @@ -449,10 +454,10 @@ { private: - static const uword fixed_n_elem = fixed_n_rows * fixed_n_cols * fixed_n_slices; - static const uword fixed_n_elem_slice = fixed_n_rows * fixed_n_cols; + static constexpr uword fixed_n_elem = fixed_n_rows * fixed_n_cols * fixed_n_slices; + static constexpr uword fixed_n_elem_slice = fixed_n_rows * fixed_n_cols; - static const bool use_extra = (fixed_n_elem > Cube_prealloc::mem_n_elem); + static constexpr bool use_extra = (fixed_n_elem > Cube_prealloc::mem_n_elem); arma_aligned Mat* mat_ptrs_local_extra[ (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? fixed_n_slices : 1 ]; arma_align_mem eT mem_local_extra [ use_extra ? fixed_n_elem : 1 ]; @@ -465,6 +470,7 @@ inline fixed(); inline fixed(const fixed& X); + inline fixed(const fill::scalar_holder f); template inline fixed(const fill::fill_class& f); template inline fixed(const BaseCube& A); template inline fixed(const BaseCube& A, const BaseCube& B); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Cube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Cube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Cube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Cube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,16 +28,17 @@ delete_mat(); - if( (mem_state == 0) && (n_elem > Cube_prealloc::mem_n_elem) ) + if( (mem_state == 0) && (n_alloc > 0) ) { + arma_extra_debug_print("Cube::destructor: releasing memory"); memory::release( access::rw(mem) ); } // try to expose buggy user code that accesses deleted objects if(arma_config::debug) { - access::rw(mem) = 0; - access::rw(mat_ptrs) = 0; + access::rw(mem) = nullptr; + access::rw(mat_ptrs) = nullptr; } arma_type_check(( is_supported_elem_type::value == false )); @@ -51,9 +54,10 @@ , n_elem_slice(0) , n_slices(0) , n_elem(0) + , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); } @@ -69,13 +73,21 @@ , n_elem_slice(in_n_rows*in_n_cols) , n_slices(in_n_slices) , n_elem(in_n_rows*in_n_cols*in_n_slices) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); init_cold(); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Cube::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } + #endif } @@ -88,13 +100,77 @@ , n_elem_slice(s.n_rows*s.n_cols) , n_slices(s.n_slices) , n_elem(s.n_rows*s.n_cols*s.n_slices) + , n_alloc() + , mem_state(0) + , mem() + , mat_ptrs(nullptr) + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Cube::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } + #endif + } + + + +//! internal use only +template +template +inline +Cube::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const arma_initmode_indicator&) + : n_rows(in_n_rows) + , n_cols(in_n_cols) + , n_elem_slice(in_n_rows*in_n_cols) + , n_slices(in_n_slices) + , n_elem(in_n_rows*in_n_cols*in_n_slices) + , n_alloc() + , mem_state(0) + , mem() + , mat_ptrs(nullptr) + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + + if(do_zeros) + { + arma_extra_debug_print("Cube::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } + } + + + +//! internal use only +template +template +inline +Cube::Cube(const SizeCube& s, const arma_initmode_indicator&) + : n_rows(s.n_rows) + , n_cols(s.n_cols) + , n_elem_slice(s.n_rows*s.n_cols) + , n_slices(s.n_slices) + , n_elem(s.n_rows*s.n_cols*s.n_slices) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); init_cold(); + + if(do_zeros) + { + arma_extra_debug_print("Cube::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } } @@ -109,20 +185,21 @@ , n_elem_slice(in_n_rows*in_n_cols) , n_slices(in_n_slices) , n_elem(in_n_rows*in_n_cols*in_n_slices) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); init_cold(); - if(is_same_type::yes) (*this).zeros(); - if(is_same_type::yes) (*this).ones(); - if(is_same_type::yes) (*this).randu(); - if(is_same_type::yes) (*this).randn(); + if(is_same_type::yes) { (*this).zeros(); } + if(is_same_type::yes) { (*this).ones(); } + if(is_same_type::yes) { (*this).randu(); } + if(is_same_type::yes) { (*this).randn(); } - if(is_same_type::yes) { arma_debug_check(true, "Cube::Cube(): unsupported fill type"); } + arma_static_check( (is_same_type::yes), "Cube::Cube(): unsupported fill type" ); } @@ -136,59 +213,102 @@ , n_elem_slice(s.n_rows*s.n_cols) , n_slices(s.n_slices) , n_elem(s.n_rows*s.n_cols*s.n_slices) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); init_cold(); - if(is_same_type::yes) (*this).zeros(); - if(is_same_type::yes) (*this).ones(); - if(is_same_type::yes) (*this).randu(); - if(is_same_type::yes) (*this).randn(); + if(is_same_type::yes) { (*this).zeros(); } + if(is_same_type::yes) { (*this).ones(); } + if(is_same_type::yes) { (*this).randu(); } + if(is_same_type::yes) { (*this).randn(); } + + arma_static_check( (is_same_type::yes), "Cube::Cube(): unsupported fill type" ); + } + + + +//! construct the cube to have user specified dimensions and fill with specified value +template +inline +Cube::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const fill::scalar_holder f) + : n_rows(in_n_rows) + , n_cols(in_n_cols) + , n_elem_slice(in_n_rows*in_n_cols) + , n_slices(in_n_slices) + , n_elem(in_n_rows*in_n_cols*in_n_slices) + , n_alloc() + , mem_state(0) + , mem() + , mat_ptrs(nullptr) + { + arma_extra_debug_sigprint_this(this); + + init_cold(); - if(is_same_type::yes) { arma_debug_check(true, "Cube::Cube(): unsupported fill type"); } + (*this).fill(f.scalar); } -#if defined(ARMA_USE_CXX11) +template +inline +Cube::Cube(const SizeCube& s, const fill::scalar_holder f) + : n_rows(s.n_rows) + , n_cols(s.n_cols) + , n_elem_slice(s.n_rows*s.n_cols) + , n_slices(s.n_slices) + , n_elem(s.n_rows*s.n_cols*s.n_slices) + , n_alloc() + , mem_state(0) + , mem() + , mat_ptrs(nullptr) + { + arma_extra_debug_sigprint_this(this); - template - inline - Cube::Cube(Cube&& in_cube) - : n_rows(0) - , n_cols(0) - , n_elem_slice(0) - , n_slices(0) - , n_elem(0) - , mem_state(0) - , mem() - , mat_ptrs(0) - { - arma_extra_debug_sigprint_this(this); - arma_extra_debug_sigprint(arma_str::format("this = %x in_cube = %x") % this % &in_cube); - - (*this).steal_mem(in_cube); - } - + init_cold(); + (*this).fill(f.scalar); + } + + + +template +inline +Cube::Cube(Cube&& in_cube) + : n_rows(0) + , n_cols(0) + , n_elem_slice(0) + , n_slices(0) + , n_elem(0) + , n_alloc(0) + , mem_state(0) + , mem() + , mat_ptrs(nullptr) + { + arma_extra_debug_sigprint_this(this); + arma_extra_debug_sigprint(arma_str::format("this = %x in_cube = %x") % this % &in_cube); - template - inline - Cube& - Cube::operator=(Cube&& in_cube) - { - arma_extra_debug_sigprint(arma_str::format("this = %x in_cube = %x") % this % &in_cube); - - (*this).steal_mem(in_cube); - - return *this; - } + (*this).steal_mem(in_cube); + } + + + +template +inline +Cube& +Cube::operator=(Cube&& in_cube) + { + arma_extra_debug_sigprint(arma_str::format("this = %x in_cube = %x") % this % &in_cube); -#endif + (*this).steal_mem(in_cube); + + return *this; + } @@ -199,10 +319,10 @@ { arma_extra_debug_sigprint( arma_str::format("n_rows = %d, n_cols = %d, n_slices = %d") % n_rows % n_cols % n_slices ); - #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD)) + #if defined(ARMA_64BIT_WORD) const char* error_message = "Cube::init(): requested size is too large"; #else - const char* error_message = "Cube::init(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD"; + const char* error_message = "Cube::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_check @@ -218,20 +338,17 @@ if(n_elem <= Cube_prealloc::mem_n_elem) { - if(n_elem == 0) - { - access::rw(mem) = NULL; - } - else - { - arma_extra_debug_print("Cube::init(): using local memory"); - access::rw(mem) = mem_local; - } + if(n_elem > 0) { arma_extra_debug_print("Cube::init(): using local memory"); } + + access::rw(mem) = (n_elem == 0) ? nullptr : mem_local; + access::rw(n_alloc) = 0; } else { arma_extra_debug_print("Cube::init(): acquiring memory"); - access::rw(mem) = memory::acquire(n_elem); + + access::rw(mem) = memory::acquire(n_elem); + access::rw(n_alloc) = n_elem; } create_mat(); @@ -251,14 +368,14 @@ const uword t_mem_state = mem_state; bool err_state = false; - char* err_msg = 0; + char* err_msg = nullptr; arma_debug_set_error( err_state, err_msg, (t_mem_state == 3), "Cube::init(): size is fixed and hence cannot be changed" ); - #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD)) + #if defined(ARMA_64BIT_WORD) const char* error_message = "Cube::init(): requested size is too large"; #else - const char* error_message = "Cube::init(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD"; + const char* error_message = "Cube::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_set_error @@ -290,68 +407,64 @@ access::rw(n_slices) = in_n_slices; create_mat(); + + return; } - else // condition: old_n_elem != new_n_elem + + arma_debug_check( (t_mem_state == 2), "Cube::init(): mismatch between size of auxiliary memory and requested size" ); + + delete_mat(); + + if(new_n_elem <= Cube_prealloc::mem_n_elem) { - arma_debug_check( (t_mem_state == 2), "Cube::init(): requested size is not compatible with the size of auxiliary memory" ); - - delete_mat(); - - if(new_n_elem < old_n_elem) // reuse existing memory if possible + if(n_alloc > 0) { - if( (t_mem_state == 0) && (new_n_elem <= Cube_prealloc::mem_n_elem) ) - { - if(old_n_elem > Cube_prealloc::mem_n_elem) - { - arma_extra_debug_print("Cube::init(): releasing memory"); - memory::release( access::rw(mem) ); - } - - if(new_n_elem == 0) - { - access::rw(mem) = NULL; - } - else - { - arma_extra_debug_print("Cube::init(): using local memory"); - access::rw(mem) = mem_local; - } - } - else - { - arma_extra_debug_print("Cube::init(): reusing memory"); - } + arma_extra_debug_print("Cube::init(): releasing memory"); + memory::release( access::rw(mem) ); } - else // condition: new_n_elem > old_n_elem + + if(new_n_elem > 0) { arma_extra_debug_print("Cube::init(): using local memory"); } + + access::rw(mem) = (new_n_elem == 0) ? nullptr : mem_local; + access::rw(n_alloc) = 0; + } + else // condition: new_n_elem > Cube_prealloc::mem_n_elem + { + if(new_n_elem > n_alloc) { - if( (t_mem_state == 0) && (old_n_elem > Cube_prealloc::mem_n_elem) ) + if(n_alloc > 0) { arma_extra_debug_print("Cube::init(): releasing memory"); memory::release( access::rw(mem) ); + + // in case memory::acquire() throws an exception + access::rw(mem) = nullptr; + access::rw(n_rows) = 0; + access::rw(n_cols) = 0; + access::rw(n_elem_slice) = 0; + access::rw(n_slices) = 0; + access::rw(n_elem) = 0; + access::rw(n_alloc) = 0; } - if(new_n_elem <= Cube_prealloc::mem_n_elem) - { - arma_extra_debug_print("Cube::init(): using local memory"); - access::rw(mem) = mem_local; - } - else - { - arma_extra_debug_print("Cube::init(): acquiring memory"); - access::rw(mem) = memory::acquire(new_n_elem); - } - - access::rw(mem_state) = 0; + arma_extra_debug_print("Cube::init(): acquiring memory"); + access::rw(mem) = memory::acquire(new_n_elem); + access::rw(n_alloc) = new_n_elem; + } + else // condition: new_n_elem <= n_alloc + { + arma_extra_debug_print("Cube::init(): reusing memory"); } - - access::rw(n_rows) = in_n_rows; - access::rw(n_cols) = in_n_cols; - access::rw(n_elem_slice) = in_n_rows*in_n_cols; - access::rw(n_slices) = in_n_slices; - access::rw(n_elem) = new_n_elem; - - create_mat(); } + + access::rw(n_rows) = in_n_rows; + access::rw(n_cols) = in_n_cols; + access::rw(n_elem_slice) = in_n_rows*in_n_cols; + access::rw(n_slices) = in_n_slices; + access::rw(n_elem) = new_n_elem; + access::rw(mem_state) = 0; + + create_mat(); } @@ -427,11 +540,11 @@ { arma_extra_debug_sigprint(); - if((n_slices > 0) && (mat_ptrs != NULL)) + if((n_slices > 0) && (mat_ptrs != nullptr)) { for(uword uslice = 0; uslice < n_slices; ++uslice) { - if(mat_ptrs[uslice] != NULL) { delete access::rw(mat_ptrs[uslice]); } + if(mat_ptrs[uslice] != nullptr) { delete access::rw(mat_ptrs[uslice]); } } if( (mem_state <= 2) && (n_slices > Cube_prealloc::mat_ptrs_size) ) @@ -452,7 +565,7 @@ if(n_slices == 0) { - access::rw(mat_ptrs) = NULL; + access::rw(mat_ptrs) = nullptr; } else { @@ -466,13 +579,13 @@ { access::rw(mat_ptrs) = new(std::nothrow) const Mat*[n_slices]; - arma_check_bad_alloc( (mat_ptrs == 0), "Cube::create_mat(): out of memory" ); + arma_check_bad_alloc( (mat_ptrs == nullptr), "Cube::create_mat(): out of memory" ); } } for(uword uslice = 0; uslice < n_slices; ++uslice) { - mat_ptrs[uslice] = NULL; + mat_ptrs[uslice] = nullptr; } } } @@ -489,7 +602,9 @@ arma_extra_debug_sigprint(); init_warm(1,1,1); + access::rw(mem[0]) = val; + return *this; } @@ -564,9 +679,10 @@ , n_elem_slice(x.n_elem_slice) , n_slices(x.n_slices) , n_elem(x.n_elem) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); arma_extra_debug_sigprint(arma_str::format("this = %x in_cube = %x") % this % &x); @@ -609,15 +725,16 @@ , n_elem_slice( aux_n_rows*aux_n_cols ) , n_slices ( aux_n_slices ) , n_elem ( aux_n_rows*aux_n_cols*aux_n_slices ) + , n_alloc ( 0 ) , mem_state ( copy_aux_mem ? 0 : (strict ? 2 : 1) ) - , mem ( copy_aux_mem ? 0 : aux_mem ) - , mat_ptrs ( 0 ) + , mem ( copy_aux_mem ? nullptr : aux_mem ) + , mat_ptrs ( nullptr ) { arma_extra_debug_sigprint_this(this); - if(prealloc_mat == true) { arma_debug_warn("Cube::Cube(): parameter 'prealloc_mat' ignored as it's no longer used"); } + if(prealloc_mat) { arma_debug_warn_level(3, "Cube::Cube(): parameter 'prealloc_mat' ignored as it's no longer used"); } - if(copy_aux_mem == true) + if(copy_aux_mem) { init_cold(); @@ -641,9 +758,10 @@ , n_elem_slice(aux_n_rows*aux_n_cols) , n_slices(aux_n_slices) , n_elem(aux_n_rows*aux_n_cols*aux_n_slices) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -736,9 +854,10 @@ , n_elem_slice(0) , n_slices(0) , n_elem(0) + , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -747,7 +866,7 @@ -//! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation) +//! construct a cube from a subview_cube instance (eg. construct a cube from a delayed subcube operation) template inline Cube::Cube(const subview_cube& X) @@ -756,9 +875,10 @@ , n_elem_slice(X.n_elem_slice) , n_slices(X.n_slices) , n_elem(X.n_elem) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -769,7 +889,7 @@ -//! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation) +//! construct a cube from a subview_cube instance (eg. construct a cube from a delayed subcube operation) template inline Cube& @@ -866,9 +986,10 @@ , n_elem_slice(0) , n_slices(0) , n_elem(0) + , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -971,7 +1092,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_row >= n_rows), "Cube::row(): index out of bounds" ); + arma_debug_check_bounds( (in_row >= n_rows), "Cube::row(): index out of bounds" ); return (*this).rows(in_row, in_row); } @@ -986,7 +1107,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_row >= n_rows), "Cube::row(): index out of bounds" ); + arma_debug_check_bounds( (in_row >= n_rows), "Cube::row(): index out of bounds" ); return (*this).rows(in_row, in_row); } @@ -1001,7 +1122,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_col >= n_cols), "Cube::col(): index out of bounds" ); + arma_debug_check_bounds( (in_col >= n_cols), "Cube::col(): index out of bounds" ); return (*this).cols(in_col, in_col); } @@ -1016,7 +1137,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_col >= n_cols), "Cube::col(): index out of bounds" ); + arma_debug_check_bounds( (in_col >= n_cols), "Cube::col(): index out of bounds" ); return (*this).cols(in_col, in_col); } @@ -1031,11 +1152,11 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_slice >= n_slices), "Cube::slice(): index out of bounds" ); + arma_debug_check_bounds( (in_slice >= n_slices), "Cube::slice(): index out of bounds" ); - if(mat_ptrs[in_slice] == NULL) + if(mat_ptrs[in_slice] == nullptr) { - const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : NULL; + const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : nullptr; mat_ptrs[in_slice] = new Mat('j', ptr, n_rows, n_cols); } @@ -1053,11 +1174,11 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_slice >= n_slices), "Cube::slice(): index out of bounds" ); + arma_debug_check_bounds( (in_slice >= n_slices), "Cube::slice(): index out of bounds" ); - if(mat_ptrs[in_slice] == NULL) + if(mat_ptrs[in_slice] == nullptr) { - const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : NULL; + const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : nullptr; mat_ptrs[in_slice] = new Mat('j', ptr, n_rows, n_cols); } @@ -1075,7 +1196,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "Cube::rows(): indices out of bounds or incorrectly used" @@ -1096,7 +1217,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "Cube::rows(): indices out of bounds or incorrectly used" @@ -1117,7 +1238,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "Cube::cols(): indices out of bounds or incorrectly used" @@ -1138,7 +1259,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "Cube::cols(): indices out of bounds or incorrectly used" @@ -1159,7 +1280,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_slice1 > in_slice2) || (in_slice2 >= n_slices), "Cube::slices(): indices out of bounds or incorrectly used" @@ -1180,7 +1301,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_slice1 > in_slice2) || (in_slice2 >= n_slices), "Cube::slices(): indices out of bounds or incorrectly used" @@ -1201,7 +1322,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) || (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices), @@ -1225,7 +1346,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) || (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices), @@ -1257,7 +1378,7 @@ const uword s_n_cols = s.n_cols; const uword s_n_slices = s.n_slices; - arma_debug_check + arma_debug_check_bounds ( ( in_row1 >= l_n_rows) || ( in_col1 >= l_n_cols) || ( in_slice1 >= l_n_slices) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols) || ((in_slice1 + s_n_slices) > l_n_slices), @@ -1285,7 +1406,7 @@ const uword s_n_cols = s.n_cols; const uword s_n_slices = s.n_slices; - arma_debug_check + arma_debug_check_bounds ( ( in_row1 >= l_n_rows) || ( in_col1 >= l_n_cols) || ( in_slice1 >= l_n_slices) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols) || ((in_slice1 + s_n_slices) > l_n_slices), @@ -1325,7 +1446,7 @@ const uword in_slice2 = slice_span.b; const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -1369,7 +1490,7 @@ const uword in_slice2 = slice_span.b; const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -1440,7 +1561,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= n_rows) || (in_col1 >= n_cols)), "Cube::tube(): indices out of bounds" @@ -1458,7 +1579,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= n_rows) || (in_col1 >= n_cols)), "Cube::tube(): indices out of bounds" @@ -1476,7 +1597,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), @@ -1498,7 +1619,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), @@ -1526,7 +1647,7 @@ const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)), "Cube::tube(): indices or size out of bounds" @@ -1550,7 +1671,7 @@ const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)), "Cube::tube(): indices or size out of bounds" @@ -1582,7 +1703,7 @@ const uword in_col2 = col_span.b; const uword subcube_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -1617,7 +1738,7 @@ const uword in_col2 = col_span.b; const uword subcube_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -1638,7 +1759,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_slices), "Cube::head_slices(): size out of bounds" ); + arma_debug_check_bounds( (N > n_slices), "Cube::head_slices(): size out of bounds" ); return subview_cube(*this, 0, 0, 0, n_rows, n_cols, N); } @@ -1652,7 +1773,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_slices), "Cube::head_slices(): size out of bounds" ); + arma_debug_check_bounds( (N > n_slices), "Cube::head_slices(): size out of bounds" ); return subview_cube(*this, 0, 0, 0, n_rows, n_cols, N); } @@ -1666,7 +1787,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_slices), "Cube::tail_slices(): size out of bounds" ); + arma_debug_check_bounds( (N > n_slices), "Cube::tail_slices(): size out of bounds" ); const uword start_slice = n_slices - N; @@ -1682,7 +1803,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_slices), "Cube::tail_slices(): size out of bounds" ); + arma_debug_check_bounds( (N > n_slices), "Cube::tail_slices(): size out of bounds" ); const uword start_slice = n_slices - N; @@ -1793,109 +1914,106 @@ -#if defined(ARMA_USE_CXX11) +//! apply a lambda function to each slice, where each slice is interpreted as a matrix +template +inline +const Cube& +Cube::each_slice(const std::function< void(Mat&) >& F) + { + arma_extra_debug_sigprint(); - //! apply a lambda function to each slice, where each slice is interpreted as a matrix - template - inline - const Cube& - Cube::each_slice(const std::function< void(Mat&) >& F) + for(uword slice_id=0; slice_id < n_slices; ++slice_id) { - arma_extra_debug_sigprint(); - - for(uword slice_id=0; slice_id < n_slices; ++slice_id) - { - Mat tmp('j', slice_memptr(slice_id), n_rows, n_cols); - - F(tmp); - } + Mat tmp('j', slice_memptr(slice_id), n_rows, n_cols); - return *this; + F(tmp); } + return *this; + } + + + +template +inline +const Cube& +Cube::each_slice(const std::function< void(const Mat&) >& F) const + { + arma_extra_debug_sigprint(); - - template - inline - const Cube& - Cube::each_slice(const std::function< void(const Mat&) >& F) const + for(uword slice_id=0; slice_id < n_slices; ++slice_id) { - arma_extra_debug_sigprint(); + const Mat tmp('j', slice_memptr(slice_id), n_rows, n_cols); - for(uword slice_id=0; slice_id < n_slices; ++slice_id) - { - const Mat tmp('j', slice_memptr(slice_id), n_rows, n_cols); - - F(tmp); - } - - return *this; + F(tmp); } + return *this; + } + + + +template +inline +const Cube& +Cube::each_slice(const std::function< void(Mat&) >& F, const bool use_mp) + { + arma_extra_debug_sigprint(); + if((use_mp == false) || (arma_config::openmp == false)) + { + return (*this).each_slice(F); + } - template - inline - const Cube& - Cube::each_slice(const std::function< void(Mat&) >& F, const bool use_mp) + #if defined(ARMA_USE_OPENMP) { - arma_extra_debug_sigprint(); + const uword local_n_slices = n_slices; + const int n_threads = mp_thread_limit::get(); - if((use_mp == false) || (arma_config::openmp == false)) + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword slice_id=0; slice_id < local_n_slices; ++slice_id) { - return (*this).each_slice(F); - } - - #if defined(ARMA_USE_OPENMP) - { - const uword local_n_slices = n_slices; - const int n_threads = mp_thread_limit::get(); + Mat tmp('j', slice_memptr(slice_id), n_rows, n_cols); - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword slice_id=0; slice_id < local_n_slices; ++slice_id) - { - Mat tmp('j', slice_memptr(slice_id), n_rows, n_cols); - - F(tmp); - } + F(tmp); } - #endif - - return *this; } + #endif + return *this; + } + + + +template +inline +const Cube& +Cube::each_slice(const std::function< void(const Mat&) >& F, const bool use_mp) const + { + arma_extra_debug_sigprint(); + if((use_mp == false) || (arma_config::openmp == false)) + { + return (*this).each_slice(F); + } - template - inline - const Cube& - Cube::each_slice(const std::function< void(const Mat&) >& F, const bool use_mp) const + #if defined(ARMA_USE_OPENMP) { - arma_extra_debug_sigprint(); - - if((use_mp == false) || (arma_config::openmp == false)) - { - return (*this).each_slice(F); - } + const uword local_n_slices = n_slices; + const int n_threads = mp_thread_limit::get(); - #if defined(ARMA_USE_OPENMP) + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword slice_id=0; slice_id < local_n_slices; ++slice_id) { - const uword local_n_slices = n_slices; - const int n_threads = mp_thread_limit::get(); + Mat tmp('j', slice_memptr(slice_id), n_rows, n_cols); - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword slice_id=0; slice_id < local_n_slices; ++slice_id) - { - Mat tmp('j', slice_memptr(slice_id), n_rows, n_cols); - - F(tmp); - } + F(tmp); } - #endif - - return *this; } -#endif + #endif + + return *this; + } @@ -1933,7 +2051,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( row_num >= n_rows, "Cube::shed_row(): index out of bounds"); + arma_debug_check_bounds( row_num >= n_rows, "Cube::shed_row(): index out of bounds" ); shed_rows(row_num, row_num); } @@ -1948,7 +2066,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "Cube::shed_col(): index out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "Cube::shed_col(): index out of bounds" ); shed_cols(col_num, col_num); } @@ -1963,7 +2081,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( slice_num >= n_slices, "Cube::shed_slice(): index out of bounds"); + arma_debug_check_bounds( slice_num >= n_slices, "Cube::shed_slice(): index out of bounds" ); shed_slices(slice_num, slice_num); } @@ -1978,7 +2096,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "Cube::shed_rows(): indices out of bounds or incorrectly used" @@ -1987,7 +2105,7 @@ const uword n_keep_front = in_row1; const uword n_keep_back = n_rows - (in_row2 + 1); - Cube X(n_keep_front + n_keep_back, n_cols, n_slices); + Cube X(n_keep_front + n_keep_back, n_cols, n_slices, arma_nozeros_indicator()); if(n_keep_front > 0) { @@ -2012,7 +2130,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "Cube::shed_cols(): indices out of bounds or incorrectly used" @@ -2021,7 +2139,7 @@ const uword n_keep_front = in_col1; const uword n_keep_back = n_cols - (in_col2 + 1); - Cube X(n_rows, n_keep_front + n_keep_back, n_slices); + Cube X(n_rows, n_keep_front + n_keep_back, n_slices, arma_nozeros_indicator()); if(n_keep_front > 0) { @@ -2046,7 +2164,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_slice1 > in_slice2) || (in_slice2 >= n_slices), "Cube::shed_slices(): indices out of bounds or incorrectly used" @@ -2055,7 +2173,7 @@ const uword n_keep_front = in_slice1; const uword n_keep_back = n_slices - (in_slice2 + 1); - Cube X(n_rows, n_cols, n_keep_front + n_keep_back); + Cube X(n_rows, n_cols, n_keep_front + n_keep_back, arma_nozeros_indicator()); if(n_keep_front > 0) { @@ -2101,11 +2219,11 @@ { for(uword i=0; i= n_slices), "Cube::shed_slices(): indices out of bounds" ); + arma_debug_check_bounds( (slices_to_shed_mem[i] >= n_slices), "Cube::shed_slices(): indices out of bounds" ); } } - Col tmp3(n_slices); + Col tmp3(n_slices, arma_nozeros_indicator()); uword* tmp3_mem = tmp3.memptr(); @@ -2155,11 +2273,11 @@ const uword B_n_rows = t_n_rows - row_num; // insertion at row_num == n_rows is in effect an append operation - arma_debug_check( (row_num > t_n_rows), "Cube::insert_rows(): index out of bounds"); + arma_debug_check_bounds( (row_num > t_n_rows), "Cube::insert_rows(): index out of bounds" ); if(N > 0) { - Cube out(t_n_rows + N, n_cols, n_slices); + Cube out(t_n_rows + N, n_cols, n_slices, arma_nozeros_indicator()); if(A_n_rows > 0) { @@ -2171,7 +2289,7 @@ out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1); } - if(set_to_zero == true) + if(set_to_zero) { out.rows(row_num, row_num + N - 1).zeros(); } @@ -2195,11 +2313,11 @@ const uword B_n_cols = t_n_cols - col_num; // insertion at col_num == n_cols is in effect an append operation - arma_debug_check( (col_num > t_n_cols), "Cube::insert_cols(): index out of bounds"); + arma_debug_check_bounds( (col_num > t_n_cols), "Cube::insert_cols(): index out of bounds" ); if(N > 0) { - Cube out(n_rows, t_n_cols + N, n_slices); + Cube out(n_rows, t_n_cols + N, n_slices, arma_nozeros_indicator()); if(A_n_cols > 0) { @@ -2211,7 +2329,7 @@ out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1); } - if(set_to_zero == true) + if(set_to_zero) { out.cols(col_num, col_num + N - 1).zeros(); } @@ -2237,11 +2355,11 @@ const uword B_n_slices = t_n_slices - slice_num; // insertion at slice_num == n_slices is in effect an append operation - arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): index out of bounds"); + arma_debug_check_bounds( (slice_num > t_n_slices), "Cube::insert_slices(): index out of bounds" ); if(N > 0) { - Cube out(n_rows, n_cols, t_n_slices + N); + Cube out(n_rows, n_cols, t_n_slices + N, arma_nozeros_indicator()); if(A_n_slices > 0) { @@ -2253,7 +2371,7 @@ out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices-1); } - if(set_to_zero == true) + if(set_to_zero) { //out.slices(slice_num, slice_num + N - 1).zeros(); @@ -2288,7 +2406,7 @@ const uword B_n_rows = t_n_rows - row_num; // insertion at row_num == n_rows is in effect an append operation - arma_debug_check( (row_num > t_n_rows), "Cube::insert_rows(): index out of bounds"); + arma_debug_check_bounds( (row_num > t_n_rows), "Cube::insert_rows(): index out of bounds" ); arma_debug_check ( @@ -2298,7 +2416,7 @@ if(N > 0) { - Cube out(t_n_rows + N, n_cols, n_slices); + Cube out(t_n_rows + N, n_cols, n_slices, arma_nozeros_indicator()); if(A_n_rows > 0) { @@ -2337,7 +2455,7 @@ const uword B_n_cols = t_n_cols - col_num; // insertion at col_num == n_cols is in effect an append operation - arma_debug_check( (col_num > t_n_cols), "Cube::insert_cols(): index out of bounds"); + arma_debug_check_bounds( (col_num > t_n_cols), "Cube::insert_cols(): index out of bounds" ); arma_debug_check ( @@ -2347,7 +2465,7 @@ if(N > 0) { - Cube out(n_rows, t_n_cols + N, n_slices); + Cube out(n_rows, t_n_cols + N, n_slices, arma_nozeros_indicator()); if(A_n_cols > 0) { @@ -2388,7 +2506,7 @@ const uword B_n_slices = t_n_slices - slice_num; // insertion at slice_num == n_slices is in effect an append operation - arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): index out of bounds"); + arma_debug_check_bounds( (slice_num > t_n_slices), "Cube::insert_slices(): index out of bounds" ); arma_debug_check ( @@ -2398,7 +2516,7 @@ if(N > 0) { - Cube out(n_rows, n_cols, t_n_slices + N); + Cube out(n_rows, n_cols, t_n_slices + N, arma_nozeros_indicator()); if(A_n_slices > 0) { @@ -2418,7 +2536,7 @@ -//! create a cube from GenCube, i.e. run the previously delayed element generation operations +//! create a cube from GenCube, ie. run the previously delayed element generation operations template template inline @@ -2428,9 +2546,10 @@ , n_elem_slice(X.n_rows*X.n_cols) , n_slices(X.n_slices) , n_elem(X.n_rows*X.n_cols*X.n_slices) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2518,7 +2637,7 @@ -//! create a cube from OpCube, i.e. run the previously delayed unary operations +//! create a cube from OpCube, ie. run the previously delayed unary operations template template inline @@ -2528,9 +2647,10 @@ , n_elem_slice(0) , n_slices(0) , n_elem(0) + , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2541,7 +2661,7 @@ -//! create a cube from OpCube, i.e. run the previously delayed unary operations +//! create a cube from OpCube, ie. run the previously delayed unary operations template template inline @@ -2631,7 +2751,7 @@ -//! create a cube from eOpCube, i.e. run the previously delayed unary operations +//! create a cube from eOpCube, ie. run the previously delayed unary operations template template inline @@ -2641,9 +2761,10 @@ , n_elem_slice(X.get_n_elem_slice()) , n_slices(X.get_n_slices()) , n_elem(X.get_n_elem()) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2656,7 +2777,7 @@ -//! create a cube from eOpCube, i.e. run the previously delayed unary operations +//! create a cube from eOpCube, ie. run the previously delayed unary operations template template inline @@ -2768,9 +2889,10 @@ , n_elem_slice(0) , n_slices(0) , n_elem(0) + , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2854,7 +2976,7 @@ -//! create a cube from GlueCube, i.e. run the previously delayed binary operations +//! create a cube from GlueCube, ie. run the previously delayed binary operations template template inline @@ -2864,17 +2986,19 @@ , n_elem_slice(0) , n_slices(0) , n_elem(0) + , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); + this->operator=(X); } -//! create a cube from GlueCube, i.e. run the previously delayed binary operations +//! create a cube from GlueCube, ie. run the previously delayed binary operations template template inline @@ -2968,7 +3092,7 @@ -//! create a cube from eGlueCube, i.e. run the previously delayed binary operations +//! create a cube from eGlueCube, ie. run the previously delayed binary operations template template inline @@ -2978,9 +3102,10 @@ , n_elem_slice(X.get_n_elem_slice()) , n_slices(X.get_n_slices()) , n_elem(X.get_n_elem()) + , n_alloc() , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2994,7 +3119,7 @@ -//! create a cube from eGlueCube, i.e. run the previously delayed binary operations +//! create a cube from eGlueCube, ie. run the previously delayed binary operations template template inline @@ -3111,9 +3236,10 @@ , n_elem_slice(0) , n_slices(0) , n_elem(0) + , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(0) + , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -3205,6 +3331,7 @@ Cube::at_alt(const uword i) const { const eT* mem_aligned = mem; + memory::mark_as_aligned(mem_aligned); return mem_aligned[i]; @@ -3219,7 +3346,8 @@ eT& Cube::operator() (const uword i) { - arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds"); + arma_debug_check_bounds( (i >= n_elem), "Cube::operator(): index out of bounds" ); + return access::rw(mem[i]); } @@ -3232,7 +3360,8 @@ const eT& Cube::operator() (const uword i) const { - arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds"); + arma_debug_check_bounds( (i >= n_elem), "Cube::operator(): index out of bounds" ); + return mem[i]; } @@ -3292,7 +3421,7 @@ eT& Cube::operator() (const uword in_row, const uword in_col, const uword in_slice) { - arma_debug_check + arma_debug_check_bounds ( (in_row >= n_rows) || (in_col >= n_cols) || @@ -3313,7 +3442,7 @@ const eT& Cube::operator() (const uword in_row, const uword in_col, const uword in_slice) const { - arma_debug_check + arma_debug_check_bounds ( (in_row >= n_rows) || (in_col >= n_cols) || @@ -3358,6 +3487,7 @@ Cube::operator++() { Cube_aux::prefix_pp(*this); + return *this; } @@ -3470,7 +3600,7 @@ { arma_extra_debug_sigprint(); - if(x.whole == true) + if(x.whole) { return true; } @@ -3520,7 +3650,7 @@ const bool slices_ok = slice_span.whole ? true : ( (in_slice1 <= in_slice2) && (in_slice2 < n_slices) ); - return ( (rows_ok == true) && (cols_ok == true) && (slices_ok == true) ); + return ( rows_ok && cols_ok && slices_ok ); } @@ -3622,102 +3752,15 @@ -//! print contents of the cube (to the cout stream), -//! optionally preceding with a user specified line of text. -//! the precision and cell width are modified. -//! on return, the stream's state are restored to their original values. -template -arma_cold -inline -void -Cube::impl_print(const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - if(extra_text.length() != 0) - { - get_cout_stream() << extra_text << '\n'; - } - - arma_ostream::print(get_cout_stream(), *this, true); - } - - -//! print contents of the cube to a user specified stream, -//! optionally preceding with a user specified line of text. -//! the precision and cell width are modified. -//! on return, the stream's state are restored to their original values. -template -arma_cold -inline -void -Cube::impl_print(std::ostream& user_stream, const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - if(extra_text.length() != 0) - { - user_stream << extra_text << '\n'; - } - - arma_ostream::print(user_stream, *this, true); - } - - - -//! print contents of the cube (to the cout stream), -//! optionally preceding with a user specified line of text. -//! the stream's state are used as is and are not modified -//! (i.e. the precision and cell width are not modified). -template -arma_cold -inline -void -Cube::impl_raw_print(const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - if(extra_text.length() != 0) - { - get_cout_stream() << extra_text << '\n'; - } - - arma_ostream::print(get_cout_stream(), *this, false); - } - - - -//! print contents of the cube to a user specified stream, -//! optionally preceding with a user specified line of text. -//! the stream's state are used as is and are not modified. -//! (i.e. the precision and cell width are not modified). -template -arma_cold -inline -void -Cube::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - if(extra_text.length() != 0) - { - user_stream << extra_text << '\n'; - } - - arma_ostream::print(user_stream, *this, false); - } - - - //! change the cube to have user specified dimensions (data is not preserved) template inline void -Cube::set_size(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) +Cube::set_size(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - init_warm(in_n_rows, in_n_cols, in_n_slices); + init_warm(new_n_rows, new_n_cols, new_n_slices); } @@ -3726,25 +3769,11 @@ template inline void -Cube::reshape(const uword in_rows, const uword in_cols, const uword in_slices) +Cube::reshape(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - *this = arma::reshape(*this, in_rows, in_cols, in_slices); - } - - - -//! NOTE: don't use this form; it's deprecated and will be removed -template -arma_deprecated -inline -void -Cube::reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim) - { - arma_extra_debug_sigprint(); - - *this = arma::reshape(*this, in_rows, in_cols, in_slices, dim); + op_reshape::apply_cube_inplace((*this), new_n_rows, new_n_cols, new_n_slices); } @@ -3753,11 +3782,11 @@ template inline void -Cube::resize(const uword in_rows, const uword in_cols, const uword in_slices) +Cube::resize(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - *this = arma::resize(*this, in_rows, in_cols, in_slices); + op_resize::apply_cube_inplace((*this), new_n_rows, new_n_cols, new_n_slices); } @@ -3781,7 +3810,7 @@ { arma_extra_debug_sigprint(); - *this = arma::reshape(*this, s.n_rows, s.n_cols, s.n_slices, 0); + op_reshape::apply_cube_inplace((*this), s.n_rows, s.n_cols, s.n_slices); } @@ -3793,7 +3822,7 @@ { arma_extra_debug_sigprint(); - *this = arma::resize(*this, s.n_rows, s.n_cols, s.n_slices); + op_resize::apply_cube_inplace((*this), s.n_rows, s.n_cols, s.n_slices); } @@ -3972,6 +4001,30 @@ +template +inline +const Cube& +Cube::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + if(is_cx::no) + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): min_val must be less than max_val" ); + } + else + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" ); + } + + arrayops::clamp(memptr(), n_elem, min_val, max_val); + + return *this; + } + + + //! fill the cube with the specified value template inline @@ -4004,11 +4057,11 @@ template inline const Cube& -Cube::zeros(const uword in_rows, const uword in_cols, const uword in_slices) +Cube::zeros(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - set_size(in_rows, in_cols, in_slices); + set_size(new_n_rows, new_n_cols, new_n_slices); return (*this).zeros(); } @@ -4042,11 +4095,11 @@ template inline const Cube& -Cube::ones(const uword in_rows, const uword in_cols, const uword in_slices) +Cube::ones(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - set_size(in_rows, in_cols, in_slices); + set_size(new_n_rows, new_n_cols, new_n_slices); return (*this).fill(eT(1)); } @@ -4082,11 +4135,11 @@ template inline const Cube& -Cube::randu(const uword in_rows, const uword in_cols, const uword in_slices) +Cube::randu(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - set_size(in_rows, in_cols, in_slices); + set_size(new_n_rows, new_n_cols, new_n_slices); return (*this).randu(); } @@ -4122,11 +4175,11 @@ template inline const Cube& -Cube::randn(const uword in_rows, const uword in_cols, const uword in_slices) +Cube::randn(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - set_size(in_rows, in_cols, in_slices); + set_size(new_n_rows, new_n_cols, new_n_slices); return (*this).randn(); } @@ -4171,7 +4224,7 @@ } else { - fill(Datum::nan); + zeros(); } } @@ -4360,7 +4413,7 @@ inline arma_cold bool -Cube::save(const std::string name, const file_type type, const bool print_status) const +Cube::save(const std::string name, const file_type type) const { arma_extra_debug_sigprint(); @@ -4397,11 +4450,11 @@ break; default: - if(print_status) { arma_debug_warn("Cube::save(): unsupported file type"); } + arma_debug_warn_level(1, "Cube::save(): unsupported file type"); save_okay = false; } - if(print_status && (save_okay == false)) { arma_debug_warn("Cube::save(): couldn't write to ", name); } + if(save_okay == false) { arma_debug_warn_level(3, "Cube::save(): couldn't write; file: ", name); } return save_okay; } @@ -4412,7 +4465,7 @@ inline arma_cold bool -Cube::save(const hdf5_name& spec, const file_type type, const bool print_status) const +Cube::save(const hdf5_name& spec, const file_type type) const { arma_extra_debug_sigprint(); @@ -4420,7 +4473,7 @@ if( (type != hdf5_binary) && (type != hdf5_binary_trans) ) { - arma_debug_check(true, "Cube::save(): unsupported file type for hdf5_name()"); + arma_stop_runtime_error("Cube::save(): unsupported file type for hdf5_name()"); return false; } @@ -4430,7 +4483,7 @@ if(append && replace) { - arma_debug_check(true, "Cube::save(): only one of 'append' or 'replace' options can be used"); + arma_stop_runtime_error("Cube::save(): only one of 'append' or 'replace' options can be used"); return false; } @@ -4450,15 +4503,15 @@ save_okay = diskio::save_hdf5_binary(*this, spec, err_msg); } - if((print_status == true) && (save_okay == false)) + if(save_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("Cube::save(): ", err_msg, spec.filename); + arma_debug_warn_level(3, "Cube::save(): ", err_msg, "; file: ", spec.filename); } else { - arma_debug_warn("Cube::save(): couldn't write to ", spec.filename); + arma_debug_warn_level(3, "Cube::save(): couldn't write; file: ", spec.filename); } } @@ -4472,7 +4525,7 @@ inline arma_cold bool -Cube::save(std::ostream& os, const file_type type, const bool print_status) const +Cube::save(std::ostream& os, const file_type type) const { arma_extra_debug_sigprint(); @@ -4501,11 +4554,11 @@ break; default: - if(print_status) { arma_debug_warn("Cube::save(): unsupported file type"); } + arma_debug_warn_level(1, "Cube::save(): unsupported file type"); save_okay = false; } - if(print_status && (save_okay == false)) { arma_debug_warn("Cube::save(): couldn't write to given stream"); } + if(save_okay == false) { arma_debug_warn_level(3, "Cube::save(): couldn't write to stream"); } return save_okay; } @@ -4517,7 +4570,7 @@ inline arma_cold bool -Cube::load(const std::string name, const file_type type, const bool print_status) +Cube::load(const std::string name, const file_type type) { arma_extra_debug_sigprint(); @@ -4559,27 +4612,24 @@ break; default: - if(print_status) { arma_debug_warn("Cube::load(): unsupported file type"); } + arma_debug_warn_level(1, "Cube::load(): unsupported file type"); load_okay = false; } - if( (print_status == true) && (load_okay == false) ) + if(load_okay == false) { + (*this).soft_reset(); + if(err_msg.length() > 0) { - arma_debug_warn("Cube::load(): ", err_msg, name); + arma_debug_warn_level(3, "Cube::load(): ", err_msg, "; file: ", name); } else { - arma_debug_warn("Cube::load(): couldn't read ", name); + arma_debug_warn_level(3, "Cube::load(): couldn't read; file: ", name); } } - if(load_okay == false) - { - (*this).soft_reset(); - } - return load_okay; } @@ -4589,14 +4639,13 @@ inline arma_cold bool -Cube::load(const hdf5_name& spec, const file_type type, const bool print_status) +Cube::load(const hdf5_name& spec, const file_type type) { arma_extra_debug_sigprint(); if( (type != hdf5_binary) && (type != hdf5_binary_trans) ) { - if(print_status) { arma_debug_warn("Cube::load(): unsupported file type for hdf5_name()"); } - (*this).soft_reset(); + arma_stop_runtime_error("Cube::load(): unsupported file type for hdf5_name()"); return false; } @@ -4619,23 +4668,20 @@ } - if( (print_status == true) && (load_okay == false) ) + if(load_okay == false) { + (*this).soft_reset(); + if(err_msg.length() > 0) { - arma_debug_warn("Cube::load(): ", err_msg, spec.filename); + arma_debug_warn_level(3, "Cube::load(): ", err_msg, "; file: ", spec.filename); } else { - arma_debug_warn("Cube::load(): couldn't read ", spec.filename); + arma_debug_warn_level(3, "Cube::load(): couldn't read; file: ", spec.filename); } } - if(load_okay == false) - { - (*this).soft_reset(); - } - return load_okay; } @@ -4646,7 +4692,7 @@ inline arma_cold bool -Cube::load(std::istream& is, const file_type type, const bool print_status) +Cube::load(std::istream& is, const file_type type) { arma_extra_debug_sigprint(); @@ -4680,33 +4726,29 @@ break; default: - if(print_status) { arma_debug_warn("Cube::load(): unsupported file type"); } + arma_debug_warn_level(1, "Cube::load(): unsupported file type"); load_okay = false; } - if( (print_status == true) && (load_okay == false) ) + if(load_okay == false) { + (*this).soft_reset(); + if(err_msg.length() > 0) { - arma_debug_warn("Cube::load(): ", err_msg, "the given stream"); + arma_debug_warn_level(3, "Cube::load(): ", err_msg); } else { - arma_debug_warn("Cube::load(): couldn't load from the given stream"); + arma_debug_warn_level(3, "Cube::load(): couldn't load from stream"); } } - if(load_okay == false) - { - (*this).soft_reset(); - } - return load_okay; } -//! save the cube to a file, without printing any error messages template inline arma_cold @@ -4715,7 +4757,7 @@ { arma_extra_debug_sigprint(); - return (*this).save(name, type, false); + return (*this).save(name, type); } @@ -4728,12 +4770,11 @@ { arma_extra_debug_sigprint(); - return (*this).save(spec, type, false); + return (*this).save(spec, type); } -//! save the cube to a stream, without printing any error messages template inline arma_cold @@ -4742,12 +4783,11 @@ { arma_extra_debug_sigprint(); - return (*this).save(os, type, false); + return (*this).save(os, type); } -//! load a cube from a file, without printing any error messages template inline arma_cold @@ -4756,7 +4796,7 @@ { arma_extra_debug_sigprint(); - return (*this).load(name, type, false); + return (*this).load(name, type); } @@ -4769,12 +4809,11 @@ { arma_extra_debug_sigprint(); - return (*this).load(spec, type, false); + return (*this).load(spec, type); } -//! load a cube from a stream, without printing any error messages template inline arma_cold @@ -4783,7 +4822,7 @@ { arma_extra_debug_sigprint(); - return (*this).load(is, type, false); + return (*this).load(is, type); } @@ -4867,7 +4906,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds"); + arma_debug_check_bounds( (slice_num >= n_slices), "begin_slice(): index out of bounds" ); return slice_memptr(slice_num); } @@ -4881,7 +4920,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds"); + arma_debug_check_bounds( (slice_num >= n_slices), "begin_slice(): index out of bounds" ); return slice_memptr(slice_num); } @@ -4895,7 +4934,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds"); + arma_debug_check_bounds( (slice_num >= n_slices), "end_slice(): index out of bounds" ); return slice_memptr(slice_num) + n_elem_slice; } @@ -4909,7 +4948,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds"); + arma_debug_check_bounds( (slice_num >= n_slices), "end_slice(): index out of bounds" ); return slice_memptr(slice_num) + n_elem_slice; } @@ -4951,6 +4990,58 @@ template inline +arma_warn_unused +eT& +Cube::front() + { + arma_debug_check( (n_elem == 0), "Cube::front(): cube is empty" ); + + return access::rw(mem[0]); + } + + + +template +inline +arma_warn_unused +const eT& +Cube::front() const + { + arma_debug_check( (n_elem == 0), "Cube::front(): cube is empty" ); + + return mem[0]; + } + + + +template +inline +arma_warn_unused +eT& +Cube::back() + { + arma_debug_check( (n_elem == 0), "Cube::back(): cube is empty" ); + + return access::rw(mem[n_elem-1]); + } + + + +template +inline +arma_warn_unused +const eT& +Cube::back() const + { + arma_debug_check( (n_elem == 0), "Cube::back(): cube is empty" ); + + return mem[n_elem-1]; + } + + + +template +inline void Cube::swap(Cube& B) { @@ -5029,7 +5120,7 @@ if(this == &x) { return; } - if( (mem_state <= 1) && ( ((x.mem_state == 0) && (x.n_elem > Cube_prealloc::mem_n_elem)) || (x.mem_state == 1) ) ) + if( (mem_state <= 1) && ( (x.n_alloc > Cube_prealloc::mem_n_elem) || (x.mem_state == 1) ) ) { reset(); @@ -5040,13 +5131,14 @@ access::rw(n_elem_slice) = x.n_elem_slice; access::rw(n_slices) = x_n_slices; access::rw(n_elem) = x.n_elem; + access::rw(n_alloc) = x.n_alloc; access::rw(mem_state) = x.mem_state; access::rw(mem) = x.mem; if(x_n_slices > Cube_prealloc::mat_ptrs_size) { access::rw( mat_ptrs) = x.mat_ptrs; - access::rw(x.mat_ptrs) = 0; + access::rw(x.mat_ptrs) = nullptr; } else { @@ -5055,7 +5147,7 @@ for(uword i=0; i < x_n_slices; ++i) { mat_ptrs[i] = x.mat_ptrs[i]; - x.mat_ptrs[i] = 0; + x.mat_ptrs[i] = nullptr; } } @@ -5064,8 +5156,9 @@ access::rw(x.n_elem_slice) = 0; access::rw(x.n_slices) = 0; access::rw(x.n_elem) = 0; + access::rw(x.n_alloc) = 0; access::rw(x.mem_state) = 0; - access::rw(x.mem) = 0; + access::rw(x.mem) = nullptr; } else { @@ -5095,6 +5188,7 @@ access::rw(Cube::n_elem_slice) = fixed_n_rows * fixed_n_cols; access::rw(Cube::n_slices) = fixed_n_slices; access::rw(Cube::n_elem) = fixed_n_elem; + access::rw(Cube::n_alloc) = 0; access::rw(Cube::mem_state) = 3; access::rw(Cube::mem) = (fixed_n_elem > Cube_prealloc::mem_n_elem) ? mem_local_extra : mem_local; access::rw(Cube::mat_ptrs) = const_cast< const Mat** >( \ @@ -5109,9 +5203,10 @@ access::rw(Cube::n_elem_slice) = 0; access::rw(Cube::n_slices) = 0; access::rw(Cube::n_elem) = 0; + access::rw(Cube::n_alloc) = 0; access::rw(Cube::mem_state) = 3; - access::rw(Cube::mem) = 0; - access::rw(Cube::mat_ptrs) = 0; + access::rw(Cube::mem) = nullptr; + access::rw(Cube::mat_ptrs) = nullptr; } } @@ -5125,6 +5220,16 @@ arma_extra_debug_sigprint_this(this); mem_setup(); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Cube::fixed::constructor: zeroing memory"); + + eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]); + + arrayops::fill_zeros(mem_use, fixed_n_elem); + } + #endif } @@ -5148,6 +5253,20 @@ template template +inline +Cube::fixed::fixed(const fill::scalar_holder f) + { + arma_extra_debug_sigprint_this(this); + + mem_setup(); + + (*this).fill(f.scalar); + } + + + +template +template template inline Cube::fixed::fixed(const fill::fill_class&) @@ -5156,12 +5275,12 @@ mem_setup(); - if(is_same_type::yes) (*this).zeros(); - if(is_same_type::yes) (*this).ones(); - if(is_same_type::yes) (*this).randu(); - if(is_same_type::yes) (*this).randn(); + if(is_same_type::yes) { (*this).zeros(); } + if(is_same_type::yes) { (*this).ones(); } + if(is_same_type::yes) { (*this).randu(); } + if(is_same_type::yes) { (*this).randn(); } - if(is_same_type::yes) { arma_debug_check(true, "Cube::fixed::fixed(): unsupported fill type"); } + arma_static_check( (is_same_type::yes), "Cube::fixed::fixed(): unsupported fill type" ); } @@ -5269,7 +5388,7 @@ eT& Cube::fixed::operator() (const uword i) { - arma_debug_check( (i >= fixed_n_elem), "Cube::operator(): index out of bounds"); + arma_debug_check_bounds( (i >= fixed_n_elem), "Cube::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[i] : mem_local[i]; } @@ -5283,7 +5402,7 @@ const eT& Cube::fixed::operator() (const uword i) const { - arma_debug_check( (i >= fixed_n_elem), "Cube::operator(): index out of bounds"); + arma_debug_check_bounds( (i >= fixed_n_elem), "Cube::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[i] : mem_local[i]; } @@ -5325,7 +5444,7 @@ eT& Cube::fixed::operator() (const uword in_row, const uword in_col, const uword in_slice) { - arma_debug_check + arma_debug_check_bounds ( (in_row >= fixed_n_rows ) || (in_col >= fixed_n_cols ) || @@ -5348,7 +5467,7 @@ const eT& Cube::fixed::operator() (const uword in_row, const uword in_col, const uword in_slice) const { - arma_debug_check + arma_debug_check_bounds ( (in_row >= fixed_n_rows ) || (in_col >= fixed_n_cols ) || diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/CubeToMatOp_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/CubeToMatOp_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/CubeToMatOp_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/CubeToMatOp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,7 +22,7 @@ template -class CubeToMatOp : public Base > +class CubeToMatOp : public Base< typename T1::elem_type, CubeToMatOp > { public: @@ -34,9 +36,9 @@ arma_aligned const T1& m; //!< the operand; must be derived from BaseCube arma_aligned elem_type aux; //!< auxiliary data, using the element type as used by T1 - static const bool is_row = op_type::template traits::is_row; - static const bool is_col = op_type::template traits::is_col; - static const bool is_xvec = op_type::template traits::is_xvec; + static constexpr bool is_row = op_type::template traits::is_row; + static constexpr bool is_col = op_type::template traits::is_col; + static constexpr bool is_xvec = op_type::template traits::is_xvec; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/CubeToMatOp_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/CubeToMatOp_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/CubeToMatOp_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/CubeToMatOp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/debug.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/debug.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/debug.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/debug.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,7 +28,7 @@ { static std::ostream* cout_stream = &(ARMA_COUT_STREAM); - if(user_stream != NULL) { cout_stream = user_stream; } + if(user_stream != nullptr) { cout_stream = user_stream; } return (*cout_stream); } @@ -40,7 +42,7 @@ { static std::ostream* cerr_stream = &(ARMA_CERR_STREAM); - if(user_stream != NULL) { cerr_stream = user_stream; } + if(user_stream != nullptr) { cerr_stream = user_stream; } return (*cerr_stream); } @@ -69,7 +71,7 @@ std::ostream& get_cout_stream() { - return arma_cout_stream(NULL); + return arma_cout_stream(nullptr); } @@ -78,7 +80,7 @@ std::ostream& get_cerr_stream() { - return arma_cerr_stream(NULL); + return arma_cerr_stream(nullptr); } @@ -135,7 +137,7 @@ void arma_stop_logic_error(const T1& x) { - #if defined(ARMA_PRINT_ERRORS) + #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS)) { get_cerr_stream() << "\nerror: " << x << std::endl; } @@ -146,6 +148,36 @@ +arma_cold +arma_noinline +static +void +arma_stop_logic_error(const char* x, const char* y) + { + arma_stop_logic_error( std::string(x) + std::string(y) ); + } + + + +//! print a message to get_cerr_stream() and throw logic_error exception +template +arma_cold +arma_noinline +static +void +arma_stop_bounds_error(const T1& x) + { + #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS)) + { + get_cerr_stream() << "\nerror: " << x << std::endl; + } + #endif + + throw std::out_of_range( std::string(x) ); + } + + + //! print a message to get_cerr_stream() and throw bad_alloc exception template arma_cold @@ -154,7 +186,7 @@ void arma_stop_bad_alloc(const T1& x) { - #if defined(ARMA_PRINT_ERRORS) + #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS)) { get_cerr_stream() << "\nerror: " << x << std::endl; } @@ -177,7 +209,7 @@ void arma_stop_runtime_error(const T1& x) { - #if defined(ARMA_PRINT_ERRORS) + #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS)) { get_cerr_stream() << "\nerror: " << x << std::endl; } @@ -313,15 +345,15 @@ arma_noinline static void -arma_warn(const T1& x) +arma_warn(const T1& arg1) { #if defined(ARMA_PRINT_ERRORS) { - get_cerr_stream() << "\nwarning: " << x << '\n'; + get_cerr_stream() << "\nwarning: " << arg1 << '\n'; } #else { - arma_ignore(x); + arma_ignore(arg1); } #endif } @@ -332,16 +364,16 @@ arma_noinline static void -arma_warn(const T1& x, const T2& y) +arma_warn(const T1& arg1, const T2& arg2) { #if defined(ARMA_PRINT_ERRORS) { - get_cerr_stream() << "\nwarning: " << x << y << '\n'; + get_cerr_stream() << "\nwarning: " << arg1 << arg2 << '\n'; } #else { - arma_ignore(x); - arma_ignore(y); + arma_ignore(arg1); + arma_ignore(arg2); } #endif } @@ -352,17 +384,39 @@ arma_noinline static void -arma_warn(const T1& x, const T2& y, const T3& z) +arma_warn(const T1& arg1, const T2& arg2, const T3& arg3) { #if defined(ARMA_PRINT_ERRORS) { - get_cerr_stream() << "\nwarning: " << x << y << z << '\n'; + get_cerr_stream() << "\nwarning: " << arg1 << arg2 << arg3 << '\n'; } #else { - arma_ignore(x); - arma_ignore(y); - arma_ignore(z); + arma_ignore(arg1); + arma_ignore(arg2); + arma_ignore(arg3); + } + #endif + } + + +template +arma_cold +arma_noinline +static +void +arma_warn(const T1& arg1, const T2& arg2, const T3& arg3, const T4& arg4) + { + #if defined(ARMA_PRINT_ERRORS) + { + get_cerr_stream() << "\nwarning: " << arg1 << arg2 << arg3 << arg4 << '\n'; + } + #else + { + arma_ignore(arg1); + arma_ignore(arg2); + arma_ignore(arg3); + arma_ignore(arg4); } #endif } @@ -370,6 +424,55 @@ // +// arma_warn_level + + +template +inline +void +arma_warn_level(const uword level, const T1& arg1) + { + constexpr uword config_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : uword(0); + + if((config_level > 0) && (level <= config_level)) { arma_warn(arg1); } + } + + +template +inline +void +arma_warn_level(const uword level, const T1& arg1, const T2& arg2) + { + constexpr uword config_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : uword(0); + + if((config_level > 0) && (level <= config_level)) { arma_warn(arg1,arg2); } + } + + +template +inline +void +arma_warn_level(const uword level, const T1& arg1, const T2& arg2, const T3& arg3) + { + constexpr uword config_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : uword(0); + + if((config_level > 0) && (level <= config_level)) { arma_warn(arg1,arg2,arg3); } + } + + +template +inline +void +arma_warn_level(const uword level, const T1& arg1, const T2& arg2, const T3& arg3, const T4& arg4) + { + constexpr uword config_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : uword(0); + + if((config_level > 0) && (level <= config_level)) { arma_warn(arg1,arg2,arg3,arg4); } + } + + + +// // arma_check //! if state is true, abort program @@ -383,13 +486,22 @@ } -template arma_hot inline void -arma_check(const bool state, const T1& x, const T2& y) +arma_check(const bool state, const char* x, const char* y) { - if(state) { arma_stop_logic_error( std::string(x) + std::string(y) ); } + if(state) { arma_stop_logic_error(x,y); } + } + + +template +arma_hot +inline +void +arma_check_bounds(const bool state, const T1& x) + { + if(state) { arma_stop_bounds_error(arma_str::str_wrapper(x)); } } @@ -780,6 +892,28 @@ +template +arma_hot +inline +void +arma_assert_same_size(const subview_cube& A, const ProxyCube& B, const char* x) + { + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + const uword A_n_slices = A.n_slices; + + const uword B_n_rows = B.get_n_rows(); + const uword B_n_cols = B.get_n_cols(); + const uword B_n_slices = B.get_n_slices(); + + if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices) ) + { + arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) ); + } + } + + + //! stop if given cube proxies have different sizes template arma_hot @@ -804,7 +938,7 @@ // -// functions for checking whether a cube or subcube can be interpreted as a matrix (i.e. single slice) +// functions for checking whether a cube or subcube can be interpreted as a matrix (ie. single slice) @@ -1236,11 +1370,11 @@ #if defined(ARMA_NO_DEBUG) - #undef ARMA_EXTRA_DEBUG - #define arma_debug_print true ? (void)0 : arma_print #define arma_debug_warn true ? (void)0 : arma_warn + #define arma_debug_warn_level true ? (void)0 : arma_warn_level #define arma_debug_check true ? (void)0 : arma_check + #define arma_debug_check_bounds true ? (void)0 : arma_check_bounds #define arma_debug_set_error true ? (void)0 : arma_set_error #define arma_debug_assert_same_size true ? (void)0 : arma_assert_same_size #define arma_debug_assert_mul_size true ? (void)0 : arma_assert_mul_size @@ -1253,7 +1387,9 @@ #define arma_debug_print arma_print #define arma_debug_warn arma_warn + #define arma_debug_warn_level arma_warn_level #define arma_debug_check arma_check + #define arma_debug_check_bounds arma_check_bounds #define arma_debug_set_error arma_set_error #define arma_debug_assert_same_size arma_assert_same_size #define arma_debug_assert_mul_size arma_assert_mul_size @@ -1268,19 +1404,18 @@ #if defined(ARMA_EXTRA_DEBUG) + #undef ARMA_WARN_LEVEL + #define ARMA_WARN_LEVEL 3 + #define arma_extra_debug_sigprint arma_sigprint(ARMA_FNSIG); arma_bktprint #define arma_extra_debug_sigprint_this arma_sigprint(ARMA_FNSIG); arma_thisprint #define arma_extra_debug_print arma_print - #define arma_extra_debug_warn arma_warn - #define arma_extra_debug_check arma_check #else #define arma_extra_debug_sigprint true ? (void)0 : arma_bktprint #define arma_extra_debug_sigprint_this true ? (void)0 : arma_thisprint #define arma_extra_debug_print true ? (void)0 : arma_print - #define arma_extra_debug_warn true ? (void)0 : arma_warn - #define arma_extra_debug_check true ? (void)0 : arma_check #endif @@ -1317,7 +1452,9 @@ << " (" << nickname << ")\n"; out << "@ arma_config::wrapper = " << arma_config::wrapper << '\n'; - out << "@ arma_config::cxx11 = " << arma_config::cxx11 << '\n'; + out << "@ arma_config::cxx14 = " << arma_config::cxx14 << '\n'; + out << "@ arma_config::cxx17 = " << arma_config::cxx17 << '\n'; + out << "@ arma_config::std_mutex = " << arma_config::std_mutex << '\n'; out << "@ arma_config::posix = " << arma_config::posix << '\n'; out << "@ arma_config::openmp = " << arma_config::openmp << '\n'; out << "@ arma_config::lapack = " << arma_config::lapack << '\n'; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/def_arpack.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/def_arpack.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/def_arpack.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/def_arpack.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/def_atlas.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/def_atlas.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/def_atlas.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/def_atlas.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/def_blas.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/def_blas.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/def_blas.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/def_blas.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,6 +24,16 @@ #pragma message ("WARNING: include the armadillo header before any other header as a workaround") #endif + +#if defined(ARMA_BLAS_NOEXCEPT) + #undef ARMA_NOEXCEPT + #define ARMA_NOEXCEPT noexcept +#else + #undef ARMA_NOEXCEPT + #define ARMA_NOEXCEPT +#endif + + #if !defined(ARMA_BLAS_CAPITALS) #define arma_sasum sasum @@ -87,62 +99,63 @@ { #if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS) - float arma_fortran(arma_sasum)(const blas_int* n, const float* x, const blas_int* incx); - double arma_fortran(arma_dasum)(const blas_int* n, const double* x, const blas_int* incx); + float arma_fortran(arma_sasum)(const blas_int* n, const float* x, const blas_int* incx) ARMA_NOEXCEPT; + double arma_fortran(arma_dasum)(const blas_int* n, const double* x, const blas_int* incx) ARMA_NOEXCEPT; - float arma_fortran(arma_snrm2)(const blas_int* n, const float* x, const blas_int* incx); - double arma_fortran(arma_dnrm2)(const blas_int* n, const double* x, const blas_int* incx); + float arma_fortran(arma_snrm2)(const blas_int* n, const float* x, const blas_int* incx) ARMA_NOEXCEPT; + double arma_fortran(arma_dnrm2)(const blas_int* n, const double* x, const blas_int* incx) ARMA_NOEXCEPT; - float arma_fortran(arma_sdot)(const blas_int* n, const float* x, const blas_int* incx, const float* y, const blas_int* incy); - double arma_fortran(arma_ddot)(const blas_int* n, const double* x, const blas_int* incx, const double* y, const blas_int* incy); + float arma_fortran(arma_sdot)(const blas_int* n, const float* x, const blas_int* incx, const float* y, const blas_int* incy) ARMA_NOEXCEPT; + double arma_fortran(arma_ddot)(const blas_int* n, const double* x, const blas_int* incx, const double* y, const blas_int* incy) ARMA_NOEXCEPT; - void arma_fortran(arma_sgemv)(const char* transA, const blas_int* m, const blas_int* n, const float* alpha, const float* A, const blas_int* ldA, const float* x, const blas_int* incx, const float* beta, float* y, const blas_int* incy, blas_len transA_len); - void arma_fortran(arma_dgemv)(const char* transA, const blas_int* m, const blas_int* n, const double* alpha, const double* A, const blas_int* ldA, const double* x, const blas_int* incx, const double* beta, double* y, const blas_int* incy, blas_len transA_len); - void arma_fortran(arma_cgemv)(const char* transA, const blas_int* m, const blas_int* n, const blas_cxf* alpha, const blas_cxf* A, const blas_int* ldA, const blas_cxf* x, const blas_int* incx, const blas_cxf* beta, blas_cxf* y, const blas_int* incy, blas_len transA_len); - void arma_fortran(arma_zgemv)(const char* transA, const blas_int* m, const blas_int* n, const blas_cxd* alpha, const blas_cxd* A, const blas_int* ldA, const blas_cxd* x, const blas_int* incx, const blas_cxd* beta, blas_cxd* y, const blas_int* incy, blas_len transA_len); - - void arma_fortran(arma_sgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const float* alpha, const float* A, const blas_int* ldA, const float* B, const blas_int* ldB, const float* beta, float* C, const blas_int* ldC, blas_len transA_len, blas_len transB_len); - void arma_fortran(arma_dgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* B, const blas_int* ldB, const double* beta, double* C, const blas_int* ldC, blas_len transA_len, blas_len transB_len); - void arma_fortran(arma_cgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const blas_cxf* alpha, const blas_cxf* A, const blas_int* ldA, const blas_cxf* B, const blas_int* ldB, const blas_cxf* beta, blas_cxf* C, const blas_int* ldC, blas_len transA_len, blas_len transB_len); - void arma_fortran(arma_zgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const blas_cxd* alpha, const blas_cxd* A, const blas_int* ldA, const blas_cxd* B, const blas_int* ldB, const blas_cxd* beta, blas_cxd* C, const blas_int* ldC, blas_len transA_len, blas_len transB_len); + void arma_fortran(arma_sgemv)(const char* transA, const blas_int* m, const blas_int* n, const float* alpha, const float* A, const blas_int* ldA, const float* x, const blas_int* incx, const float* beta, float* y, const blas_int* incy, blas_len transA_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgemv)(const char* transA, const blas_int* m, const blas_int* n, const double* alpha, const double* A, const blas_int* ldA, const double* x, const blas_int* incx, const double* beta, double* y, const blas_int* incy, blas_len transA_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cgemv)(const char* transA, const blas_int* m, const blas_int* n, const blas_cxf* alpha, const blas_cxf* A, const blas_int* ldA, const blas_cxf* x, const blas_int* incx, const blas_cxf* beta, blas_cxf* y, const blas_int* incy, blas_len transA_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgemv)(const char* transA, const blas_int* m, const blas_int* n, const blas_cxd* alpha, const blas_cxd* A, const blas_int* ldA, const blas_cxd* x, const blas_int* incx, const blas_cxd* beta, blas_cxd* y, const blas_int* incy, blas_len transA_len) ARMA_NOEXCEPT; + + void arma_fortran(arma_sgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const float* alpha, const float* A, const blas_int* ldA, const float* B, const blas_int* ldB, const float* beta, float* C, const blas_int* ldC, blas_len transA_len, blas_len transB_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* B, const blas_int* ldB, const double* beta, double* C, const blas_int* ldC, blas_len transA_len, blas_len transB_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const blas_cxf* alpha, const blas_cxf* A, const blas_int* ldA, const blas_cxf* B, const blas_int* ldB, const blas_cxf* beta, blas_cxf* C, const blas_int* ldC, blas_len transA_len, blas_len transB_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const blas_cxd* alpha, const blas_cxd* A, const blas_int* ldA, const blas_cxd* B, const blas_int* ldB, const blas_cxd* beta, blas_cxd* C, const blas_int* ldC, blas_len transA_len, blas_len transB_len) ARMA_NOEXCEPT; - void arma_fortran(arma_ssyrk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const float* alpha, const float* A, const blas_int* ldA, const float* beta, float* C, const blas_int* ldC, blas_len uplo_len, blas_len transA_len); - void arma_fortran(arma_dsyrk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* beta, double* C, const blas_int* ldC, blas_len uplo_len, blas_len transA_len); + void arma_fortran(arma_ssyrk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const float* alpha, const float* A, const blas_int* ldA, const float* beta, float* C, const blas_int* ldC, blas_len uplo_len, blas_len transA_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dsyrk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* beta, double* C, const blas_int* ldC, blas_len uplo_len, blas_len transA_len) ARMA_NOEXCEPT; - void arma_fortran(arma_cherk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const float* alpha, const blas_cxf* A, const blas_int* ldA, const float* beta, blas_cxf* C, const blas_int* ldC, blas_len uplo_len, blas_len transA_len); - void arma_fortran(arma_zherk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const double* alpha, const blas_cxd* A, const blas_int* ldA, const double* beta, blas_cxd* C, const blas_int* ldC, blas_len uplo_len, blas_len transA_len); + void arma_fortran(arma_cherk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const float* alpha, const blas_cxf* A, const blas_int* ldA, const float* beta, blas_cxf* C, const blas_int* ldC, blas_len uplo_len, blas_len transA_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zherk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const double* alpha, const blas_cxd* A, const blas_int* ldA, const double* beta, blas_cxd* C, const blas_int* ldC, blas_len uplo_len, blas_len transA_len) ARMA_NOEXCEPT; #else // prototypes without hidden arguments - float arma_fortran(arma_sasum)(const blas_int* n, const float* x, const blas_int* incx); - double arma_fortran(arma_dasum)(const blas_int* n, const double* x, const blas_int* incx); + float arma_fortran(arma_sasum)(const blas_int* n, const float* x, const blas_int* incx) ARMA_NOEXCEPT; + double arma_fortran(arma_dasum)(const blas_int* n, const double* x, const blas_int* incx) ARMA_NOEXCEPT; - float arma_fortran(arma_snrm2)(const blas_int* n, const float* x, const blas_int* incx); - double arma_fortran(arma_dnrm2)(const blas_int* n, const double* x, const blas_int* incx); + float arma_fortran(arma_snrm2)(const blas_int* n, const float* x, const blas_int* incx) ARMA_NOEXCEPT; + double arma_fortran(arma_dnrm2)(const blas_int* n, const double* x, const blas_int* incx) ARMA_NOEXCEPT; - float arma_fortran(arma_sdot)(const blas_int* n, const float* x, const blas_int* incx, const float* y, const blas_int* incy); - double arma_fortran(arma_ddot)(const blas_int* n, const double* x, const blas_int* incx, const double* y, const blas_int* incy); + float arma_fortran(arma_sdot)(const blas_int* n, const float* x, const blas_int* incx, const float* y, const blas_int* incy) ARMA_NOEXCEPT; + double arma_fortran(arma_ddot)(const blas_int* n, const double* x, const blas_int* incx, const double* y, const blas_int* incy) ARMA_NOEXCEPT; - void arma_fortran(arma_sgemv)(const char* transA, const blas_int* m, const blas_int* n, const float* alpha, const float* A, const blas_int* ldA, const float* x, const blas_int* incx, const float* beta, float* y, const blas_int* incy); - void arma_fortran(arma_dgemv)(const char* transA, const blas_int* m, const blas_int* n, const double* alpha, const double* A, const blas_int* ldA, const double* x, const blas_int* incx, const double* beta, double* y, const blas_int* incy); - void arma_fortran(arma_cgemv)(const char* transA, const blas_int* m, const blas_int* n, const blas_cxf* alpha, const blas_cxf* A, const blas_int* ldA, const blas_cxf* x, const blas_int* incx, const blas_cxf* beta, blas_cxf* y, const blas_int* incy); - void arma_fortran(arma_zgemv)(const char* transA, const blas_int* m, const blas_int* n, const blas_cxd* alpha, const blas_cxd* A, const blas_int* ldA, const blas_cxd* x, const blas_int* incx, const blas_cxd* beta, blas_cxd* y, const blas_int* incy); - - void arma_fortran(arma_sgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const float* alpha, const float* A, const blas_int* ldA, const float* B, const blas_int* ldB, const float* beta, float* C, const blas_int* ldC); - void arma_fortran(arma_dgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* B, const blas_int* ldB, const double* beta, double* C, const blas_int* ldC); - void arma_fortran(arma_cgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const blas_cxf* alpha, const blas_cxf* A, const blas_int* ldA, const blas_cxf* B, const blas_int* ldB, const blas_cxf* beta, blas_cxf* C, const blas_int* ldC); - void arma_fortran(arma_zgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const blas_cxd* alpha, const blas_cxd* A, const blas_int* ldA, const blas_cxd* B, const blas_int* ldB, const blas_cxd* beta, blas_cxd* C, const blas_int* ldC); + void arma_fortran(arma_sgemv)(const char* transA, const blas_int* m, const blas_int* n, const float* alpha, const float* A, const blas_int* ldA, const float* x, const blas_int* incx, const float* beta, float* y, const blas_int* incy) ARMA_NOEXCEPT; + void arma_fortran(arma_dgemv)(const char* transA, const blas_int* m, const blas_int* n, const double* alpha, const double* A, const blas_int* ldA, const double* x, const blas_int* incx, const double* beta, double* y, const blas_int* incy) ARMA_NOEXCEPT; + void arma_fortran(arma_cgemv)(const char* transA, const blas_int* m, const blas_int* n, const blas_cxf* alpha, const blas_cxf* A, const blas_int* ldA, const blas_cxf* x, const blas_int* incx, const blas_cxf* beta, blas_cxf* y, const blas_int* incy) ARMA_NOEXCEPT; + void arma_fortran(arma_zgemv)(const char* transA, const blas_int* m, const blas_int* n, const blas_cxd* alpha, const blas_cxd* A, const blas_int* ldA, const blas_cxd* x, const blas_int* incx, const blas_cxd* beta, blas_cxd* y, const blas_int* incy) ARMA_NOEXCEPT; + + void arma_fortran(arma_sgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const float* alpha, const float* A, const blas_int* ldA, const float* B, const blas_int* ldB, const float* beta, float* C, const blas_int* ldC) ARMA_NOEXCEPT; + void arma_fortran(arma_dgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* B, const blas_int* ldB, const double* beta, double* C, const blas_int* ldC) ARMA_NOEXCEPT; + void arma_fortran(arma_cgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const blas_cxf* alpha, const blas_cxf* A, const blas_int* ldA, const blas_cxf* B, const blas_int* ldB, const blas_cxf* beta, blas_cxf* C, const blas_int* ldC) ARMA_NOEXCEPT; + void arma_fortran(arma_zgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const blas_cxd* alpha, const blas_cxd* A, const blas_int* ldA, const blas_cxd* B, const blas_int* ldB, const blas_cxd* beta, blas_cxd* C, const blas_int* ldC) ARMA_NOEXCEPT; - void arma_fortran(arma_ssyrk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const float* alpha, const float* A, const blas_int* ldA, const float* beta, float* C, const blas_int* ldC); - void arma_fortran(arma_dsyrk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* beta, double* C, const blas_int* ldC); + void arma_fortran(arma_ssyrk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const float* alpha, const float* A, const blas_int* ldA, const float* beta, float* C, const blas_int* ldC) ARMA_NOEXCEPT; + void arma_fortran(arma_dsyrk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* beta, double* C, const blas_int* ldC) ARMA_NOEXCEPT; - void arma_fortran(arma_cherk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const float* alpha, const blas_cxf* A, const blas_int* ldA, const float* beta, blas_cxf* C, const blas_int* ldC); - void arma_fortran(arma_zherk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const double* alpha, const blas_cxd* A, const blas_int* ldA, const double* beta, blas_cxd* C, const blas_int* ldC); + void arma_fortran(arma_cherk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const float* alpha, const blas_cxf* A, const blas_int* ldA, const float* beta, blas_cxf* C, const blas_int* ldC) ARMA_NOEXCEPT; + void arma_fortran(arma_zherk)(const char* uplo, const char* transA, const blas_int* n, const blas_int* k, const double* alpha, const blas_cxd* A, const blas_int* ldA, const double* beta, blas_cxd* C, const blas_int* ldC) ARMA_NOEXCEPT; #endif } +#undef ARMA_NOEXCEPT #endif diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/def_hdf5.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/def_hdf5.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/def_hdf5.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/def_hdf5.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/def_lapack.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/def_lapack.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/def_lapack.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/def_lapack.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,6 +24,16 @@ #pragma message ("WARNING: include the armadillo header before any other header as a workaround") #endif + +#if defined(ARMA_LAPACK_NOEXCEPT) + #undef ARMA_NOEXCEPT + #define ARMA_NOEXCEPT noexcept +#else + #undef ARMA_NOEXCEPT + #define ARMA_NOEXCEPT +#endif + + #if !defined(ARMA_BLAS_CAPITALS) #define arma_sgetrf sgetrf #define arma_dgetrf dgetrf @@ -96,6 +108,11 @@ #define arma_cgeqrf cgeqrf #define arma_zgeqrf zgeqrf + #define arma_sgeqp3 sgeqp3 + #define arma_dgeqp3 dgeqp3 + #define arma_cgeqp3 cgeqp3 + #define arma_zgeqp3 zgeqp3 + #define arma_sorgqr sorgqr #define arma_dorgqr dorgqr @@ -250,6 +267,11 @@ #define arma_cgehrd cgehrd #define arma_zgehrd zgehrd + #define arma_spstrf spstrf + #define arma_dpstrf dpstrf + #define arma_cpstrf cpstrf + #define arma_zpstrf zpstrf + #else #define arma_sgetrf SGETRF @@ -325,6 +347,11 @@ #define arma_cgeqrf CGEQRF #define arma_zgeqrf ZGEQRF + #define arma_sgeqp3 SGEQP3 + #define arma_dgeqp3 DGEQP3 + #define arma_cgeqp3 CGEQP3 + #define arma_zgeqp3 ZGEQP3 + #define arma_sorgqr SORGQR #define arma_dorgqr DORGQR @@ -479,6 +506,11 @@ #define arma_cgehrd CGEHRD #define arma_zgehrd ZGEHRD + #define arma_spstrf SPSTRF + #define arma_dpstrf DPSTRF + #define arma_cpstrf CPSTRF + #define arma_zpstrf ZPSTRF + #endif @@ -504,627 +536,657 @@ #if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS) // LU decomposition - void arma_fortran(arma_sgetrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_dgetrf)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_cgetrf)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_zgetrf)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_int* info); + void arma_fortran(arma_sgetrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgetrf)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgetrf)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgetrf)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations using pre-computed LU decomposition - void arma_fortran(arma_sgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info, const blas_len trans_len); - void arma_fortran(arma_dgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info, const blas_len trans_len); - void arma_fortran(arma_cgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info, const blas_len trans_len); - void arma_fortran(arma_zgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info, const blas_len trans_len); + void arma_fortran(arma_sgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info, const blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info, const blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info, const blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info, const blas_len trans_len) ARMA_NOEXCEPT; // matrix inversion (using pre-computed LU decomposition) - void arma_fortran(arma_sgetri)(const blas_int* n, float* a, const blas_int* lda, const blas_int* ipiv, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgetri)(const blas_int* n, double* a, const blas_int* lda, const blas_int* ipiv, double* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_cgetri)(const blas_int* n, blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zgetri)(const blas_int* n, blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sgetri)(const blas_int* n, float* a, const blas_int* lda, const blas_int* ipiv, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgetri)(const blas_int* n, double* a, const blas_int* lda, const blas_int* ipiv, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgetri)(const blas_int* n, blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgetri)(const blas_int* n, blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // matrix inversion (triangular matrices) - void arma_fortran(arma_strtri)(const char* uplo, const char* diag, const blas_int* n, float* a, const blas_int* lda, blas_int* info, blas_len uplo_len, blas_len diag_len); - void arma_fortran(arma_dtrtri)(const char* uplo, const char* diag, const blas_int* n, double* a, const blas_int* lda, blas_int* info, blas_len uplo_len, blas_len diag_len); - void arma_fortran(arma_ctrtri)(const char* uplo, const char* diag, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info, blas_len uplo_len, blas_len diag_len); - void arma_fortran(arma_ztrtri)(const char* uplo, const char* diag, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info, blas_len uplo_len, blas_len diag_len); + void arma_fortran(arma_strtri)(const char* uplo, const char* diag, const blas_int* n, float* a, const blas_int* lda, blas_int* info, blas_len uplo_len, blas_len diag_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrtri)(const char* uplo, const char* diag, const blas_int* n, double* a, const blas_int* lda, blas_int* info, blas_len uplo_len, blas_len diag_len) ARMA_NOEXCEPT; + void arma_fortran(arma_ctrtri)(const char* uplo, const char* diag, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info, blas_len uplo_len, blas_len diag_len) ARMA_NOEXCEPT; + void arma_fortran(arma_ztrtri)(const char* uplo, const char* diag, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info, blas_len uplo_len, blas_len diag_len) ARMA_NOEXCEPT; // eigen decomposition of general matrix (real) - void arma_fortran(arma_sgeev)(const char* jobvl, const char* jobvr, const blas_int* n, float* a, const blas_int* lda, float* wr, float* wi, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, float* work, const blas_int* lwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len); - void arma_fortran(arma_dgeev)(const char* jobvl, const char* jobvr, const blas_int* n, double* a, const blas_int* lda, double* wr, double* wi, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, double* work, const blas_int* lwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len); + void arma_fortran(arma_sgeev)(const char* jobvl, const char* jobvr, const blas_int* n, float* a, const blas_int* lda, float* wr, float* wi, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, float* work, const blas_int* lwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgeev)(const char* jobvl, const char* jobvr, const blas_int* n, double* a, const blas_int* lda, double* wr, double* wi, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, double* work, const blas_int* lwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len) ARMA_NOEXCEPT; // eigen decomposition of general matrix (complex) - void arma_fortran(arma_cgeev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* w, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len); - void arma_fortran(arma_zgeev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* w, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len); + void arma_fortran(arma_cgeev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* w, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgeev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* w, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len) ARMA_NOEXCEPT; // eigen decomposition of general matrix (real; advanced form) - void arma_fortran(arma_sgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, float* a, const blas_int* lda, float* wr, float* wi, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info, blas_len balanc_len, blas_len jobvl_len, blas_len jobvr_len, blas_len sense_len); - void arma_fortran(arma_dgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, double* a, const blas_int* lda, double* wr, double* wi, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info, blas_len balanc_len, blas_len jobvl_len, blas_len jobvr_len, blas_len sense_len); + void arma_fortran(arma_sgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, float* a, const blas_int* lda, float* wr, float* wi, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info, blas_len balanc_len, blas_len jobvl_len, blas_len jobvr_len, blas_len sense_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, double* a, const blas_int* lda, double* wr, double* wi, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info, blas_len balanc_len, blas_len jobvl_len, blas_len jobvr_len, blas_len sense_len) ARMA_NOEXCEPT; // eigen decomposition of general matrix (complex; advanced form) - void arma_fortran(arma_cgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* w, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, blas_cxf* work, const blas_int* lwork, float* rwork, const blas_int* info, blas_len balanc_len, blas_len jobvl_len, blas_len jobvr_len, blas_len sense_len); - void arma_fortran(arma_zgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* w, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, blas_cxd* work, const blas_int* lwork, double* rwork, const blas_int* info, blas_len balanc_len, blas_len jobvl_len, blas_len jobvr_len, blas_len sense_len); + void arma_fortran(arma_cgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* w, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, blas_cxf* work, const blas_int* lwork, float* rwork, const blas_int* info, blas_len balanc_len, blas_len jobvl_len, blas_len jobvr_len, blas_len sense_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* w, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, blas_cxd* work, const blas_int* lwork, double* rwork, const blas_int* info, blas_len balanc_len, blas_len jobvl_len, blas_len jobvr_len, blas_len sense_len) ARMA_NOEXCEPT; // eigen decomposition of symmetric real matrices - void arma_fortran(arma_ssyev)(const char* jobz, const char* uplo, const blas_int* n, float* a, const blas_int* lda, float* w, float* work, const blas_int* lwork, blas_int* info, blas_len jobz_len, blas_len uplo_len); - void arma_fortran(arma_dsyev)(const char* jobz, const char* uplo, const blas_int* n, double* a, const blas_int* lda, double* w, double* work, const blas_int* lwork, blas_int* info, blas_len jobz_len, blas_len uplo_len); + void arma_fortran(arma_ssyev)(const char* jobz, const char* uplo, const blas_int* n, float* a, const blas_int* lda, float* w, float* work, const blas_int* lwork, blas_int* info, blas_len jobz_len, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dsyev)(const char* jobz, const char* uplo, const blas_int* n, double* a, const blas_int* lda, double* w, double* work, const blas_int* lwork, blas_int* info, blas_len jobz_len, blas_len uplo_len) ARMA_NOEXCEPT; // eigen decomposition of hermitian matrices (complex) - void arma_fortran(arma_cheev)(const char* jobz, const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, float* w, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info, blas_len jobz_len, blas_len uplo_len); - void arma_fortran(arma_zheev)(const char* jobz, const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, double* w, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info, blas_len jobz_len, blas_len uplo_len); + void arma_fortran(arma_cheev)(const char* jobz, const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, float* w, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info, blas_len jobz_len, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zheev)(const char* jobz, const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, double* w, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info, blas_len jobz_len, blas_len uplo_len) ARMA_NOEXCEPT; // eigen decomposition of symmetric real matrices by divide and conquer - void arma_fortran(arma_ssyevd)(const char* jobz, const char* uplo, const blas_int* n, float* a, const blas_int* lda, float* w, float* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len jobz_len, blas_len uplo_len); - void arma_fortran(arma_dsyevd)(const char* jobz, const char* uplo, const blas_int* n, double* a, const blas_int* lda, double* w, double* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len jobz_len, blas_len uplo_len); + void arma_fortran(arma_ssyevd)(const char* jobz, const char* uplo, const blas_int* n, float* a, const blas_int* lda, float* w, float* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len jobz_len, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dsyevd)(const char* jobz, const char* uplo, const blas_int* n, double* a, const blas_int* lda, double* w, double* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len jobz_len, blas_len uplo_len) ARMA_NOEXCEPT; // eigen decomposition of hermitian matrices (complex) by divide and conquer - void arma_fortran(arma_cheevd)(const char* jobz, const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, float* w, blas_cxf* work, const blas_int* lwork, float* rwork, const blas_int* lrwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len jobz_len, blas_len uplo_len); - void arma_fortran(arma_zheevd)(const char* jobz, const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, double* w, blas_cxd* work, const blas_int* lwork, double* rwork, const blas_int* lrwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len jobz_len, blas_len uplo_len); + void arma_fortran(arma_cheevd)(const char* jobz, const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, float* w, blas_cxf* work, const blas_int* lwork, float* rwork, const blas_int* lrwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len jobz_len, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zheevd)(const char* jobz, const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, double* w, blas_cxd* work, const blas_int* lwork, double* rwork, const blas_int* lrwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len jobz_len, blas_len uplo_len) ARMA_NOEXCEPT; // eigen decomposition of general real matrix pair - void arma_fortran(arma_sggev)(const char* jobvl, const char* jobvr, const blas_int* n, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* alphar, float* alphai, float* beta, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, float* work, const blas_int* lwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len); - void arma_fortran(arma_dggev)(const char* jobvl, const char* jobvr, const blas_int* n, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* alphar, double* alphai, double* beta, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, double* work, const blas_int* lwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len); + void arma_fortran(arma_sggev)(const char* jobvl, const char* jobvr, const blas_int* n, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* alphar, float* alphai, float* beta, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, float* work, const blas_int* lwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dggev)(const char* jobvl, const char* jobvr, const blas_int* n, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* alphar, double* alphai, double* beta, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, double* work, const blas_int* lwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len) ARMA_NOEXCEPT; // eigen decomposition of general complex matrix pair - void arma_fortran(arma_cggev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_cxf* alpha, blas_cxf* beta, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len); - void arma_fortran(arma_zggev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_cxd* alpha, blas_cxd* beta, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len); + void arma_fortran(arma_cggev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_cxf* alpha, blas_cxf* beta, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zggev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_cxd* alpha, blas_cxd* beta, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info, blas_len jobvl_len, blas_len jobvr_len) ARMA_NOEXCEPT; // Cholesky decomposition - void arma_fortran(arma_spotrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_dpotrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_cpotrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_zpotrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info, blas_len uplo_len); + void arma_fortran(arma_spotrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dpotrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cpotrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zpotrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; // solve system of linear equations using pre-computed Cholesky decomposition - void arma_fortran(arma_spotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_dpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_cpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_zpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len uplo_len); + void arma_fortran(arma_spotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; // Cholesky decomposition (band matrices) - void arma_fortran(arma_spbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, float* ab, const blas_int* ldab, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_dpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, double* ab, const blas_int* ldab, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_cpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, blas_cxf* ab, const blas_int* ldab, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_zpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, blas_cxd* ab, const blas_int* ldab, blas_int* info, blas_len uplo_len); + void arma_fortran(arma_spbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, float* ab, const blas_int* ldab, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, double* ab, const blas_int* ldab, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, blas_cxf* ab, const blas_int* ldab, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, blas_cxd* ab, const blas_int* ldab, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; // matrix inversion (using pre-computed Cholesky decomposition) - void arma_fortran(arma_spotri)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_dpotri)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_cpotri)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_zpotri)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info, blas_len uplo_len); + void arma_fortran(arma_spotri)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dpotri)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cpotri)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zpotri)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; // QR decomposition - void arma_fortran(arma_sgeqrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* tau, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgeqrf)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* tau, double* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_cgeqrf)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* tau, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zgeqrf)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* tau, blas_cxd* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sgeqrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* tau, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgeqrf)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* tau, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgeqrf)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* tau, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgeqrf)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* tau, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + + // QR decomposition with pivoting (real matrices) + void arma_fortran(arma_sgeqp3)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* jpvt, float* tau, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgeqp3)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, blas_int* jpvt, double* tau, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + + // QR decomposition with pivoting (complex matrices) + void arma_fortran(arma_cgeqp3)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* jpvt, blas_cxf* tau, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgeqp3)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* jpvt, blas_cxd* tau, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) ARMA_NOEXCEPT; // Q matrix calculation from QR decomposition (real matrices) - void arma_fortran(arma_sorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, float* a, const blas_int* lda, const float* tau, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, double* a, const blas_int* lda, const double* tau, double* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, float* a, const blas_int* lda, const float* tau, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, double* a, const blas_int* lda, const double* tau, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // Q matrix calculation from QR decomposition (complex matrices) - void arma_fortran(arma_cungqr)(const blas_int* m, const blas_int* n, const blas_int* k, blas_cxf* a, const blas_int* lda, const blas_cxf* tau, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zungqr)(const blas_int* m, const blas_int* n, const blas_int* k, blas_cxd* a, const blas_int* lda, const blas_cxd* tau, blas_cxd* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_cungqr)(const blas_int* m, const blas_int* n, const blas_int* k, blas_cxf* a, const blas_int* lda, const blas_cxf* tau, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zungqr)(const blas_int* m, const blas_int* n, const blas_int* k, blas_cxd* a, const blas_int* lda, const blas_cxd* tau, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // SVD (real matrices) - void arma_fortran(arma_sgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* s, float* u, const blas_int* ldu, float* vt, const blas_int* ldvt, float* work, const blas_int* lwork, blas_int* info, blas_len jobu_len, blas_len jobvt_len); - void arma_fortran(arma_dgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* s, double* u, const blas_int* ldu, double* vt, const blas_int* ldvt, double* work, const blas_int* lwork, blas_int* info, blas_len jobu_len, blas_len jobvt_len); + void arma_fortran(arma_sgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* s, float* u, const blas_int* ldu, float* vt, const blas_int* ldvt, float* work, const blas_int* lwork, blas_int* info, blas_len jobu_len, blas_len jobvt_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* s, double* u, const blas_int* ldu, double* vt, const blas_int* ldvt, double* work, const blas_int* lwork, blas_int* info, blas_len jobu_len, blas_len jobvt_len) ARMA_NOEXCEPT; // SVD (complex matrices) - void arma_fortran(arma_cgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, float* s, blas_cxf* u, const blas_int* ldu, blas_cxf* vt, const blas_int* ldvt, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info, blas_len jobu_len, blas_len jobvt_len); - void arma_fortran(arma_zgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, double* s, blas_cxd* u, const blas_int* ldu, blas_cxd* vt, const blas_int* ldvt, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info, blas_len jobu_len, blas_len jobvt_len); + void arma_fortran(arma_cgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, float* s, blas_cxf* u, const blas_int* ldu, blas_cxf* vt, const blas_int* ldvt, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info, blas_len jobu_len, blas_len jobvt_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, double* s, blas_cxd* u, const blas_int* ldu, blas_cxd* vt, const blas_int* ldvt, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info, blas_len jobu_len, blas_len jobvt_len) ARMA_NOEXCEPT; // SVD (real matrices) by divide and conquer - void arma_fortran(arma_sgesdd)(const char* jobz, const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* s, float* u, const blas_int* ldu, float* vt, const blas_int* ldvt, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info, blas_len jobz_len); - void arma_fortran(arma_dgesdd)(const char* jobz, const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* s, double* u, const blas_int* ldu, double* vt, const blas_int* ldvt, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info, blas_len jobz_len); + void arma_fortran(arma_sgesdd)(const char* jobz, const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* s, float* u, const blas_int* ldu, float* vt, const blas_int* ldvt, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info, blas_len jobz_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgesdd)(const char* jobz, const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* s, double* u, const blas_int* ldu, double* vt, const blas_int* ldvt, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info, blas_len jobz_len) ARMA_NOEXCEPT; // SVD (complex matrices) by divide and conquer - void arma_fortran(arma_cgesdd)(const char* jobz, const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, float* s, blas_cxf* u, const blas_int* ldu, blas_cxf* vt, const blas_int* ldvt, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* iwork, blas_int* info, blas_len jobz_len); - void arma_fortran(arma_zgesdd)(const char* jobz, const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, double* s, blas_cxd* u, const blas_int* ldu, blas_cxd* vt, const blas_int* ldvt, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info, blas_len jobz_len); + void arma_fortran(arma_cgesdd)(const char* jobz, const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, float* s, blas_cxf* u, const blas_int* ldu, blas_cxf* vt, const blas_int* ldvt, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* iwork, blas_int* info, blas_len jobz_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgesdd)(const char* jobz, const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, double* s, blas_cxd* u, const blas_int* ldu, blas_cxd* vt, const blas_int* ldvt, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info, blas_len jobz_len) ARMA_NOEXCEPT; // solve system of linear equations (general square matrix) - void arma_fortran(arma_sgesv)(const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dgesv)(const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cgesv)(const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zgesv)(const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sgesv)(const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgesv)(const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgesv)(const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgesv)(const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (general square matrix, advanced form, real matrices) - void arma_fortran(arma_sgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* af, const blas_int* ldaf, blas_int* ipiv, char* equed, float* r, float* c, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len); - void arma_fortran(arma_dgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* af, const blas_int* ldaf, blas_int* ipiv, char* equed, double* r, double* c, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len); + void arma_fortran(arma_sgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* af, const blas_int* ldaf, blas_int* ipiv, char* equed, float* r, float* c, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* af, const blas_int* ldaf, blas_int* ipiv, char* equed, double* r, double* c, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len) ARMA_NOEXCEPT; // solve system of linear equations (general square matrix, advanced form, complex matrices) - void arma_fortran(arma_cgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* af, const blas_int* ldaf, blas_int* ipiv, char* equed, float* r, float* c, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len); - void arma_fortran(arma_zgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* af, const blas_int* ldaf, blas_int* ipiv, char* equed, double* r, double* c, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len); + void arma_fortran(arma_cgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* af, const blas_int* ldaf, blas_int* ipiv, char* equed, float* r, float* c, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* af, const blas_int* ldaf, blas_int* ipiv, char* equed, double* r, double* c, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len) ARMA_NOEXCEPT; // solve system of linear equations (symmetric positive definite matrix) - void arma_fortran(arma_sposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_dposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_cposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_zposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len uplo_len); + void arma_fortran(arma_sposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; // solve system of linear equations (symmetric positive definite matrix, advanced form, real matrices) - void arma_fortran(arma_sposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* af, const blas_int* ldaf, char* equed, float* s, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len uplo_len, blas_len equed_len); - void arma_fortran(arma_dposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* af, const blas_int* ldaf, char* equed, double* s, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len uplo_len, blas_len equed_len); + void arma_fortran(arma_sposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* af, const blas_int* ldaf, char* equed, float* s, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len uplo_len, blas_len equed_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* af, const blas_int* ldaf, char* equed, double* s, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len uplo_len, blas_len equed_len) ARMA_NOEXCEPT; // solve system of linear equations (hermitian positive definite matrix, advanced form, complex matrices) - void arma_fortran(arma_cposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* af, const blas_int* ldaf, char* equed, float* s, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info, blas_len fact_len, blas_len uplo_len, blas_len equed_len); - void arma_fortran(arma_zposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* af, const blas_int* ldaf, char* equed, double* s, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info, blas_len fact_len, blas_len uplo_len, blas_len equed_len); + void arma_fortran(arma_cposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* af, const blas_int* ldaf, char* equed, float* s, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info, blas_len fact_len, blas_len uplo_len, blas_len equed_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* af, const blas_int* ldaf, char* equed, double* s, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info, blas_len fact_len, blas_len uplo_len, blas_len equed_len) ARMA_NOEXCEPT; // solve over/under-determined system of linear equations - void arma_fortran(arma_sgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* work, const blas_int* lwork, blas_int* info, blas_len trans_len); - void arma_fortran(arma_dgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* work, const blas_int* lwork, blas_int* info, blas_len trans_len); - void arma_fortran(arma_cgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_cxf* work, const blas_int* lwork, blas_int* info, blas_len trans_len); - void arma_fortran(arma_zgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_cxd* work, const blas_int* lwork, blas_int* info, blas_len trans_len); + void arma_fortran(arma_sgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* work, const blas_int* lwork, blas_int* info, blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* work, const blas_int* lwork, blas_int* info, blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_cxf* work, const blas_int* lwork, blas_int* info, blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_cxd* work, const blas_int* lwork, blas_int* info, blas_len trans_len) ARMA_NOEXCEPT; // approximately solve system of linear equations using svd (real) - void arma_fortran(arma_sgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* S, const float* rcond, blas_int* rank, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* S, const double* rcond, blas_int* rank, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* S, const float* rcond, blas_int* rank, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* S, const double* rcond, blas_int* rank, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // approximately solve system of linear equations using svd (complex) - void arma_fortran(arma_cgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, float* S, const float* rcond, blas_int* rank, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* iwork, blas_int* info); - void arma_fortran(arma_zgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, double* S, const double* rcond, blas_int* rank, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info); + void arma_fortran(arma_cgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, float* S, const float* rcond, blas_int* rank, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, double* S, const double* rcond, blas_int* rank, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (triangular matrix) - void arma_fortran(arma_strtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info, blas_len uplo_len, blas_len trans_len, blas_len diag_len); - void arma_fortran(arma_dtrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info, blas_len uplo_len, blas_len trans_len, blas_len diag_len); - void arma_fortran(arma_ctrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len uplo_len, blas_len trans_len, blas_len diag_len); - void arma_fortran(arma_ztrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len uplo_len, blas_len trans_len, blas_len diag_len); + void arma_fortran(arma_strtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info, blas_len uplo_len, blas_len trans_len, blas_len diag_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info, blas_len uplo_len, blas_len trans_len, blas_len diag_len) ARMA_NOEXCEPT; + void arma_fortran(arma_ctrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len uplo_len, blas_len trans_len, blas_len diag_len) ARMA_NOEXCEPT; + void arma_fortran(arma_ztrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len uplo_len, blas_len trans_len, blas_len diag_len) ARMA_NOEXCEPT; // LU factorisation (general band matrix) - void arma_fortran(arma_sgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, float* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_dgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, double* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_cgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, blas_cxf* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_zgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, blas_cxd* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info); + void arma_fortran(arma_sgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, float* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, double* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, blas_cxf* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, blas_cxd* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations using pre-computed LU decomposition (general band matrix) - void arma_fortran(arma_sgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const float* ab, const blas_int* ldab, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info, blas_len trans_len); - void arma_fortran(arma_dgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const double* ab, const blas_int* ldab, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info, blas_len trans_len); - void arma_fortran(arma_cgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const blas_cxf* ab, const blas_int* ldab, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len trans_len); - void arma_fortran(arma_zgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const blas_cxd* ab, const blas_int* ldab, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len trans_len); + void arma_fortran(arma_sgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const float* ab, const blas_int* ldab, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info, blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const double* ab, const blas_int* ldab, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info, blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const blas_cxf* ab, const blas_int* ldab, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const blas_cxd* ab, const blas_int* ldab, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len trans_len) ARMA_NOEXCEPT; // solve system of linear equations (general band matrix) - void arma_fortran(arma_sgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, float* ab, const blas_int* ldab, blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, double* ab, const blas_int* ldab, blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxf* ab, const blas_int* ldab, blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxd* ab, const blas_int* ldab, blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, float* ab, const blas_int* ldab, blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, double* ab, const blas_int* ldab, blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxf* ab, const blas_int* ldab, blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxd* ab, const blas_int* ldab, blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (general band matrix, advanced form, real matrices) - void arma_fortran(arma_sgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, float* ab, const blas_int* ldab, float* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, float* r, float* c, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len); - void arma_fortran(arma_dgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, double* ab, const blas_int* ldab, double* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, double* r, double* c, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len); + void arma_fortran(arma_sgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, float* ab, const blas_int* ldab, float* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, float* r, float* c, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, double* ab, const blas_int* ldab, double* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, double* r, double* c, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len) ARMA_NOEXCEPT; // solve system of linear equations (general band matrix, advanced form, complex matrices) - void arma_fortran(arma_cgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxf* ab, const blas_int* ldab, blas_cxf* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, float* r, float* c, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len); - void arma_fortran(arma_zgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxd* ab, const blas_int* ldab, blas_cxd* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, double* r, double* c, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len); + void arma_fortran(arma_cgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxf* ab, const blas_int* ldab, blas_cxf* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, float* r, float* c, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxd* ab, const blas_int* ldab, blas_cxd* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, double* r, double* c, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info, blas_len fact_len, blas_len trans_len, blas_len equed_len) ARMA_NOEXCEPT; // solve system of linear equations (tridiagonal band matrix) - void arma_fortran(arma_sgtsv)(const blas_int* n, const blas_int* nrhs, float* dl, float* d, float* du, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dgtsv)(const blas_int* n, const blas_int* nrhs, double* dl, double* d, double* du, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cgtsv)(const blas_int* n, const blas_int* nrhs, blas_cxf* dl, blas_cxf* d, blas_cxf* du, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zgtsv)(const blas_int* n, const blas_int* nrhs, blas_cxd* dl, blas_cxd* d, blas_cxd* du, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sgtsv)(const blas_int* n, const blas_int* nrhs, float* dl, float* d, float* du, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgtsv)(const blas_int* n, const blas_int* nrhs, double* dl, double* d, double* du, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgtsv)(const blas_int* n, const blas_int* nrhs, blas_cxf* dl, blas_cxf* d, blas_cxf* du, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgtsv)(const blas_int* n, const blas_int* nrhs, blas_cxd* dl, blas_cxd* d, blas_cxd* du, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (tridiagonal band matrix, advanced form, real matrices) - void arma_fortran(arma_sgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const float* dl, const float* d, const float* du, float* dlf, float* df, float* duf, float* du2, blas_int* ipiv, const float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len); - void arma_fortran(arma_dgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const double* dl, const double* d, const double* du, double* dlf, double* df, double* duf, double* du2, blas_int* ipiv, const double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len); + void arma_fortran(arma_sgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const float* dl, const float* d, const float* du, float* dlf, float* df, float* duf, float* du2, blas_int* ipiv, const float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const double* dl, const double* d, const double* du, double* dlf, double* df, double* duf, double* du2, blas_int* ipiv, const double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info, blas_len fact_len, blas_len trans_len) ARMA_NOEXCEPT; // solve system of linear equations (tridiagonal band matrix, advanced form, complex matrices) - void arma_fortran(arma_cgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxf* dl, const blas_cxf* d, const blas_cxf* du, blas_cxf* dlf, blas_cxf* df, blas_cxf* duf, blas_cxf* du2, blas_int* ipiv, const blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info, blas_len fact_len, blas_len trans_len); - void arma_fortran(arma_zgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxd* dl, const blas_cxd* d, const blas_cxd* du, blas_cxd* dlf, blas_cxd* df, blas_cxd* duf, blas_cxd* du2, blas_int* ipiv, const blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info, blas_len fact_len, blas_len trans_len); + void arma_fortran(arma_cgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxf* dl, const blas_cxf* d, const blas_cxf* du, blas_cxf* dlf, blas_cxf* df, blas_cxf* duf, blas_cxf* du2, blas_int* ipiv, const blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info, blas_len fact_len, blas_len trans_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxd* dl, const blas_cxd* d, const blas_cxd* du, blas_cxd* dlf, blas_cxd* df, blas_cxd* duf, blas_cxd* du2, blas_int* ipiv, const blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info, blas_len fact_len, blas_len trans_len) ARMA_NOEXCEPT; // Schur decomposition (real matrices) - void arma_fortran(arma_sgees)(const char* jobvs, const char* sort, fn_select_s2 select, const blas_int* n, float* a, const blas_int* lda, blas_int* sdim, float* wr, float* wi, float* vs, const blas_int* ldvs, float* work, const blas_int* lwork, blas_int* bwork, blas_int* info, blas_len jobvs_len, blas_len sort_len); - void arma_fortran(arma_dgees)(const char* jobvs, const char* sort, fn_select_d2 select, const blas_int* n, double* a, const blas_int* lda, blas_int* sdim, double* wr, double* wi, double* vs, const blas_int* ldvs, double* work, const blas_int* lwork, blas_int* bwork, blas_int* info, blas_len jobvs_len, blas_len sort_len); + void arma_fortran(arma_sgees)(const char* jobvs, const char* sort, fn_select_s2 select, const blas_int* n, float* a, const blas_int* lda, blas_int* sdim, float* wr, float* wi, float* vs, const blas_int* ldvs, float* work, const blas_int* lwork, blas_int* bwork, blas_int* info, blas_len jobvs_len, blas_len sort_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgees)(const char* jobvs, const char* sort, fn_select_d2 select, const blas_int* n, double* a, const blas_int* lda, blas_int* sdim, double* wr, double* wi, double* vs, const blas_int* ldvs, double* work, const blas_int* lwork, blas_int* bwork, blas_int* info, blas_len jobvs_len, blas_len sort_len) ARMA_NOEXCEPT; // Schur decomposition (complex matrices) - void arma_fortran(arma_cgees)(const char* jobvs, const char* sort, fn_select_c1 select, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* sdim, blas_cxf* w, blas_cxf* vs, const blas_int* ldvs, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* bwork, blas_int* info, blas_len jobvs_len, blas_len sort_len); - void arma_fortran(arma_zgees)(const char* jobvs, const char* sort, fn_select_z1 select, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* sdim, blas_cxd* w, blas_cxd* vs, const blas_int* ldvs, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info, blas_len jobvs_len, blas_len sort_len); + void arma_fortran(arma_cgees)(const char* jobvs, const char* sort, fn_select_c1 select, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* sdim, blas_cxf* w, blas_cxf* vs, const blas_int* ldvs, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* bwork, blas_int* info, blas_len jobvs_len, blas_len sort_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgees)(const char* jobvs, const char* sort, fn_select_z1 select, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* sdim, blas_cxd* w, blas_cxd* vs, const blas_int* ldvs, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info, blas_len jobvs_len, blas_len sort_len) ARMA_NOEXCEPT; // solve a Sylvester equation ax + xb = c, with a and b assumed to be in Schur form - void arma_fortran(arma_strsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const float* a, const blas_int* lda, const float* b, const blas_int* ldb, float* c, const blas_int* ldc, float* scale, blas_int* info, blas_len transa_len, blas_len transb_len); - void arma_fortran(arma_dtrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const double* a, const blas_int* lda, const double* b, const blas_int* ldb, double* c, const blas_int* ldc, double* scale, blas_int* info, blas_len transa_len, blas_len transb_len); - void arma_fortran(arma_ctrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const blas_cxf* a, const blas_int* lda, const blas_cxf* b, const blas_int* ldb, blas_cxf* c, const blas_int* ldc, float* scale, blas_int* info, blas_len transa_len, blas_len transb_len); - void arma_fortran(arma_ztrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const blas_cxd* a, const blas_int* lda, const blas_cxd* b, const blas_int* ldb, blas_cxd* c, const blas_int* ldc, double* scale, blas_int* info, blas_len transa_len, blas_len transb_len); + void arma_fortran(arma_strsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const float* a, const blas_int* lda, const float* b, const blas_int* ldb, float* c, const blas_int* ldc, float* scale, blas_int* info, blas_len transa_len, blas_len transb_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const double* a, const blas_int* lda, const double* b, const blas_int* ldb, double* c, const blas_int* ldc, double* scale, blas_int* info, blas_len transa_len, blas_len transb_len) ARMA_NOEXCEPT; + void arma_fortran(arma_ctrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const blas_cxf* a, const blas_int* lda, const blas_cxf* b, const blas_int* ldb, blas_cxf* c, const blas_int* ldc, float* scale, blas_int* info, blas_len transa_len, blas_len transb_len) ARMA_NOEXCEPT; + void arma_fortran(arma_ztrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const blas_cxd* a, const blas_int* lda, const blas_cxd* b, const blas_int* ldb, blas_cxd* c, const blas_int* ldc, double* scale, blas_int* info, blas_len transa_len, blas_len transb_len) ARMA_NOEXCEPT; // QZ decomposition (real matrices) - void arma_fortran(arma_sgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_s3 selctg, const blas_int* n, float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, const blas_int* ldvsl, float* vsr, const blas_int* ldvsr, float* work, const blas_int* lwork, blas_int* bwork, blas_int* info, blas_len jobvsl_len, blas_len jobvsr_len, blas_len sort_len); - void arma_fortran(arma_dgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_d3 selctg, const blas_int* n, double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, const blas_int* ldvsl, double* vsr, const blas_int* ldvsr, double* work, const blas_int* lwork, blas_int* bwork, blas_int* info, blas_len jobvsl_len, blas_len jobvsr_len, blas_len sort_len); + void arma_fortran(arma_sgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_s3 selctg, const blas_int* n, float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, const blas_int* ldvsl, float* vsr, const blas_int* ldvsr, float* work, const blas_int* lwork, blas_int* bwork, blas_int* info, blas_len jobvsl_len, blas_len jobvsr_len, blas_len sort_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_d3 selctg, const blas_int* n, double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, const blas_int* ldvsl, double* vsr, const blas_int* ldvsr, double* work, const blas_int* lwork, blas_int* bwork, blas_int* info, blas_len jobvsl_len, blas_len jobvsr_len, blas_len sort_len) ARMA_NOEXCEPT; // QZ decomposition (complex matrices) - void arma_fortran(arma_cgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_c2 selctg, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* sdim, blas_cxf* alpha, blas_cxf* beta, blas_cxf* vsl, const blas_int* ldvsl, blas_cxf* vsr, const blas_int* ldvsr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* bwork, blas_int* info, blas_len jobvsl_len, blas_len jobvsr_len, blas_len sort_len); - void arma_fortran(arma_zgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_z2 selctg, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* sdim, blas_cxd* alpha, blas_cxd* beta, blas_cxd* vsl, const blas_int* ldvsl, blas_cxd* vsr, const blas_int* ldvsr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info, blas_len jobvsl_len, blas_len jobvsr_len, blas_len sort_len); + void arma_fortran(arma_cgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_c2 selctg, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* sdim, blas_cxf* alpha, blas_cxf* beta, blas_cxf* vsl, const blas_int* ldvsl, blas_cxf* vsr, const blas_int* ldvsr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* bwork, blas_int* info, blas_len jobvsl_len, blas_len jobvsr_len, blas_len sort_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_z2 selctg, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* sdim, blas_cxd* alpha, blas_cxd* beta, blas_cxd* vsl, const blas_int* ldvsl, blas_cxd* vsr, const blas_int* ldvsr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info, blas_len jobvsl_len, blas_len jobvsr_len, blas_len sort_len) ARMA_NOEXCEPT; // 1-norm (general matrix) - float arma_fortran(arma_slange)(const char* norm, const blas_int* m, const blas_int* n, const float* a, const blas_int* lda, float* work, blas_len norm_len); - double arma_fortran(arma_dlange)(const char* norm, const blas_int* m, const blas_int* n, const double* a, const blas_int* lda, double* work, blas_len norm_len); - float arma_fortran(arma_clange)(const char* norm, const blas_int* m, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work, blas_len norm_len); - double arma_fortran(arma_zlange)(const char* norm, const blas_int* m, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work, blas_len norm_len); + float arma_fortran(arma_slange)(const char* norm, const blas_int* m, const blas_int* n, const float* a, const blas_int* lda, float* work, blas_len norm_len) ARMA_NOEXCEPT; + double arma_fortran(arma_dlange)(const char* norm, const blas_int* m, const blas_int* n, const double* a, const blas_int* lda, double* work, blas_len norm_len) ARMA_NOEXCEPT; + float arma_fortran(arma_clange)(const char* norm, const blas_int* m, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work, blas_len norm_len) ARMA_NOEXCEPT; + double arma_fortran(arma_zlange)(const char* norm, const blas_int* m, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work, blas_len norm_len) ARMA_NOEXCEPT; // 1-norm (real symmetric matrix) - float arma_fortran(arma_slansy)(const char* norm, const char* uplo, const blas_int* n, const float* a, const blas_int* lda, float* work, blas_len norm_len, blas_len uplo_len); - double arma_fortran(arma_dlansy)(const char* norm, const char* uplo, const blas_int* n, const double* a, const blas_int* lda, double* work, blas_len norm_len, blas_len uplo_len); - float arma_fortran(arma_clansy)(const char* norm, const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work, blas_len norm_len, blas_len uplo_len); - double arma_fortran(arma_zlansy)(const char* norm, const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work, blas_len norm_len, blas_len uplo_len); + float arma_fortran(arma_slansy)(const char* norm, const char* uplo, const blas_int* n, const float* a, const blas_int* lda, float* work, blas_len norm_len, blas_len uplo_len) ARMA_NOEXCEPT; + double arma_fortran(arma_dlansy)(const char* norm, const char* uplo, const blas_int* n, const double* a, const blas_int* lda, double* work, blas_len norm_len, blas_len uplo_len) ARMA_NOEXCEPT; + float arma_fortran(arma_clansy)(const char* norm, const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work, blas_len norm_len, blas_len uplo_len) ARMA_NOEXCEPT; + double arma_fortran(arma_zlansy)(const char* norm, const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work, blas_len norm_len, blas_len uplo_len) ARMA_NOEXCEPT; // 1-norm (complex hermitian matrix) - float arma_fortran(arma_clanhe)(const char* norm, const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work, blas_len norm_len, blas_len uplo_len); - double arma_fortran(arma_zlanhe)(const char* norm, const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work, blas_len norm_len, blas_len uplo_len); + float arma_fortran(arma_clanhe)(const char* norm, const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work, blas_len norm_len, blas_len uplo_len) ARMA_NOEXCEPT; + double arma_fortran(arma_zlanhe)(const char* norm, const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work, blas_len norm_len, blas_len uplo_len) ARMA_NOEXCEPT; // 1-norm (band matrix) - float arma_fortran(arma_slangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const float* ab, const blas_int* ldab, float* work, blas_len norm_len); - double arma_fortran(arma_dlangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const double* ab, const blas_int* ldab, double* work, blas_len norm_len); - float arma_fortran(arma_clangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxf* ab, const blas_int* ldab, float* work, blas_len norm_len); - double arma_fortran(arma_zlangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxd* ab, const blas_int* ldab, double* work, blas_len norm_len); + float arma_fortran(arma_slangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const float* ab, const blas_int* ldab, float* work, blas_len norm_len) ARMA_NOEXCEPT; + double arma_fortran(arma_dlangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const double* ab, const blas_int* ldab, double* work, blas_len norm_len) ARMA_NOEXCEPT; + float arma_fortran(arma_clangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxf* ab, const blas_int* ldab, float* work, blas_len norm_len) ARMA_NOEXCEPT; + double arma_fortran(arma_zlangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxd* ab, const blas_int* ldab, double* work, blas_len norm_len) ARMA_NOEXCEPT; // reciprocal of condition number (real, generic matrix) - void arma_fortran(arma_sgecon)(const char* norm, const blas_int* n, const float* a, const blas_int* lda, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len norm_len); - void arma_fortran(arma_dgecon)(const char* norm, const blas_int* n, const double* a, const blas_int* lda, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len norm_len); + void arma_fortran(arma_sgecon)(const char* norm, const blas_int* n, const float* a, const blas_int* lda, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len norm_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgecon)(const char* norm, const blas_int* n, const double* a, const blas_int* lda, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len norm_len) ARMA_NOEXCEPT; // reciprocal of condition number (complex, generic matrix) - void arma_fortran(arma_cgecon)(const char* norm, const blas_int* n, const blas_cxf* a, const blas_int* lda, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info, blas_len norm_len); - void arma_fortran(arma_zgecon)(const char* norm, const blas_int* n, const blas_cxd* a, const blas_int* lda, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info, blas_len norm_len); + void arma_fortran(arma_cgecon)(const char* norm, const blas_int* n, const blas_cxf* a, const blas_int* lda, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info, blas_len norm_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgecon)(const char* norm, const blas_int* n, const blas_cxd* a, const blas_int* lda, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info, blas_len norm_len) ARMA_NOEXCEPT; // reciprocal of condition number (real, symmetric positive definite matrix) - void arma_fortran(arma_spocon)(const char* uplo, const blas_int* n, const float* a, const blas_int* lda, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_dpocon)(const char* uplo, const blas_int* n, const double* a, const blas_int* lda, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len uplo_len); + void arma_fortran(arma_spocon)(const char* uplo, const blas_int* n, const float* a, const blas_int* lda, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dpocon)(const char* uplo, const blas_int* n, const double* a, const blas_int* lda, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; // reciprocal of condition number (complex, hermitian positive definite matrix) - void arma_fortran(arma_cpocon)(const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info, blas_len uplo_len); - void arma_fortran(arma_zpocon)(const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info, blas_len uplo_len); + void arma_fortran(arma_cpocon)(const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zpocon)(const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; // reciprocal of condition number (real, triangular matrix) - void arma_fortran(arma_strcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const float* a, const blas_int* lda, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len norm_len, blas_len uplo_len, blas_len diag_len); - void arma_fortran(arma_dtrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const double* a, const blas_int* lda, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len norm_len, blas_len uplo_len, blas_len diag_len); + void arma_fortran(arma_strcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const float* a, const blas_int* lda, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len norm_len, blas_len uplo_len, blas_len diag_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const double* a, const blas_int* lda, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len norm_len, blas_len uplo_len, blas_len diag_len) ARMA_NOEXCEPT; // reciprocal of condition number (complex, triangular matrix) - void arma_fortran(arma_ctrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* rcond, blas_cxf* work, float* rwork, blas_int* info, blas_len norm_len, blas_len uplo_len, blas_len diag_len); - void arma_fortran(arma_ztrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* rcond, blas_cxd* work, double* rwork, blas_int* info, blas_len norm_len, blas_len uplo_len, blas_len diag_len); + void arma_fortran(arma_ctrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* rcond, blas_cxf* work, float* rwork, blas_int* info, blas_len norm_len, blas_len uplo_len, blas_len diag_len) ARMA_NOEXCEPT; + void arma_fortran(arma_ztrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* rcond, blas_cxd* work, double* rwork, blas_int* info, blas_len norm_len, blas_len uplo_len, blas_len diag_len) ARMA_NOEXCEPT; // reciprocal of condition number (real, band matrix) - void arma_fortran(arma_sgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const float* ab, const blas_int* ldab, const blas_int* ipiv, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len norm_len); - void arma_fortran(arma_dgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const double* ab, const blas_int* ldab, const blas_int* ipiv, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len norm_len); + void arma_fortran(arma_sgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const float* ab, const blas_int* ldab, const blas_int* ipiv, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len norm_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const double* ab, const blas_int* ldab, const blas_int* ipiv, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len norm_len) ARMA_NOEXCEPT; // reciprocal of condition number (complex, band matrix) - void arma_fortran(arma_cgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxf* ab, const blas_int* ldab, const blas_int* ipiv, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info, blas_len norm_len); - void arma_fortran(arma_zgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxd* ab, const blas_int* ldab, const blas_int* ipiv, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info, blas_len norm_len); + void arma_fortran(arma_cgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxf* ab, const blas_int* ldab, const blas_int* ipiv, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info, blas_len norm_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxd* ab, const blas_int* ldab, const blas_int* ipiv, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info, blas_len norm_len) ARMA_NOEXCEPT; // obtain parameters according to the local configuration of lapack - blas_int arma_fortran(arma_ilaenv)(const blas_int* ispec, const char* name, const char* opts, const blas_int* n1, const blas_int* n2, const blas_int* n3, const blas_int* n4, blas_len name_len, blas_len opts_len); + blas_int arma_fortran(arma_ilaenv)(const blas_int* ispec, const char* name, const char* opts, const blas_int* n1, const blas_int* n2, const blas_int* n3, const blas_int* n4, blas_len name_len, blas_len opts_len) ARMA_NOEXCEPT; // calculate eigenvalues of an upper Hessenberg matrix - void arma_fortran(arma_slahqr)(const blas_int* wantt, const blas_int* wantz, const blas_int* n, const blas_int* ilo, const blas_int* ihi, float* h, const blas_int* ldh, float* wr, float* wi, const blas_int* iloz, const blas_int* ihiz, float* z, const blas_int* ldz, blas_int* info); - void arma_fortran(arma_dlahqr)(const blas_int* wantt, const blas_int* wantz, const blas_int* n, const blas_int* ilo, const blas_int* ihi, double* h, const blas_int* ldh, double* wr, double* wi, const blas_int* iloz, const blas_int* ihiz, double* z, const blas_int* ldz, blas_int* info); + void arma_fortran(arma_slahqr)(const blas_int* wantt, const blas_int* wantz, const blas_int* n, const blas_int* ilo, const blas_int* ihi, float* h, const blas_int* ldh, float* wr, float* wi, const blas_int* iloz, const blas_int* ihiz, float* z, const blas_int* ldz, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dlahqr)(const blas_int* wantt, const blas_int* wantz, const blas_int* n, const blas_int* ilo, const blas_int* ihi, double* h, const blas_int* ldh, double* wr, double* wi, const blas_int* iloz, const blas_int* ihiz, double* z, const blas_int* ldz, blas_int* info) ARMA_NOEXCEPT; // calculate eigenvalues of a symmetric tridiagonal matrix - void arma_fortran(arma_sstedc)(const char* compz, const blas_int* n, float* d, float* e, float* z, const blas_int* ldz, float* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len compz_len); - void arma_fortran(arma_dstedc)(const char* compz, const blas_int* n, double* d, double* e, double* z, const blas_int* ldz, double* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len compz_len); + void arma_fortran(arma_sstedc)(const char* compz, const blas_int* n, float* d, float* e, float* z, const blas_int* ldz, float* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len compz_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dstedc)(const char* compz, const blas_int* n, double* d, double* e, double* z, const blas_int* ldz, double* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info, blas_len compz_len) ARMA_NOEXCEPT; // calculate eigenvectors of a Schur form matrix - void arma_fortran(arma_strevc)(const char* side, const char* howmny, blas_int* select, const blas_int* n, const float* t, const blas_int* ldt, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, const blas_int* mm, blas_int* m, float* work, blas_int* info, blas_len side_len, blas_len howmny_len); - void arma_fortran(arma_dtrevc)(const char* side, const char* howmny, blas_int* select, const blas_int* n, const double* t, const blas_int* ldt, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, const blas_int* mm, blas_int* m, double* work, blas_int* info, blas_len side_len, blas_len howmny_len); + void arma_fortran(arma_strevc)(const char* side, const char* howmny, blas_int* select, const blas_int* n, const float* t, const blas_int* ldt, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, const blas_int* mm, blas_int* m, float* work, blas_int* info, blas_len side_len, blas_len howmny_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrevc)(const char* side, const char* howmny, blas_int* select, const blas_int* n, const double* t, const blas_int* ldt, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, const blas_int* mm, blas_int* m, double* work, blas_int* info, blas_len side_len, blas_len howmny_len) ARMA_NOEXCEPT; // generate a vector of random numbers - void arma_fortran(arma_slarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, float* x); - void arma_fortran(arma_dlarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, double* x); + void arma_fortran(arma_slarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, float* x) ARMA_NOEXCEPT; + void arma_fortran(arma_dlarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, double* x) ARMA_NOEXCEPT; // hessenberg decomposition - void arma_fortran(arma_sgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, float* a, const blas_int* lda, float* tao, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, double* a, const blas_int* lda, double* tao, double* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_cgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, blas_cxf* a, const blas_int* lda, blas_cxf* tao, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, blas_cxd* a, const blas_int* lda, blas_cxd* tao, blas_cxd* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, float* a, const blas_int* lda, float* tao, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, double* a, const blas_int* lda, double* tao, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, blas_cxf* a, const blas_int* lda, blas_cxf* tao, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, blas_cxd* a, const blas_int* lda, blas_cxd* tao, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + + // pivoted cholesky + void arma_fortran(arma_spstrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_dpstrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_cpstrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; + void arma_fortran(arma_zpstrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT; #else // prototypes without hidden arguments // LU decomposition - void arma_fortran(arma_sgetrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_dgetrf)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_cgetrf)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_zgetrf)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_int* info); + void arma_fortran(arma_sgetrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgetrf)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgetrf)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgetrf)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations using pre-computed LU decomposition - void arma_fortran(arma_sgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgetrs)(const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // matrix inversion (using pre-computed LU decomposition) - void arma_fortran(arma_sgetri)(const blas_int* n, float* a, const blas_int* lda, const blas_int* ipiv, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgetri)(const blas_int* n, double* a, const blas_int* lda, const blas_int* ipiv, double* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_cgetri)(const blas_int* n, blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zgetri)(const blas_int* n, blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sgetri)(const blas_int* n, float* a, const blas_int* lda, const blas_int* ipiv, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgetri)(const blas_int* n, double* a, const blas_int* lda, const blas_int* ipiv, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgetri)(const blas_int* n, blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgetri)(const blas_int* n, blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // matrix inversion (triangular matrices) - void arma_fortran(arma_strtri)(const char* uplo, const char* diag, const blas_int* n, float* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_dtrtri)(const char* uplo, const char* diag, const blas_int* n, double* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_ctrtri)(const char* uplo, const char* diag, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_ztrtri)(const char* uplo, const char* diag, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info); + void arma_fortran(arma_strtri)(const char* uplo, const char* diag, const blas_int* n, float* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrtri)(const char* uplo, const char* diag, const blas_int* n, double* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_ctrtri)(const char* uplo, const char* diag, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_ztrtri)(const char* uplo, const char* diag, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of general matrix (real) - void arma_fortran(arma_sgeev)(const char* jobvl, const char* jobvr, const blas_int* n, float* a, const blas_int* lda, float* wr, float* wi, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgeev)(const char* jobvl, const char* jobvr, const blas_int* n, double* a, const blas_int* lda, double* wr, double* wi, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, double* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sgeev)(const char* jobvl, const char* jobvr, const blas_int* n, float* a, const blas_int* lda, float* wr, float* wi, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgeev)(const char* jobvl, const char* jobvr, const blas_int* n, double* a, const blas_int* lda, double* wr, double* wi, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of general matrix (complex) - void arma_fortran(arma_cgeev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* w, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info); - void arma_fortran(arma_zgeev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* w, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info); + void arma_fortran(arma_cgeev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* w, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgeev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* w, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of general matrix (real; advanced form) - void arma_fortran(arma_sgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, float* a, const blas_int* lda, float* wr, float* wi, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, double* a, const blas_int* lda, double* wr, double* wi, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, float* a, const blas_int* lda, float* wr, float* wi, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, double* a, const blas_int* lda, double* wr, double* wi, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of general matrix (complex; advanced form) - void arma_fortran(arma_cgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* w, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info); - void arma_fortran(arma_zgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* w, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info); + void arma_fortran(arma_cgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* w, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgeevx)(const char* balanc, const char* jobvl, const char* jobvr, const char* sense, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* w, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_int* ilo, blas_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of symmetric real matrices - void arma_fortran(arma_ssyev)(const char* jobz, const char* uplo, const blas_int* n, float* a, const blas_int* lda, float* w, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dsyev)(const char* jobz, const char* uplo, const blas_int* n, double* a, const blas_int* lda, double* w, double* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_ssyev)(const char* jobz, const char* uplo, const blas_int* n, float* a, const blas_int* lda, float* w, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dsyev)(const char* jobz, const char* uplo, const blas_int* n, double* a, const blas_int* lda, double* w, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of hermitian matrices (complex) - void arma_fortran(arma_cheev)(const char* jobz, const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, float* w, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info); - void arma_fortran(arma_zheev)(const char* jobz, const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, double* w, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info); + void arma_fortran(arma_cheev)(const char* jobz, const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, float* w, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zheev)(const char* jobz, const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, double* w, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of symmetric real matrices by divide and conquer - void arma_fortran(arma_ssyevd)(const char* jobz, const char* uplo, const blas_int* n, float* a, const blas_int* lda, float* w, float* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info); - void arma_fortran(arma_dsyevd)(const char* jobz, const char* uplo, const blas_int* n, double* a, const blas_int* lda, double* w, double* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info); + void arma_fortran(arma_ssyevd)(const char* jobz, const char* uplo, const blas_int* n, float* a, const blas_int* lda, float* w, float* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dsyevd)(const char* jobz, const char* uplo, const blas_int* n, double* a, const blas_int* lda, double* w, double* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of hermitian matrices (complex) by divide and conquer - void arma_fortran(arma_cheevd)(const char* jobz, const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, float* w, blas_cxf* work, const blas_int* lwork, float* rwork, const blas_int* lrwork, blas_int* iwork, const blas_int* liwork, blas_int* info); - void arma_fortran(arma_zheevd)(const char* jobz, const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, double* w, blas_cxd* work, const blas_int* lwork, double* rwork, const blas_int* lrwork, blas_int* iwork, const blas_int* liwork, blas_int* info); + void arma_fortran(arma_cheevd)(const char* jobz, const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, float* w, blas_cxf* work, const blas_int* lwork, float* rwork, const blas_int* lrwork, blas_int* iwork, const blas_int* liwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zheevd)(const char* jobz, const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, double* w, blas_cxd* work, const blas_int* lwork, double* rwork, const blas_int* lrwork, blas_int* iwork, const blas_int* liwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of general real matrix pair - void arma_fortran(arma_sggev)(const char* jobvl, const char* jobvr, const blas_int* n, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* alphar, float* alphai, float* beta, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dggev)(const char* jobvl, const char* jobvr, const blas_int* n, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* alphar, double* alphai, double* beta, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, double* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sggev)(const char* jobvl, const char* jobvr, const blas_int* n, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* alphar, float* alphai, float* beta, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dggev)(const char* jobvl, const char* jobvr, const blas_int* n, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* alphar, double* alphai, double* beta, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // eigen decomposition of general complex matrix pair - void arma_fortran(arma_cggev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_cxf* alpha, blas_cxf* beta, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info); - void arma_fortran(arma_zggev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_cxd* alpha, blas_cxd* beta, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info); + void arma_fortran(arma_cggev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_cxf* alpha, blas_cxf* beta, blas_cxf* vl, const blas_int* ldvl, blas_cxf* vr, const blas_int* ldvr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zggev)(const char* jobvl, const char* jobvr, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_cxd* alpha, blas_cxd* beta, blas_cxd* vl, const blas_int* ldvl, blas_cxd* vr, const blas_int* ldvr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) ARMA_NOEXCEPT; // Cholesky decomposition - void arma_fortran(arma_spotrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_dpotrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_cpotrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_zpotrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info); + void arma_fortran(arma_spotrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dpotrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cpotrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zpotrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations with pre-computed Cholesky decomposition - void arma_fortran(arma_spotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_spotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zpotrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // Cholesky decomposition (band matrices) - void arma_fortran(arma_spbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, float* ab, const blas_int* ldab, blas_int* info); - void arma_fortran(arma_dpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, double* ab, const blas_int* ldab, blas_int* info); - void arma_fortran(arma_cpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, blas_cxf* ab, const blas_int* ldab, blas_int* info); - void arma_fortran(arma_zpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, blas_cxd* ab, const blas_int* ldab, blas_int* info); + void arma_fortran(arma_spbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, float* ab, const blas_int* ldab, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, double* ab, const blas_int* ldab, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, blas_cxf* ab, const blas_int* ldab, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zpbtrf)(const char* uplo, const blas_int* n, const blas_int* kd, blas_cxd* ab, const blas_int* ldab, blas_int* info) ARMA_NOEXCEPT; // matrix inversion (using pre-computed Cholesky decomposition) - void arma_fortran(arma_spotri)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_dpotri)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_cpotri)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info); - void arma_fortran(arma_zpotri)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info); + void arma_fortran(arma_spotri)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dpotri)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cpotri)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zpotri)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* info) ARMA_NOEXCEPT; // QR decomposition - void arma_fortran(arma_sgeqrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* tau, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgeqrf)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* tau, double* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_cgeqrf)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* tau, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zgeqrf)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* tau, blas_cxd* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sgeqrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* tau, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgeqrf)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* tau, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgeqrf)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* tau, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgeqrf)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* tau, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + + // QR decomposition with pivoting (real matrices) + void arma_fortran(arma_sgeqp3)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* jpvt, float* tau, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgeqp3)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, blas_int* jpvt, double* tau, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + + // QR decomposition with pivoting (complex matrices) + void arma_fortran(arma_cgeqp3)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* jpvt, blas_cxf* tau, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgeqp3)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* jpvt, blas_cxd* tau, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) ARMA_NOEXCEPT; // Q matrix calculation from QR decomposition (real matrices) - void arma_fortran(arma_sorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, float* a, const blas_int* lda, const float* tau, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, double* a, const blas_int* lda, const double* tau, double* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, float* a, const blas_int* lda, const float* tau, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, double* a, const blas_int* lda, const double* tau, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // Q matrix calculation from QR decomposition (complex matrices) - void arma_fortran(arma_cungqr)(const blas_int* m, const blas_int* n, const blas_int* k, blas_cxf* a, const blas_int* lda, const blas_cxf* tau, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zungqr)(const blas_int* m, const blas_int* n, const blas_int* k, blas_cxd* a, const blas_int* lda, const blas_cxd* tau, blas_cxd* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_cungqr)(const blas_int* m, const blas_int* n, const blas_int* k, blas_cxf* a, const blas_int* lda, const blas_cxf* tau, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zungqr)(const blas_int* m, const blas_int* n, const blas_int* k, blas_cxd* a, const blas_int* lda, const blas_cxd* tau, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // SVD (real matrices) - void arma_fortran(arma_sgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* s, float* u, const blas_int* ldu, float* vt, const blas_int* ldvt, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* s, double* u, const blas_int* ldu, double* vt, const blas_int* ldvt, double* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* s, float* u, const blas_int* ldu, float* vt, const blas_int* ldvt, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* s, double* u, const blas_int* ldu, double* vt, const blas_int* ldvt, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // SVD (complex matrices) - void arma_fortran(arma_cgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, float* s, blas_cxf* u, const blas_int* ldu, blas_cxf* vt, const blas_int* ldvt, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info); - void arma_fortran(arma_zgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, double* s, blas_cxd* u, const blas_int* ldu, blas_cxd* vt, const blas_int* ldvt, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info); + void arma_fortran(arma_cgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, float* s, blas_cxf* u, const blas_int* ldu, blas_cxf* vt, const blas_int* ldvt, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgesvd)(const char* jobu, const char* jobvt, const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, double* s, blas_cxd* u, const blas_int* ldu, blas_cxd* vt, const blas_int* ldvt, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) ARMA_NOEXCEPT; // SVD (real matrices) by divide and conquer - void arma_fortran(arma_sgesdd)(const char* jobz, const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* s, float* u, const blas_int* ldu, float* vt, const blas_int* ldvt, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgesdd)(const char* jobz, const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* s, double* u, const blas_int* ldu, double* vt, const blas_int* ldvt, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgesdd)(const char* jobz, const blas_int* m, const blas_int* n, float* a, const blas_int* lda, float* s, float* u, const blas_int* ldu, float* vt, const blas_int* ldvt, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgesdd)(const char* jobz, const blas_int* m, const blas_int* n, double* a, const blas_int* lda, double* s, double* u, const blas_int* ldu, double* vt, const blas_int* ldvt, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // SVD (complex matrices) by divide and conquer - void arma_fortran(arma_cgesdd)(const char* jobz, const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, float* s, blas_cxf* u, const blas_int* ldu, blas_cxf* vt, const blas_int* ldvt, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* iwork, blas_int* info); - void arma_fortran(arma_zgesdd)(const char* jobz, const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, double* s, blas_cxd* u, const blas_int* ldu, blas_cxd* vt, const blas_int* ldvt, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info); + void arma_fortran(arma_cgesdd)(const char* jobz, const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, float* s, blas_cxf* u, const blas_int* ldu, blas_cxf* vt, const blas_int* ldvt, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgesdd)(const char* jobz, const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, double* s, blas_cxd* u, const blas_int* ldu, blas_cxd* vt, const blas_int* ldvt, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (general square matrix) - void arma_fortran(arma_sgesv)(const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dgesv)(const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cgesv)(const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zgesv)(const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sgesv)(const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgesv)(const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgesv)(const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgesv)(const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (general square matrix, advanced form, real matrices) - void arma_fortran(arma_sgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* af, const blas_int* ldaf, blas_int* ipiv, char* equed, float* r, float* c, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* af, const blas_int* ldaf, blas_int* ipiv, char* equed, double* r, double* c, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* af, const blas_int* ldaf, blas_int* ipiv, char* equed, float* r, float* c, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* af, const blas_int* ldaf, blas_int* ipiv, char* equed, double* r, double* c, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (general square matrix, advanced form, complex matrices) - void arma_fortran(arma_cgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* af, const blas_int* ldaf, blas_int* ipiv, char* equed, float* r, float* c, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info); - void arma_fortran(arma_zgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* af, const blas_int* ldaf, blas_int* ipiv, char* equed, double* r, double* c, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info); + void arma_fortran(arma_cgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* af, const blas_int* ldaf, blas_int* ipiv, char* equed, float* r, float* c, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgesvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* af, const blas_int* ldaf, blas_int* ipiv, char* equed, double* r, double* c, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (symmetric positive definite matrix) - void arma_fortran(arma_sposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zposv)(const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (symmetric positive definite matrix, advanced form, real matrices) - void arma_fortran(arma_sposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* af, const blas_int* ldaf, char* equed, float* s, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* af, const blas_int* ldaf, char* equed, double* s, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* af, const blas_int* ldaf, char* equed, float* s, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* af, const blas_int* ldaf, char* equed, double* s, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (hermitian positive definite matrix, advanced form, complex matrices) - void arma_fortran(arma_cposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* af, const blas_int* ldaf, char* equed, float* s, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info); - void arma_fortran(arma_zposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* af, const blas_int* ldaf, char* equed, double* s, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info); + void arma_fortran(arma_cposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* af, const blas_int* ldaf, char* equed, float* s, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zposvx)(const char* fact, const char* uplo, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* af, const blas_int* ldaf, char* equed, double* s, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info) ARMA_NOEXCEPT; // solve over/under-determined system of linear equations - void arma_fortran(arma_sgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_cgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_cxd* work, const blas_int* lwork, blas_int* info); + void arma_fortran(arma_sgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgels)(const char* trans, const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; // approximately solve system of linear equations using svd (real) - void arma_fortran(arma_sgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* S, const float* rcond, blas_int* rank, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* S, const double* rcond, blas_int* rank, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, float* a, const blas_int* lda, float* b, const blas_int* ldb, float* S, const float* rcond, blas_int* rank, float* work, const blas_int* lwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, double* a, const blas_int* lda, double* b, const blas_int* ldb, double* S, const double* rcond, blas_int* rank, double* work, const blas_int* lwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + // approximately solve system of linear equations using svd (complex) - void arma_fortran(arma_cgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, float* S, const float* rcond, blas_int* rank, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* iwork, blas_int* info); - void arma_fortran(arma_zgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, double* S, const double* rcond, blas_int* rank, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info); + void arma_fortran(arma_cgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, float* S, const float* rcond, blas_int* rank, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgelsd)(const blas_int* m, const blas_int* n, const blas_int* nrhs, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, double* S, const double* rcond, blas_int* rank, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (triangular matrix) - void arma_fortran(arma_strtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dtrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_ctrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_ztrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_strtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_ctrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_ztrtrs)(const char* uplo, const char* trans, const char* diag, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // LU factorisation (general band matrix) - void arma_fortran(arma_sgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, float* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_dgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, double* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_cgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, blas_cxf* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info); - void arma_fortran(arma_zgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, blas_cxd* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info); + void arma_fortran(arma_sgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, float* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, double* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, blas_cxf* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbtrf)(const blas_int* m, const blas_int* n, const blas_int* kl, const blas_int* ku, blas_cxd* ab, const blas_int* ldab, blas_int* ipiv, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations using pre-computed LU decomposition (general band matrix) - void arma_fortran(arma_sgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const float* ab, const blas_int* ldab, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const double* ab, const blas_int* ldab, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const blas_cxf* ab, const blas_int* ldab, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const blas_cxd* ab, const blas_int* ldab, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const float* ab, const blas_int* ldab, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const double* ab, const blas_int* ldab, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const blas_cxf* ab, const blas_int* ldab, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbtrs)(const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, const blas_cxd* ab, const blas_int* ldab, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (general band matrix) - void arma_fortran(arma_sgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, float* ab, const blas_int* ldab, blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, double* ab, const blas_int* ldab, blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxf* ab, const blas_int* ldab, blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxd* ab, const blas_int* ldab, blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, float* ab, const blas_int* ldab, blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, double* ab, const blas_int* ldab, blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxf* ab, const blas_int* ldab, blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbsv)(const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxd* ab, const blas_int* ldab, blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (general band matrix, advanced form, real matrices) - void arma_fortran(arma_sgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, float* ab, const blas_int* ldab, float* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, float* r, float* c, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, double* ab, const blas_int* ldab, double* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, double* r, double* c, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, float* ab, const blas_int* ldab, float* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, float* r, float* c, float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, double* ab, const blas_int* ldab, double* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, double* r, double* c, double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (general band matrix, advanced form, complex matrices) - void arma_fortran(arma_cgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxf* ab, const blas_int* ldab, blas_cxf* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, float* r, float* c, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info); - void arma_fortran(arma_zgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxd* ab, const blas_int* ldab, blas_cxd* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, double* r, double* c, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info); + void arma_fortran(arma_cgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxf* ab, const blas_int* ldab, blas_cxf* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, float* r, float* c, blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_int* nrhs, blas_cxd* ab, const blas_int* ldab, blas_cxd* afb, const blas_int* ldafb, blas_int* ipiv, char* equed, double* r, double* c, blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (tridiagonal band matrix) - void arma_fortran(arma_sgtsv)(const blas_int* n, const blas_int* nrhs, float* dl, float* d, float* du, float* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_dgtsv)(const blas_int* n, const blas_int* nrhs, double* dl, double* d, double* du, double* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_cgtsv)(const blas_int* n, const blas_int* nrhs, blas_cxf* dl, blas_cxf* d, blas_cxf* du, blas_cxf* b, const blas_int* ldb, blas_int* info); - void arma_fortran(arma_zgtsv)(const blas_int* n, const blas_int* nrhs, blas_cxd* dl, blas_cxd* d, blas_cxd* du, blas_cxd* b, const blas_int* ldb, blas_int* info); + void arma_fortran(arma_sgtsv)(const blas_int* n, const blas_int* nrhs, float* dl, float* d, float* du, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgtsv)(const blas_int* n, const blas_int* nrhs, double* dl, double* d, double* du, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgtsv)(const blas_int* n, const blas_int* nrhs, blas_cxf* dl, blas_cxf* d, blas_cxf* du, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgtsv)(const blas_int* n, const blas_int* nrhs, blas_cxd* dl, blas_cxd* d, blas_cxd* du, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (tridiagonal band matrix, advanced form, real matrices) - void arma_fortran(arma_sgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const float* dl, const float* d, const float* du, float* dlf, float* df, float* duf, float* du2, blas_int* ipiv, const float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const double* dl, const double* d, const double* du, double* dlf, double* df, double* duf, double* du2, blas_int* ipiv, const double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const float* dl, const float* d, const float* du, float* dlf, float* df, float* duf, float* du2, blas_int* ipiv, const float* b, const blas_int* ldb, float* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const double* dl, const double* d, const double* du, double* dlf, double* df, double* duf, double* du2, blas_int* ipiv, const double* b, const blas_int* ldb, double* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // solve system of linear equations (tridiagonal band matrix, advanced form, complex matrices) - void arma_fortran(arma_cgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxf* dl, const blas_cxf* d, const blas_cxf* du, blas_cxf* dlf, blas_cxf* df, blas_cxf* duf, blas_cxf* du2, blas_int* ipiv, const blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info); - void arma_fortran(arma_zgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxd* dl, const blas_cxd* d, const blas_cxd* du, blas_cxd* dlf, blas_cxd* df, blas_cxd* duf, blas_cxd* du2, blas_int* ipiv, const blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info); + void arma_fortran(arma_cgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxf* dl, const blas_cxf* d, const blas_cxf* du, blas_cxf* dlf, blas_cxf* df, blas_cxf* duf, blas_cxf* du2, blas_int* ipiv, const blas_cxf* b, const blas_int* ldb, blas_cxf* x, const blas_int* ldx, float* rcond, float* ferr, float* berr, blas_cxf* work, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgtsvx)(const char* fact, const char* trans, const blas_int* n, const blas_int* nrhs, const blas_cxd* dl, const blas_cxd* d, const blas_cxd* du, blas_cxd* dlf, blas_cxd* df, blas_cxd* duf, blas_cxd* du2, blas_int* ipiv, const blas_cxd* b, const blas_int* ldb, blas_cxd* x, const blas_int* ldx, double* rcond, double* ferr, double* berr, blas_cxd* work, double* rwork, blas_int* info) ARMA_NOEXCEPT; // Schur decomposition (real matrices) - void arma_fortran(arma_sgees)(const char* jobvs, const char* sort, fn_select_s2 select, const blas_int* n, float* a, const blas_int* lda, blas_int* sdim, float* wr, float* wi, float* vs, const blas_int* ldvs, float* work, const blas_int* lwork, blas_int* bwork, blas_int* info); - void arma_fortran(arma_dgees)(const char* jobvs, const char* sort, fn_select_d2 select, const blas_int* n, double* a, const blas_int* lda, blas_int* sdim, double* wr, double* wi, double* vs, const blas_int* ldvs, double* work, const blas_int* lwork, blas_int* bwork, blas_int* info); + void arma_fortran(arma_sgees)(const char* jobvs, const char* sort, fn_select_s2 select, const blas_int* n, float* a, const blas_int* lda, blas_int* sdim, float* wr, float* wi, float* vs, const blas_int* ldvs, float* work, const blas_int* lwork, blas_int* bwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgees)(const char* jobvs, const char* sort, fn_select_d2 select, const blas_int* n, double* a, const blas_int* lda, blas_int* sdim, double* wr, double* wi, double* vs, const blas_int* ldvs, double* work, const blas_int* lwork, blas_int* bwork, blas_int* info) ARMA_NOEXCEPT; // Schur decomposition (complex matrices) - void arma_fortran(arma_cgees)(const char* jobvs, const char* sort, fn_select_c1 select, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* sdim, blas_cxf* w, blas_cxf* vs, const blas_int* ldvs, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* bwork, blas_int* info); - void arma_fortran(arma_zgees)(const char* jobvs, const char* sort, fn_select_z1 select, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* sdim, blas_cxd* w, blas_cxd* vs, const blas_int* ldvs, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info); + void arma_fortran(arma_cgees)(const char* jobvs, const char* sort, fn_select_c1 select, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* sdim, blas_cxf* w, blas_cxf* vs, const blas_int* ldvs, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* bwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgees)(const char* jobvs, const char* sort, fn_select_z1 select, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* sdim, blas_cxd* w, blas_cxd* vs, const blas_int* ldvs, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info) ARMA_NOEXCEPT; // solve a Sylvester equation ax + xb = c, with a and b assumed to be in Schur form - void arma_fortran(arma_strsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const float* a, const blas_int* lda, const float* b, const blas_int* ldb, float* c, const blas_int* ldc, float* scale, blas_int* info); - void arma_fortran(arma_dtrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const double* a, const blas_int* lda, const double* b, const blas_int* ldb, double* c, const blas_int* ldc, double* scale, blas_int* info); - void arma_fortran(arma_ctrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const blas_cxf* a, const blas_int* lda, const blas_cxf* b, const blas_int* ldb, blas_cxf* c, const blas_int* ldc, float* scale, blas_int* info); - void arma_fortran(arma_ztrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const blas_cxd* a, const blas_int* lda, const blas_cxd* b, const blas_int* ldb, blas_cxd* c, const blas_int* ldc, double* scale, blas_int* info); + void arma_fortran(arma_strsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const float* a, const blas_int* lda, const float* b, const blas_int* ldb, float* c, const blas_int* ldc, float* scale, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const double* a, const blas_int* lda, const double* b, const blas_int* ldb, double* c, const blas_int* ldc, double* scale, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_ctrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const blas_cxf* a, const blas_int* lda, const blas_cxf* b, const blas_int* ldb, blas_cxf* c, const blas_int* ldc, float* scale, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_ztrsyl)(const char* transa, const char* transb, const blas_int* isgn, const blas_int* m, const blas_int* n, const blas_cxd* a, const blas_int* lda, const blas_cxd* b, const blas_int* ldb, blas_cxd* c, const blas_int* ldc, double* scale, blas_int* info) ARMA_NOEXCEPT; // QZ decomposition (real matrices) - void arma_fortran(arma_sgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_s3 selctg, const blas_int* n, float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, const blas_int* ldvsl, float* vsr, const blas_int* ldvsr, float* work, const blas_int* lwork, blas_int* bwork, blas_int* info); - void arma_fortran(arma_dgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_d3 selctg, const blas_int* n, double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, const blas_int* ldvsl, double* vsr, const blas_int* ldvsr, double* work, const blas_int* lwork, blas_int* bwork, blas_int* info); + void arma_fortran(arma_sgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_s3 selctg, const blas_int* n, float* a, const blas_int* lda, float* b, const blas_int* ldb, blas_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, const blas_int* ldvsl, float* vsr, const blas_int* ldvsr, float* work, const blas_int* lwork, blas_int* bwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_d3 selctg, const blas_int* n, double* a, const blas_int* lda, double* b, const blas_int* ldb, blas_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, const blas_int* ldvsl, double* vsr, const blas_int* ldvsr, double* work, const blas_int* lwork, blas_int* bwork, blas_int* info) ARMA_NOEXCEPT; // QZ decomposition (complex matrices) - void arma_fortran(arma_cgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_c2 selctg, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* sdim, blas_cxf* alpha, blas_cxf* beta, blas_cxf* vsl, const blas_int* ldvsl, blas_cxf* vsr, const blas_int* ldvsr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* bwork, blas_int* info); - void arma_fortran(arma_zgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_z2 selctg, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* sdim, blas_cxd* alpha, blas_cxd* beta, blas_cxd* vsl, const blas_int* ldvsl, blas_cxd* vsr, const blas_int* ldvsr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info); + void arma_fortran(arma_cgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_c2 selctg, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_cxf* b, const blas_int* ldb, blas_int* sdim, blas_cxf* alpha, blas_cxf* beta, blas_cxf* vsl, const blas_int* ldvsl, blas_cxf* vsr, const blas_int* ldvsr, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* bwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgges)(const char* jobvsl, const char* jobvsr, const char* sort, fn_select_z2 selctg, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_cxd* b, const blas_int* ldb, blas_int* sdim, blas_cxd* alpha, blas_cxd* beta, blas_cxd* vsl, const blas_int* ldvsl, blas_cxd* vsr, const blas_int* ldvsr, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info) ARMA_NOEXCEPT; // 1-norm (general matrix) - float arma_fortran(arma_slange)(const char* norm, const blas_int* m, const blas_int* n, const float* a, const blas_int* lda, float* work); - double arma_fortran(arma_dlange)(const char* norm, const blas_int* m, const blas_int* n, const double* a, const blas_int* lda, double* work); - float arma_fortran(arma_clange)(const char* norm, const blas_int* m, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work); - double arma_fortran(arma_zlange)(const char* norm, const blas_int* m, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work); + float arma_fortran(arma_slange)(const char* norm, const blas_int* m, const blas_int* n, const float* a, const blas_int* lda, float* work) ARMA_NOEXCEPT; + double arma_fortran(arma_dlange)(const char* norm, const blas_int* m, const blas_int* n, const double* a, const blas_int* lda, double* work) ARMA_NOEXCEPT; + float arma_fortran(arma_clange)(const char* norm, const blas_int* m, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work) ARMA_NOEXCEPT; + double arma_fortran(arma_zlange)(const char* norm, const blas_int* m, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work) ARMA_NOEXCEPT; // 1-norm (real symmetric matrix) - float arma_fortran(arma_slansy)(const char* norm, const char* uplo, const blas_int* n, const float* a, const blas_int* lda, float* work); - double arma_fortran(arma_dlansy)(const char* norm, const char* uplo, const blas_int* n, const double* a, const blas_int* lda, double* work); - float arma_fortran(arma_clansy)(const char* norm, const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work); - double arma_fortran(arma_zlansy)(const char* norm, const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work); + float arma_fortran(arma_slansy)(const char* norm, const char* uplo, const blas_int* n, const float* a, const blas_int* lda, float* work) ARMA_NOEXCEPT; + double arma_fortran(arma_dlansy)(const char* norm, const char* uplo, const blas_int* n, const double* a, const blas_int* lda, double* work) ARMA_NOEXCEPT; + float arma_fortran(arma_clansy)(const char* norm, const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work) ARMA_NOEXCEPT; + double arma_fortran(arma_zlansy)(const char* norm, const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work) ARMA_NOEXCEPT; // 1-norm (complex hermitian matrix) - float arma_fortran(arma_clanhe)(const char* norm, const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work); - double arma_fortran(arma_zlanhe)(const char* norm, const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work); + float arma_fortran(arma_clanhe)(const char* norm, const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* work) ARMA_NOEXCEPT; + double arma_fortran(arma_zlanhe)(const char* norm, const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* work) ARMA_NOEXCEPT; // 1-norm (band matrix) - float arma_fortran(arma_slangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const float* ab, const blas_int* ldab, float* work); - double arma_fortran(arma_dlangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const double* ab, const blas_int* ldab, double* work); - float arma_fortran(arma_clangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxf* ab, const blas_int* ldab, float* work); - double arma_fortran(arma_zlangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxd* ab, const blas_int* ldab, double* work); + float arma_fortran(arma_slangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const float* ab, const blas_int* ldab, float* work) ARMA_NOEXCEPT; + double arma_fortran(arma_dlangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const double* ab, const blas_int* ldab, double* work) ARMA_NOEXCEPT; + float arma_fortran(arma_clangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxf* ab, const blas_int* ldab, float* work) ARMA_NOEXCEPT; + double arma_fortran(arma_zlangb)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxd* ab, const blas_int* ldab, double* work) ARMA_NOEXCEPT; // reciprocal of condition number (real, generic matrix) - void arma_fortran(arma_sgecon)(const char* norm, const blas_int* n, const float* a, const blas_int* lda, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgecon)(const char* norm, const blas_int* n, const double* a, const blas_int* lda, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgecon)(const char* norm, const blas_int* n, const float* a, const blas_int* lda, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgecon)(const char* norm, const blas_int* n, const double* a, const blas_int* lda, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // reciprocal of condition number (complex, generic matrix) - void arma_fortran(arma_cgecon)(const char* norm, const blas_int* n, const blas_cxf* a, const blas_int* lda, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info); - void arma_fortran(arma_zgecon)(const char* norm, const blas_int* n, const blas_cxd* a, const blas_int* lda, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info); + void arma_fortran(arma_cgecon)(const char* norm, const blas_int* n, const blas_cxf* a, const blas_int* lda, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgecon)(const char* norm, const blas_int* n, const blas_cxd* a, const blas_int* lda, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info) ARMA_NOEXCEPT; // reciprocal of condition number (real, symmetric positive definite matrix) - void arma_fortran(arma_spocon)(const char* uplo, const blas_int* n, const float* a, const blas_int* lda, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dpocon)(const char* uplo, const blas_int* n, const double* a, const blas_int* lda, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info); + void arma_fortran(arma_spocon)(const char* uplo, const blas_int* n, const float* a, const blas_int* lda, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dpocon)(const char* uplo, const blas_int* n, const double* a, const blas_int* lda, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // reciprocal of condition number (complex, hermitian positive definite matrix) - void arma_fortran(arma_cpocon)(const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info); - void arma_fortran(arma_zpocon)(const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info); + void arma_fortran(arma_cpocon)(const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zpocon)(const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info) ARMA_NOEXCEPT; // reciprocal of condition number (real, triangular matrix) - void arma_fortran(arma_strcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const float* a, const blas_int* lda, float* rcond, float* work, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dtrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const double* a, const blas_int* lda, double* rcond, double* work, blas_int* iwork, blas_int* info); + void arma_fortran(arma_strcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const float* a, const blas_int* lda, float* rcond, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const double* a, const blas_int* lda, double* rcond, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // reciprocal of condition number (complex, triangular matrix) - void arma_fortran(arma_ctrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* rcond, blas_cxf* work, float* rwork, blas_int* info); - void arma_fortran(arma_ztrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* rcond, blas_cxd* work, double* rwork, blas_int* info); + void arma_fortran(arma_ctrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const blas_cxf* a, const blas_int* lda, float* rcond, blas_cxf* work, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_ztrcon)(const char* norm, const char* uplo, const char* diag, const blas_int* n, const blas_cxd* a, const blas_int* lda, double* rcond, blas_cxd* work, double* rwork, blas_int* info) ARMA_NOEXCEPT; // reciprocal of condition number (real, band matrix) - void arma_fortran(arma_sgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const float* ab, const blas_int* ldab, const blas_int* ipiv, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info); - void arma_fortran(arma_dgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const double* ab, const blas_int* ldab, const blas_int* ipiv, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info); + void arma_fortran(arma_sgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const float* ab, const blas_int* ldab, const blas_int* ipiv, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const double* ab, const blas_int* ldab, const blas_int* ipiv, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT; // reciprocal of condition number (complex, band matrix) - void arma_fortran(arma_cgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxf* ab, const blas_int* ldab, const blas_int* ipiv, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info); - void arma_fortran(arma_zgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxd* ab, const blas_int* ldab, const blas_int* ipiv, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info); + void arma_fortran(arma_cgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxf* ab, const blas_int* ldab, const blas_int* ipiv, const float* anorm, float* rcond, blas_cxf* work, float* rwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgbcon)(const char* norm, const blas_int* n, const blas_int* kl, const blas_int* ku, const blas_cxd* ab, const blas_int* ldab, const blas_int* ipiv, const double* anorm, double* rcond, blas_cxd* work, double* rwork, blas_int* info) ARMA_NOEXCEPT; // obtain parameters according to the local configuration of lapack // NOTE: DO NOT USE THIS FORM; kept only for compatibility // NOTE: this function takes 'name' and 'opts' argumments, which are strings with length != 1; their length needs to be given via "hidden" parameters, which this form lacks - blas_int arma_fortran(arma_ilaenv)(const blas_int* ispec, const char* name, const char* opts, const blas_int* n1, const blas_int* n2, const blas_int* n3, const blas_int* n4); + blas_int arma_fortran(arma_ilaenv)(const blas_int* ispec, const char* name, const char* opts, const blas_int* n1, const blas_int* n2, const blas_int* n3, const blas_int* n4) ARMA_NOEXCEPT; // calculate eigenvalues of an upper Hessenberg matrix - void arma_fortran(arma_slahqr)(const blas_int* wantt, const blas_int* wantz, const blas_int* n, const blas_int* ilo, const blas_int* ihi, float* h, const blas_int* ldh, float* wr, float* wi, const blas_int* iloz, const blas_int* ihiz, float* z, const blas_int* ldz, blas_int* info); - void arma_fortran(arma_dlahqr)(const blas_int* wantt, const blas_int* wantz, const blas_int* n, const blas_int* ilo, const blas_int* ihi, double* h, const blas_int* ldh, double* wr, double* wi, const blas_int* iloz, const blas_int* ihiz, double* z, const blas_int* ldz, blas_int* info); + void arma_fortran(arma_slahqr)(const blas_int* wantt, const blas_int* wantz, const blas_int* n, const blas_int* ilo, const blas_int* ihi, float* h, const blas_int* ldh, float* wr, float* wi, const blas_int* iloz, const blas_int* ihiz, float* z, const blas_int* ldz, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dlahqr)(const blas_int* wantt, const blas_int* wantz, const blas_int* n, const blas_int* ilo, const blas_int* ihi, double* h, const blas_int* ldh, double* wr, double* wi, const blas_int* iloz, const blas_int* ihiz, double* z, const blas_int* ldz, blas_int* info) ARMA_NOEXCEPT; // calculate eigenvalues of a symmetric tridiagonal matrix - void arma_fortran(arma_sstedc)(const char* compz, const blas_int* n, float* d, float* e, float* z, const blas_int* ldz, float* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info); - void arma_fortran(arma_dstedc)(const char* compz, const blas_int* n, double* d, double* e, double* z, const blas_int* ldz, double* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info); + void arma_fortran(arma_sstedc)(const char* compz, const blas_int* n, float* d, float* e, float* z, const blas_int* ldz, float* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dstedc)(const char* compz, const blas_int* n, double* d, double* e, double* z, const blas_int* ldz, double* work, const blas_int* lwork, blas_int* iwork, const blas_int* liwork, blas_int* info) ARMA_NOEXCEPT; // calculate eigenvectors of a Schur form matrix - void arma_fortran(arma_strevc)(const char* side, const char* howmny, blas_int* select, const blas_int* n, const float* t, const blas_int* ldt, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, const blas_int* mm, blas_int* m, float* work, blas_int* info); - void arma_fortran(arma_dtrevc)(const char* side, const char* howmny, blas_int* select, const blas_int* n, const double* t, const blas_int* ldt, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, const blas_int* mm, blas_int* m, double* work, blas_int* info); + void arma_fortran(arma_strevc)(const char* side, const char* howmny, blas_int* select, const blas_int* n, const float* t, const blas_int* ldt, float* vl, const blas_int* ldvl, float* vr, const blas_int* ldvr, const blas_int* mm, blas_int* m, float* work, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dtrevc)(const char* side, const char* howmny, blas_int* select, const blas_int* n, const double* t, const blas_int* ldt, double* vl, const blas_int* ldvl, double* vr, const blas_int* ldvr, const blas_int* mm, blas_int* m, double* work, blas_int* info) ARMA_NOEXCEPT; // generate a vector of random numbers - void arma_fortran(arma_slarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, float* x); - void arma_fortran(arma_dlarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, double* x); + void arma_fortran(arma_slarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, float* x) ARMA_NOEXCEPT; + void arma_fortran(arma_dlarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, double* x) ARMA_NOEXCEPT; // hessenberg decomposition - void arma_fortran(arma_sgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, float* a, const blas_int* lda, float* tao, float* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_dgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, double* a, const blas_int* lda, double* tao, double* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_cgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, blas_cxf* a, const blas_int* lda, blas_cxf* tao, blas_cxf* work, const blas_int* lwork, blas_int* info); - void arma_fortran(arma_zgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, blas_cxd* a, const blas_int* lda, blas_cxd* tao, blas_cxd* work, const blas_int* lwork, blas_int* info); - + void arma_fortran(arma_sgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, float* a, const blas_int* lda, float* tao, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, double* a, const blas_int* lda, double* tao, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, blas_cxf* a, const blas_int* lda, blas_cxf* tao, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zgehrd)(const blas_int* n, const blas_int* ilo, const blas_int* ihi, blas_cxd* a, const blas_int* lda, blas_cxd* tao, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT; + + // pivoted cholesky + void arma_fortran(arma_spstrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_dpstrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_cpstrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info) ARMA_NOEXCEPT; + void arma_fortran(arma_zpstrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info) ARMA_NOEXCEPT; + #endif } +#undef ARMA_NOEXCEPT #endif diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/def_superlu.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/def_superlu.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/def_superlu.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/def_superlu.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,12 +29,37 @@ extern void arma_wrapper(cgssvx)(superlu::superlu_options_t*, superlu::SuperMatrix*, int*, int*, int*, char*, float*, float*, superlu::SuperMatrix*, superlu::SuperMatrix*, void*, int, superlu::SuperMatrix*, superlu::SuperMatrix*, float*, float*, float*, float*, superlu::GlobalLU_t*, superlu::mem_usage_t*, superlu::SuperLUStat_t*, int*); extern void arma_wrapper(zgssvx)(superlu::superlu_options_t*, superlu::SuperMatrix*, int*, int*, int*, char*, double*, double*, superlu::SuperMatrix*, superlu::SuperMatrix*, void*, int, superlu::SuperMatrix*, superlu::SuperMatrix*, double*, double*, double*, double*, superlu::GlobalLU_t*, superlu::mem_usage_t*, superlu::SuperLUStat_t*, int*); + extern void arma_wrapper(sgstrf)(superlu::superlu_options_t*, superlu::SuperMatrix*, int, int, int*, void*, int, int*, int*, superlu::SuperMatrix*, superlu::SuperMatrix*, superlu::GlobalLU_t*, superlu::SuperLUStat_t*, int*); + extern void arma_wrapper(dgstrf)(superlu::superlu_options_t*, superlu::SuperMatrix*, int, int, int*, void*, int, int*, int*, superlu::SuperMatrix*, superlu::SuperMatrix*, superlu::GlobalLU_t*, superlu::SuperLUStat_t*, int*); + extern void arma_wrapper(cgstrf)(superlu::superlu_options_t*, superlu::SuperMatrix*, int, int, int*, void*, int, int*, int*, superlu::SuperMatrix*, superlu::SuperMatrix*, superlu::GlobalLU_t*, superlu::SuperLUStat_t*, int*); + extern void arma_wrapper(zgstrf)(superlu::superlu_options_t*, superlu::SuperMatrix*, int, int, int*, void*, int, int*, int*, superlu::SuperMatrix*, superlu::SuperMatrix*, superlu::GlobalLU_t*, superlu::SuperLUStat_t*, int*); + + extern void arma_wrapper(sgstrs)(superlu::trans_t, superlu::SuperMatrix*, superlu::SuperMatrix*, int*, int*, superlu::SuperMatrix*, superlu::SuperLUStat_t*, int*); + extern void arma_wrapper(dgstrs)(superlu::trans_t, superlu::SuperMatrix*, superlu::SuperMatrix*, int*, int*, superlu::SuperMatrix*, superlu::SuperLUStat_t*, int*); + extern void arma_wrapper(cgstrs)(superlu::trans_t, superlu::SuperMatrix*, superlu::SuperMatrix*, int*, int*, superlu::SuperMatrix*, superlu::SuperLUStat_t*, int*); + extern void arma_wrapper(zgstrs)(superlu::trans_t, superlu::SuperMatrix*, superlu::SuperMatrix*, int*, int*, superlu::SuperMatrix*, superlu::SuperLUStat_t*, int*); + + extern float arma_wrapper(slangs)(char* norm, superlu::SuperMatrix* A); + extern double arma_wrapper(dlangs)(char* norm, superlu::SuperMatrix* A); + extern float arma_wrapper(clangs)(char* norm, superlu::SuperMatrix* A); + extern double arma_wrapper(zlangs)(char* norm, superlu::SuperMatrix* A); + + extern void arma_wrapper(sgscon)(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, float anorm, float* rcond, superlu::SuperLUStat_t* stat, int* info); + extern void arma_wrapper(dgscon)(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, double anorm, double* rcond, superlu::SuperLUStat_t* stat, int* info); + extern void arma_wrapper(cgscon)(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, float anorm, float* rcond, superlu::SuperLUStat_t* stat, int* info); + extern void arma_wrapper(zgscon)(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, double anorm, double* rcond, superlu::SuperLUStat_t* stat, int* info); + extern void arma_wrapper(StatInit)(superlu::SuperLUStat_t*); extern void arma_wrapper(StatFree)(superlu::SuperLUStat_t*); extern void arma_wrapper(set_default_options)(superlu::superlu_options_t*); + extern void arma_wrapper(get_perm_c)(int, superlu::SuperMatrix*, int*); + extern int arma_wrapper(sp_ienv)(int); + extern void arma_wrapper(sp_preorder)(superlu::superlu_options_t*, superlu::SuperMatrix*, int*, int*, superlu::SuperMatrix*); + extern void arma_wrapper(Destroy_SuperNode_Matrix)(superlu::SuperMatrix*); extern void arma_wrapper(Destroy_CompCol_Matrix)(superlu::SuperMatrix*); + extern void arma_wrapper(Destroy_CompCol_Permuted)(superlu::SuperMatrix*); extern void arma_wrapper(Destroy_SuperMatrix_Store)(superlu::SuperMatrix*); // We also need superlu_malloc() and superlu_free(). diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/diagmat_proxy.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/diagmat_proxy.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/diagmat_proxy.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/diagmat_proxy.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -90,7 +92,7 @@ } - arma_inline bool is_alias(const Mat&) const { return false; } + inline bool is_alias(const Mat& X) const { return P.is_alias(X); } const Proxy P; const bool P_is_vec; @@ -143,6 +145,12 @@ const T1& P; + //// this may require T1::n_elem etc to be declared as static constexpr inline variables (C++17) + //// see also the notes in Mat::fixed + // static constexpr bool P_is_vec = (T1::n_rows == 1) || (T1::n_cols == 1); + // static constexpr uword n_rows = P_is_vec ? T1::n_elem : T1::n_rows; + // static constexpr uword n_cols = P_is_vec ? T1::n_elem : T1::n_cols; + static const bool P_is_vec = (T1::n_rows == 1) || (T1::n_cols == 1); static const uword n_rows = P_is_vec ? T1::n_elem : T1::n_rows; static const uword n_cols = P_is_vec ? T1::n_elem : T1::n_cols; @@ -161,11 +169,11 @@ template -class diagmat_proxy : public diagmat_proxy_redirect::value >::result +class diagmat_proxy : public diagmat_proxy_redirect::value>::result { public: inline diagmat_proxy(const T1& X) - : diagmat_proxy_redirect< T1, is_Mat_fixed::value >::result(X) + : diagmat_proxy_redirect::value>::result(X) { } }; @@ -226,7 +234,7 @@ arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&P)); } - static const bool P_is_vec = true; + static constexpr bool P_is_vec = true; const Row& P; const uword n_rows; @@ -258,7 +266,7 @@ arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&P)); } - static const bool P_is_vec = true; + static constexpr bool P_is_vec = true; const Col& P; const uword n_rows; @@ -290,7 +298,7 @@ arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&(P.m))); } - static const bool P_is_vec = true; + static constexpr bool P_is_vec = true; const subview_row& P; const uword n_rows; @@ -322,7 +330,7 @@ arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&(P.m))); } - static const bool P_is_vec = true; + static constexpr bool P_is_vec = true; const subview_col& P; const uword n_rows; @@ -331,255 +339,35 @@ -// -// -// - - - -template -class diagmat_proxy_check_default - { - public: - - typedef typename T1::elem_type elem_type; - typedef typename get_pod_type::result pod_type; - - inline - diagmat_proxy_check_default(const T1& X, const Mat&) - : P(X) - , P_is_vec( (resolves_to_vector::yes) || (P.n_rows == 1) || (P.n_cols == 1) ) - , n_rows( P_is_vec ? P.n_elem : P.n_rows ) - , n_cols( P_is_vec ? P.n_elem : P.n_cols ) - { - arma_extra_debug_sigprint(); - } - - arma_inline elem_type operator[] (const uword i) const { return P_is_vec ? P[i] : P.at(i,i); } - arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); } - - const Mat P; - const bool P_is_vec; - const uword n_rows; - const uword n_cols; - }; - - - -template -class diagmat_proxy_check_fixed +template +class diagmat_proxy< Glue > { public: - typedef typename T1::elem_type eT; typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; inline - diagmat_proxy_check_fixed(const T1& X, const Mat& out) - : P( const_cast(X.memptr()), T1::n_rows, T1::n_cols, (&X == &out), false ) + diagmat_proxy(const Glue& X) { + op_diagmat::apply_times(P, X.A, X.B); + + n_rows = P.n_rows; + n_cols = P.n_cols; + arma_extra_debug_sigprint(); } + arma_inline elem_type operator[] (const uword i) const { return P.at(i,i); } + arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P.at(row,row) : elem_type(0); } - arma_inline eT operator[] (const uword i) const { return P_is_vec ? P[i] : P.at(i,i); } - arma_inline eT at (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); } - - const Mat P; // TODO: why not just store X directly as T1& ? test with fixed size vectors and matrices - - static const bool P_is_vec = (T1::n_rows == 1) || (T1::n_cols == 1); - static const uword n_rows = P_is_vec ? T1::n_elem : T1::n_rows; - static const uword n_cols = P_is_vec ? T1::n_elem : T1::n_cols; - }; - - - -template -struct diagmat_proxy_check_redirect {}; - -template -struct diagmat_proxy_check_redirect { typedef diagmat_proxy_check_default result; }; - -template -struct diagmat_proxy_check_redirect { typedef diagmat_proxy_check_fixed result; }; - - -template -class diagmat_proxy_check : public diagmat_proxy_check_redirect::value >::result - { - public: - inline diagmat_proxy_check(const T1& X, const Mat& out) - : diagmat_proxy_check_redirect< T1, is_Mat_fixed::value >::result(X, out) - { - } - }; - - - -template -class diagmat_proxy_check< Mat > - { - public: - - typedef eT elem_type; - typedef typename get_pod_type::result pod_type; - - - inline - diagmat_proxy_check(const Mat& X, const Mat& out) - : P_local ( (&X == &out) ? new Mat(X) : 0 ) - , P ( (&X == &out) ? (*P_local) : X ) - , P_is_vec( (P.n_rows == 1) || (P.n_cols == 1) ) - , n_rows ( P_is_vec ? P.n_elem : P.n_rows ) - , n_cols ( P_is_vec ? P.n_elem : P.n_cols ) - { - arma_extra_debug_sigprint(); - } - - inline ~diagmat_proxy_check() - { - if(P_local) { delete P_local; } - } - - arma_inline elem_type operator[] (const uword i) const { return P_is_vec ? P[i] : P.at(i,i); } - arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); } - - const Mat* P_local; - const Mat& P; - const bool P_is_vec; - const uword n_rows; - const uword n_cols; - }; - - - -template -class diagmat_proxy_check< Row > - { - public: - - typedef eT elem_type; - typedef typename get_pod_type::result pod_type; - - inline - diagmat_proxy_check(const Row& X, const Mat& out) - : P_local ( (&X == reinterpret_cast*>(&out)) ? new Row(X) : 0 ) - , P ( (&X == reinterpret_cast*>(&out)) ? (*P_local) : X ) - , n_rows (X.n_elem) - , n_cols (X.n_elem) - { - arma_extra_debug_sigprint(); - } - - inline ~diagmat_proxy_check() - { - if(P_local) { delete P_local; } - } - - arma_inline elem_type operator[] (const uword i) const { return P[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); } - - static const bool P_is_vec = true; - - const Row* P_local; - const Row& P; - const uword n_rows; - const uword n_cols; - }; - - - -template -class diagmat_proxy_check< Col > - { - public: - - typedef eT elem_type; - typedef typename get_pod_type::result pod_type; - - inline - diagmat_proxy_check(const Col& X, const Mat& out) - : P_local ( (&X == reinterpret_cast*>(&out)) ? new Col(X) : 0 ) - , P ( (&X == reinterpret_cast*>(&out)) ? (*P_local) : X ) - , n_rows (X.n_elem) - , n_cols (X.n_elem) - { - arma_extra_debug_sigprint(); - } - - inline ~diagmat_proxy_check() - { - if(P_local) { delete P_local; } - } - - arma_inline elem_type operator[] (const uword i) const { return P[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); } - - static const bool P_is_vec = true; - - const Col* P_local; - const Col& P; - const uword n_rows; - const uword n_cols; - }; - - - -template -class diagmat_proxy_check< subview_row > - { - public: - - typedef eT elem_type; - typedef typename get_pod_type::result pod_type; - - inline - diagmat_proxy_check(const subview_row& X, const Mat&) - : P ( X ) - , n_rows ( X.n_elem ) - , n_cols ( X.n_elem ) - { - arma_extra_debug_sigprint(); - } - - arma_inline elem_type operator[] (const uword i) const { return P[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); } - - static const bool P_is_vec = true; - - const Row P; - const uword n_rows; - const uword n_cols; - }; - - - -template -class diagmat_proxy_check< subview_col > - { - public: - - typedef eT elem_type; - typedef typename get_pod_type::result pod_type; - - inline - diagmat_proxy_check(const subview_col& X, const Mat& out) - : P ( const_cast(X.colptr(0)), X.n_rows, (&(X.m) == &out), false ) - , n_rows( X.n_elem ) - , n_cols( X.n_elem ) - { - arma_extra_debug_sigprint(); - } - - arma_inline elem_type operator[] (const uword i) const { return P[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool P_is_vec = true; + static constexpr bool P_is_vec = false; - const Col P; - const uword n_rows; - const uword n_cols; + Mat P; + uword n_rows; + uword n_cols; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/diagview_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/diagview_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/diagview_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/diagview_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,7 +22,7 @@ //! Class for storing data required to extract and set the diagonals of a matrix template -class diagview : public Base > +class diagview : public Base< eT, diagview > { public: @@ -29,9 +31,9 @@ arma_aligned const Mat& m; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; const uword row_offset; const uword col_offset; @@ -39,17 +41,21 @@ const uword n_rows; // equal to n_elem const uword n_elem; - static const uword n_cols = 1; + static constexpr uword n_cols = 1; protected: arma_inline diagview(const Mat& in_m, const uword in_row_offset, const uword in_col_offset, const uword len); - + public: inline ~diagview(); + inline diagview() = delete; + + inline diagview(const diagview& in); + inline diagview( diagview&& in); inline void operator=(const diagview& x); @@ -83,12 +89,12 @@ arma_inline eT operator()(const uword in_n_row, const uword in_n_col) const; - arma_inline const Op,op_htrans> t() const; - arma_inline const Op,op_htrans> ht() const; - arma_inline const Op,op_strans> st() const; - inline void replace(const eT old_val, const eT new_val); + inline void clean(const pod_type threshold); + + inline void clamp(const eT min_val, const eT max_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); @@ -103,13 +109,8 @@ inline static void div_inplace(Mat& out, const diagview& in); - private: - friend class Mat; friend class subview; - - diagview(); - //diagview(const diagview&); // making this private causes an error under gcc 4.1/4.2, but not 4.3 }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/diagview_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/diagview_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/diagview_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/diagview_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,20 +24,56 @@ inline diagview::~diagview() { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); } + template arma_inline diagview::diagview(const Mat& in_m, const uword in_row_offset, const uword in_col_offset, const uword in_len) - : m(in_m) + : m (in_m ) , row_offset(in_row_offset) , col_offset(in_col_offset) - , n_rows(in_len) - , n_elem(in_len) + , n_rows (in_len ) + , n_elem (in_len ) { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); + } + + + +template +inline +diagview::diagview(const diagview& in) + : m (in.m ) + , row_offset(in.row_offset) + , col_offset(in.col_offset) + , n_rows (in.n_rows ) + , n_elem (in.n_elem ) + { + arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in); + } + + + +template +inline +diagview::diagview(diagview&& in) + : m (in.m ) + , row_offset(in.row_offset) + , col_offset(in.col_offset) + , n_rows (in.n_rows ) + , n_elem (in.n_elem ) + { + arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in); + + // for paranoia + + access::rw(in.row_offset) = 0; + access::rw(in.col_offset) = 0; + access::rw(in.n_rows ) = 0; + access::rw(in.n_elem ) = 0; } @@ -50,7 +88,7 @@ diagview& d = *this; - arma_debug_check( (d.n_elem != x.n_elem), "diagview: diagonals have incompatible lengths"); + arma_debug_check( (d.n_elem != x.n_elem), "diagview: diagonals have incompatible lengths" ); Mat& d_m = const_cast< Mat& >(d.m); const Mat& x_m = x.m; @@ -775,7 +813,7 @@ eT& diagview::operator()(const uword ii) { - arma_debug_check( (ii >= n_elem), "diagview::operator(): out of bounds" ); + arma_debug_check_bounds( (ii >= n_elem), "diagview::operator(): out of bounds" ); return (const_cast< Mat& >(m)).at(ii+row_offset, ii+col_offset); } @@ -787,7 +825,7 @@ eT diagview::operator()(const uword ii) const { - arma_debug_check( (ii >= n_elem), "diagview::operator(): out of bounds" ); + arma_debug_check_bounds( (ii >= n_elem), "diagview::operator(): out of bounds" ); return m.at(ii+row_offset, ii+col_offset); } @@ -819,7 +857,7 @@ eT& diagview::operator()(const uword row, const uword col) { - arma_debug_check( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" ); + arma_debug_check_bounds( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" ); return (const_cast< Mat& >(m)).at(row+row_offset, row+col_offset); } @@ -831,7 +869,7 @@ eT diagview::operator()(const uword row, const uword col) const { - arma_debug_check( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" ); + arma_debug_check_bounds( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" ); return m.at(row+row_offset, row+col_offset); } @@ -839,36 +877,6 @@ template -arma_inline -const Op,op_htrans> -diagview::t() const - { - return Op,op_htrans>(*this); - } - - - -template -arma_inline -const Op,op_htrans> -diagview::ht() const - { - return Op,op_htrans>(*this); - } - - - -template -arma_inline -const Op,op_strans> -diagview::st() const - { - return Op,op_strans>(*this); - } - - - -template inline void diagview::replace(const eT old_val, const eT new_val) @@ -900,6 +908,38 @@ } + +template +inline +void +diagview::clean(const typename get_pod_type::result threshold) + { + arma_extra_debug_sigprint(); + + Mat tmp(*this); + + tmp.clean(threshold); + + (*this).operator=(tmp); + } + + + +template +inline +void +diagview::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + Mat tmp(*this); + + tmp.clamp(min_val, max_val); + + (*this).operator=(tmp); + } + + template inline diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/diskio_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/diskio_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/diskio_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/diskio_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,6 +25,21 @@ { public: + inline arma_deprecated static file_type guess_file_type(std::istream& f); + + + private: + + template friend class Mat; + template friend class Cube; + template friend class SpMat; + template friend class field; + + friend class Mat_aux; + friend class Cube_aux; + friend class SpMat_aux; + friend class field_aux; + template inline arma_cold static std::string gen_txt_header(const Mat&); template inline arma_cold static std::string gen_bin_header(const Mat&); @@ -31,8 +48,6 @@ template inline arma_cold static std::string gen_txt_header(const Cube&); template inline arma_cold static std::string gen_bin_header(const Cube&); - inline arma_deprecated static file_type guess_file_type(std::istream& f); - inline arma_cold static file_type guess_file_type_internal(std::istream& f); inline arma_cold static std::string gen_tmp_name(const std::string& x); @@ -42,7 +57,7 @@ template inline static bool convert_token(eT& val, const std::string& token); template inline static bool convert_token(std::complex& val, const std::string& token); - template arma_deprecated inline static bool convert_naninf(eT& val, const std::string& token); + template inline static std::streamsize prepare_stream(std::ostream& f); // @@ -51,7 +66,8 @@ template inline static bool save_raw_ascii (const Mat& x, const std::string& final_name); template inline static bool save_raw_binary (const Mat& x, const std::string& final_name); template inline static bool save_arma_ascii (const Mat& x, const std::string& final_name); - template inline static bool save_csv_ascii (const Mat& x, const std::string& final_name); + template inline static bool save_csv_ascii (const Mat& x, const std::string& final_name, const field& header, const bool with_header, const char separator); + template inline static bool save_coord_ascii(const Mat& x, const std::string& final_name); template inline static bool save_arma_binary(const Mat& x, const std::string& final_name); template inline static bool save_pgm_binary (const Mat& x, const std::string& final_name); template inline static bool save_pgm_binary (const Mat< std::complex >& x, const std::string& final_name); @@ -60,8 +76,10 @@ template inline static bool save_raw_ascii (const Mat& x, std::ostream& f); template inline static bool save_raw_binary (const Mat& x, std::ostream& f); template inline static bool save_arma_ascii (const Mat& x, std::ostream& f); - template inline static bool save_csv_ascii (const Mat& x, std::ostream& f); - template inline static bool save_csv_ascii (const Mat< std::complex >& x, std::ostream& f); + template inline static bool save_csv_ascii (const Mat& x, std::ostream& f, const char separator); + template inline static bool save_csv_ascii (const Mat< std::complex >& x, std::ostream& f, const char separator); + template inline static bool save_coord_ascii(const Mat& x, std::ostream& f); + template inline static bool save_coord_ascii(const Mat< std::complex >& x, std::ostream& f); template inline static bool save_arma_binary(const Mat& x, std::ostream& f); template inline static bool save_pgm_binary (const Mat& x, std::ostream& f); template inline static bool save_pgm_binary (const Mat< std::complex >& x, std::ostream& f); @@ -73,7 +91,8 @@ template inline static bool load_raw_ascii (Mat& x, const std::string& name, std::string& err_msg); template inline static bool load_raw_binary (Mat& x, const std::string& name, std::string& err_msg); template inline static bool load_arma_ascii (Mat& x, const std::string& name, std::string& err_msg); - template inline static bool load_csv_ascii (Mat& x, const std::string& name, std::string& err_msg); + template inline static bool load_csv_ascii (Mat& x, const std::string& name, std::string& err_msg, field& header, const bool with_header, const char separator); + template inline static bool load_coord_ascii(Mat& x, const std::string& name, std::string& err_msg); template inline static bool load_arma_binary(Mat& x, const std::string& name, std::string& err_msg); template inline static bool load_pgm_binary (Mat& x, const std::string& name, std::string& err_msg); template inline static bool load_pgm_binary (Mat< std::complex >& x, const std::string& name, std::string& err_msg); @@ -83,8 +102,10 @@ template inline static bool load_raw_ascii (Mat& x, std::istream& f, std::string& err_msg); template inline static bool load_raw_binary (Mat& x, std::istream& f, std::string& err_msg); template inline static bool load_arma_ascii (Mat& x, std::istream& f, std::string& err_msg); - template inline static bool load_csv_ascii (Mat& x, std::istream& f, std::string& err_msg); - template inline static bool load_csv_ascii (Mat< std::complex >& x, std::istream& f, std::string& err_msg); + template inline static bool load_csv_ascii (Mat& x, std::istream& f, std::string& err_msg, const char separator); + template inline static bool load_csv_ascii (Mat< std::complex >& x, std::istream& f, std::string& err_msg, const char separator); + template inline static bool load_coord_ascii(Mat& x, std::istream& f, std::string& err_msg); + template inline static bool load_coord_ascii(Mat< std::complex >& x, std::istream& f, std::string& err_msg); template inline static bool load_arma_binary(Mat& x, std::istream& f, std::string& err_msg); template inline static bool load_pgm_binary (Mat& x, std::istream& is, std::string& err_msg); template inline static bool load_pgm_binary (Mat< std::complex >& x, std::istream& is, std::string& err_msg); @@ -96,12 +117,12 @@ // // sparse matrix saving - template inline static bool save_csv_ascii (const SpMat& x, const std::string& final_name); + template inline static bool save_csv_ascii (const SpMat& x, const std::string& final_name, const field& header, const bool with_header, const char separator); template inline static bool save_coord_ascii(const SpMat& x, const std::string& final_name); template inline static bool save_arma_binary(const SpMat& x, const std::string& final_name); - template inline static bool save_csv_ascii (const SpMat& x, std::ostream& f); - template inline static bool save_csv_ascii (const SpMat< std::complex >& x, std::ostream& f); + template inline static bool save_csv_ascii (const SpMat& x, std::ostream& f, const char separator); + template inline static bool save_csv_ascii (const SpMat< std::complex >& x, std::ostream& f, const char separator); template inline static bool save_coord_ascii(const SpMat& x, std::ostream& f); template inline static bool save_coord_ascii(const SpMat< std::complex >& x, std::ostream& f); template inline static bool save_arma_binary(const SpMat& x, std::ostream& f); @@ -110,12 +131,12 @@ // // sparse matrix loading - template inline static bool load_csv_ascii (SpMat& x, const std::string& name, std::string& err_msg); + template inline static bool load_csv_ascii (SpMat& x, const std::string& name, std::string& err_msg, field& header, const bool with_header, const char separator); template inline static bool load_coord_ascii(SpMat& x, const std::string& name, std::string& err_msg); template inline static bool load_arma_binary(SpMat& x, const std::string& name, std::string& err_msg); - template inline static bool load_csv_ascii (SpMat& x, std::istream& f, std::string& err_msg); - template inline static bool load_csv_ascii (SpMat< std::complex >& x, std::istream& f, std::string& err_msg); + template inline static bool load_csv_ascii (SpMat& x, std::istream& f, std::string& err_msg, const char separator); + template inline static bool load_csv_ascii (SpMat< std::complex >& x, std::istream& f, std::string& err_msg, const char separator); template inline static bool load_coord_ascii(SpMat& x, std::istream& f, std::string& err_msg); template inline static bool load_coord_ascii(SpMat< std::complex >& x, std::istream& f, std::string& err_msg); template inline static bool load_arma_binary(SpMat& x, std::istream& f, std::string& err_msg); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/diskio_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/diskio_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/diskio_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/diskio_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,7 +24,7 @@ //! Format: "ARMA_MAT_TXT_ABXYZ". //! A is one of: I (for integral types) or F (for floating point types). //! B is one of: U (for unsigned types), S (for signed types), N (for not applicable) or C (for complex types). -//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes. +//! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline arma_cold @@ -31,28 +33,39 @@ { arma_type_check(( is_supported_elem_type::value == false )); - if( is_u8::value) { return std::string("ARMA_MAT_TXT_IU001"); } - else if( is_s8::value) { return std::string("ARMA_MAT_TXT_IS001"); } - else if(is_u16::value) { return std::string("ARMA_MAT_TXT_IU002"); } - else if(is_s16::value) { return std::string("ARMA_MAT_TXT_IS002"); } - else if(is_u32::value) { return std::string("ARMA_MAT_TXT_IU004"); } - else if(is_s32::value) { return std::string("ARMA_MAT_TXT_IS004"); } -#if defined(ARMA_USE_U64S64) - else if(is_u64::value) { return std::string("ARMA_MAT_TXT_IU008"); } - else if(is_s64::value) { return std::string("ARMA_MAT_TXT_IS008"); } -#endif -#if defined(ARMA_ALLOW_LONG) - else if(is_ulng_t_32::value) { return std::string("ARMA_MAT_TXT_IU004"); } - else if(is_slng_t_32::value) { return std::string("ARMA_MAT_TXT_IS004"); } - else if(is_ulng_t_64::value) { return std::string("ARMA_MAT_TXT_IU008"); } - else if(is_slng_t_64::value) { return std::string("ARMA_MAT_TXT_IS008"); } -#endif - else if( is_float::value) { return std::string("ARMA_MAT_TXT_FN004"); } - else if( is_double::value) { return std::string("ARMA_MAT_TXT_FN008"); } - else if( is_cx_float::value) { return std::string("ARMA_MAT_TXT_FC008"); } - else if(is_cx_double::value) { return std::string("ARMA_MAT_TXT_FC016"); } + const char* ARMA_MAT_TXT_IU001 = "ARMA_MAT_TXT_IU001"; + const char* ARMA_MAT_TXT_IS001 = "ARMA_MAT_TXT_IS001"; + const char* ARMA_MAT_TXT_IU002 = "ARMA_MAT_TXT_IU002"; + const char* ARMA_MAT_TXT_IS002 = "ARMA_MAT_TXT_IS002"; + const char* ARMA_MAT_TXT_IU004 = "ARMA_MAT_TXT_IU004"; + const char* ARMA_MAT_TXT_IS004 = "ARMA_MAT_TXT_IS004"; + const char* ARMA_MAT_TXT_IU008 = "ARMA_MAT_TXT_IU008"; + const char* ARMA_MAT_TXT_IS008 = "ARMA_MAT_TXT_IS008"; + const char* ARMA_MAT_TXT_FN004 = "ARMA_MAT_TXT_FN004"; + const char* ARMA_MAT_TXT_FN008 = "ARMA_MAT_TXT_FN008"; + const char* ARMA_MAT_TXT_FC008 = "ARMA_MAT_TXT_FC008"; + const char* ARMA_MAT_TXT_FC016 = "ARMA_MAT_TXT_FC016"; + + char* header = nullptr; + + if( is_u8::value) { header = const_cast(ARMA_MAT_TXT_IU001); } + else if( is_s8::value) { header = const_cast(ARMA_MAT_TXT_IS001); } + else if( is_u16::value) { header = const_cast(ARMA_MAT_TXT_IU002); } + else if( is_s16::value) { header = const_cast(ARMA_MAT_TXT_IS002); } + else if( is_u32::value) { header = const_cast(ARMA_MAT_TXT_IU004); } + else if( is_s32::value) { header = const_cast(ARMA_MAT_TXT_IS004); } + else if( is_u64::value) { header = const_cast(ARMA_MAT_TXT_IU008); } + else if( is_s64::value) { header = const_cast(ARMA_MAT_TXT_IS008); } + else if(is_ulng_t_32::value) { header = const_cast(ARMA_MAT_TXT_IU004); } + else if(is_slng_t_32::value) { header = const_cast(ARMA_MAT_TXT_IS004); } + else if(is_ulng_t_64::value) { header = const_cast(ARMA_MAT_TXT_IU008); } + else if(is_slng_t_64::value) { header = const_cast(ARMA_MAT_TXT_IS008); } + else if( is_float::value) { header = const_cast(ARMA_MAT_TXT_FN004); } + else if( is_double::value) { header = const_cast(ARMA_MAT_TXT_FN008); } + else if( is_cx_float::value) { header = const_cast(ARMA_MAT_TXT_FC008); } + else if(is_cx_double::value) { header = const_cast(ARMA_MAT_TXT_FC016); } - return std::string(); + return std::string(header); } @@ -61,7 +74,7 @@ //! Format: "ARMA_MAT_BIN_ABXYZ". //! A is one of: I (for integral types) or F (for floating point types). //! B is one of: U (for unsigned types), S (for signed types), N (for not applicable) or C (for complex types). -//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes. +//! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline arma_cold @@ -70,28 +83,39 @@ { arma_type_check(( is_supported_elem_type::value == false )); - if( is_u8::value) { return std::string("ARMA_MAT_BIN_IU001"); } - else if( is_s8::value) { return std::string("ARMA_MAT_BIN_IS001"); } - else if(is_u16::value) { return std::string("ARMA_MAT_BIN_IU002"); } - else if(is_s16::value) { return std::string("ARMA_MAT_BIN_IS002"); } - else if(is_u32::value) { return std::string("ARMA_MAT_BIN_IU004"); } - else if(is_s32::value) { return std::string("ARMA_MAT_BIN_IS004"); } -#if defined(ARMA_USE_U64S64) - else if(is_u64::value) { return std::string("ARMA_MAT_BIN_IU008"); } - else if(is_s64::value) { return std::string("ARMA_MAT_BIN_IS008"); } -#endif -#if defined(ARMA_ALLOW_LONG) - else if(is_ulng_t_32::value) { return std::string("ARMA_MAT_BIN_IU004"); } - else if(is_slng_t_32::value) { return std::string("ARMA_MAT_BIN_IS004"); } - else if(is_ulng_t_64::value) { return std::string("ARMA_MAT_BIN_IU008"); } - else if(is_slng_t_64::value) { return std::string("ARMA_MAT_BIN_IS008"); } -#endif - else if( is_float::value) { return std::string("ARMA_MAT_BIN_FN004"); } - else if( is_double::value) { return std::string("ARMA_MAT_BIN_FN008"); } - else if( is_cx_float::value) { return std::string("ARMA_MAT_BIN_FC008"); } - else if(is_cx_double::value) { return std::string("ARMA_MAT_BIN_FC016"); } + const char* ARMA_MAT_BIN_IU001 = "ARMA_MAT_BIN_IU001"; + const char* ARMA_MAT_BIN_IS001 = "ARMA_MAT_BIN_IS001"; + const char* ARMA_MAT_BIN_IU002 = "ARMA_MAT_BIN_IU002"; + const char* ARMA_MAT_BIN_IS002 = "ARMA_MAT_BIN_IS002"; + const char* ARMA_MAT_BIN_IU004 = "ARMA_MAT_BIN_IU004"; + const char* ARMA_MAT_BIN_IS004 = "ARMA_MAT_BIN_IS004"; + const char* ARMA_MAT_BIN_IU008 = "ARMA_MAT_BIN_IU008"; + const char* ARMA_MAT_BIN_IS008 = "ARMA_MAT_BIN_IS008"; + const char* ARMA_MAT_BIN_FN004 = "ARMA_MAT_BIN_FN004"; + const char* ARMA_MAT_BIN_FN008 = "ARMA_MAT_BIN_FN008"; + const char* ARMA_MAT_BIN_FC008 = "ARMA_MAT_BIN_FC008"; + const char* ARMA_MAT_BIN_FC016 = "ARMA_MAT_BIN_FC016"; + + char* header = nullptr; + + if( is_u8::value) { header = const_cast(ARMA_MAT_BIN_IU001); } + else if( is_s8::value) { header = const_cast(ARMA_MAT_BIN_IS001); } + else if( is_u16::value) { header = const_cast(ARMA_MAT_BIN_IU002); } + else if( is_s16::value) { header = const_cast(ARMA_MAT_BIN_IS002); } + else if( is_u32::value) { header = const_cast(ARMA_MAT_BIN_IU004); } + else if( is_s32::value) { header = const_cast(ARMA_MAT_BIN_IS004); } + else if( is_u64::value) { header = const_cast(ARMA_MAT_BIN_IU008); } + else if( is_s64::value) { header = const_cast(ARMA_MAT_BIN_IS008); } + else if(is_ulng_t_32::value) { header = const_cast(ARMA_MAT_BIN_IU004); } + else if(is_slng_t_32::value) { header = const_cast(ARMA_MAT_BIN_IS004); } + else if(is_ulng_t_64::value) { header = const_cast(ARMA_MAT_BIN_IU008); } + else if(is_slng_t_64::value) { header = const_cast(ARMA_MAT_BIN_IS008); } + else if( is_float::value) { header = const_cast(ARMA_MAT_BIN_FN004); } + else if( is_double::value) { header = const_cast(ARMA_MAT_BIN_FN008); } + else if( is_cx_float::value) { header = const_cast(ARMA_MAT_BIN_FC008); } + else if(is_cx_double::value) { header = const_cast(ARMA_MAT_BIN_FC016); } - return std::string(); + return std::string(header); } @@ -100,7 +124,7 @@ //! Format: "ARMA_SPM_BIN_ABXYZ". //! A is one of: I (for integral types) or F (for floating point types). //! B is one of: U (for unsigned types), S (for signed types), N (for not applicable) or C (for complex types). -//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes. +//! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline arma_cold @@ -109,28 +133,39 @@ { arma_type_check(( is_supported_elem_type::value == false )); - if( is_u8::value) { return std::string("ARMA_SPM_BIN_IU001"); } - else if( is_s8::value) { return std::string("ARMA_SPM_BIN_IS001"); } - else if(is_u16::value) { return std::string("ARMA_SPM_BIN_IU002"); } - else if(is_s16::value) { return std::string("ARMA_SPM_BIN_IS002"); } - else if(is_u32::value) { return std::string("ARMA_SPM_BIN_IU004"); } - else if(is_s32::value) { return std::string("ARMA_SPM_BIN_IS004"); } -#if defined(ARMA_USE_U64S64) - else if(is_u64::value) { return std::string("ARMA_SPM_BIN_IU008"); } - else if(is_s64::value) { return std::string("ARMA_SPM_BIN_IS008"); } -#endif -#if defined(ARMA_ALLOW_LONG) - else if(is_ulng_t_32::value) { return std::string("ARMA_SPM_BIN_IU004"); } - else if(is_slng_t_32::value) { return std::string("ARMA_SPM_BIN_IS004"); } - else if(is_ulng_t_64::value) { return std::string("ARMA_SPM_BIN_IU008"); } - else if(is_slng_t_64::value) { return std::string("ARMA_SPM_BIN_IS008"); } -#endif - else if( is_float::value) { return std::string("ARMA_SPM_BIN_FN004"); } - else if( is_double::value) { return std::string("ARMA_SPM_BIN_FN008"); } - else if( is_cx_float::value) { return std::string("ARMA_SPM_BIN_FC008"); } - else if(is_cx_double::value) { return std::string("ARMA_SPM_BIN_FC016"); } + const char* ARMA_SPM_BIN_IU001 = "ARMA_SPM_BIN_IU001"; + const char* ARMA_SPM_BIN_IS001 = "ARMA_SPM_BIN_IS001"; + const char* ARMA_SPM_BIN_IU002 = "ARMA_SPM_BIN_IU002"; + const char* ARMA_SPM_BIN_IS002 = "ARMA_SPM_BIN_IS002"; + const char* ARMA_SPM_BIN_IU004 = "ARMA_SPM_BIN_IU004"; + const char* ARMA_SPM_BIN_IS004 = "ARMA_SPM_BIN_IS004"; + const char* ARMA_SPM_BIN_IU008 = "ARMA_SPM_BIN_IU008"; + const char* ARMA_SPM_BIN_IS008 = "ARMA_SPM_BIN_IS008"; + const char* ARMA_SPM_BIN_FN004 = "ARMA_SPM_BIN_FN004"; + const char* ARMA_SPM_BIN_FN008 = "ARMA_SPM_BIN_FN008"; + const char* ARMA_SPM_BIN_FC008 = "ARMA_SPM_BIN_FC008"; + const char* ARMA_SPM_BIN_FC016 = "ARMA_SPM_BIN_FC016"; + + char* header = nullptr; + + if( is_u8::value) { header = const_cast(ARMA_SPM_BIN_IU001); } + else if( is_s8::value) { header = const_cast(ARMA_SPM_BIN_IS001); } + else if( is_u16::value) { header = const_cast(ARMA_SPM_BIN_IU002); } + else if( is_s16::value) { header = const_cast(ARMA_SPM_BIN_IS002); } + else if( is_u32::value) { header = const_cast(ARMA_SPM_BIN_IU004); } + else if( is_s32::value) { header = const_cast(ARMA_SPM_BIN_IS004); } + else if( is_u64::value) { header = const_cast(ARMA_SPM_BIN_IU008); } + else if( is_s64::value) { header = const_cast(ARMA_SPM_BIN_IS008); } + else if(is_ulng_t_32::value) { header = const_cast(ARMA_SPM_BIN_IU004); } + else if(is_slng_t_32::value) { header = const_cast(ARMA_SPM_BIN_IS004); } + else if(is_ulng_t_64::value) { header = const_cast(ARMA_SPM_BIN_IU008); } + else if(is_slng_t_64::value) { header = const_cast(ARMA_SPM_BIN_IS008); } + else if( is_float::value) { header = const_cast(ARMA_SPM_BIN_FN004); } + else if( is_double::value) { header = const_cast(ARMA_SPM_BIN_FN008); } + else if( is_cx_float::value) { header = const_cast(ARMA_SPM_BIN_FC008); } + else if(is_cx_double::value) { header = const_cast(ARMA_SPM_BIN_FC016); } - return std::string(); + return std::string(header); } @@ -138,7 +173,7 @@ //! Format: "ARMA_CUB_TXT_ABXYZ". //! A is one of: I (for integral types) or F (for floating point types). //! B is one of: U (for unsigned types), S (for signed types), N (for not applicable) or C (for complex types). -//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes. +//! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline arma_cold @@ -146,29 +181,40 @@ diskio::gen_txt_header(const Cube&) { arma_type_check(( is_supported_elem_type::value == false )); + + const char* ARMA_CUB_TXT_IU001 = "ARMA_CUB_TXT_IU001"; + const char* ARMA_CUB_TXT_IS001 = "ARMA_CUB_TXT_IS001"; + const char* ARMA_CUB_TXT_IU002 = "ARMA_CUB_TXT_IU002"; + const char* ARMA_CUB_TXT_IS002 = "ARMA_CUB_TXT_IS002"; + const char* ARMA_CUB_TXT_IU004 = "ARMA_CUB_TXT_IU004"; + const char* ARMA_CUB_TXT_IS004 = "ARMA_CUB_TXT_IS004"; + const char* ARMA_CUB_TXT_IU008 = "ARMA_CUB_TXT_IU008"; + const char* ARMA_CUB_TXT_IS008 = "ARMA_CUB_TXT_IS008"; + const char* ARMA_CUB_TXT_FN004 = "ARMA_CUB_TXT_FN004"; + const char* ARMA_CUB_TXT_FN008 = "ARMA_CUB_TXT_FN008"; + const char* ARMA_CUB_TXT_FC008 = "ARMA_CUB_TXT_FC008"; + const char* ARMA_CUB_TXT_FC016 = "ARMA_CUB_TXT_FC016"; + + char* header = nullptr; + + if( is_u8::value) { header = const_cast(ARMA_CUB_TXT_IU001); } + else if( is_s8::value) { header = const_cast(ARMA_CUB_TXT_IS001); } + else if( is_u16::value) { header = const_cast(ARMA_CUB_TXT_IU002); } + else if( is_s16::value) { header = const_cast(ARMA_CUB_TXT_IS002); } + else if( is_u32::value) { header = const_cast(ARMA_CUB_TXT_IU004); } + else if( is_s32::value) { header = const_cast(ARMA_CUB_TXT_IS004); } + else if( is_u64::value) { header = const_cast(ARMA_CUB_TXT_IU008); } + else if( is_s64::value) { header = const_cast(ARMA_CUB_TXT_IS008); } + else if(is_ulng_t_32::value) { header = const_cast(ARMA_CUB_TXT_IU004); } + else if(is_slng_t_32::value) { header = const_cast(ARMA_CUB_TXT_IS004); } + else if(is_ulng_t_64::value) { header = const_cast(ARMA_CUB_TXT_IU008); } + else if(is_slng_t_64::value) { header = const_cast(ARMA_CUB_TXT_IS008); } + else if( is_float::value) { header = const_cast(ARMA_CUB_TXT_FN004); } + else if( is_double::value) { header = const_cast(ARMA_CUB_TXT_FN008); } + else if( is_cx_float::value) { header = const_cast(ARMA_CUB_TXT_FC008); } + else if(is_cx_double::value) { header = const_cast(ARMA_CUB_TXT_FC016); } - if( is_u8::value) { return std::string("ARMA_CUB_TXT_IU001"); } - else if( is_s8::value) { return std::string("ARMA_CUB_TXT_IS001"); } - else if(is_u16::value) { return std::string("ARMA_CUB_TXT_IU002"); } - else if(is_s16::value) { return std::string("ARMA_CUB_TXT_IS002"); } - else if(is_u32::value) { return std::string("ARMA_CUB_TXT_IU004"); } - else if(is_s32::value) { return std::string("ARMA_CUB_TXT_IS004"); } -#if defined(ARMA_USE_U64S64) - else if(is_u64::value) { return std::string("ARMA_CUB_TXT_IU008"); } - else if(is_s64::value) { return std::string("ARMA_CUB_TXT_IS008"); } -#endif -#if defined(ARMA_ALLOW_LONG) - else if(is_ulng_t_32::value) { return std::string("ARMA_CUB_TXT_IU004"); } - else if(is_slng_t_32::value) { return std::string("ARMA_CUB_TXT_IS004"); } - else if(is_ulng_t_64::value) { return std::string("ARMA_CUB_TXT_IU008"); } - else if(is_slng_t_64::value) { return std::string("ARMA_CUB_TXT_IS008"); } -#endif - else if( is_float::value) { return std::string("ARMA_CUB_TXT_FN004"); } - else if( is_double::value) { return std::string("ARMA_CUB_TXT_FN008"); } - else if( is_cx_float::value) { return std::string("ARMA_CUB_TXT_FC008"); } - else if(is_cx_double::value) { return std::string("ARMA_CUB_TXT_FC016"); } - - return std::string(); + return std::string(header); } @@ -177,7 +223,7 @@ //! Format: "ARMA_CUB_BIN_ABXYZ". //! A is one of: I (for integral types) or F (for floating point types). //! B is one of: U (for unsigned types), S (for signed types), N (for not applicable) or C (for complex types). -//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes. +//! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline arma_cold @@ -186,28 +232,39 @@ { arma_type_check(( is_supported_elem_type::value == false )); - if( is_u8::value) { return std::string("ARMA_CUB_BIN_IU001"); } - else if( is_s8::value) { return std::string("ARMA_CUB_BIN_IS001"); } - else if(is_u16::value) { return std::string("ARMA_CUB_BIN_IU002"); } - else if(is_s16::value) { return std::string("ARMA_CUB_BIN_IS002"); } - else if(is_u32::value) { return std::string("ARMA_CUB_BIN_IU004"); } - else if(is_s32::value) { return std::string("ARMA_CUB_BIN_IS004"); } -#if defined(ARMA_USE_U64S64) - else if(is_u64::value) { return std::string("ARMA_CUB_BIN_IU008"); } - else if(is_s64::value) { return std::string("ARMA_CUB_BIN_IS008"); } -#endif -#if defined(ARMA_ALLOW_LONG) - else if(is_ulng_t_32::value) { return std::string("ARMA_CUB_BIN_IU004"); } - else if(is_slng_t_32::value) { return std::string("ARMA_CUB_BIN_IS004"); } - else if(is_ulng_t_64::value) { return std::string("ARMA_CUB_BIN_IU008"); } - else if(is_slng_t_64::value) { return std::string("ARMA_CUB_BIN_IS008"); } -#endif - else if( is_float::value) { return std::string("ARMA_CUB_BIN_FN004"); } - else if( is_double::value) { return std::string("ARMA_CUB_BIN_FN008"); } - else if( is_cx_float::value) { return std::string("ARMA_CUB_BIN_FC008"); } - else if(is_cx_double::value) { return std::string("ARMA_CUB_BIN_FC016"); } + const char* ARMA_CUB_BIN_IU001 = "ARMA_CUB_BIN_IU001"; + const char* ARMA_CUB_BIN_IS001 = "ARMA_CUB_BIN_IS001"; + const char* ARMA_CUB_BIN_IU002 = "ARMA_CUB_BIN_IU002"; + const char* ARMA_CUB_BIN_IS002 = "ARMA_CUB_BIN_IS002"; + const char* ARMA_CUB_BIN_IU004 = "ARMA_CUB_BIN_IU004"; + const char* ARMA_CUB_BIN_IS004 = "ARMA_CUB_BIN_IS004"; + const char* ARMA_CUB_BIN_IU008 = "ARMA_CUB_BIN_IU008"; + const char* ARMA_CUB_BIN_IS008 = "ARMA_CUB_BIN_IS008"; + const char* ARMA_CUB_BIN_FN004 = "ARMA_CUB_BIN_FN004"; + const char* ARMA_CUB_BIN_FN008 = "ARMA_CUB_BIN_FN008"; + const char* ARMA_CUB_BIN_FC008 = "ARMA_CUB_BIN_FC008"; + const char* ARMA_CUB_BIN_FC016 = "ARMA_CUB_BIN_FC016"; + + char* header = nullptr; + + if( is_u8::value) { header = const_cast(ARMA_CUB_BIN_IU001); } + else if( is_s8::value) { header = const_cast(ARMA_CUB_BIN_IS001); } + else if( is_u16::value) { header = const_cast(ARMA_CUB_BIN_IU002); } + else if( is_s16::value) { header = const_cast(ARMA_CUB_BIN_IS002); } + else if( is_u32::value) { header = const_cast(ARMA_CUB_BIN_IU004); } + else if( is_s32::value) { header = const_cast(ARMA_CUB_BIN_IS004); } + else if( is_u64::value) { header = const_cast(ARMA_CUB_BIN_IU008); } + else if( is_s64::value) { header = const_cast(ARMA_CUB_BIN_IS008); } + else if(is_ulng_t_32::value) { header = const_cast(ARMA_CUB_BIN_IU004); } + else if(is_slng_t_32::value) { header = const_cast(ARMA_CUB_BIN_IS004); } + else if(is_ulng_t_64::value) { header = const_cast(ARMA_CUB_BIN_IU008); } + else if(is_slng_t_64::value) { header = const_cast(ARMA_CUB_BIN_IS008); } + else if( is_float::value) { header = const_cast(ARMA_CUB_BIN_FN004); } + else if( is_double::value) { header = const_cast(ARMA_CUB_BIN_FN008); } + else if( is_cx_float::value) { header = const_cast(ARMA_CUB_BIN_FC008); } + else if(is_cx_double::value) { header = const_cast(ARMA_CUB_BIN_FC016); } - return std::string(); + return std::string(header); } @@ -264,24 +321,33 @@ if(load_okay == false) { return file_type_unknown; } - bool has_binary = false; - bool has_bracket = false; - bool has_comma = false; + bool has_binary = false; + bool has_bracket = false; + bool has_comma = false; + bool has_semicolon = false; for(uword i=0; i= 123) ) { has_binary = true; break; } // the range checking can be made more elaborate + if( (val <= 8) || (val >= 123) ) { has_binary = true; break; } // the range checking can be made more elaborate + + if( (val == '(') || (val == ')') ) { has_bracket = true; } - if( (val == '(') || (val == ')') ) { has_bracket = true; } + if( (val == ';') ) { has_semicolon = true; } - if( (val == ',') ) { has_comma = true; } + if( (val == ',') ) { has_comma = true; } } if(has_binary) { return raw_binary; } - if(has_comma && (has_bracket == false)) { return csv_ascii; } + // ssv_ascii has to be before csv_ascii; + // if the data has semicolons, it suggests a CSV file with semicolon as the separating character; + // the semicolon may be used to allow the comma character to represent the decimal point (eg. 1,2345 vs 1.2345) + + if(has_semicolon && (has_bracket == false)) { return ssv_ascii; } + + if(has_comma && (has_bracket == false)) { return csv_ascii; } return raw_ascii; } @@ -385,7 +451,7 @@ } - char* endptr = NULL; + char* endptr = nullptr; if(is_real::value) { @@ -397,31 +463,28 @@ { // signed integer - #if defined(ARMA_USE_CXX11) || (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) - { - val = eT( std::strtoll(str, &endptr, 10) ); - } - #else - { - val = eT( std::strtol(str, &endptr, 10) ); - } - #endif + val = eT( std::strtoll(str, &endptr, 10) ); } else { // unsigned integer - if(str[0] == '-') { val = eT(0); return true; } - - #if defined(ARMA_USE_CXX11) || (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) - { - val = eT( std::strtoull(str, &endptr, 10) ); - } - #else + if((str[0] == '-') && (N >= 2)) { - val = eT( std::strtoul(str, &endptr, 10) ); + val = eT(0); + + if((str[1] == '-') || (str[1] == '+')) { return false; } + + const char* str_offset1 = &(str[1]); + + std::strtoull(str_offset1, &endptr, 10); + + if(str_offset1 == endptr) { return false; } + + return true; } - #endif + + val = eT( std::strtoull(str, &endptr, 10) ); } } @@ -495,7 +558,7 @@ const bool state_real = diskio::convert_token(val_real, token_real); const bool state_imag = diskio::convert_token(val_imag, token_imag); - state = ((state_real == true) && (state_imag == true)); + state = (state_real && state_imag); val = std::complex(val_real, val_imag); } @@ -506,18 +569,37 @@ template -arma_deprecated inline -bool -diskio::convert_naninf(eT& val, const std::string& token) +std::streamsize +diskio::prepare_stream(std::ostream& f) { - // TODO: remove this function; - // TODO: this function is kept only to allow compilation of old versions of mlpack + std::streamsize cell_width = f.width(); - arma_debug_warn("*** arma::diskio::convert_naninf() is an internal armadillo function subject to removal ***"); + if(is_real::value) + { + f.unsetf(ios::fixed); + f.setf(ios::scientific); + f.fill(' '); + + f.precision(16); + cell_width = 24; + + // NOTE: for 'float' the optimum settings are f.precision(8) and cell_width = 15 + // NOTE: however, to avoid introducing errors in case single precision data is loaded as double precision, + // NOTE: the same settings must be used for both 'float' and 'double' + } + else + if(is_cx::value) + { + f.unsetf(ios::fixed); + f.setf(ios::scientific); + + f.precision(16); + } - return diskio::convert_token(val, token); + return cell_width; } + @@ -560,22 +642,9 @@ { arma_extra_debug_sigprint(); - uword cell_width; - - if(is_real::value) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - cell_width = 22; - } + const arma_ostream_state stream_state(f); - if(is_cx::value) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } + const std::streamsize cell_width = diskio::prepare_stream(f); for(uword row=0; row < x.n_rows; ++row) { @@ -583,15 +652,19 @@ { f.put(' '); - if(is_real::value) { f.width(std::streamsize(cell_width)); } + if(is_real::value) { f.width(cell_width); } - arma_ostream::print_elem(f, x.at(row,col), false); + arma_ostream::raw_print_elem(f, x.at(row,col)); } f.put('\n'); } - return f.good(); + const bool save_okay = f.good(); + + stream_state.restore(f); + + return save_okay; } @@ -653,8 +726,8 @@ std::ofstream f(tmp_name.c_str()); bool save_okay = f.is_open(); - - if(save_okay) + + if(save_okay) { save_okay = diskio::save_arma_ascii(x, f); @@ -678,27 +751,12 @@ { arma_extra_debug_sigprint(); - const ios::fmtflags orig_flags = f.flags(); + const arma_ostream_state stream_state(f); f << diskio::gen_txt_header(x) << '\n'; f << x.n_rows << ' ' << x.n_cols << '\n'; - uword cell_width; - - if(is_real::value) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - cell_width = 22; - } - - if(is_cx::value) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } + const std::streamsize cell_width = diskio::prepare_stream(f); for(uword row=0; row < x.n_rows; ++row) { @@ -706,9 +764,9 @@ { f.put(' '); - if(is_real::value) { f.width(std::streamsize(cell_width)); } + if(is_real::value) { f.width(cell_width); } - arma_ostream::print_elem(f, x.at(row,col), false); + arma_ostream::raw_print_elem(f, x.at(row,col)); } f.put('\n'); @@ -716,7 +774,7 @@ const bool save_okay = f.good(); - f.flags(orig_flags); + stream_state.restore(f); return save_okay; } @@ -727,7 +785,7 @@ template inline bool -diskio::save_csv_ascii(const Mat& x, const std::string& final_name) +diskio::save_csv_ascii(const Mat& x, const std::string& final_name, const field& header, const bool with_header, const char separator) { arma_extra_debug_sigprint(); @@ -737,16 +795,31 @@ bool save_okay = f.is_open(); - if(save_okay) + if(save_okay == false) { return false; } + + if(with_header) { - save_okay = diskio::save_csv_ascii(x, f); + arma_extra_debug_print("diskio::save_csv_ascii(): writing header"); - f.flush(); - f.close(); + for(uword i=0; i < header.n_elem; ++i) + { + f << header.at(i); + + if(i != (header.n_elem-1)) { f.put(separator); } + } - if(save_okay) { save_okay = diskio::safe_rename(tmp_name, final_name); } + f.put('\n'); + + save_okay = f.good(); } + if(save_okay) { save_okay = diskio::save_csv_ascii(x, f, separator); } + + f.flush(); + f.close(); + + if(save_okay) { save_okay = diskio::safe_rename(tmp_name, final_name); } + return save_okay; } @@ -756,18 +829,13 @@ template inline bool -diskio::save_csv_ascii(const Mat& x, std::ostream& f) +diskio::save_csv_ascii(const Mat& x, std::ostream& f, const char separator) { arma_extra_debug_sigprint(); - const ios::fmtflags orig_flags = f.flags(); + const arma_ostream_state stream_state(f); - if( (is_float::value) || (is_double::value) ) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } + diskio::prepare_stream(f); uword x_n_rows = x.n_rows; uword x_n_cols = x.n_cols; @@ -776,9 +844,9 @@ { for(uword col=0; col < x_n_cols; ++col) { - arma_ostream::print_elem(f, x.at(row,col), false); + arma_ostream::raw_print_elem(f, x.at(row,col)); - if( col < (x_n_cols-1) ) { f.put(','); } + if( col < (x_n_cols-1) ) { f.put(separator); } } f.put('\n'); @@ -786,7 +854,7 @@ const bool save_okay = f.good(); - f.flags(orig_flags); + stream_state.restore(f); return save_okay; } @@ -797,20 +865,15 @@ template inline bool -diskio::save_csv_ascii(const Mat< std::complex >& x, std::ostream& f) +diskio::save_csv_ascii(const Mat< std::complex >& x, std::ostream& f, const char separator) { arma_extra_debug_sigprint(); typedef typename std::complex eT; - const ios::fmtflags orig_flags = f.flags(); + const arma_ostream_state stream_state(f); - if( (is_float::value) || (is_double::value) ) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } + diskio::prepare_stream(f); uword x_n_rows = x.n_rows; uword x_n_cols = x.n_cols; @@ -826,12 +889,12 @@ const T tmp_i_abs = (tmp_i < T(0)) ? T(-tmp_i) : T(tmp_i); const char tmp_sign = (tmp_i < T(0)) ? char('-') : char('+'); - arma_ostream::print_elem(f, tmp_r, false); + arma_ostream::raw_print_elem(f, tmp_r ); f.put(tmp_sign); - arma_ostream::print_elem(f, tmp_i_abs, false); + arma_ostream::raw_print_elem(f, tmp_i_abs); f.put('i'); - if( col < (x_n_cols-1) ) { f.put(','); } + if( col < (x_n_cols-1) ) { f.put(separator); } } f.put('\n'); @@ -839,7 +902,125 @@ const bool save_okay = f.good(); - f.flags(orig_flags); + stream_state.restore(f); + + return save_okay; + } + + + +template +inline +bool +diskio::save_coord_ascii(const Mat& x, const std::string& final_name) + { + arma_extra_debug_sigprint(); + + const std::string tmp_name = diskio::gen_tmp_name(final_name); + + std::ofstream f(tmp_name.c_str()); + + bool save_okay = f.is_open(); + + if(save_okay) + { + save_okay = diskio::save_coord_ascii(x, f); + + f.flush(); + f.close(); + + if(save_okay) { save_okay = diskio::safe_rename(tmp_name, final_name); } + } + + return save_okay; + } + + + +template +inline +bool +diskio::save_coord_ascii(const Mat& x, std::ostream& f) + { + arma_extra_debug_sigprint(); + + const arma_ostream_state stream_state(f); + + diskio::prepare_stream(f); + + for(uword col=0; col < x.n_cols; ++col) + for(uword row=0; row < x.n_rows; ++row) + { + const eT val = x.at(row,col); + + if(val != eT(0)) + { + f << row << ' ' << col << ' ' << val << '\n'; + } + } + + // make sure it's possible to figure out the matrix size later + if( (x.n_rows > 0) && (x.n_cols > 0) ) + { + const uword max_row = (x.n_rows > 0) ? x.n_rows-1 : 0; + const uword max_col = (x.n_cols > 0) ? x.n_cols-1 : 0; + + if( x.at(max_row, max_col) == eT(0) ) + { + f << max_row << ' ' << max_col << " 0\n"; + } + } + + const bool save_okay = f.good(); + + stream_state.restore(f); + + return save_okay; + } + + + +template +inline +bool +diskio::save_coord_ascii(const Mat< std::complex >& x, std::ostream& f) + { + arma_extra_debug_sigprint(); + + typedef typename std::complex eT; + + const arma_ostream_state stream_state(f); + + diskio::prepare_stream(f); + + const eT eT_zero = eT(0); + + for(uword col=0; col < x.n_cols; ++col) + for(uword row=0; row < x.n_rows; ++row) + { + const eT val = x.at(row,col); + + if(val != eT_zero) + { + f << row << ' ' << col << ' ' << val.real() << ' ' << val.imag() << '\n'; + } + } + + // make sure it's possible to figure out the matrix size later + if( (x.n_rows > 0) && (x.n_cols > 0) ) + { + const uword max_row = (x.n_rows > 0) ? x.n_rows-1 : 0; + const uword max_col = (x.n_cols > 0) ? x.n_cols-1 : 0; + + if( x.at(max_row, max_col) == eT_zero ) + { + f << max_row << ' ' << max_col << " 0 0\n"; + } + } + + const bool save_okay = f.good(); + + stream_state.restore(f); return save_okay; } @@ -884,7 +1065,7 @@ diskio::save_arma_binary(const Mat& x, std::ostream& f) { arma_extra_debug_sigprint(); - + f << diskio::gen_bin_header(x) << '\n'; f << x.n_rows << ' ' << x.n_cols << '\n'; @@ -927,7 +1108,7 @@ // // TODO: // add functionality to save the image in a normalised format, -// i.e. scaled so that every value falls in the [0,255] range. +// ie. scaled so that every value falls in the [0,255] range. //! Save a matrix as a PGM greyscale image template @@ -1034,10 +1215,10 @@ std::vector groups; std::string full_name = spec.dsname; size_t loc; - while ((loc = full_name.find("/")) != std::string::npos) + while((loc = full_name.find("/")) != std::string::npos) { // Create another group... - if (loc != 0) // Ignore the first /, if there is a leading /. + if(loc != 0) // Ignore the first /, if there is a leading /. { hid_t gid = arma_H5Gcreate((groups.size() == 0) ? file : groups[groups.size() - 1], full_name.substr(0, loc).c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); @@ -1071,7 +1252,7 @@ { save_okay = false; - err_msg = "couldn't create dataset in "; + err_msg = "couldn't create dataset"; } else { @@ -1082,7 +1263,7 @@ arma_H5Tclose(datatype); arma_H5Sclose(dataspace); - for (size_t i = 0; i < groups.size(); ++i) { arma_H5Gclose(groups[i]); } + for(size_t i = 0; i < groups.size(); ++i) { arma_H5Gclose(groups[i]); } arma_H5Fclose(file); if((use_existing_file == false) && (save_okay == true)) { save_okay = diskio::safe_rename(tmp_name, spec.filename); } @@ -1113,7 +1294,7 @@ diskio::load_raw_ascii(Mat& x, const std::string& name, std::string& err_msg) { arma_extra_debug_sigprint(); - + std::fstream f; f.open(name.c_str(), std::fstream::in); @@ -1170,7 +1351,7 @@ uword line_n_cols = 0; - while (line_stream >> token) { ++line_n_cols; } + while(line_stream >> token) { ++line_n_cols; } if(f_n_cols_found == false) { @@ -1182,7 +1363,7 @@ if(line_n_cols != f_n_cols) { load_okay = false; - err_msg = "inconsistent number of columns in "; + err_msg = "inconsistent number of columns"; } } @@ -1195,7 +1376,7 @@ f.clear(); f.seekg(pos1); - x.set_size(f_n_rows, f_n_cols); + try { x.set_size(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } for(uword row=0; ((row < x.n_rows) && load_okay); ++row) for(uword col=0; ((col < x.n_cols) && load_okay); ++col) @@ -1205,7 +1386,7 @@ if(diskio::convert_token(x.at(row,col), token) == false) { load_okay = false; - err_msg = "couldn't interpret data in "; + err_msg = "couldn't interpret data"; } } } @@ -1251,7 +1432,6 @@ diskio::load_raw_binary(Mat& x, std::istream& f, std::string& err_msg) { arma_extra_debug_sigprint(); - arma_ignore(err_msg); f.clear(); const std::streampos pos1 = f.tellg(); @@ -1268,7 +1448,7 @@ //f.seekg(0, ios::beg); f.seekg(pos1); - x.set_size(N / uword(sizeof(eT)), 1); + try { x.set_size(N / uword(sizeof(eT)), 1); } catch(...) { err_msg = "not enough memory"; return false; } f.clear(); f.read( reinterpret_cast(x.memptr()), std::streamsize(x.n_elem * uword(sizeof(eT))) ); @@ -1312,7 +1492,7 @@ arma_extra_debug_sigprint(); std::streampos pos = f.tellg(); - + bool load_okay = true; std::string f_header; @@ -1325,7 +1505,7 @@ if(f_header == diskio::gen_txt_header(x)) { - x.zeros(f_n_rows, f_n_cols); + try { x.zeros(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } std::string token; @@ -1342,7 +1522,7 @@ else { load_okay = false; - err_msg = "incorrect header in "; + err_msg = "incorrect header"; } @@ -1386,7 +1566,7 @@ template inline bool -diskio::load_csv_ascii(Mat& x, const std::string& name, std::string& err_msg) +diskio::load_csv_ascii(Mat& x, const std::string& name, std::string& err_msg, field& header, const bool with_header, const char separator) { arma_extra_debug_sigprint(); @@ -1395,12 +1575,56 @@ bool load_okay = f.is_open(); + if(load_okay == false) { return false; } + + if(with_header) + { + arma_extra_debug_print("diskio::load_csv_ascii(): reading header"); + + std::string header_line; + std::stringstream header_stream; + std::vector header_tokens; + + std::getline(f, header_line); + + load_okay = f.good(); + + if(load_okay) + { + std::string token; + + header_stream.clear(); + header_stream.str(header_line); + + uword header_n_tokens = 0; + + while(header_stream.good()) + { + std::getline(header_stream, token, separator); + ++header_n_tokens; + header_tokens.push_back(token); + } + + if(header_n_tokens == uword(0)) + { + header.reset(); + } + else + { + header.set_size(1,header_n_tokens); + + for(uword i=0; i < header_n_tokens; ++i) { header.at(i) = header_tokens[i]; } + } + } + } + if(load_okay) { - load_okay = diskio::load_csv_ascii(x, f, err_msg); - f.close(); + load_okay = diskio::load_csv_ascii(x, f, err_msg, separator); } + f.close(); + return load_okay; } @@ -1410,13 +1634,13 @@ template inline bool -diskio::load_csv_ascii(Mat& x, std::istream& f, std::string&) +diskio::load_csv_ascii(Mat& x, std::istream& f, std::string& err_msg, const char separator) { arma_extra_debug_sigprint(); // TODO: replace with more efficient implementation - bool load_okay = f.good(); + if(f.good() == false) { return false; } f.clear(); const std::fstream::pos_type pos1 = f.tellg(); @@ -1432,7 +1656,7 @@ std::string token; - while( f.good() && load_okay ) + while(f.good()) { std::getline(f, line_string); @@ -1445,7 +1669,7 @@ while(line_stream.good()) { - std::getline(line_stream, token, ','); + std::getline(line_stream, token, separator); ++line_n_cols; } @@ -1457,49 +1681,113 @@ f.clear(); f.seekg(pos1); - x.zeros(f_n_rows, f_n_cols); + try { x.zeros(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } - uword row = 0; + const bool use_mp = (arma_config::openmp) && (f_n_rows >= 2) && (f_n_cols >= 64); - while(f.good()) + field token_array; + + bool token_array_ok = false; + + if(use_mp) { - std::getline(f, line_string); - - if(line_string.size() == 0) { break; } - - line_stream.clear(); - line_stream.str(line_string); - - uword col = 0; - - while(line_stream.good()) + try { - std::getline(line_stream, token, ','); + token_array.set_size(f_n_cols); - diskio::convert_token( x.at(row,col), token ); + for(uword i=0; i < f_n_cols; ++i) { token_array(i).reserve(32); } - ++col; + token_array_ok = true; + } + catch(...) + { + token_array.reset(); } - - ++row; } - return load_okay; - } - - - -//! Load a matrix in CSV text format (human readable); complex numbers stored in "a+bi" format -template -inline -bool -diskio::load_csv_ascii(Mat< std::complex >& x, std::istream& f, std::string&) - { - arma_extra_debug_sigprint(); - - // TODO: replace with more efficient implementation + if(use_mp && token_array_ok) + { + #if defined(ARMA_USE_OPENMP) + { + uword row = 0; + + while(f.good()) + { + std::getline(f, line_string); + + if(line_string.size() == 0) { break; } + + line_stream.clear(); + line_stream.str(line_string); + + for(uword i=0; i < f_n_cols; ++i) { token_array(i).clear(); } + + uword line_stream_col = 0; + + while(line_stream.good()) + { + std::getline(line_stream, token_array(line_stream_col), separator); + + ++line_stream_col; + } + + const int n_threads = mp_thread_limit::get(); + + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword col=0; col < line_stream_col; ++col) + { + diskio::convert_token( x.at(row,col), token_array(col) ); + } + + ++row; + } + } + #endif + } + else // serial implementation + { + uword row = 0; + + while(f.good()) + { + std::getline(f, line_string); + + if(line_string.size() == 0) { break; } + + line_stream.clear(); + line_stream.str(line_string); + + uword col = 0; + + while(line_stream.good()) + { + std::getline(line_stream, token, separator); + + diskio::convert_token( x.at(row,col), token ); + + ++col; + } + + ++row; + } + } - bool load_okay = f.good(); + return true; + } + + + +//! Load a matrix in CSV text format (human readable); complex numbers stored in "a+bi" format +template +inline +bool +diskio::load_csv_ascii(Mat< std::complex >& x, std::istream& f, std::string& err_msg, const char separator) + { + arma_extra_debug_sigprint(); + + // TODO: replace with more efficient implementation + + if(f.good() == false) { return false; } f.clear(); const std::fstream::pos_type pos1 = f.tellg(); @@ -1515,7 +1803,7 @@ std::string token; - while( f.good() && load_okay ) + while(f.good()) { std::getline(f, line_string); @@ -1528,7 +1816,7 @@ while(line_stream.good()) { - std::getline(line_stream, token, ','); + std::getline(line_stream, token, separator); ++line_n_cols; } @@ -1540,7 +1828,7 @@ f.clear(); f.seekg(pos1); - x.zeros(f_n_rows, f_n_cols); + try { x.zeros(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } uword row = 0; @@ -1560,7 +1848,19 @@ while(line_stream.good()) { - std::getline(line_stream, token, ','); + std::getline(line_stream, token, separator); + + // remove spaces and tabs + if(token.length() > 0) + { + const char c_front = token.front(); + const char c_back = token.back(); + + if( (c_front == ' ') || (c_front == '\t') || (c_back == ' ') || (c_back == '\t') ) + { + token.erase(std::remove_if(token.begin(), token.end(), [](char c) { return ((c == ' ') || (c == '\t')); }), token.end()); + } + } const size_t token_len = size_t( token.length() ); @@ -1714,11 +2014,251 @@ ++row; } + return true; + } + + + +template +inline +bool +diskio::load_coord_ascii(Mat& x, const std::string& name, std::string& err_msg) + { + arma_extra_debug_sigprint(); + + std::fstream f; + f.open(name.c_str(), std::fstream::in); + + bool load_okay = f.is_open(); + + if(load_okay == false) { return false; } + + if(load_okay) + { + load_okay = diskio::load_coord_ascii(x, f, err_msg); + } + + f.close(); + return load_okay; } +//! Load a matrix in CSV text format (human readable) +template +inline +bool +diskio::load_coord_ascii(Mat& x, std::istream& f, std::string& err_msg) + { + arma_extra_debug_sigprint(); + + if(f.good() == false) { return false; } + + f.clear(); + const std::fstream::pos_type pos1 = f.tellg(); + + // work out the size + + uword f_n_rows = 0; + uword f_n_cols = 0; + + bool size_found = false; + + std::string line_string; + std::stringstream line_stream; + + std::string token; + + while(f.good()) + { + std::getline(f, line_string); + + if(line_string.size() == 0) { break; } + + line_stream.clear(); + line_stream.str(line_string); + + uword line_row = 0; + uword line_col = 0; + + // a valid line in co-ord format has at least 2 entries + + line_stream >> line_row; + + if(line_stream.good() == false) { err_msg = "incorrect format"; return false; } + + line_stream >> line_col; + + size_found = true; + + if(f_n_rows < line_row) { f_n_rows = line_row; } + if(f_n_cols < line_col) { f_n_cols = line_col; } + } + + // take into account that indices start at 0 + if(size_found) { ++f_n_rows; ++f_n_cols; } + + f.clear(); + f.seekg(pos1); + + try + { + Mat tmp(f_n_rows, f_n_cols, arma_zeros_indicator()); + + while(f.good()) + { + std::getline(f, line_string); + + if(line_string.size() == 0) { break; } + + line_stream.clear(); + line_stream.str(line_string); + + uword line_row = 0; + uword line_col = 0; + + line_stream >> line_row; + line_stream >> line_col; + + eT val = eT(0); + + line_stream >> token; + + if(line_stream.fail() == false) + { + diskio::convert_token( val, token ); + } + + if(val != eT(0)) { tmp(line_row,line_col) = val; } + } + + x.steal_mem(tmp); + } + catch(...) + { + err_msg = "not enough memory"; + return false; + } + + return true; + } + + + +template +inline +bool +diskio::load_coord_ascii(Mat< std::complex >& x, std::istream& f, std::string& err_msg) + { + arma_extra_debug_sigprint(); + + if(f.good() == false) { return false; } + + f.clear(); + const std::fstream::pos_type pos1 = f.tellg(); + + // work out the size + + uword f_n_rows = 0; + uword f_n_cols = 0; + + bool size_found = false; + + std::string line_string; + std::stringstream line_stream; + + std::string token_real; + std::string token_imag; + + while(f.good()) + { + std::getline(f, line_string); + + if(line_string.size() == 0) { break; } + + line_stream.clear(); + line_stream.str(line_string); + + uword line_row = 0; + uword line_col = 0; + + // a valid line in co-ord format has at least 2 entries + + line_stream >> line_row; + + if(line_stream.good() == false) { err_msg = "incorrect format"; return false; } + + line_stream >> line_col; + + size_found = true; + + if(f_n_rows < line_row) f_n_rows = line_row; + if(f_n_cols < line_col) f_n_cols = line_col; + } + + // take into account that indices start at 0 + if(size_found) { ++f_n_rows; ++f_n_cols; } + + f.clear(); + f.seekg(pos1); + + try + { + Mat< std::complex > tmp(f_n_rows, f_n_cols, arma_zeros_indicator()); + + while(f.good()) + { + std::getline(f, line_string); + + if(line_string.size() == 0) { break; } + + line_stream.clear(); + line_stream.str(line_string); + + uword line_row = 0; + uword line_col = 0; + + line_stream >> line_row; + line_stream >> line_col; + + T val_real = T(0); + T val_imag = T(0); + + line_stream >> token_real; + + if(line_stream.fail() == false) + { + diskio::convert_token( val_real, token_real ); + } + + + line_stream >> token_imag; + + if(line_stream.fail() == false) + { + diskio::convert_token( val_imag, token_imag ); + } + + if( (val_real != T(0)) || (val_imag != T(0)) ) + { + tmp(line_row,line_col) = std::complex(val_real, val_imag); + } + } + + x.steal_mem(tmp); + } + catch(...) + { + err_msg = "not enough memory"; + return false; + } + + return true; + } + + + //! Load a matrix in binary format, //! with a header that indicates the matrix type as well as its dimensions template @@ -1752,7 +2292,7 @@ arma_extra_debug_sigprint(); std::streampos pos = f.tellg(); - + bool load_okay = true; std::string f_header; @@ -1768,7 +2308,8 @@ //f.seekg(1, ios::cur); // NOTE: this may not be portable, as on a Windows machine a newline could be two characters f.get(); - x.set_size(f_n_rows,f_n_cols); + try { x.set_size(f_n_rows,f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } + f.read( reinterpret_cast(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) ); load_okay = f.good(); @@ -1776,7 +2317,7 @@ else { load_okay = false; - err_msg = "incorrect header in "; + err_msg = "incorrect header"; } @@ -1823,7 +2364,7 @@ while( isspace(f.peek()) ) { while( isspace(f.peek()) ) { f.get(); } - + if(f.peek() == '#') { while( (f.peek() != '\r') && (f.peek() != '\n') ) { f.get(); } @@ -1874,21 +2415,21 @@ uword f_n_rows = 0; uword f_n_cols = 0; int f_maxval = 0; - + diskio::pnm_skip_comments(f); - + f >> f_n_cols; diskio::pnm_skip_comments(f); - + f >> f_n_rows; diskio::pnm_skip_comments(f); - + f >> f_maxval; f.get(); if( (f_maxval > 0) && (f_maxval <= 65535) ) { - x.set_size(f_n_rows,f_n_cols); + try { x.set_size(f_n_rows,f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } if(f_maxval <= 255) { @@ -1929,7 +2470,7 @@ else { load_okay = false; - err_msg = "functionality unimplemented to handle loading "; + err_msg = "functionality unimplemented"; } if(f.good() == false) { load_okay = false; } @@ -1937,7 +2478,7 @@ else { load_okay = false; - err_msg = "unsupported header in "; + err_msg = "unsupported header"; } return load_okay; @@ -2033,7 +2574,7 @@ // arma_check(query_status < 0, "Mat::load(): cannot get size of HDF5 dataset"); if(query_status < 0) { - err_msg = "cannot get size of HDF5 dataset in "; + err_msg = "cannot get size of HDF5 dataset"; arma_H5Sclose(filespace); arma_H5Dclose(dataset); @@ -2044,7 +2585,7 @@ if(ndims == 1) { dims[1] = 1; } // Vector case; fake second dimension (one column). - x.set_size(dims[1], dims[0]); + try { x.set_size(dims[1], dims[0]); } catch(...) { err_msg = "not enough memory"; return false; } // Now we have to see what type is stored to figure out how to load it. hid_t datatype = arma_H5Dget_type(dataset); @@ -2073,19 +2614,19 @@ } arma_H5Dclose(dataset); - + arma_H5Fclose(fid); - + if(load_okay == false) { - err_msg = "unsupported or missing HDF5 data in "; + err_msg = "unsupported or missing HDF5 data"; } } else { - err_msg = "cannot open file "; + err_msg = "cannot open"; } - + return load_okay; } #else @@ -2093,9 +2634,9 @@ arma_ignore(x); arma_ignore(spec); arma_ignore(err_msg); - + arma_stop_logic_error("Mat::load(): use of HDF5 must be enabled"); - + return false; } #endif @@ -2115,7 +2656,7 @@ // We're currently using the C bindings for the HDF5 library, which don't support C++ streams if( arma_H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name, err_msg); } #endif - + std::fstream f; f.open(name.c_str(), std::fstream::in | std::fstream::binary); @@ -2181,7 +2722,11 @@ switch(ft) { case csv_ascii: - return load_csv_ascii(x, f, err_msg); + return load_csv_ascii(x, f, err_msg, char(',')); + break; + + case ssv_ascii: + return load_csv_ascii(x, f, err_msg, char(';')); break; case raw_binary: @@ -2193,7 +2738,7 @@ break; default: - err_msg = "unknown data in "; + err_msg = "unknown data"; return false; } } @@ -2213,7 +2758,7 @@ template inline bool -diskio::save_csv_ascii(const SpMat& x, const std::string& final_name) +diskio::save_csv_ascii(const SpMat& x, const std::string& final_name, const field& header, const bool with_header, const char separator) { arma_extra_debug_sigprint(); @@ -2223,16 +2768,31 @@ bool save_okay = f.is_open(); - if(save_okay) + if(save_okay == false) { return false; } + + if(with_header) { - save_okay = diskio::save_csv_ascii(x, f); + arma_extra_debug_print("diskio::save_csv_ascii(): writing header"); - f.flush(); - f.close(); + for(uword i=0; i < header.n_elem; ++i) + { + f << header(i); + + if(i != (header.n_elem-1)) { f.put(separator); } + } - if(save_okay) { save_okay = diskio::safe_rename(tmp_name, final_name); } + f.put('\n'); + + save_okay = f.good(); } + if(save_okay) { save_okay = diskio::save_csv_ascii(x, f, separator); } + + f.flush(); + f.close(); + + if(save_okay) { save_okay = diskio::safe_rename(tmp_name, final_name); } + return save_okay; } @@ -2242,19 +2802,14 @@ template inline bool -diskio::save_csv_ascii(const SpMat& x, std::ostream& f) +diskio::save_csv_ascii(const SpMat& x, std::ostream& f, const char separator) { arma_extra_debug_sigprint(); - const ios::fmtflags orig_flags = f.flags(); - - if( (is_float::value) || (is_double::value) ) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } - + const arma_ostream_state stream_state(f); + + diskio::prepare_stream(f); + x.sync(); uword x_n_rows = x.n_rows; @@ -2266,9 +2821,9 @@ { const eT val = x.at(row,col); - if(val != eT(0)) { arma_ostream::print_elem(f, val, false); } + if(val != eT(0)) { arma_ostream::raw_print_elem(f, val); } - if( col < (x_n_cols-1) ) { f.put(','); } + if( col < (x_n_cols-1) ) { f.put(separator); } } f.put('\n'); @@ -2276,7 +2831,7 @@ const bool save_okay = f.good(); - f.flags(orig_flags); + stream_state.restore(f); return save_okay; } @@ -2287,14 +2842,15 @@ template inline bool -diskio::save_csv_ascii(const SpMat< std::complex >& x, std::ostream& f) +diskio::save_csv_ascii(const SpMat< std::complex >& x, std::ostream& f, const char separator) { arma_extra_debug_sigprint(); arma_ignore(x); arma_ignore(f); + arma_ignore(separator); - arma_warn("saving complex sparse matrices as csv_ascii not yet implemented"); + arma_debug_warn_level(1, "saving complex sparse matrices as csv_ascii not yet implemented"); return false; } @@ -2308,23 +2864,23 @@ diskio::save_coord_ascii(const SpMat& x, const std::string& final_name) { arma_extra_debug_sigprint(); - + const std::string tmp_name = diskio::gen_tmp_name(final_name); - + std::ofstream f(tmp_name.c_str()); - + bool save_okay = f.is_open(); - + if(save_okay) { save_okay = diskio::save_coord_ascii(x, f); - + f.flush(); f.close(); - + if(save_okay) { save_okay = diskio::safe_rename(tmp_name, final_name); } } - + return save_okay; } @@ -2338,21 +2894,18 @@ { arma_extra_debug_sigprint(); - const ios::fmtflags orig_flags = f.flags(); + const arma_ostream_state stream_state(f); + + diskio::prepare_stream(f); - if( (is_float::value) || (is_double::value) ) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } - typename SpMat::const_iterator iter = x.begin(); typename SpMat::const_iterator iter_end = x.end(); for(; iter != iter_end; ++iter) { - f << iter.row() << ' ' << iter.col() << ' ' << (*iter) << '\n'; + const eT val = (*iter); + + f << iter.row() << ' ' << iter.col() << ' ' << val << '\n'; } @@ -2370,7 +2923,7 @@ const bool save_okay = f.good(); - f.flags(orig_flags); + stream_state.restore(f); return save_okay; } @@ -2387,14 +2940,9 @@ typedef typename std::complex eT; - const ios::fmtflags orig_flags = f.flags(); + const arma_ostream_state stream_state(f); - if( (is_float::value) || (is_double::value) ) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } + diskio::prepare_stream(f); typename SpMat::const_iterator iter = x.begin(); typename SpMat::const_iterator iter_end = x.end(); @@ -2420,7 +2968,7 @@ const bool save_okay = f.good(); - f.flags(orig_flags); + stream_state.restore(f); return save_okay; } @@ -2435,23 +2983,23 @@ diskio::save_arma_binary(const SpMat& x, const std::string& final_name) { arma_extra_debug_sigprint(); - + const std::string tmp_name = diskio::gen_tmp_name(final_name); - + std::ofstream f(tmp_name.c_str(), std::fstream::binary); - + bool save_okay = f.is_open(); - + if(save_okay) { save_okay = diskio::save_arma_binary(x, f); - + f.flush(); f.close(); - + if(save_okay) { save_okay = diskio::safe_rename(tmp_name, final_name); } } - + return save_okay; } @@ -2481,21 +3029,65 @@ template inline bool -diskio::load_csv_ascii(SpMat& x, const std::string& name, std::string& err_msg) +diskio::load_csv_ascii(SpMat& x, const std::string& name, std::string& err_msg, field& header, const bool with_header, const char separator) { arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in | std::fstream::binary); + f.open(name.c_str(), std::fstream::in); bool load_okay = f.is_open(); + if(load_okay == false) { return false; } + + if(with_header) + { + arma_extra_debug_print("diskio::load_csv_ascii(): reading header"); + + std::string header_line; + std::stringstream header_stream; + std::vector header_tokens; + + std::getline(f, header_line); + + load_okay = f.good(); + + if(load_okay) + { + std::string token; + + header_stream.clear(); + header_stream.str(header_line); + + uword header_n_tokens = 0; + + while(header_stream.good()) + { + std::getline(header_stream, token, separator); + ++header_n_tokens; + header_tokens.push_back(token); + } + + if(header_n_tokens == uword(0)) + { + header.reset(); + } + else + { + header.set_size(1,header_n_tokens); + + for(uword i=0; i < header_n_tokens; ++i) { header.at(i) = header_tokens[i]; } + } + } + } + if(load_okay) { - load_okay = diskio::load_csv_ascii(x, f, err_msg); - f.close(); + load_okay = diskio::load_csv_ascii(x, f, err_msg, separator); } + f.close(); + return load_okay; } @@ -2504,14 +3096,13 @@ template inline bool -diskio::load_csv_ascii(SpMat& x, std::istream& f, std::string& err_msg) +diskio::load_csv_ascii(SpMat& x, std::istream& f, std::string& err_msg, const char separator) { arma_extra_debug_sigprint(); - arma_ignore(err_msg); // TODO: replace with more efficient implementation - bool load_okay = f.good(); + if(f.good() == false) { return false; } f.clear(); const std::fstream::pos_type pos1 = f.tellg(); @@ -2527,7 +3118,7 @@ std::string token; - while( f.good() && load_okay ) + while(f.good()) { std::getline(f, line_string); @@ -2540,7 +3131,7 @@ while(line_stream.good()) { - std::getline(line_stream, token, ','); + std::getline(line_stream, token, separator); ++line_n_cols; } @@ -2552,38 +3143,48 @@ f.clear(); f.seekg(pos1); - x.zeros(f_n_rows, f_n_cols); - - uword row = 0; - - while(f.good()) + try { - std::getline(f, line_string); - - if(line_string.size() == 0) { break; } - - line_stream.clear(); - line_stream.str(line_string); + MapMat tmp(f_n_rows, f_n_cols); - uword col = 0; + uword row = 0; - while(line_stream.good()) + while(f.good()) { - std::getline(line_stream, token, ','); + std::getline(f, line_string); - eT val = eT(0); + if(line_string.size() == 0) { break; } - diskio::convert_token( val, token ); + line_stream.clear(); + line_stream.str(line_string); - if(val != eT(0)) { x(row,col) = val; } + uword col = 0; - ++col; + while(line_stream.good()) + { + std::getline(line_stream, token, separator); + + eT val = eT(0); + + diskio::convert_token( val, token ); + + if(val != eT(0)) { tmp(row,col) = val; } + + ++col; + } + + ++row; } - ++row; + x = tmp; + } + catch(...) + { + err_msg = "not enough memory"; + return false; } - return load_okay; + return true; } @@ -2591,15 +3192,16 @@ template inline bool -diskio::load_csv_ascii(SpMat< std::complex >& x, std::istream& f, std::string& err_msg) +diskio::load_csv_ascii(SpMat< std::complex >& x, std::istream& f, std::string& err_msg, const char separator) { arma_extra_debug_sigprint(); arma_ignore(x); arma_ignore(f); arma_ignore(err_msg); + arma_ignore(separator); - arma_warn("loading complex sparse matrices as csv_ascii not yet implemented"); + arma_debug_warn_level(1, "loading complex sparse matrices as csv_ascii not yet implemented"); return false; } @@ -2635,9 +3237,8 @@ diskio::load_coord_ascii(SpMat& x, std::istream& f, std::string& err_msg) { arma_extra_debug_sigprint(); - arma_ignore(err_msg); - bool load_okay = f.good(); + if(f.good() == false) { return false; } f.clear(); const std::fstream::pos_type pos1 = f.tellg(); @@ -2654,7 +3255,7 @@ std::string token; - while( f.good() && load_okay ) + while(f.good()) { std::getline(f, line_string); @@ -2670,7 +3271,7 @@ line_stream >> line_row; - if(line_stream.good() == false) { load_okay = false; break; } + if(line_stream.good() == false) { err_msg = "incorrect format"; return false; } line_stream >> line_col; @@ -2680,16 +3281,14 @@ if(f_n_cols < line_col) { f_n_cols = line_col; } } - // take into account that indices start at 0 if(size_found) { ++f_n_rows; ++f_n_cols; } + f.clear(); + f.seekg(pos1); - if(load_okay) + try { - f.clear(); - f.seekg(pos1); - MapMat tmp(f_n_rows, f_n_cols); while(f.good()) @@ -2721,8 +3320,13 @@ x = tmp; } + catch(...) + { + err_msg = "not enough memory"; + return false; + } - return load_okay; + return true; } @@ -2733,9 +3337,8 @@ diskio::load_coord_ascii(SpMat< std::complex >& x, std::istream& f, std::string& err_msg) { arma_extra_debug_sigprint(); - arma_ignore(err_msg); - bool load_okay = f.good(); + if(f.good() == false) { return false; } f.clear(); const std::fstream::pos_type pos1 = f.tellg(); @@ -2753,7 +3356,7 @@ std::string token_real; std::string token_imag; - while( f.good() && load_okay ) + while(f.good()) { std::getline(f, line_string); @@ -2769,7 +3372,7 @@ line_stream >> line_row; - if(line_stream.good() == false) { load_okay = false; break; } + if(line_stream.good() == false) { err_msg = "incorrect format"; return false; } line_stream >> line_col; @@ -2782,11 +3385,11 @@ // take into account that indices start at 0 if(size_found) { ++f_n_rows; ++f_n_cols; } - if(load_okay) + f.clear(); + f.seekg(pos1); + + try { - f.clear(); - f.seekg(pos1); - MapMat< std::complex > tmp(f_n_rows, f_n_cols); while(f.good()) @@ -2830,8 +3433,13 @@ x = tmp; } + catch(...) + { + err_msg = "not enough memory"; + return false; + } - return load_okay; + return true; } @@ -2844,18 +3452,18 @@ diskio::load_arma_binary(SpMat& x, const std::string& name, std::string& err_msg) { arma_extra_debug_sigprint(); - + std::ifstream f; f.open(name.c_str(), std::fstream::binary); - + bool load_okay = f.is_open(); - + if(load_okay) { load_okay = diskio::load_arma_binary(x, f, err_msg); f.close(); } - + return load_okay; } @@ -2887,7 +3495,7 @@ //f.seekg(1, ios::cur); // NOTE: this may not be portable, as on a Windows machine a newline could be two characters f.get(); - x.reserve(f_n_rows, f_n_cols, f_n_nz); + try { x.reserve(f_n_rows, f_n_cols, f_n_nz); } catch(...) { err_msg = "not enough memory"; return false; } f.read( reinterpret_cast(access::rwp(x.values)), std::streamsize(x.n_nonzero*sizeof(eT)) ); @@ -2940,7 +3548,7 @@ if((check1 == false) || (check2 == false) || (check3 == false)) { load_okay = false; - err_msg = "inconsistent data in "; + err_msg = "inconsistent data"; } else { @@ -2950,9 +3558,9 @@ else { load_okay = false; - err_msg = "incorrect header in "; + err_msg = "incorrect header"; } - + return load_okay; } @@ -2999,22 +3607,9 @@ { arma_extra_debug_sigprint(); - uword cell_width; - - if(is_real::value) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - cell_width = 22; - } + const arma_ostream_state stream_state(f); - if(is_cx::value) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } + const std::streamsize cell_width = diskio::prepare_stream(f); for(uword slice=0; slice < x.n_slices; ++slice) { @@ -3024,19 +3619,20 @@ { f.put(' '); - if(is_real::value) - { - f.width(std::streamsize(cell_width)); - } + if(is_real::value) { f.width(cell_width); } - arma_ostream::print_elem(f, x.at(row,col,slice), false); + arma_ostream::raw_print_elem(f, x.at(row,col,slice)); } f.put('\n'); } } - return f.good(); + const bool save_okay = f.good(); + + stream_state.restore(f); + + return save_okay; } @@ -3123,27 +3719,12 @@ { arma_extra_debug_sigprint(); - const ios::fmtflags orig_flags = f.flags(); + const arma_ostream_state stream_state(f); f << diskio::gen_txt_header(x) << '\n'; f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n'; - uword cell_width; - - if(is_real::value) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - cell_width = 22; - } - - if(is_cx::value) - { - f.unsetf(ios::fixed); - f.setf(ios::scientific); - f.precision(14); - } + const std::streamsize cell_width = diskio::prepare_stream(f); for(uword slice=0; slice < x.n_slices; ++slice) { @@ -3153,12 +3734,9 @@ { f.put(' '); - if(is_real::value) - { - f.width(std::streamsize(cell_width)); - } + if(is_real::value) { f.width(cell_width); } - arma_ostream::print_elem(f, x.at(row,col,slice), false); + arma_ostream::raw_print_elem(f, x.at(row,col,slice)); } f.put('\n'); @@ -3167,7 +3745,7 @@ const bool save_okay = f.good(); - f.flags(orig_flags); + stream_state.restore(f); return save_okay; } @@ -3268,10 +3846,10 @@ std::vector groups; std::string full_name = spec.dsname; size_t loc; - while ((loc = full_name.find("/")) != std::string::npos) + while((loc = full_name.find("/")) != std::string::npos) { // Create another group... - if (loc != 0) // Ignore the first /, if there is a leading /. + if(loc != 0) // Ignore the first /, if there is a leading /. { hid_t gid = arma_H5Gcreate((groups.size() == 0) ? file : groups[groups.size() - 1], full_name.substr(0, loc).c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); @@ -3305,7 +3883,7 @@ { save_okay = false; - err_msg = "couldn't create dataset in "; + err_msg = "couldn't create dataset"; } else { @@ -3316,7 +3894,7 @@ arma_H5Tclose(datatype); arma_H5Sclose(dataspace); - for (size_t i = 0; i < groups.size(); ++i) { arma_H5Gclose(groups[i]); } + for(size_t i = 0; i < groups.size(); ++i) { arma_H5Gclose(groups[i]); } arma_H5Fclose(file); if((use_existing_file == false) && (save_okay == true)) { save_okay = diskio::safe_rename(tmp_name, spec.filename); } @@ -3354,7 +3932,7 @@ { if(tmp.is_empty() == false) { - x.set_size(tmp.n_rows, tmp.n_cols, 1); + try { x.set_size(tmp.n_rows, tmp.n_cols, 1); } catch(...) { err_msg = "not enough memory"; return false; } x.slice(0) = tmp; } @@ -3385,7 +3963,7 @@ { if(tmp.is_empty() == false) { - x.set_size(tmp.n_rows, tmp.n_cols, 1); + try { x.set_size(tmp.n_rows, tmp.n_cols, 1); } catch(...) { err_msg = "not enough memory"; return false; } x.slice(0) = tmp; } @@ -3431,7 +4009,6 @@ diskio::load_raw_binary(Cube& x, std::istream& f, std::string& err_msg) { arma_extra_debug_sigprint(); - arma_ignore(err_msg); f.clear(); const std::streampos pos1 = f.tellg(); @@ -3448,7 +4025,7 @@ //f.seekg(0, ios::beg); f.seekg(pos1); - x.set_size(N / uword(sizeof(eT)), 1, 1); + try { x.set_size(N / uword(sizeof(eT)), 1, 1); } catch(...) { err_msg = "not enough memory"; return false; } f.clear(); f.read( reinterpret_cast(x.memptr()), std::streamsize(x.n_elem * uword(sizeof(eT))) ); @@ -3492,7 +4069,7 @@ arma_extra_debug_sigprint(); std::streampos pos = f.tellg(); - + bool load_okay = true; std::string f_header; @@ -3507,7 +4084,7 @@ if(f_header == diskio::gen_txt_header(x)) { - x.set_size(f_n_rows, f_n_cols, f_n_slices); + try { x.set_size(f_n_rows, f_n_cols, f_n_slices); } catch(...) { err_msg = "not enough memory"; return false; } for(uword slice = 0; slice < x.n_slices; ++slice) for(uword row = 0; row < x.n_rows; ++row ) @@ -3521,7 +4098,7 @@ else { load_okay = false; - err_msg = "incorrect header in "; + err_msg = "incorrect header"; } @@ -3612,7 +4189,8 @@ //f.seekg(1, ios::cur); // NOTE: this may not be portable, as on a Windows machine a newline could be two characters f.get(); - x.set_size(f_n_rows, f_n_cols, f_n_slices); + try { x.set_size(f_n_rows, f_n_cols, f_n_slices); } catch(...) { err_msg = "not enough memory"; return false; } + f.read( reinterpret_cast(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) ); load_okay = f.good(); @@ -3620,7 +4198,7 @@ else { load_okay = false; - err_msg = "incorrect header in "; + err_msg = "incorrect header"; } @@ -3667,15 +4245,15 @@ diskio::load_hdf5_binary(Cube& x, const hdf5_name& spec, std::string& err_msg) { arma_extra_debug_sigprint(); - + #if defined(ARMA_USE_HDF5) { hdf5_misc::hdf5_suspend_printing_errors hdf5_print_suspender; - + bool load_okay = false; - + hid_t fid = arma_H5Fopen(spec.filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); - + if(fid >= 0) { // MATLAB HDF5 dataset names are user-specified; @@ -3702,70 +4280,70 @@ if(dataset >= 0) { hid_t filespace = arma_H5Dget_space(dataset); - + // This must be <= 3 due to our search rules. const int ndims = arma_H5Sget_simple_extent_ndims(filespace); - + hsize_t dims[3]; const herr_t query_status = arma_H5Sget_simple_extent_dims(filespace, dims, NULL); - + // arma_check(query_status < 0, "Cube::load(): cannot get size of HDF5 dataset"); if(query_status < 0) { - err_msg = "cannot get size of HDF5 dataset in "; - + err_msg = "cannot get size of HDF5 dataset"; + arma_H5Sclose(filespace); arma_H5Dclose(dataset); arma_H5Fclose(fid); - + return false; } - - if (ndims == 1) { dims[1] = 1; dims[2] = 1; } // Vector case; one row/colum, several slices - if (ndims == 2) { dims[2] = 1; } // Matrix case; one column, several rows/slices - - x.set_size(dims[2], dims[1], dims[0]); - + + if(ndims == 1) { dims[1] = 1; dims[2] = 1; } // Vector case; one row/colum, several slices + if(ndims == 2) { dims[2] = 1; } // Matrix case; one column, several rows/slices + + try { x.set_size(dims[2], dims[1], dims[0]); } catch(...) { err_msg = "not enough memory"; return false; } + // Now we have to see what type is stored to figure out how to load it. hid_t datatype = arma_H5Dget_type(dataset); hid_t mat_type = hdf5_misc::get_hdf5_type(); - + // If these are the same type, it is simple. if(arma_H5Tequal(datatype, mat_type) > 0) { // Load directly; H5S_ALL used so that we load the entire dataset. hid_t read_status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(x.memptr())); - + if(read_status >= 0) { load_okay = true; } } else { // Load into another array and convert its type accordingly. hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(), dataset, datatype, x.n_elem); - + if(read_status >= 0) { load_okay = true; } } - + // Now clean up. arma_H5Tclose(datatype); arma_H5Tclose(mat_type); arma_H5Sclose(filespace); } - + arma_H5Dclose(dataset); - + arma_H5Fclose(fid); - + if(load_okay == false) { - err_msg = "unsupported or missing HDF5 data in "; + err_msg = "unsupported or missing HDF5 data"; } } else { - err_msg = "cannot open file "; + err_msg = "cannot open"; } - + return load_okay; } #else @@ -3795,7 +4373,7 @@ // We're currently using the C bindings for the HDF5 library, which don't support C++ streams if( arma_H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name, err_msg); } #endif - + std::fstream f; f.open(name.c_str(), std::fstream::in | std::fstream::binary); @@ -3873,7 +4451,7 @@ break; default: - err_msg = "unknown data in "; + err_msg = "unknown data"; return false; } } @@ -3994,13 +4572,13 @@ { uword f_n_rows; uword f_n_cols; - + f >> f_n_rows; f >> f_n_cols; - x.set_size(f_n_rows, f_n_cols); + try { x.set_size(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } - f.get(); + f.get(); for(uword i=0; i> f_n_rows; f >> f_n_cols; f >> f_n_slices; - x.set_size(f_n_rows, f_n_cols, f_n_slices); + try { x.set_size(f_n_rows, f_n_cols, f_n_slices); } catch(...) { err_msg = "not enough memory"; return false; } - f.get(); + f.get(); for(uword i=0; i> token) { line_n_cols++; } + while(line_stream >> token) { line_n_cols++; } if(f_n_cols_found == false) { @@ -4157,7 +4735,7 @@ if(line_n_cols != f_n_cols) { load_okay = false; - err_msg = "inconsistent number of columns in "; + err_msg = "inconsistent number of columns"; } } @@ -4170,8 +4748,8 @@ f.seekg(0, ios::beg); //f.seekg(start); - x.set_size(f_n_rows, f_n_cols); - + try { x.set_size(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } + for(uword row=0; row < x.n_rows; ++row) for(uword col=0; col < x.n_cols; ++col) { @@ -4253,7 +4831,7 @@ } else { - err_msg = "unsupported header in "; + err_msg = "unsupported header"; return false; } } @@ -4305,21 +4883,21 @@ uword f_n_rows = 0; uword f_n_cols = 0; int f_maxval = 0; - + diskio::pnm_skip_comments(f); - + f >> f_n_cols; diskio::pnm_skip_comments(f); - + f >> f_n_rows; diskio::pnm_skip_comments(f); - + 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); + try { x.set_size(f_n_rows, f_n_cols, 3); } catch(...) { err_msg = "not enough memory"; return false; } if(f_maxval <= 255) { @@ -4364,15 +4942,15 @@ else { load_okay = false; - err_msg = "currently no code available to handle loading "; + err_msg = "functionality unimplemented"; } - + if(f.good() == false) { load_okay = false; } } else { load_okay = false; - err_msg = "unsupported header in "; + err_msg = "unsupported header"; } return load_okay; @@ -4494,28 +5072,28 @@ uword f_n_rows = 0; uword f_n_cols = 0; int f_maxval = 0; - + diskio::pnm_skip_comments(f); - + f >> f_n_cols; diskio::pnm_skip_comments(f); - + f >> f_n_rows; diskio::pnm_skip_comments(f); - + f >> f_maxval; f.get(); - if( (f_maxval > 0) || (f_maxval <= 65535) ) + if( (f_maxval > 0) && (f_maxval <= 65535) ) { x.set_size(3); Mat& R = x(0); Mat& G = x(1); Mat& B = x(2); - R.set_size(f_n_rows,f_n_cols); - G.set_size(f_n_rows,f_n_cols); - B.set_size(f_n_rows,f_n_cols); + try { R.set_size(f_n_rows,f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } + try { G.set_size(f_n_rows,f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } + try { B.set_size(f_n_rows,f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } if(f_maxval <= 255) { @@ -4564,7 +5142,7 @@ else { load_okay = false; - err_msg = "currently no code available to handle loading "; + err_msg = "functionality unimplemented"; } if(f.good() == false) { load_okay = false; } @@ -4572,7 +5150,7 @@ else { load_okay = false; - err_msg = "unsupported header in "; + err_msg = "unsupported header"; } return load_okay; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/distr_param.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/distr_param.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/distr_param.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/distr_param.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eGlue_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eGlue_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eGlue_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eGlue_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,7 +21,7 @@ template -class eGlue : public Base > +class eGlue : public Base< typename T1::elem_type, eGlue > { public: @@ -28,14 +30,13 @@ typedef Proxy proxy1_type; typedef Proxy proxy2_type; - static const bool use_at = (Proxy::use_at || Proxy::use_at ); - static const bool use_mp = (Proxy::use_mp || Proxy::use_mp ); - static const bool has_subview = (Proxy::has_subview || Proxy::has_subview); - static const bool fake_mat = (Proxy::fake_mat || Proxy::fake_mat ); + static constexpr bool use_at = (Proxy::use_at || Proxy::use_at ); + static constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp ); + static constexpr bool has_subview = (Proxy::has_subview || Proxy::has_subview); - static const bool is_col = (Proxy::is_col || Proxy::is_col ); - static const bool is_row = (Proxy::is_row || Proxy::is_row ); - static const bool is_xvec = (Proxy::is_xvec || Proxy::is_xvec); + static constexpr bool is_col = (Proxy::is_col || Proxy::is_col ); + static constexpr bool is_row = (Proxy::is_row || Proxy::is_row ); + static constexpr bool is_xvec = (Proxy::is_xvec || Proxy::is_xvec); arma_aligned const Proxy P1; arma_aligned const Proxy P2; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eglue_core_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eglue_core_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eglue_core_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eglue_core_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eglue_core_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eglue_core_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eglue_core_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eglue_core_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -177,7 +179,7 @@ -#if (defined(ARMA_USE_OPENMP) && defined(ARMA_USE_CXX11)) +#if defined(ARMA_USE_OPENMP) #define arma_applier_1_mp(operatorA, operatorB) \ {\ @@ -263,7 +265,7 @@ typedef typename T1::elem_type eT; const bool use_at = (Proxy::use_at || Proxy::use_at); - const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); // 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 contructor or operator=() @@ -370,7 +372,7 @@ eT* out_mem = out.memptr(); const bool use_at = (Proxy::use_at || Proxy::use_at); - const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -468,7 +470,7 @@ eT* out_mem = out.memptr(); const bool use_at = (Proxy::use_at || Proxy::use_at); - const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -566,7 +568,7 @@ eT* out_mem = out.memptr(); const bool use_at = (Proxy::use_at || Proxy::use_at); - const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -664,7 +666,7 @@ eT* out_mem = out.memptr(); const bool use_at = (Proxy::use_at || Proxy::use_at); - const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -760,7 +762,7 @@ typedef typename T1::elem_type eT; const bool use_at = (ProxyCube::use_at || ProxyCube::use_at); - const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); // 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 contructor or operator=() @@ -869,7 +871,7 @@ eT* out_mem = out.memptr(); const bool use_at = (ProxyCube::use_at || ProxyCube::use_at); - const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -968,7 +970,7 @@ eT* out_mem = out.memptr(); const bool use_at = (ProxyCube::use_at || ProxyCube::use_at); - const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -1067,7 +1069,7 @@ eT* out_mem = out.memptr(); const bool use_at = (ProxyCube::use_at || ProxyCube::use_at); - const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -1166,7 +1168,7 @@ eT* out_mem = out.memptr(); const bool use_at = (ProxyCube::use_at || ProxyCube::use_at); - const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::cxx11 && arma_config::openmp); + const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); if(use_at == false) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eGlueCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eGlueCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eGlueCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eGlueCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,16 +21,16 @@ template -class eGlueCube : public BaseCube > +class eGlueCube : public BaseCube< typename T1::elem_type, eGlueCube > { public: typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - static const bool use_at = (ProxyCube::use_at || ProxyCube::use_at ); - static const bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp ); - static const bool has_subview = (ProxyCube::has_subview || ProxyCube::has_subview); + static constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at ); + static constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp ); + static constexpr bool has_subview = (ProxyCube::has_subview || ProxyCube::has_subview); arma_aligned const ProxyCube P1; arma_aligned const ProxyCube P2; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eGlueCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eGlueCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eGlueCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eGlueCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eGlue_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eGlue_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eGlue_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eGlue_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eop_aux.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eop_aux.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eop_aux.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eop_aux.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -34,17 +36,17 @@ template arma_inline static typename arma_real_only::result asin (const eT x) { return std::asin(x); } template arma_inline static typename arma_real_only::result atan (const eT x) { return std::atan(x); } - template arma_inline static typename arma_cx_only::result acos (const eT x) { return arma_acos(x); } - template arma_inline static typename arma_cx_only::result asin (const eT x) { return arma_asin(x); } - template arma_inline static typename arma_cx_only::result atan (const eT x) { return arma_atan(x); } - - template arma_inline static typename arma_integral_only::result acosh (const eT x) { return eT( arma_acosh(double(x)) ); } - template arma_inline static typename arma_integral_only::result asinh (const eT x) { return eT( arma_asinh(double(x)) ); } - template arma_inline static typename arma_integral_only::result atanh (const eT x) { return eT( arma_atanh(double(x)) ); } - - template arma_inline static typename arma_real_or_cx_only::result acosh (const eT x) { return arma_acosh(x); } - template arma_inline static typename arma_real_or_cx_only::result asinh (const eT x) { return arma_asinh(x); } - template arma_inline static typename arma_real_or_cx_only::result atanh (const eT x) { return arma_atanh(x); } + template arma_inline static typename arma_cx_only::result acos (const eT x) { return std::acos(x); } + template arma_inline static typename arma_cx_only::result asin (const eT x) { return std::asin(x); } + template arma_inline static typename arma_cx_only::result atan (const eT x) { return std::atan(x); } + + template arma_inline static typename arma_integral_only::result acosh (const eT x) { return eT( std::acosh(double(x)) ); } + template arma_inline static typename arma_integral_only::result asinh (const eT x) { return eT( std::asinh(double(x)) ); } + template arma_inline static typename arma_integral_only::result atanh (const eT x) { return eT( std::atanh(double(x)) ); } + + template arma_inline static typename arma_real_or_cx_only::result acosh (const eT x) { return std::acosh(x); } + template arma_inline static typename arma_real_or_cx_only::result asinh (const eT x) { return std::asinh(x); } + template arma_inline static typename arma_real_or_cx_only::result atanh (const eT x) { return std::atanh(x); } template arma_inline static typename arma_not_cx::result conj(const eT x) { return x; } template arma_inline static std::complex conj(const std::complex& x) { return std::conj(x); } @@ -82,123 +84,56 @@ template arma_inline static typename arma_real_only::result ceil (const eT x) { return std::ceil(x); } template arma_inline static typename arma_cx_only::result ceil (const eT& x) { return eT( std::ceil(x.real()), std::ceil(x.imag()) ); } - - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result round (const eT x) { return x; } template arma_inline static typename arma_real_only::result round (const eT x) { return std::round(x); } template arma_inline static typename arma_cx_only::result round (const eT& x) { return eT( std::round(x.real()), std::round(x.imag()) ); } - #else - template arma_inline static typename arma_integral_only::result round (const eT x) { return x; } - template arma_inline static typename arma_real_only::result round (const eT x) { return (x >= eT(0)) ? std::floor(x+0.5) : std::ceil(x-0.5); } - template arma_inline static typename arma_cx_only::result round (const eT& x) { return eT( eop_aux::round(x.real()), eop_aux::round(x.imag()) ); } - #endif - - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result trunc (const eT x) { return x; } template arma_inline static typename arma_real_only::result trunc (const eT x) { return std::trunc(x); } template arma_inline static typename arma_cx_only::result trunc (const eT& x) { return eT( std::trunc(x.real()), std::trunc(x.imag()) ); } - #else - template arma_inline static typename arma_integral_only::result trunc (const eT x) { return x; } - template arma_inline static typename arma_real_only::result trunc (const eT x) { return (x >= eT(0)) ? std::floor(x) : std::ceil(x); } - template arma_inline static typename arma_cx_only::result trunc (const eT& x) { return eT( eop_aux::trunc(x.real()), eop_aux::trunc(x.imag()) ); } - #endif - - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result log2 (const eT x) { return eT( std::log(double(x))/ double(0.69314718055994530942) ); } template arma_inline static typename arma_real_only::result log2 (const eT x) { return std::log2(x); } template arma_inline static typename arma_cx_only::result log2 (const eT& x) { typedef typename get_pod_type::result T; return std::log(x) / T(0.69314718055994530942); } - #else - template arma_inline static typename arma_integral_only::result log2 (const eT x) { return eT( std::log(double(x))/ double(0.69314718055994530942) ); } - template arma_inline static typename arma_real_or_cx_only::result log2 (const eT x) { typedef typename get_pod_type::result T; return std::log(x) / T(0.69314718055994530942); } - #endif - - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result log1p (const eT x) { return eT( std::log1p(double(x)) ); } template arma_inline static typename arma_real_only::result log1p (const eT x) { return std::log1p(x); } template arma_inline static typename arma_cx_only::result log1p (const eT& x) { arma_ignore(x); return eT(0); } - #elif defined(ARMA_HAVE_TR1) - template arma_inline static typename arma_integral_only::result log1p (const eT x) { return eT( std::tr1::log1p(double(x)) ); } - template arma_inline static typename arma_real_only::result log1p (const eT x) { return std::tr1::log1p(x); } - template arma_inline static typename arma_cx_only::result log1p (const eT& x) { arma_ignore(x); return eT(0); } - #else - template arma_inline static eT log1p (const eT x) { arma_ignore(x); arma_stop_logic_error("log1p(): C++11 compiler required"); return eT(0); } - #endif - - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result exp2 (const eT x) { return eT( std::pow(double(2), double(x)) ); } template arma_inline static typename arma_real_only::result exp2 (const eT x) { return std::exp2(x); } template arma_inline static typename arma_cx_only::result exp2 (const eT& x) { typedef typename get_pod_type::result T; return std::pow( T(2), x); } - #else - template arma_inline static typename arma_integral_only::result exp2 (const eT x) { return eT( std::pow(double(2), double(x)) ); } - template arma_inline static typename arma_real_or_cx_only::result exp2 (const eT x) { typedef typename get_pod_type::result T; return std::pow( T(2), x); } - #endif - template arma_inline static typename arma_integral_only::result exp10 (const eT x) { return eT( std::pow(double(10), double(x)) ); } template arma_inline static typename arma_real_or_cx_only::result exp10 (const eT x) { typedef typename get_pod_type::result T; return std::pow( T(10), x); } - - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result expm1 (const eT x) { return eT( std::expm1(double(x)) ); } template arma_inline static typename arma_real_only::result expm1 (const eT x) { return std::expm1(x); } template arma_inline static typename arma_cx_only::result expm1 (const eT& x) { arma_ignore(x); return eT(0); } - #elif defined(ARMA_HAVE_TR1) - template arma_inline static typename arma_integral_only::result expm1 (const eT x) { return eT( std::tr1::expm1(double(x)) ); } - template arma_inline static typename arma_real_only::result expm1 (const eT x) { return std::tr1::expm1(x); } - template arma_inline static typename arma_cx_only::result expm1 (const eT& x) { arma_ignore(x); return eT(0); } - #else - template arma_inline static eT expm1 (const eT x) { arma_ignore(x); arma_stop_logic_error("expm1(): C++11 compiler required"); return eT(0); } - #endif - template arma_inline static typename arma_unsigned_integral_only::result arma_abs (const eT x) { return x; } template arma_inline static typename arma_signed_integral_only::result arma_abs (const eT x) { return std::abs(x); } template arma_inline static typename arma_real_only::result arma_abs (const eT x) { return std::abs(x); } template arma_inline static typename arma_real_only< T>::result arma_abs (const std::complex& x) { return std::abs(x); } - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result erf (const eT x) { return eT( std::erf(double(x)) ); } template arma_inline static typename arma_real_only::result erf (const eT x) { return std::erf(x); } template arma_inline static typename arma_cx_only::result erf (const eT& x) { arma_ignore(x); return eT(0); } - #elif defined(ARMA_HAVE_TR1) - template arma_inline static typename arma_integral_only::result erf (const eT x) { return eT( std::tr1::erf(double(x)) ); } - template arma_inline static typename arma_real_only::result erf (const eT x) { return std::tr1::erf(x); } - template arma_inline static typename arma_cx_only::result erf (const eT& x) { arma_ignore(x); return eT(0); } - #else - template arma_inline static eT erf (const eT x) { arma_ignore(x); arma_stop_logic_error("erf(): C++11 compiler required"); return eT(0); } - #endif - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result erfc (const eT x) { return eT( std::erfc(double(x)) ); } template arma_inline static typename arma_real_only::result erfc (const eT x) { return std::erfc(x); } template arma_inline static typename arma_cx_only::result erfc (const eT& x) { arma_ignore(x); return eT(0); } - #elif defined(ARMA_HAVE_TR1) - template arma_inline static typename arma_integral_only::result erfc (const eT x) { return eT( std::tr1::erfc(double(x)) ); } - template arma_inline static typename arma_real_only::result erfc (const eT x) { return std::tr1::erfc(x); } - template arma_inline static typename arma_cx_only::result erfc (const eT& x) { arma_ignore(x); return eT(0); } - #else - template arma_inline static eT erfc (const eT x) { arma_ignore(x); arma_stop_logic_error("erfc(): C++11 compiler required"); return eT(0); } - #endif - #if defined(ARMA_USE_CXX11) template arma_inline static typename arma_integral_only::result lgamma (const eT x) { return eT( std::lgamma(double(x)) ); } template arma_inline static typename arma_real_only::result lgamma (const eT x) { return std::lgamma(x); } template arma_inline static typename arma_cx_only::result lgamma (const eT& x) { arma_ignore(x); return eT(0); } - #elif defined(ARMA_HAVE_TR1) - template arma_inline static typename arma_integral_only::result lgamma (const eT x) { return eT( std::tr1::lgamma(double(x)) ); } - template arma_inline static typename arma_real_only::result lgamma (const eT x) { return std::tr1::lgamma(x); } - template arma_inline static typename arma_cx_only::result lgamma (const eT& x) { arma_ignore(x); return eT(0); } - #else - template arma_inline static eT lgamma (const eT x) { arma_ignore(x); arma_stop_logic_error("lgamma(): C++11 compiler required"); return eT(0); } - #endif + template arma_inline static typename arma_integral_only::result tgamma (const eT x) { return eT( std::tgamma(double(x)) ); } + template arma_inline static typename arma_real_only::result tgamma (const eT x) { return std::tgamma(x); } + template arma_inline static typename arma_cx_only::result tgamma (const eT& x) { arma_ignore(x); return eT(0); } template arma_inline static typename arma_integral_only::result pow (const T1 base, const T2 exponent) { return T1( std::pow( double(base), double(exponent) ) ); } - template arma_inline static typename arma_real_or_cx_only::result pow (const T1 base, const T2 exponent) { return std::pow(base, exponent); } + template arma_inline static typename arma_real_or_cx_only::result pow (const T1 base, const T2 exponent) { return T1( std::pow( base, exponent ) ); } template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eOp_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eOp_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eOp_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eOp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,7 +22,7 @@ template -class eOp : public Base > +class eOp : public Base< typename T1::elem_type, eOp > { public: @@ -28,14 +30,13 @@ typedef typename get_pod_type::result pod_type; typedef Proxy proxy_type; - static const bool use_at = Proxy::use_at; - static const bool use_mp = Proxy::use_mp || eop_type::use_mp; - static const bool has_subview = Proxy::has_subview; - static const bool fake_mat = Proxy::fake_mat; + static constexpr bool use_at = Proxy::use_at; + static constexpr bool use_mp = Proxy::use_mp || eop_type::use_mp; + static constexpr bool has_subview = Proxy::has_subview; - static const bool is_row = Proxy::is_row; - static const bool is_col = Proxy::is_col; - static const bool is_xvec = Proxy::is_xvec; + static constexpr bool is_row = Proxy::is_row; + static constexpr bool is_col = Proxy::is_col; + static constexpr bool is_xvec = Proxy::is_xvec; arma_aligned const Proxy P; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eop_core_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eop_core_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eop_core_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eop_core_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -46,12 +48,12 @@ // common - template arma_hot arma_inline static eT process(const eT val, const eT k); + template arma_inline static eT process(const eT val, const eT k); }; -struct eop_use_mp_true { static const bool use_mp = true; }; -struct eop_use_mp_false { static const bool use_mp = false; }; +struct eop_use_mp_true { static constexpr bool use_mp = true; }; +struct eop_use_mp_false { static constexpr bool use_mp = false; }; class eop_neg : public eop_core , public eop_use_mp_false {}; @@ -99,6 +101,7 @@ class eop_erf : public eop_core , public eop_use_mp_true {}; class eop_erfc : public eop_core , public eop_use_mp_true {}; class eop_lgamma : public eop_core , public eop_use_mp_true {}; +class eop_tgamma : public eop_core , public eop_use_mp_true {}; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eop_core_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eop_core_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eop_core_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eop_core_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -163,7 +165,7 @@ -#if (defined(ARMA_USE_OPENMP) && defined(ARMA_USE_CXX11)) +#if defined(ARMA_USE_OPENMP) #define arma_applier_1_mp(operatorA) \ {\ @@ -254,7 +256,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(Proxy::use_at == false) { @@ -332,7 +334,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(Proxy::use_at == false) { @@ -407,7 +409,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(Proxy::use_at == false) { @@ -482,7 +484,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(Proxy::use_at == false) { @@ -557,7 +559,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOp::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(Proxy::use_at == false) { @@ -635,7 +637,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(ProxyCube::use_at == false) { @@ -715,7 +717,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(ProxyCube::use_at == false) { @@ -791,7 +793,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(ProxyCube::use_at == false) { @@ -867,7 +869,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(ProxyCube::use_at == false) { @@ -943,7 +945,7 @@ const eT k = x.aux; eT* out_mem = out.memptr(); - const bool use_mp = (arma_config::cxx11 && arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); + const bool use_mp = (arma_config::openmp) && (eOpCube::use_mp || (is_same_type::value && (is_cx::yes || x.aux != eT(2)))); if(ProxyCube::use_at == false) { @@ -1006,7 +1008,6 @@ template template -arma_hot arma_inline eT eop_core::process(const eT, const eT) @@ -1017,141 +1018,144 @@ -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT k) { return val + k; } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT k) { return k - val; } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT k) { return val - k; } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT k) { return val * k; } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT k) { return k / val; } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT k) { return val / k; } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return val*val; } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::neg(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::sqrt(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::log(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::log2(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::log10(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return arma::trunc_log(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::log1p(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::exp(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::exp2(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::exp10(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return arma::trunc_exp(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::expm1(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::cos(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::sin(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::tan(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::acos(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::asin(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::atan(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::cosh(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::sinh(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::tanh(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::acosh(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::asinh(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::atanh(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return arma_sinc(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::direct_eps(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::arma_abs(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return arma_arg::eval(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::conj(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT k) { return eop_aux::pow(val, k); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::floor(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::ceil(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::round(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::trunc(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return arma_sign(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::erf(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::erfc(val); } -template<> template arma_hot arma_inline eT +template<> template arma_inline eT eop_core::process(const eT val, const eT ) { return eop_aux::lgamma(val); } +template<> template arma_inline eT +eop_core::process(const eT val, const eT ) { return eop_aux::tgamma(val); } + #undef arma_applier_1u #undef arma_applier_1a diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eOpCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eOpCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eOpCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eOpCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,16 +22,16 @@ template -class eOpCube : public BaseCube > +class eOpCube : public BaseCube< typename T1::elem_type, eOpCube > { public: typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - static const bool use_at = ProxyCube::use_at; - static const bool use_mp = ProxyCube::use_mp || eop_type::use_mp; - static const bool has_subview = ProxyCube::has_subview; + static constexpr bool use_at = ProxyCube::use_at; + static constexpr bool use_mp = ProxyCube::use_mp || eop_type::use_mp; + static constexpr bool has_subview = ProxyCube::has_subview; arma_aligned const ProxyCube P; arma_aligned elem_type aux; //!< storage of auxiliary data, user defined format diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eOpCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eOpCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eOpCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eOpCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/eOp_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/eOp_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/eOp_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/eOp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fft_engine.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fft_engine.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fft_engine.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fft_engine.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -18,7 +20,6 @@ // licensed under the following conditions. // // Copyright (c) 2003-2010 Mark Borgerding -// // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, @@ -59,7 +60,7 @@ template struct fft_store { - static const uword N = fixed_N; + static constexpr uword N = fixed_N; arma_aligned cx_type coeffs_array[fixed_N]; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/field_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/field_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/field_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/field_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,7 +23,7 @@ struct field_prealloc_n_elem { - static const uword val = 16; + static constexpr uword val = 16; }; @@ -71,7 +73,9 @@ inline void set_size(const SizeMat& s); inline void set_size(const SizeCube& s); - #if defined(ARMA_USE_CXX11) + inline field(const std::vector& x); + inline field& operator=(const std::vector& x); + inline field(const std::initializer_list& list); inline field& operator=(const std::initializer_list& list); @@ -80,34 +84,41 @@ inline field(field&& X); inline field& operator=(field&& X); - #endif template inline void copy_size(const field& x); - arma_inline oT& operator[](const uword i); - arma_inline const oT& operator[](const uword i) const; + arma_inline arma_warn_unused oT& operator[](const uword i); + arma_inline arma_warn_unused const oT& operator[](const uword i) const; - arma_inline oT& at(const uword i); - arma_inline const oT& at(const uword i) const; + arma_inline arma_warn_unused oT& at(const uword i); + arma_inline arma_warn_unused const oT& at(const uword i) const; - arma_inline oT& operator()(const uword i); - arma_inline const oT& operator()(const uword i) const; + arma_inline arma_warn_unused oT& operator()(const uword i); + arma_inline arma_warn_unused const oT& operator()(const uword i) const; - arma_inline oT& at(const uword row, const uword col); - arma_inline const oT& at(const uword row, const uword col) const; + arma_inline arma_warn_unused oT& at(const uword row, const uword col); + arma_inline arma_warn_unused const oT& at(const uword row, const uword col) const; - arma_inline oT& at(const uword row, const uword col, const uword slice); - arma_inline const oT& at(const uword row, const uword col, const uword slice) const; + arma_inline arma_warn_unused oT& at(const uword row, const uword col, const uword slice); + arma_inline arma_warn_unused const oT& at(const uword row, const uword col, const uword slice) const; - arma_inline oT& operator()(const uword row, const uword col); - arma_inline const oT& operator()(const uword row, const uword col) const; + arma_inline arma_warn_unused oT& operator()(const uword row, const uword col); + arma_inline arma_warn_unused const oT& operator()(const uword row, const uword col) const; - arma_inline oT& operator()(const uword row, const uword col, const uword slice); - arma_inline const oT& operator()(const uword row, const uword col, const uword slice) const; + arma_inline arma_warn_unused oT& operator()(const uword row, const uword col, const uword slice); + arma_inline arma_warn_unused const oT& operator()(const uword row, const uword col, const uword slice) const; + + + arma_inline arma_warn_unused oT& front(); + arma_inline arma_warn_unused const oT& front() const; + + arma_inline arma_warn_unused oT& back(); + arma_inline arma_warn_unused const oT& back() const; + - inline field_injector operator<<(const oT& val); - inline field_injector operator<<(const injector_end_of_row<>& x); + arma_cold inline field_injector operator<<(const oT& val); + arma_cold inline field_injector operator<<(const injector_end_of_row<>& x); inline subview_field row(const uword row_num); @@ -162,13 +173,8 @@ arma_cold inline void print( const std::string extra_text = "") const; arma_cold inline void print(std::ostream& user_stream, const std::string extra_text = "") const; - #if defined(ARMA_USE_CXX11) inline const field& for_each(const std::function< void( oT&) >& F); inline const field& for_each(const std::function< void(const oT&) >& F) const; - #else - template inline const field& for_each(functor F); - template inline const field& for_each(functor F) const; - #endif inline const field& fill(const oT& x); @@ -194,11 +200,11 @@ arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const uword in_slice, const SizeCube& s) const; - inline arma_cold bool save(const std::string name, const file_type type = arma_binary, const bool print_status = true) const; - inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary, const bool print_status = true) const; + inline arma_cold bool save(const std::string name, const file_type type = arma_binary) const; + inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary) const; - inline arma_cold bool load(const std::string name, const file_type type = auto_detect, const bool print_status = true); - inline arma_cold bool load( std::istream& is, const file_type type = auto_detect, const bool print_status = true); + inline arma_cold bool load(const std::string name, const file_type type = auto_detect); + inline arma_cold bool load( std::istream& is, const file_type type = auto_detect); inline arma_cold bool quiet_save(const std::string name, const file_type type = arma_binary) const; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/field_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/field_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/field_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/field_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,7 +31,7 @@ if(n_elem > field_prealloc_n_elem::val) { delete [] mem; } // try to expose buggy user code that accesses deleted objects - if(arma_config::debug) { mem = 0; } + if(arma_config::debug) { mem = nullptr; } } @@ -41,7 +43,7 @@ , n_cols(0) , n_slices(0) , n_elem(0) - , mem(0) + , mem(nullptr) { arma_extra_debug_sigprint_this(this); } @@ -56,7 +58,7 @@ , n_cols(0) , n_slices(0) , n_elem(0) - , mem(0) + , mem(nullptr) { arma_extra_debug_sigprint(arma_str::format("this = %x x = %x") % this % &x); @@ -74,12 +76,13 @@ arma_extra_debug_sigprint(); init(x); + return *this; } -//! construct a field from subview_field (e.g. construct a field from a delayed subfield operation) +//! construct a field from subview_field (eg. construct a field from a delayed subfield operation) template inline field::field(const subview_field& X) @@ -87,7 +90,7 @@ , n_cols(0) , n_slices(0) , n_elem(0) - , mem(0) + , mem(nullptr) { arma_extra_debug_sigprint_this(this); @@ -96,7 +99,7 @@ -//! construct a field from subview_field (e.g. construct a field from a delayed subfield operation) +//! construct a field from subview_field (eg. construct a field from a delayed subfield operation) template inline field& @@ -105,6 +108,7 @@ arma_extra_debug_sigprint(); subview_field::extract(*this, X); + return *this; } @@ -119,7 +123,7 @@ , n_cols(0) , n_slices(0) , n_elem(0) - , mem(0) + , mem(nullptr) { arma_extra_debug_sigprint_this(this); @@ -136,7 +140,7 @@ , n_cols(0) , n_slices(0) , n_elem(0) - , mem(0) + , mem(nullptr) { arma_extra_debug_sigprint_this(this); @@ -153,7 +157,7 @@ , n_cols(0) , n_slices(0) , n_elem(0) - , mem(0) + , mem(nullptr) { arma_extra_debug_sigprint_this(this); @@ -169,7 +173,7 @@ , n_cols(0) , n_slices(0) , n_elem(0) - , mem(0) + , mem(nullptr) { arma_extra_debug_sigprint_this(this); @@ -185,7 +189,7 @@ , n_cols(0) , n_slices(0) , n_elem(0) - , mem(0) + , mem(nullptr) { arma_extra_debug_sigprint_this(this); @@ -254,182 +258,200 @@ -#if defined(ARMA_USE_CXX11) +template +inline +field::field(const std::vector& x) + : n_rows (0) + , n_cols (0) + , n_slices(0) + , n_elem (0) + { + arma_extra_debug_sigprint_this(this); - template - inline - field::field(const std::initializer_list& list) - : n_rows (0) - , n_cols (0) - , n_slices(0) - , n_elem (0) - { - arma_extra_debug_sigprint_this(this); - - (*this).operator=(list); - } + (*this).operator=(x); + } + + + +template +inline +field& +field::operator=(const std::vector& x) + { + arma_extra_debug_sigprint(); + const uword N = uword(x.size()); + set_size(N, 1); - template - inline - field& - field::operator=(const std::initializer_list& list) - { - arma_extra_debug_sigprint(); - - const uword N = uword(list.size()); - - set_size(1, N); - - const oT* item_ptr = list.begin(); - - for(uword i=0; i +inline +field::field(const std::initializer_list& list) + : n_rows (0) + , n_cols (0) + , n_slices(0) + , n_elem (0) + { + arma_extra_debug_sigprint_this(this); + (*this).operator=(list); + } + + + +template +inline +field& +field::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); - template - inline - field::field(const std::initializer_list< std::initializer_list >& list) - : n_rows (0) - , n_cols (0) - , n_slices(0) - , n_elem (0) - { - arma_extra_debug_sigprint_this(this); - - (*this).operator=(list); - } + const uword N = uword(list.size()); + + set_size(1, N); + + const oT* item_ptr = list.begin(); + + for(uword i=0; i +inline +field::field(const std::initializer_list< std::initializer_list >& list) + : n_rows (0) + , n_cols (0) + , n_slices(0) + , n_elem (0) + { + arma_extra_debug_sigprint_this(this); + + (*this).operator=(list); + } + + + +template +inline +field& +field::operator=(const std::initializer_list< std::initializer_list >& list) + { + arma_extra_debug_sigprint(); + + uword x_n_rows = uword(list.size()); + uword x_n_cols = 0; + + auto it = list.begin(); + auto it_end = list.end(); + for(; it != it_end; ++it) { x_n_cols = (std::max)(x_n_cols, uword((*it).size())); } + field& t = (*this); - template - inline - field& - field::operator=(const std::initializer_list< std::initializer_list >& list) + t.set_size(x_n_rows, x_n_cols); + + uword row_num = 0; + + auto row_it = list.begin(); + auto row_it_end = list.end(); + + for(; row_it != row_it_end; ++row_it) { - arma_extra_debug_sigprint(); - - uword x_n_rows = uword(list.size()); - uword x_n_cols = 0; - - bool x_n_cols_found = false; + uword col_num = 0; - auto it = list.begin(); - auto it_end = list.end(); + auto col_it = (*row_it).begin(); + auto col_it_end = (*row_it).end(); - for(; it != it_end; ++it) + for(; col_it != col_it_end; ++col_it) { - if(x_n_cols_found == false) - { - x_n_cols = uword( (*it).size() ); - x_n_cols_found = true; - } - else - { - arma_check( (uword((*it).size()) != x_n_cols), "field::init(): inconsistent number of columns in initialiser list" ); - } + t.at(row_num, col_num) = (*col_it); + ++col_num; } - field& t = (*this); - - t.set_size(x_n_rows, x_n_cols); - - uword row_num = 0; - - auto row_it = list.begin(); - auto row_it_end = list.end(); - - for(; row_it != row_it_end; ++row_it) + for(uword c=col_num; c < x_n_cols; ++c) { - uword col_num = 0; - - auto col_it = (*row_it).begin(); - auto col_it_end = (*row_it).end(); - - for(; col_it != col_it_end; ++col_it) - { - t.at(row_num, col_num) = (*col_it); - ++col_num; - } - - ++row_num; + t.at(row_num, c) = oT(); } - return *this; + ++row_num; } + return *this; + } + + + +template +inline +field::field(field&& X) + : n_rows (X.n_rows ) + , n_cols (X.n_cols ) + , n_slices(X.n_slices) + , n_elem (X.n_elem ) + { + arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - - template - inline - field::field(field&& X) - : n_rows (X.n_rows ) - , n_cols (X.n_cols ) - , n_slices(X.n_slices) - , n_elem (X.n_elem ) + if(n_elem > field_prealloc_n_elem::val) { - arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - - if(n_elem > field_prealloc_n_elem::val) - { - mem = X.mem; - } - else - { - arrayops::copy(&mem_local[0], &X.mem_local[0], n_elem); - mem = mem_local; - } - - access::rw(X.n_rows ) = 0; - access::rw(X.n_cols ) = 0; - access::rw(X.n_slices) = 0; - access::rw(X.n_elem ) = 0; - access::rw(X.mem ) = 0; + mem = X.mem; } + else + { + arrayops::copy(&mem_local[0], &X.mem_local[0], n_elem); + mem = mem_local; + } + + access::rw(X.n_rows ) = 0; + access::rw(X.n_cols ) = 0; + access::rw(X.n_slices) = 0; + access::rw(X.n_elem ) = 0; + access::rw(X.mem ) = nullptr; + } + + + +template +inline +field& +field::operator=(field&& X) + { + arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); + reset(); + access::rw(n_rows ) = X.n_rows; + access::rw(n_cols ) = X.n_cols; + access::rw(n_slices) = X.n_slices; + access::rw(n_elem ) = X.n_elem; - template - inline - field& - field::operator=(field&& X) + if(n_elem > field_prealloc_n_elem::val) { - arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - - reset(); - - access::rw(n_rows ) = X.n_rows; - access::rw(n_cols ) = X.n_cols; - access::rw(n_slices) = X.n_slices; - access::rw(n_elem ) = X.n_elem; - - if(n_elem > field_prealloc_n_elem::val) - { - mem = X.mem; - } - else - { - arrayops::copy(&mem_local[0], &X.mem_local[0], n_elem); - mem = mem_local; - } - - access::rw(X.n_rows ) = 0; - access::rw(X.n_cols ) = 0; - access::rw(X.n_elem ) = 0; - access::rw(X.n_slices) = 0; - access::rw(X.mem ) = 0; - - return *this; + mem = X.mem; + } + else + { + arrayops::copy(&mem_local[0], &X.mem_local[0], n_elem); + mem = mem_local; } -#endif + access::rw(X.n_rows ) = 0; + access::rw(X.n_cols ) = 0; + access::rw(X.n_elem ) = 0; + access::rw(X.n_slices) = 0; + access::rw(X.mem ) = nullptr; + + return *this; + } @@ -450,6 +472,7 @@ //! linear element accessor (treats the field as a vector); no bounds check template arma_inline +arma_warn_unused oT& field::operator[] (const uword i) { @@ -461,6 +484,7 @@ //! linear element accessor (treats the field as a vector); no bounds check template arma_inline +arma_warn_unused const oT& field::operator[] (const uword i) const { @@ -472,6 +496,7 @@ //! linear element accessor (treats the field as a vector); no bounds check template arma_inline +arma_warn_unused oT& field::at(const uword i) { @@ -483,6 +508,7 @@ //! linear element accessor (treats the field as a vector); no bounds check template arma_inline +arma_warn_unused const oT& field::at(const uword i) const { @@ -494,10 +520,12 @@ //! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline +arma_warn_unused oT& field::operator() (const uword i) { - arma_debug_check( (i >= n_elem), "field::operator(): index out of bounds" ); + arma_debug_check_bounds( (i >= n_elem), "field::operator(): index out of bounds" ); + return (*mem[i]); } @@ -506,10 +534,12 @@ //! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline +arma_warn_unused const oT& field::operator() (const uword i) const { - arma_debug_check( (i >= n_elem), "field::operator(): index out of bounds" ); + arma_debug_check_bounds( (i >= n_elem), "field::operator(): index out of bounds" ); + return (*mem[i]); } @@ -518,10 +548,12 @@ //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline +arma_warn_unused oT& field::operator() (const uword in_row, const uword in_col) { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols) || (0 >= n_slices) ), "field::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols) || (0 >= n_slices) ), "field::operator(): index out of bounds" ); + return (*mem[in_row + in_col*n_rows]); } @@ -530,10 +562,12 @@ //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline +arma_warn_unused const oT& field::operator() (const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols) || (0 >= n_slices) ), "field::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols) || (0 >= n_slices) ), "field::operator(): index out of bounds" ); + return (*mem[in_row + in_col*n_rows]); } @@ -542,10 +576,12 @@ //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline +arma_warn_unused oT& field::operator() (const uword in_row, const uword in_col, const uword in_slice) { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "field::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "field::operator(): index out of bounds" ); + return (*mem[in_row + in_col*n_rows + in_slice*(n_rows*n_cols)]); } @@ -554,10 +590,12 @@ //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline +arma_warn_unused const oT& field::operator() (const uword in_row, const uword in_col, const uword in_slice) const { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "field::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "field::operator(): index out of bounds" ); + return (*mem[in_row + in_col*n_rows + in_slice*(n_rows*n_cols)]); } @@ -566,6 +604,7 @@ //! element accessor; no bounds check template arma_inline +arma_warn_unused oT& field::at(const uword in_row, const uword in_col) { @@ -577,6 +616,7 @@ //! element accessor; no bounds check template arma_inline +arma_warn_unused const oT& field::at(const uword in_row, const uword in_col) const { @@ -588,6 +628,7 @@ //! element accessor; no bounds check template arma_inline +arma_warn_unused oT& field::at(const uword in_row, const uword in_col, const uword in_slice) { @@ -599,6 +640,7 @@ //! element accessor; no bounds check template arma_inline +arma_warn_unused const oT& field::at(const uword in_row, const uword in_col, const uword in_slice) const { @@ -608,6 +650,59 @@ template +arma_inline +arma_warn_unused +oT& +field::front() + { + arma_debug_check( (n_elem == 0), "field::front(): field is empty" ); + + return (*mem[0]); + } + + + +template +arma_inline +arma_warn_unused +const oT& +field::front() const + { + arma_debug_check( (n_elem == 0), "field::front(): field is empty" ); + + return (*mem[0]); + } + + + +template +arma_inline +arma_warn_unused +oT& +field::back() + { + arma_debug_check( (n_elem == 0), "field::back(): field is empty" ); + + return (*mem[n_elem-1]); + } + + + +template +arma_inline +arma_warn_unused +const oT& +field::back() const + { + arma_debug_check( (n_elem == 0), "field::back(): field is empty" ); + + return (*mem[n_elem-1]); + } + + + +template +arma_cold inline field_injector< field > field::operator<<(const oT& val) @@ -618,6 +713,7 @@ template +arma_cold inline field_injector< field > field::operator<<(const injector_end_of_row<>& x) @@ -637,7 +733,7 @@ arma_debug_check( (n_slices >= 2), "field::row(): field must be 2D" ); - arma_debug_check( (row_num >= n_rows), "field::row(): row out of bounds" ); + arma_debug_check_bounds( (row_num >= n_rows), "field::row(): row out of bounds" ); return subview_field(*this, row_num, 0, 1, n_cols); } @@ -654,7 +750,7 @@ arma_debug_check( (n_slices >= 2), "field::row(): field must be 2D" ); - arma_debug_check( (row_num >= n_rows), "field::row(): row out of bounds" ); + arma_debug_check_bounds( (row_num >= n_rows), "field::row(): row out of bounds" ); return subview_field(*this, row_num, 0, 1, n_cols); } @@ -671,7 +767,7 @@ arma_debug_check( (n_slices >= 2), "field::col(): field must be 2D" ); - arma_debug_check( (col_num >= n_cols), "field::col(): out of bounds" ); + arma_debug_check_bounds( (col_num >= n_cols), "field::col(): out of bounds" ); return subview_field(*this, 0, col_num, n_rows, 1); } @@ -688,7 +784,7 @@ arma_debug_check( (n_slices >= 2), "field::col(): field must be 2D" ); - arma_debug_check( (col_num >= n_cols), "field::col(): out of bounds" ); + arma_debug_check_bounds( (col_num >= n_cols), "field::col(): out of bounds" ); return subview_field(*this, 0, col_num, n_rows, 1); } @@ -703,7 +799,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (slice_num >= n_slices), "field::slice(): out of bounds" ); + arma_debug_check_bounds( (slice_num >= n_slices), "field::slice(): out of bounds" ); return subview_field(*this, 0, 0, slice_num, n_rows, n_cols, 1); } @@ -718,7 +814,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (slice_num >= n_slices), "field::slice(): out of bounds" ); + arma_debug_check_bounds( (slice_num >= n_slices), "field::slice(): out of bounds" ); return subview_field(*this, 0, 0, slice_num, n_rows, n_cols, 1); } @@ -735,7 +831,7 @@ arma_debug_check( (n_slices >= 2), "field::rows(): field must be 2D" ); - arma_debug_check + arma_debug_check_bounds ( ( (in_row1 > in_row2) || (in_row2 >= n_rows) ), "field::rows(): indicies out of bounds or incorrectly used" @@ -758,7 +854,7 @@ arma_debug_check( (n_slices >= 2), "field::rows(): field must be 2D" ); - arma_debug_check + arma_debug_check_bounds ( ( (in_row1 > in_row2) || (in_row2 >= n_rows) ), "field::rows(): indicies out of bounds or incorrectly used" @@ -781,7 +877,7 @@ arma_debug_check( (n_slices >= 2), "field::cols(): field must be 2D" ); - arma_debug_check + arma_debug_check_bounds ( ( (in_col1 > in_col2) || (in_col2 >= n_cols) ), "field::cols(): indicies out of bounds or incorrectly used" @@ -804,7 +900,7 @@ arma_debug_check( (n_slices >= 2), "field::cols(): field must be 2D" ); - arma_debug_check + arma_debug_check_bounds ( ( (in_col1 > in_col2) || (in_col2 >= n_cols) ), "field::cols(): indicies out of bounds or incorrectly used" @@ -825,7 +921,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( ( (in_slice1 > in_slice2) || (in_slice2 >= n_slices) ), "field::slices(): indicies out of bounds or incorrectly used" @@ -846,7 +942,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( ( (in_slice1 > in_slice2) || (in_slice2 >= n_slices) ), "field::slices(): indicies out of bounds or incorrectly used" @@ -869,7 +965,7 @@ arma_debug_check( (n_slices >= 2), "field::subfield(): field must be 2D" ); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "field::subfield(): indices out of bounds or incorrectly used" @@ -893,7 +989,7 @@ arma_debug_check( (n_slices >= 2), "field::subfield(): field must be 2D" ); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "field::subfield(): indices out of bounds or incorrectly used" @@ -915,7 +1011,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) || (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices), "field::subfield(): indices out of bounds or incorrectly used" @@ -938,7 +1034,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) || (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices), "field::subfield(): indices out of bounds or incorrectly used" @@ -969,7 +1065,7 @@ const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)), "field::subfield(): indices or size out of bounds" @@ -996,7 +1092,7 @@ const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)), "field::subfield(): indices or size out of bounds" @@ -1023,7 +1119,7 @@ const uword s_n_cols = s.n_cols; const uword sub_n_slices = s.n_slices; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || (in_slice1 >= l_n_slices) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols) || ((in_slice1 + sub_n_slices) > l_n_slices)), "field::subfield(): indices or size out of bounds" @@ -1050,7 +1146,7 @@ const uword s_n_cols = s.n_cols; const uword sub_n_slices = s.n_slices; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || (in_slice1 >= l_n_slices) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols) || ((in_slice1 + sub_n_slices) > l_n_slices)), "field::subfield(): indices or size out of bounds" @@ -1085,7 +1181,7 @@ const uword in_col2 = col_span.b; const uword sub_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -1123,7 +1219,7 @@ const uword in_col2 = col_span.b; const uword sub_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -1165,7 +1261,7 @@ const uword in_slice2 = slice_span.b; const uword sub_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -1209,7 +1305,7 @@ const uword in_slice2 = slice_span.b; const uword sub_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -1327,7 +1423,7 @@ //! but the associated operator<< function for type oT //! may still modify the stream's parameters. //! NOTE: this function assumes that type oT can be printed, -//! i.e. the function "std::ostream& operator<< (std::ostream&, const oT&)" +//! ie. the function "std::ostream& operator<< (std::ostream&, const oT&)" //! has been defined. template @@ -1358,7 +1454,7 @@ //! but the associated operator<< function for type oT //! may still modify the stream's parameters. //! NOTE: this function assumes that type oT can be printed, -//! i.e. the function "std::ostream& operator<< (std::ostream&, const oT&)" +//! ie. the function "std::ostream& operator<< (std::ostream&, const oT&)" //! has been defined. template @@ -1383,79 +1479,32 @@ -#if defined(ARMA_USE_CXX11) - - //! apply a lambda function to each object - template - inline - const field& - field::for_each(const std::function< void(oT&) >& F) - { - arma_extra_debug_sigprint(); - - for(uword i=0; i < n_elem; ++i) - { - F(operator[](i)); - } - - return *this; - } - - - - template - inline - const field& - field::for_each(const std::function< void(const oT&) >& F) const - { - arma_extra_debug_sigprint(); - - for(uword i=0; i < n_elem; ++i) - { - F(operator[](i)); - } - - return *this; - } - -#else - - //! apply a functor to each object - template - template - inline - const field& - field::for_each(functor F) - { - arma_extra_debug_sigprint(); - - for(uword i=0; i < n_elem; ++i) - { - F(operator[](i)); - } - - return *this; - } +//! apply a lambda function to each object +template +inline +const field& +field::for_each(const std::function< void(oT&) >& F) + { + arma_extra_debug_sigprint(); + for(uword i=0; i < n_elem; ++i) { F(operator[](i)); } + return *this; + } + + + +template +inline +const field& +field::for_each(const std::function< void(const oT&) >& F) const + { + arma_extra_debug_sigprint(); - template - template - inline - const field& - field::for_each(functor F) const - { - arma_extra_debug_sigprint(); - - for(uword i=0; i < n_elem; ++i) - { - F(operator[](i)); - } - - return *this; - } + for(uword i=0; i < n_elem; ++i) { F(operator[](i)); } -#endif + return *this; + } @@ -1469,17 +1518,14 @@ field& t = *this; - for(uword i=0; i inline void @@ -1537,7 +1583,7 @@ { arma_extra_debug_sigprint(); - if(x.whole == true) + if(x.whole) { return true; } @@ -1572,7 +1618,7 @@ { arma_extra_debug_sigprint(); - if(row_span.whole == true) + if(row_span.whole) { return (in_col < n_cols); } @@ -1595,7 +1641,7 @@ { arma_extra_debug_sigprint(); - if(col_span.whole == true) + if(col_span.whole) { return (in_row < n_rows); } @@ -1627,7 +1673,7 @@ const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) ); const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) ); - return ( (rows_ok == true) && (cols_ok == true) ); + return ( rows_ok && cols_ok ); } @@ -1685,7 +1731,7 @@ const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2 ) && (in_col2 < n_cols ) ); const bool slices_ok = slice_span.whole ? true : ( (in_slice1 <= in_slice2) && (in_slice2 < n_slices) ); - return ( (rows_ok == true) && (cols_ok == true) && (slices_ok == true) ); + return ( rows_ok && cols_ok && slices_ok ); } @@ -1716,22 +1762,23 @@ inline arma_cold bool -field::save(const std::string name, const file_type type, const bool print_status) const +field::save(const std::string name, const file_type type) const { arma_extra_debug_sigprint(); std::string err_msg; + const bool save_okay = field_aux::save(*this, name, type, err_msg); - if( (print_status == true) && (save_okay == false) ) + if(save_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("field::save(): ", err_msg, name); + arma_debug_warn_level(3, "field::save(): ", err_msg, "; file: ", name); } else { - arma_debug_warn("field::save(): couldn't write to ", name); + arma_debug_warn_level(3, "field::save(): couldn't write; file: ", name); } } @@ -1744,22 +1791,23 @@ inline arma_cold bool -field::save(std::ostream& os, const file_type type, const bool print_status) const +field::save(std::ostream& os, const file_type type) const { arma_extra_debug_sigprint(); std::string err_msg; + const bool save_okay = field_aux::save(*this, os, type, err_msg); - if( (print_status == true) && (save_okay == false) ) + if(save_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("field::save(): ", err_msg, "[ostream]"); + arma_debug_warn_level(3, "field::save(): ", err_msg); } else { - arma_debug_warn("field::save(): couldn't write to [ostream]"); + arma_debug_warn_level(3, "field::save(): couldn't write to stream"); } } @@ -1772,29 +1820,27 @@ inline arma_cold bool -field::load(const std::string name, const file_type type, const bool print_status) +field::load(const std::string name, const file_type type) { arma_extra_debug_sigprint(); std::string err_msg; + const bool load_okay = field_aux::load(*this, name, type, err_msg); - if( (print_status == true) && (load_okay == false) ) + if(load_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("field::load(): ", err_msg, name); + arma_debug_warn_level(3, "field::load(): ", err_msg, "; file: ", name); } else { - arma_debug_warn("field::load(): couldn't read from ", name); + arma_debug_warn_level(3, "field::load(): couldn't read; file: ", name); } } - if(load_okay == false) - { - (*this).reset(); - } + if(load_okay == false) { (*this).reset(); } return load_okay; } @@ -1805,29 +1851,26 @@ inline arma_cold bool -field::load(std::istream& is, const file_type type, const bool print_status) +field::load(std::istream& is, const file_type type) { arma_extra_debug_sigprint(); std::string err_msg; const bool load_okay = field_aux::load(*this, is, type, err_msg); - if( (print_status == true) && (load_okay == false) ) + if(load_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("field::load(): ", err_msg, "[istream]"); + arma_debug_warn_level(3, "field::load(): ", err_msg); } else { - arma_debug_warn("field::load(): couldn't read from [istream]"); + arma_debug_warn_level(3, "field::load(): couldn't read from stream"); } } - if(load_okay == false) - { - (*this).reset(); - } + if(load_okay == false) { (*this).reset(); } return load_okay; } @@ -1842,7 +1885,7 @@ { arma_extra_debug_sigprint(); - return (*this).save(name, type, false); + return (*this).save(name, type); } @@ -1855,7 +1898,7 @@ { arma_extra_debug_sigprint(); - return (*this).save(os, type, false); + return (*this).save(os, type); } @@ -1868,7 +1911,7 @@ { arma_extra_debug_sigprint(); - return (*this).load(name, type, false); + return (*this).load(name, type); } @@ -1881,7 +1924,7 @@ { arma_extra_debug_sigprint(); - return (*this).load(is, type, false); + return (*this).load(is, type); } @@ -1943,10 +1986,10 @@ { arma_extra_debug_sigprint( arma_str::format("n_rows_in = %d, n_cols_in = %d, n_slices_in = %d") % n_rows_in % n_cols_in % n_slices_in ); - #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD)) + #if defined(ARMA_64BIT_WORD) const char* error_message = "field::init(): requested size is too large"; #else - const char* error_message = "field::init(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD"; + const char* error_message = "field::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_check @@ -1973,26 +2016,17 @@ { delete_objects(); - if(n_elem > field_prealloc_n_elem::val) - { - delete [] mem; - } + if(n_elem > field_prealloc_n_elem::val) { delete [] mem; } if(n_elem_new <= field_prealloc_n_elem::val) { - if(n_elem_new == 0) - { - mem = NULL; - } - else - { - mem = mem_local; - } + mem = (n_elem_new == 0) ? nullptr : mem_local; } else { mem = new(std::nothrow) oT* [n_elem_new]; - arma_check_bad_alloc( (mem == 0), "field::init(): out of memory" ); + + arma_check_bad_alloc( (mem == nullptr), "field::init(): out of memory" ); } access::rw(n_rows) = n_rows_in; @@ -2015,10 +2049,10 @@ for(uword i=0; i::iterator& field::iterator::operator--() { - if(i > 0) - { - --i; - } + if(i > 0) { --i; } return *this; } @@ -2187,10 +2215,7 @@ typename field::const_iterator& field::const_iterator::operator--() { - if(i > 0) - { - --i; - } + if(i > 0) { --i; } return *this; } @@ -2355,10 +2380,7 @@ { arma_extra_debug_sigprint(); - for(uword i=0; i + struct fill_class { inline fill_class() {} }; + + static const fill_class none; + static const fill_class zeros; + static const fill_class ones; + static const fill_class eye; + static const fill_class randu; + static const fill_class randn; + + // + + template + struct allow_conversion + { + static constexpr bool value = true; + }; + + template<> struct allow_conversion, double> { static constexpr bool value = false; }; + template<> struct allow_conversion, float > { static constexpr bool value = false; }; + template<> struct allow_conversion, u64 > { static constexpr bool value = false; }; + template<> struct allow_conversion, s64 > { static constexpr bool value = false; }; + template<> struct allow_conversion, u32 > { static constexpr bool value = false; }; + template<> struct allow_conversion, s32 > { static constexpr bool value = false; }; + template<> struct allow_conversion, u16 > { static constexpr bool value = false; }; + template<> struct allow_conversion, s16 > { static constexpr bool value = false; }; + template<> struct allow_conversion, u8 > { static constexpr bool value = false; }; + template<> struct allow_conversion, s8 > { static constexpr bool value = false; }; + + template<> struct allow_conversion, double> { static constexpr bool value = false; }; + template<> struct allow_conversion, float > { static constexpr bool value = false; }; + template<> struct allow_conversion, u64 > { static constexpr bool value = false; }; + template<> struct allow_conversion, s64 > { static constexpr bool value = false; }; + template<> struct allow_conversion, u32 > { static constexpr bool value = false; }; + template<> struct allow_conversion, s32 > { static constexpr bool value = false; }; + template<> struct allow_conversion, u16 > { static constexpr bool value = false; }; + template<> struct allow_conversion, s16 > { static constexpr bool value = false; }; + template<> struct allow_conversion, u8 > { static constexpr bool value = false; }; + template<> struct allow_conversion, s8 > { static constexpr bool value = false; }; + + // + + template inline bool isfinite_wrapper(eT ) { return true; } + template<> inline bool isfinite_wrapper(float x) { return std::isfinite(x); } + template<> inline bool isfinite_wrapper(double x) { return std::isfinite(x); } + template inline bool isfinite_wrapper(std::complex& x) { return std::isfinite(x.real()) && std::isfinite(x.imag()); } + + // + + template + struct scalar_holder + { + const scalar_type1 scalar; + + inline explicit scalar_holder(const scalar_type1& in_scalar) : scalar(in_scalar) {} + + inline scalar_holder() = delete; + + template + < + typename scalar_type2, + typename arma::enable_if2::value, int>::result = 0 + > + inline + operator scalar_holder() const + { + const bool ok_conversion = (std::is_integral::value && std::is_floating_point::value) ? isfinite_wrapper(scalar) : true; + + return scalar_holder( ok_conversion ? scalar_type2(scalar) : scalar_type2(0) ); + } + }; + + // + + template + inline + typename enable_if2< is_supported_elem_type::value, scalar_holder >::result + value(const scalar_type& in_scalar) + { + return scalar_holder(in_scalar); + } + } + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_accu.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_accu.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_accu.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_accu.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -413,6 +415,118 @@ +template +arma_warn_unused +inline +uword +accu(const mtGlue& X) + { + arma_extra_debug_sigprint(); + + const Proxy PA(X.A); + const Proxy PB(X.B); + + arma_debug_assert_same_size(PA, PB, "operator!="); + + uword n_nonzero = 0; + + if( (Proxy::use_at == false) && (Proxy::use_at == false) ) + { + typedef typename Proxy::ea_type PA_ea_type; + typedef typename Proxy::ea_type PB_ea_type; + + PA_ea_type A = PA.get_ea(); + PB_ea_type B = PB.get_ea(); + const uword n_elem = PA.get_n_elem(); + + for(uword i=0; i < n_elem; ++i) + { + n_nonzero += (A[i] != B[i]) ? uword(1) : uword(0); + } + } + else + { + const uword PA_n_cols = PA.get_n_cols(); + const uword PA_n_rows = PA.get_n_rows(); + + if(PA_n_rows == 1) + { + for(uword col=0; col < PA_n_cols; ++col) + { + n_nonzero += (PA.at(0,col) != PB.at(0,col)) ? uword(1) : uword(0); + } + } + else + { + for(uword col=0; col < PA_n_cols; ++col) + for(uword row=0; row < PA_n_rows; ++row) + { + n_nonzero += (PA.at(row,col) != PB.at(row,col)) ? uword(1) : uword(0); + } + } + } + + return n_nonzero; + } + + + +template +arma_warn_unused +inline +uword +accu(const mtGlue& X) + { + arma_extra_debug_sigprint(); + + const Proxy PA(X.A); + const Proxy PB(X.B); + + arma_debug_assert_same_size(PA, PB, "operator=="); + + uword n_nonzero = 0; + + if( (Proxy::use_at == false) && (Proxy::use_at == false) ) + { + typedef typename Proxy::ea_type PA_ea_type; + typedef typename Proxy::ea_type PB_ea_type; + + PA_ea_type A = PA.get_ea(); + PB_ea_type B = PB.get_ea(); + const uword n_elem = PA.get_n_elem(); + + for(uword i=0; i < n_elem; ++i) + { + n_nonzero += (A[i] == B[i]) ? uword(1) : uword(0); + } + } + else + { + const uword PA_n_cols = PA.get_n_cols(); + const uword PA_n_rows = PA.get_n_rows(); + + if(PA_n_rows == 1) + { + for(uword col=0; col < PA_n_cols; ++col) + { + n_nonzero += (PA.at(0,col) == PB.at(0,col)) ? uword(1) : uword(0); + } + } + else + { + for(uword col=0; col < PA_n_cols; ++col) + for(uword row=0; row < PA_n_rows; ++row) + { + n_nonzero += (PA.at(row,col) == PB.at(row,col)) ? uword(1) : uword(0); + } + } + } + + return n_nonzero; + } + + + //! accumulate the elements of a subview (submatrix) template arma_warn_unused @@ -426,29 +540,35 @@ const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; - eT val = eT(0); - if(X_n_rows == 1) { - typedef subview_row sv_type; + const Mat& m = X.m; - const sv_type& sv = reinterpret_cast(X); // subview_row is a child class of subview and has no extra data + const uword col_offset = X.aux_col1; + const uword row_offset = X.aux_row1; - const Proxy P(sv); + eT val1 = eT(0); + eT val2 = eT(0); - val = accu_proxy_linear(P); - } - else - if(X_n_cols == 1) - { - val = arrayops::accumulate( X.colptr(0), X_n_rows ); - } - else - { - for(uword col=0; col < X_n_cols; ++col) + uword i,j; + for(i=0, j=1; j < X_n_cols; i+=2, j+=2) { - val += arrayops::accumulate( X.colptr(col), X_n_rows ); + val1 += m.at(row_offset, col_offset + i); + val2 += m.at(row_offset, col_offset + j); } + + if(i < X_n_cols) { val1 += m.at(row_offset, col_offset + i); } + + return val1 + val2; + } + + if(X_n_cols == 1) { return arrayops::accumulate( X.colptr(0), X_n_rows ); } + + eT val = eT(0); + + for(uword col=0; col < X_n_cols; ++col) + { + val += arrayops::accumulate( X.colptr(col), X_n_rows ); } return val; @@ -465,7 +585,7 @@ { arma_extra_debug_sigprint(); - return arrayops::accumulate( X.colptr(0), X.n_rows ); + return arrayops::accumulate( X.colmem, X.n_rows ); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_all.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_all.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_all.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_all.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_any.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_any.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_any.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_any.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_approx_equal.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_approx_equal.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_approx_equal.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_approx_equal.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -287,7 +289,7 @@ typedef typename T1::pod_type T; - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 'a') && (sig != 'r') && (sig != 'b')), "approx_equal(): argument 'method' must be \"absdiff\" or \"reldiff\" or \"both\"" ); @@ -322,7 +324,7 @@ typedef typename T1::pod_type T; - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 'a') && (sig != 'r') && (sig != 'b')), "approx_equal(): argument 'method' must be \"absdiff\" or \"reldiff\" or \"both\"" ); @@ -408,7 +410,7 @@ typedef typename T1::elem_type eT; typedef typename T1::pod_type T; - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 'a') && (sig != 'r') && (sig != 'b')), "approx_equal(): argument 'method' must be \"absdiff\" or \"reldiff\" or \"both\"" ); @@ -452,7 +454,7 @@ typedef typename T1::pod_type T; - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 'a') && (sig != 'r') && (sig != 'b')), "approx_equal(): argument 'method' must be \"absdiff\" or \"reldiff\" or \"both\"" ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_as_scalar.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_as_scalar.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_as_scalar.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_as_scalar.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -53,16 +55,9 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - const Proxy P(X); - if(P.get_n_elem() != 1) - { - arma_debug_check(true, "as_scalar(): expression doesn't evaluate to exactly one element"); - - return Datum::nan; - } + arma_debug_check( (P.get_n_elem() != 1), "as_scalar(): expression must evaluate to exactly one element" ); return (Proxy::use_at) ? P.at(0,0) : P[0]; } @@ -152,12 +147,7 @@ { const Mat tmp(X); - if(tmp.n_elem != 1) - { - arma_debug_check(true, "as_scalar(): expression doesn't evaluate to exactly one element"); - - return Datum::nan; - } + arma_debug_check( (tmp.n_elem != 1), "as_scalar(): expression must evaluate to exactly one element" ); return tmp[0]; } @@ -234,12 +224,7 @@ const unwrap tmp(X.get_ref()); const Mat& A = tmp.M; - if(A.n_elem != 1) - { - arma_debug_check(true, "as_scalar(): expression doesn't evaluate to exactly one element"); - - return Datum::nan; - } + arma_debug_check( (A.n_elem != 1), "as_scalar(): expression must evaluate to exactly one element" ); return A.mem[0]; } @@ -309,25 +294,20 @@ template arma_warn_unused -arma_inline +inline typename T1::elem_type -as_scalar(const Glue& X, const typename arma_not_cx::result* junk = 0) +as_scalar(const Glue& X, const typename arma_not_cx::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); - if(is_glue_times_diag::value == false) - { - const sword N_mat = 1 + depth_lhs< glue_times, Glue >::num; - - arma_extra_debug_print(arma_str::format("N_mat = %d") % N_mat); - - return as_scalar_redirect::apply(X); - } - else - { - return as_scalar_diag(X); - } + if(is_glue_times_diag::value) { return as_scalar_diag(X); } + + constexpr uword N_mat = 1 + depth_lhs< glue_times, Glue >::num; + + arma_extra_debug_print(arma_str::format("N_mat = %u") % N_mat); + + return as_scalar_redirect::apply(X); } @@ -340,16 +320,9 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - const Proxy P(X.get_ref()); - if(P.get_n_elem() != 1) - { - arma_debug_check(true, "as_scalar(): expression doesn't evaluate to exactly one element"); - - return Datum::nan; - } + arma_debug_check( (P.get_n_elem() != 1), "as_scalar(): expression must evaluate to exactly one element" ); return (Proxy::use_at) ? P.at(0,0) : P[0]; } @@ -365,12 +338,7 @@ typedef typename T1::elem_type eT; - if( (X.n_rows != 1) || (X.n_cols != 1) ) - { - arma_debug_check(true, "as_scalar(): expression doesn't evaluate to exactly one element"); - - return Datum::nan; - } + arma_debug_check( ((X.n_rows != 1) || (X.n_cols != 1)), "as_scalar(): expression must evaluate to exactly one element" ); return eT(arma_rng::randu()); } @@ -387,12 +355,7 @@ typedef typename T1::elem_type eT; - if( (X.n_rows != 1) || (X.n_cols != 1) ) - { - arma_debug_check(true, "as_scalar(): expression doesn't evaluate to exactly one element"); - - return Datum::nan; - } + arma_debug_check( ((X.n_rows != 1) || (X.n_cols != 1)), "as_scalar(): expression must evaluate to exactly one element" ); return eT(arma_rng::randn()); } @@ -407,16 +370,9 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - const ProxyCube P(X.get_ref()); - if(P.get_n_elem() != 1) - { - arma_debug_check(true, "as_scalar(): expression doesn't evaluate to exactly one element"); - - return Datum::nan; - } + arma_debug_check( (P.get_n_elem() != 1), "as_scalar(): expression must evaluate to exactly one element" ); return (ProxyCube::use_at) ? P.at(0,0,0) : P[0]; } @@ -445,12 +401,7 @@ const unwrap_spmat tmp(X.get_ref()); const SpMat& A = tmp.M; - if(A.n_elem != 1) - { - arma_debug_check(true, "as_scalar(): expression doesn't evaluate to exactly one element"); - - return Datum::nan; - } + arma_debug_check( (A.n_elem != 1), "as_scalar(): expression must evaluate to exactly one element" ); return A.at(0,0); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_chi2rnd.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_chi2rnd.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_chi2rnd.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_chi2rnd.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,19 +28,9 @@ { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_CXX11) - { - op_chi2rnd_varying_df generator; - - return generator(df); - } - #else - { - arma_stop_logic_error("chi2rnd(): C++11 compiler required"); - - return double(0); - } - #endif + op_chi2rnd_varying_df generator; + + return generator(df); } @@ -51,19 +43,9 @@ { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_CXX11) - { - op_chi2rnd_varying_df generator; - - return generator(df); - } - #else - { - arma_stop_logic_error("chi2rnd(): C++11 compiler required"); - - return eT(0); - } - #endif + op_chi2rnd_varying_df generator; + + return generator(df); } @@ -109,7 +91,7 @@ arma_debug_check( (n_rows != 1), "chi2rnd(): incompatible size" ); } - obj_type out(n_rows, n_cols); + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); op_chi2rnd::fill_constant_df(out, df); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_chol.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_chol.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_chol.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_chol.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -31,7 +33,7 @@ { arma_extra_debug_sigprint(); - const char sig = (layout != NULL) ? layout[0] : char(0); + const char sig = (layout != nullptr) ? layout[0] : char(0); arma_debug_check( ((sig != 'u') && (sig != 'l')), "chol(): layout must be \"upper\" or \"lower\"" ); @@ -52,7 +54,7 @@ { arma_extra_debug_sigprint(); - const char sig = (layout != NULL) ? layout[0] : char(0); + const char sig = (layout != nullptr) ? layout[0] : char(0); arma_debug_check( ((sig != 'u') && (sig != 'l')), "chol(): layout must be \"upper\" or \"lower\"" ); @@ -61,7 +63,82 @@ if(status == false) { out.soft_reset(); - arma_debug_warn("chol(): decomposition failed"); + arma_debug_warn_level(3, "chol(): decomposition failed"); + } + + return status; + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +chol + ( + Mat& out, + Mat& P, + const Base& X, + const char* layout = "upper", + const char* P_mode = "matrix" + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const char sig_layout = (layout != nullptr) ? layout[0] : char(0); + const char sig_P_mode = (P_mode != nullptr) ? P_mode[0] : char(0); + + arma_debug_check( ((sig_layout != 'u') && (sig_layout != 'l')), "chol(): argument 'layout' must be \"upper\" or \"lower\"" ); + arma_debug_check( ((sig_P_mode != 'm') && (sig_P_mode != 'v')), "chol(): argument 'P_mode' must be \"vector\" or \"matrix\"" ); + + out = X.get_ref(); + + arma_debug_check( (out.is_square() == false), "chol(): given matrix must be square sized" ); + + if(out.is_empty()) + { + P.reset(); + return true; + } + + if((arma_config::debug) && (auxlib::rudimentary_sym_check(out) == false)) + { + if(is_cx::no ) { arma_debug_warn_level(1, "chol(): given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, "chol(): given matrix is not hermitian"); } + } + + bool status = false; + + if(sig_P_mode == 'v') + { + status = auxlib::chol_pivot(out, P, ((sig_layout == 'u') ? 0 : 1)); + } + else + if(sig_P_mode == 'm') + { + Mat P_vec; + + status = auxlib::chol_pivot(out, P_vec, ((sig_layout == 'u') ? 0 : 1)); + + if(status) + { + // construct P + + const uword N = P_vec.n_rows; + + P.zeros(N,N); + + for(uword i=0; i < N; ++i) { P.at(P_vec[i], i) = uword(1); } + } + } + + if(status == false) + { + out.soft_reset(); + P.soft_reset(); + arma_debug_warn_level(3, "chol(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_clamp.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_clamp.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_clamp.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_clamp.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -32,8 +34,6 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (min_val > max_val), "clamp(): min_val has to be smaller than max_val" ); - return mtOp(mtOp_dual_aux_indicator(), X, min_val, max_val); } @@ -42,14 +42,30 @@ template arma_warn_unused inline +typename +enable_if2 + < + is_arma_type::value && is_cx::yes, + const mtOp + >::result +clamp(const T1& X, const typename T1::elem_type min_val, const typename T1::elem_type max_val) + { + arma_extra_debug_sigprint(); + + return mtOp(mtOp_dual_aux_indicator(), X, min_val, max_val); + } + + + +template +arma_warn_unused +inline const mtOpCube -clamp(const BaseCube& X, const typename T1::elem_type min_val, const typename T1::elem_type max_val, typename arma_not_cx::result* junk = 0) +clamp(const BaseCube& X, const typename T1::elem_type min_val, const typename T1::elem_type max_val, typename arma_not_cx::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); - arma_debug_check( (min_val > max_val), "clamp(): min_val has to be smaller than max_val" ); - return mtOpCube(mtOpCube_dual_aux_indicator(), X.get_ref(), min_val, max_val); } @@ -58,36 +74,40 @@ template arma_warn_unused inline -typename -enable_if2 - < - is_cx::no, - SpMat - >::result +const mtOpCube +clamp(const BaseCube& X, const typename T1::elem_type min_val, const typename T1::elem_type max_val, typename arma_cx_only::result* junk = nullptr) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + return mtOpCube(mtOpCube_dual_aux_indicator(), X.get_ref(), min_val, max_val); + } + + + +template +arma_warn_unused +inline +SpMat clamp(const SpBase& X, const typename T1::elem_type min_val, const typename T1::elem_type max_val) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - arma_debug_check( (min_val > max_val), "clamp(): min_val has to be smaller than max_val" ); - - SpMat out = X.get_ref(); - - out.sync(); - - const uword N = out.n_nonzero; - - eT* out_values = access::rwp(out.values); - - for(uword i=0; i::no) + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "clamp(): min_val must be less than max_val" ); + } + else { - eT& out_val = out_values[i]; - - out_val = (out_val < min_val) ? min_val : ( (out_val > max_val) ? max_val : out_val ); + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "clamp(): imag(min_val) must be less than imag(max_val)" ); } - if( (min_val == eT(0)) || (max_val == eT(0)) ) { out.remove_zeros(); } + SpMat out = X.get_ref(); + + out.clamp(min_val, max_val); return out; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cond.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cond.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cond.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cond.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -45,4 +47,17 @@ +// template +// arma_warn_unused +// inline +// typename enable_if2::value, typename T1::pod_type>::result +// rcond(const SpBase& X) +// { +// arma_extra_debug_sigprint(); +// +// return sp_auxlib::rcond(X.get_ref()); +// } + + + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_conv.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_conv.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_conv.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_conv.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -34,7 +36,7 @@ { arma_extra_debug_sigprint(); - const char sig = (shape != NULL) ? shape[0] : char(0); + const char sig = (shape != nullptr) ? shape[0] : char(0); arma_debug_check( ((sig != 'f') && (sig != 's')), "conv(): unsupported value of 'shape' parameter" ); @@ -58,7 +60,7 @@ { arma_extra_debug_sigprint(); - const char sig = (shape != NULL) ? shape[0] : char(0); + const char sig = (shape != nullptr) ? shape[0] : char(0); arma_debug_check( ((sig != 'f') && (sig != 's')), "conv2(): unsupported value of 'shape' parameter" ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_conv_to.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_conv_to.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_conv_to.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_conv_to.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,16 +29,16 @@ public: template - inline static out_eT from(const Base& in, const typename arma_not_cx::result* junk = 0); + inline static out_eT from(const Base& in, const typename arma_not_cx::result* junk = nullptr); template - inline static out_eT from(const Base& in, const typename arma_cx_only::result* junk = 0); + inline static out_eT from(const Base& in, const typename arma_cx_only::result* junk = nullptr); template - inline static out_eT from(const BaseCube& in, const typename arma_not_cx::result* junk = 0); + inline static out_eT from(const BaseCube& in, const typename arma_not_cx::result* junk = nullptr); template - inline static out_eT from(const BaseCube& in, const typename arma_cx_only::result* junk = 0); + inline static out_eT from(const BaseCube& in, const typename arma_cx_only::result* junk = nullptr); }; @@ -140,10 +142,10 @@ public: template - inline static Mat from(const Base& in, const typename arma_not_cx::result* junk = 0); + inline static Mat from(const Base& in, const typename arma_not_cx::result* junk = nullptr); template - inline static Mat from(const Base& in, const typename arma_cx_only::result* junk = 0); + inline static Mat from(const Base& in, const typename arma_cx_only::result* junk = nullptr); template inline static Mat from(const SpBase& in); @@ -151,10 +153,10 @@ template - inline static Mat from(const std::vector& in, const typename arma_not_cx::result* junk = 0); + inline static Mat from(const std::vector& in, const typename arma_not_cx::result* junk = nullptr); template - inline static Mat from(const std::vector& in, const typename arma_cx_only::result* junk = 0); + inline static Mat from(const std::vector& in, const typename arma_cx_only::result* junk = nullptr); }; @@ -172,7 +174,7 @@ const quasi_unwrap tmp(in.get_ref()); const Mat& X = tmp.M; - Mat out(X.n_rows, X.n_cols); + Mat out(X.n_rows, X.n_cols, arma_nozeros_indicator()); arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); @@ -194,7 +196,7 @@ const quasi_unwrap tmp(in.get_ref()); const Mat& X = tmp.M; - Mat out(X.n_rows, X.n_cols); + Mat out(X.n_rows, X.n_cols, arma_nozeros_indicator()); arrayops::convert_cx( out.memptr(), X.memptr(), X.n_elem ); @@ -229,7 +231,7 @@ const uword N = uword( in.size() ); - Mat out(N, 1); + Mat out(N, 1, arma_nozeros_indicator()); if(N > 0) { @@ -253,7 +255,7 @@ const uword N = uword( in.size() ); - Mat out(N, 1); + Mat out(N, 1, arma_nozeros_indicator()); if(N > 0) { @@ -272,18 +274,18 @@ public: template - inline static Row from(const Base& in, const typename arma_not_cx::result* junk = 0); + inline static Row from(const Base& in, const typename arma_not_cx::result* junk = nullptr); template - inline static Row from(const Base& in, const typename arma_cx_only::result* junk = 0); + inline static Row from(const Base& in, const typename arma_cx_only::result* junk = nullptr); template - inline static Row from(const std::vector& in, const typename arma_not_cx::result* junk = 0); + inline static Row from(const std::vector& in, const typename arma_not_cx::result* junk = nullptr); template - inline static Row from(const std::vector& in, const typename arma_cx_only::result* junk = 0); + inline static Row from(const std::vector& in, const typename arma_cx_only::result* junk = nullptr); }; @@ -303,7 +305,7 @@ arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); - Row out(X.n_elem); + Row out(X.n_elem, arma_nozeros_indicator()); arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); @@ -327,7 +329,7 @@ arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); - Row out(X.n_rows, X.n_cols); + Row out(X.n_rows, X.n_cols, arma_nozeros_indicator()); arrayops::convert_cx( out.memptr(), X.memptr(), X.n_elem ); @@ -348,7 +350,7 @@ const uword N = uword( in.size() ); - Row out(N); + Row out(N, arma_nozeros_indicator()); if(N > 0) { @@ -372,7 +374,7 @@ const uword N = uword( in.size() ); - Row out(N); + Row out(N, arma_nozeros_indicator()); if(N > 0) { @@ -391,18 +393,18 @@ public: template - inline static Col from(const Base& in, const typename arma_not_cx::result* junk = 0); + inline static Col from(const Base& in, const typename arma_not_cx::result* junk = nullptr); template - inline static Col from(const Base& in, const typename arma_cx_only::result* junk = 0); + inline static Col from(const Base& in, const typename arma_cx_only::result* junk = nullptr); template - inline static Col from(const std::vector& in, const typename arma_not_cx::result* junk = 0); + inline static Col from(const std::vector& in, const typename arma_not_cx::result* junk = nullptr); template - inline static Col from(const std::vector& in, const typename arma_cx_only::result* junk = 0); + inline static Col from(const std::vector& in, const typename arma_cx_only::result* junk = nullptr); }; @@ -422,7 +424,7 @@ arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); - Col out(X.n_elem); + Col out(X.n_elem, arma_nozeros_indicator()); arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); @@ -446,7 +448,7 @@ arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); - Col out(X.n_rows, X.n_cols); + Col out(X.n_rows, X.n_cols, arma_nozeros_indicator()); arrayops::convert_cx( out.memptr(), X.memptr(), X.n_elem ); @@ -467,7 +469,7 @@ const uword N = uword( in.size() ); - Col out(N); + Col out(N, arma_nozeros_indicator()); if(N > 0) { @@ -491,7 +493,7 @@ const uword N = uword( in.size() ); - Col out(N); + Col out(N, arma_nozeros_indicator()); if(N > 0) { @@ -510,10 +512,10 @@ public: template - inline static SpMat from(const SpBase& in, const typename arma_not_cx::result* junk = 0); + inline static SpMat from(const SpBase& in, const typename arma_not_cx::result* junk = nullptr); template - inline static SpMat from(const SpBase& in, const typename arma_cx_only::result* junk = 0); + inline static SpMat from(const SpBase& in, const typename arma_cx_only::result* junk = nullptr); template inline static SpMat from(const Base& in); @@ -590,10 +592,10 @@ public: template - inline static Cube from(const BaseCube& in, const typename arma_not_cx::result* junk = 0); + inline static Cube from(const BaseCube& in, const typename arma_not_cx::result* junk = nullptr); template - inline static Cube from(const BaseCube& in, const typename arma_cx_only::result* junk = 0); + inline static Cube from(const BaseCube& in, const typename arma_cx_only::result* junk = nullptr); }; @@ -611,7 +613,7 @@ const unwrap_cube tmp( in.get_ref() ); const Cube& X = tmp.M; - Cube out(X.n_rows, X.n_cols, X.n_slices); + Cube out(X.n_rows, X.n_cols, X.n_slices, arma_nozeros_indicator()); arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); @@ -633,7 +635,7 @@ const unwrap_cube tmp( in.get_ref() ); const Cube& X = tmp.M; - Cube out(X.n_rows, X.n_cols, X.n_slices); + Cube out(X.n_rows, X.n_cols, X.n_slices, arma_nozeros_indicator()); arrayops::convert_cx( out.memptr(), X.memptr(), X.n_elem ); @@ -649,10 +651,10 @@ public: template - inline static std::vector from(const Base& in, const typename arma_not_cx::result* junk = 0); + inline static std::vector from(const Base& in, const typename arma_not_cx::result* junk = nullptr); template - inline static std::vector from(const Base& in, const typename arma_cx_only::result* junk = 0); + inline static std::vector from(const Base& in, const typename arma_cx_only::result* junk = nullptr); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cor.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cor.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cor.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cor.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cov.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cov.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cov.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cov.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cross.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cross.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cross.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cross.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,12 +25,17 @@ template arma_warn_unused inline -const Glue -cross(const Base& X, const Base& Y) +typename +enable_if2 + < + is_arma_type::value && is_arma_type::value && is_same_type::value, + const Glue + >::result +cross(const T1& X, const T2& Y) { arma_extra_debug_sigprint(); - return Glue(X.get_ref(), Y.get_ref()); + return Glue(X, Y); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cumprod.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cumprod.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cumprod.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cumprod.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cumsum.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cumsum.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_cumsum.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cumsum.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_det.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_det.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_det.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_det.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,156 +25,45 @@ arma_warn_unused inline typename enable_if2< is_supported_blas_type::value, typename T1::elem_type >::result -det - ( - const Base& X - ) - { - arma_extra_debug_sigprint(); - - return auxlib::det(X.get_ref()); - } - - - -template -arma_warn_unused -inline -typename T1::elem_type -det - ( - const Op& X - ) +det(const Base& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const diagmat_proxy A(X.m); - - arma_debug_check( (A.n_rows != A.n_cols), "det(): given matrix must be square sized" ); + eT out_val = eT(0); - const uword N = (std::min)(A.n_rows, A.n_cols); + const bool status = op_det::apply_direct(out_val, X.get_ref()); - eT val1 = eT(1); - eT val2 = eT(1); - - uword i,j; - for(i=0, j=1; j -arma_warn_unused inline -typename T1::elem_type -det - ( - const Op& X - ) +typename enable_if2< is_supported_blas_type::value, bool >::result +det(typename T1::elem_type& out_val, const Base& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const Proxy P(X.m); - - const uword N = P.get_n_rows(); - - arma_debug_check( (N != P.get_n_cols()), "det(): given matrix must be square sized" ); - - eT val1 = eT(1); - eT val2 = eT(1); - - uword i,j; - for(i=0, j=1; j -arma_warn_unused -inline -typename enable_if2< is_supported_blas_type::value, typename T1::elem_type >::result -det - ( - const Op& X - ) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - const eT tmp = det(X.m); - - if(tmp == eT(0)) { arma_debug_warn("det(): denominator is zero" ); } - - return eT(1) / tmp; - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, typename T1::elem_type >::result -det - ( - const Base& X, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("det(X,bool) is deprecated and will be removed; change to det(X)"); - - return det(X.get_ref()); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, typename T1::elem_type >::result -det - ( - const Base& X, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("det(X,char*) is deprecated and will be removed; change to det(X)"); - - return det(X.get_ref()); + return status; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_diagmat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_diagmat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_diagmat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_diagmat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -18,7 +20,7 @@ //! @{ -//! interpret a matrix or a vector as a diagonal matrix (i.e. off-diagonal entries are zero) +//! interpret a matrix or a vector as a diagonal matrix (ie. off-diagonal entries are zero) template arma_warn_unused arma_inline diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_diagvec.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_diagvec.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_diagvec.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_diagvec.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -18,16 +20,30 @@ //! @{ -//! extract a diagonal from a matrix +//! extract main diagonal from matrix template arma_warn_unused arma_inline const Op -diagvec(const Base& X, const sword diag_id = 0) +diagvec(const Base& X) + { + arma_extra_debug_sigprint(); + + return Op(X.get_ref()); + } + + + +//! extract arbitrary diagonal from matrix +template +arma_warn_unused +arma_inline +const Op +diagvec(const Base& X, const sword diag_id) { arma_extra_debug_sigprint(); - return Op(X.get_ref(), ((diag_id < 0) ? -diag_id : diag_id), ((diag_id < 0) ? 1 : 0) ); + return Op(X.get_ref(), ((diag_id < 0) ? -diag_id : diag_id), ((diag_id < 0) ? 1 : 0) ); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_diff.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_diff.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_diff.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_diff.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_dot.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_dot.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_dot.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_dot.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eig_gen.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eig_gen.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eig_gen.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eig_gen.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -33,11 +35,11 @@ typedef typename T1::pod_type T; typedef typename std::complex eT; - const char sig = (option != NULL) ? option[0] : char(0); + const char sig = (option != nullptr) ? option[0] : char(0); arma_debug_check( ((sig != 'n') && (sig != 'b')), "eig_gen(): unknown option" ); - if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn( "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); } + if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn_level(1, "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); } Col eigvals; Mat eigvecs; @@ -70,11 +72,11 @@ typedef typename T1::pod_type T; typedef typename std::complex eT; - const char sig = (option != NULL) ? option[0] : char(0); + const char sig = (option != nullptr) ? option[0] : char(0); arma_debug_check( ((sig != 'n') && (sig != 'b')), "eig_gen(): unknown option" ); - if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn( "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); } + if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn_level(1, "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); } Mat eigvecs; @@ -83,7 +85,7 @@ if(status == false) { eigvals.soft_reset(); - arma_debug_warn("eig_gen(): decomposition failed"); + arma_debug_warn_level(3, "eig_gen(): decomposition failed"); } return status; @@ -106,11 +108,11 @@ arma_debug_check( (void_ptr(&eigvals) == void_ptr(&eigvecs)), "eig_gen(): parameter 'eigval' is an alias of parameter 'eigvec'" ); - const char sig = (option != NULL) ? option[0] : char(0); + const char sig = (option != nullptr) ? option[0] : char(0); arma_debug_check( ((sig != 'n') && (sig != 'b')), "eig_gen(): unknown option" ); - if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn( "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); } + if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn_level(1, "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); } const bool status = (sig == 'b') ? auxlib::eig_gen_balance(eigvals, eigvecs, true, expr.get_ref()) : auxlib::eig_gen(eigvals, eigvecs, true, expr.get_ref()); @@ -118,7 +120,46 @@ { eigvals.soft_reset(); eigvecs.soft_reset(); - arma_debug_warn("eig_gen(): decomposition failed"); + arma_debug_warn_level(3, "eig_gen(): decomposition failed"); + } + + return status; + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +eig_gen + ( + Col< std::complex >& eigvals, + Mat< std::complex >& leigvecs, + Mat< std::complex >& reigvecs, + const Base& expr, + const char* option = "nobalance" + ) + { + arma_extra_debug_sigprint(); + + arma_debug_check( (void_ptr(&eigvals) == void_ptr(&leigvecs)), "eig_gen(): parameter 'eigval' is an alias of parameter 'leigvec'" ); + arma_debug_check( (void_ptr(&eigvals) == void_ptr(&reigvecs)), "eig_gen(): parameter 'eigval' is an alias of parameter 'reigvec'" ); + arma_debug_check( (void_ptr(&leigvecs) == void_ptr(&reigvecs)), "eig_gen(): parameter 'leigvec' is an alias of parameter 'reigvec'" ); + + const char sig = (option != nullptr) ? option[0] : char(0); + + arma_debug_check( ((sig != 'n') && (sig != 'b')), "eig_gen(): unknown option" ); + + if( auxlib::crippled_lapack(expr) && (sig == 'b') ) { arma_debug_warn_level(1, "eig_gen(): 'balance' option ignored due to linking with crippled lapack"); } + + const bool status = (sig == 'b') ? auxlib::eig_gen_twosided_balance(eigvals, leigvecs, reigvecs, expr.get_ref()) : auxlib::eig_gen_twosided(eigvals, leigvecs, reigvecs, expr.get_ref()); + + if(status == false) + { + eigvals.soft_reset(); + leigvecs.soft_reset(); + reigvecs.soft_reset(); + arma_debug_warn_level(3, "eig_gen(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eig_pair.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eig_pair.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eig_pair.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eig_pair.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -69,7 +71,7 @@ if(status == false) { eigvals.soft_reset(); - arma_debug_warn("eig_pair(): decomposition failed"); + arma_debug_warn_level(3, "eig_pair(): decomposition failed"); } return status; @@ -98,11 +100,45 @@ { eigvals.soft_reset(); eigvecs.soft_reset(); - arma_debug_warn("eig_pair(): decomposition failed"); + arma_debug_warn_level(3, "eig_pair(): decomposition failed"); + } + + return status; + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +eig_pair + ( + Col< std::complex >& eigvals, + Mat< std::complex >& leigvecs, + Mat< std::complex >& reigvecs, + const Base< typename T1::elem_type, T1 >& A_expr, + const Base< typename T1::elem_type, T2 >& B_expr + ) + { + arma_extra_debug_sigprint(); + + arma_debug_check( (void_ptr(&eigvals) == void_ptr(&leigvecs)), "eig_pair(): parameter 'eigval' is an alias of parameter 'leigvec'" ); + arma_debug_check( (void_ptr(&eigvals) == void_ptr(&reigvecs)), "eig_pair(): parameter 'eigval' is an alias of parameter 'reigvec'" ); + arma_debug_check( (void_ptr(&leigvecs) == void_ptr(&reigvecs)), "eig_pair(): parameter 'leigvec' is an alias of parameter 'reigvec'" ); + + const bool status = auxlib::eig_pair_twosided(eigvals, leigvecs, reigvecs, A_expr.get_ref(), B_expr.get_ref()); + + if(status == false) + { + eigvals.soft_reset(); + leigvecs.soft_reset(); + reigvecs.soft_reset(); + arma_debug_warn_level(3, "eig_pair(): decomposition failed"); } return status; } + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eigs_gen.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eigs_gen.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eigs_gen.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eigs_gen.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,25 +24,123 @@ template arma_warn_unused inline -Col< std::complex > +typename enable_if2< is_real::value, Col< std::complex > >::result eigs_gen ( const SpBase& X, const uword n_eigvals, const char* form = "lm", - const typename T1::pod_type tol = 0.0, - const typename arma_blas_type_only::result* junk = 0 + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + Mat< std::complex > eigvec; + Col< std::complex > eigval; + + sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form); + + const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form_val, opts); + + if(status == false) + { + eigval.soft_reset(); + arma_stop_runtime_error("eigs_gen(): decomposition failed"); + } + + return eigval; + } + + + +//! this form is deprecated; use eigs_gen(X, n_eigvals, form, opts) instead +template +arma_deprecated +inline +typename enable_if2< is_real::value, Col< std::complex > >::result +eigs_gen + ( + const SpBase& X, + const uword n_eigvals, + const char* form, + const typename T1::pod_type tol + ) + { + arma_extra_debug_sigprint(); + + eigs_opts opts; + opts.tol = tol; + + return eigs_gen(X, n_eigvals, form, opts); + } + + + +template +arma_warn_unused +inline +typename enable_if2< is_real::value, Col< std::complex > >::result +eigs_gen + ( + const SpBase& X, + const uword n_eigvals, + const std::complex sigma, + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + Mat< std::complex > eigvec; + Col< std::complex > eigval; + + bool status = false; + + // If X is real and sigma is truly complex, treat X as complex. + // The reason is that we are still not able to apply truly complex shifts to real matrices + if( (is_real::yes) && (std::imag(sigma) != T(0)) ) + { + status = sp_auxlib::eigs_gen(eigval, eigvec, conv_to< SpMat< std::complex > >::from(X), n_eigvals, sigma, opts); + } + else + { + status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, sigma, opts); + } + + if(status == false) + { + eigval.soft_reset(); + arma_stop_runtime_error("eigs_gen(): decomposition failed"); + } + + return eigval; + } + + + +template +arma_warn_unused +inline +typename enable_if2< is_real::value, Col< std::complex > >::result +eigs_gen + ( + const SpBase& X, + const uword n_eigvals, + const double sigma, + const eigs_opts opts = eigs_opts() ) { arma_extra_debug_sigprint(); - arma_ignore(junk); typedef typename T1::pod_type T; Mat< std::complex > eigvec; Col< std::complex > eigval; - const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form, tol); + const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, std::complex(T(sigma)), opts); if(status == false) { @@ -56,30 +156,127 @@ //! eigenvalues of general sparse matrix X template inline -bool +typename enable_if2< is_real::value, bool >::result eigs_gen ( Col< std::complex >& eigval, const SpBase& X, const uword n_eigvals, const char* form = "lm", - const typename T1::pod_type tol = 0.0, - const typename arma_blas_type_only::result* junk = 0 + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + Mat< std::complex > eigvec; + + sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form); + + const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form_val, opts); + + if(status == false) + { + eigval.soft_reset(); + arma_debug_warn_level(3, "eigs_gen(): decomposition failed"); + } + + return status; + } + + + +//! this form is deprecated; use eigs_gen(eigval, X, n_eigvals, form, opts) instead +template +arma_deprecated +inline +typename enable_if2< is_real::value, bool >::result +eigs_gen + ( + Col< std::complex >& eigval, + const SpBase& X, + const uword n_eigvals, + const char* form, + const typename T1::pod_type tol + ) + { + arma_extra_debug_sigprint(); + + eigs_opts opts; + opts.tol = tol; + + return eigs_gen(eigval, X, n_eigvals, form, opts); + } + + + +template +inline +typename enable_if2< is_real::value, bool >::result +eigs_gen + ( + Col< std::complex >& eigval, + const SpBase& X, + const uword n_eigvals, + const std::complex sigma, + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + Mat< std::complex > eigvec; + + bool status = false; + + // If X is real and sigma is truly complex, treat X as complex. + // The reason is that we are still not able to apply truly complex shifts to real matrices + if( (is_real::yes) && (std::imag(sigma) != T(0)) ) + { + status = sp_auxlib::eigs_gen(eigval, eigvec, conv_to< SpMat< std::complex > >::from(X), n_eigvals, sigma, opts); + } + else + { + status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, sigma, opts); + } + + if(status == false) + { + eigval.soft_reset(); + arma_debug_warn_level(3, "eigs_gen(): decomposition failed"); + } + + return status; + } + + + +template +inline +typename enable_if2< is_real::value, bool >::result +eigs_gen + ( + Col< std::complex >& eigval, + const SpBase& X, + const uword n_eigvals, + const double sigma, + const eigs_opts opts = eigs_opts() ) { arma_extra_debug_sigprint(); - arma_ignore(junk); typedef typename T1::pod_type T; Mat< std::complex > eigvec; - const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form, tol); + const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, std::complex(T(sigma)), opts); if(status == false) { eigval.soft_reset(); - arma_debug_warn("eigs_gen(): decomposition failed"); + arma_debug_warn_level(3, "eigs_gen(): decomposition failed"); } return status; @@ -87,10 +284,10 @@ -//! eigenvalues and eigenvectors of general real sparse matrix X +//! eigenvalues and eigenvectors of general sparse matrix X template inline -bool +typename enable_if2< is_real::value, bool >::result eigs_gen ( Col< std::complex >& eigval, @@ -98,22 +295,126 @@ const SpBase& X, const uword n_eigvals, const char* form = "lm", - const typename T1::pod_type tol = 0.0, - const typename arma_blas_type_only::result* junk = 0 + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + // typedef typename T1::pod_type T; + + arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_gen(): parameter 'eigval' is an alias of parameter 'eigvec'" ); + + sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form); + + const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form_val, opts); + + if(status == false) + { + eigval.soft_reset(); + eigvec.soft_reset(); + arma_debug_warn_level(3, "eigs_gen(): decomposition failed"); + } + + return status; + } + + + +//! this form is deprecated; use eigs_gen(eigval, eigvec, X, n_eigvals, form, opts) instead +template +arma_deprecated +inline +typename enable_if2< is_real::value, bool >::result +eigs_gen + ( + Col< std::complex >& eigval, + Mat< std::complex >& eigvec, + const SpBase& X, + const uword n_eigvals, + const char* form, + const typename T1::pod_type tol + ) + { + arma_extra_debug_sigprint(); + + eigs_opts opts; + opts.tol = tol; + + return eigs_gen(eigval, eigvec, X, n_eigvals, form, opts); + } + + + +template +inline +typename enable_if2< is_real::value, bool >::result +eigs_gen + ( + Col< std::complex >& eigval, + Mat< std::complex >& eigvec, + const SpBase& X, + const uword n_eigvals, + const std::complex sigma, + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_gen(): parameter 'eigval' is an alias of parameter 'eigvec'" ); + + bool status = false; + + // If X is real and sigma is truly complex, treat X as complex. + // The reason is that we are still not able to apply truly complex shifts to real matrices + if( (is_real::yes) && (std::imag(sigma) != T(0)) ) + { + status = sp_auxlib::eigs_gen(eigval, eigvec, conv_to< SpMat< std::complex > >::from(X), n_eigvals, sigma, opts); + } + else + { + status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, sigma, opts); + } + + if(status == false) + { + eigval.soft_reset(); + eigvec.soft_reset(); + arma_debug_warn_level(3, "eigs_gen(): decomposition failed"); + } + + return status; + } + + + +template +inline +typename enable_if2< is_real::value, bool >::result +eigs_gen + ( + Col< std::complex >& eigval, + Mat< std::complex >& eigvec, + const SpBase& X, + const uword n_eigvals, + const double sigma, + const eigs_opts opts = eigs_opts() ) { arma_extra_debug_sigprint(); - arma_ignore(junk); + + typedef typename T1::pod_type T; arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_gen(): parameter 'eigval' is an alias of parameter 'eigvec'" ); - const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, form, tol); + const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, std::complex(T(sigma)), opts); if(status == false) { eigval.soft_reset(); eigvec.soft_reset(); - arma_debug_warn("eigs_gen(): decomposition failed"); + arma_debug_warn_level(3, "eigs_gen(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eigs_sym.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eigs_sym.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eigs_sym.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eigs_sym.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,23 +24,78 @@ template arma_warn_unused inline -Col +typename enable_if2< is_real::value, Col >::result eigs_sym ( const SpBase& X, const uword n_eigvals, const char* form = "lm", - const typename T1::elem_type tol = 0.0, - const typename arma_real_only::result* junk = 0 + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + Mat eigvec; + Col eigval; + + sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form); + + const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, form_val, opts); + + if(status == false) + { + eigval.soft_reset(); + arma_stop_runtime_error("eigs_sym(): decomposition failed"); + } + + return eigval; + } + + + +//! this form is deprecated; use eigs_sym(X, n_eigvals, form, opts) instead +template +arma_deprecated +inline +typename enable_if2< is_real::value, Col >::result +eigs_sym + ( + const SpBase& X, + const uword n_eigvals, + const char* form, + const typename T1::elem_type tol + ) + { + arma_extra_debug_sigprint(); + + eigs_opts opts; + opts.tol = tol; + + return eigs_sym(X, n_eigvals, form, opts); + } + + + +template +arma_warn_unused +inline +typename enable_if2< is_real::value, Col >::result +eigs_sym + ( + const SpBase& X, + const uword n_eigvals, + const double sigma, + const eigs_opts opts = eigs_opts() ) { arma_extra_debug_sigprint(); - arma_ignore(junk); + + typedef typename T1::pod_type T; Mat eigvec; Col eigval; - const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, form, tol); + const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, T(sigma), opts); if(status == false) { @@ -54,28 +111,83 @@ //! eigenvalues of symmetric real sparse matrix X template inline -bool +typename enable_if2< is_real::value, bool >::result eigs_sym ( Col& eigval, const SpBase& X, const uword n_eigvals, const char* form = "lm", - const typename T1::elem_type tol = 0.0, - const typename arma_real_only::result* junk = 0 + const eigs_opts opts = eigs_opts() ) { arma_extra_debug_sigprint(); - arma_ignore(junk); Mat eigvec; - const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, form, tol); + sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form); + + const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, form_val, opts); if(status == false) { eigval.soft_reset(); - arma_debug_warn("eigs_sym(): decomposition failed"); + arma_debug_warn_level(3, "eigs_sym(): decomposition failed"); + } + + return status; + } + + + +//! this form is deprecated; use eigs_sym(eigval, X, n_eigvals, form, opts) instead +template +arma_deprecated +inline +typename enable_if2< is_real::value, bool >::result +eigs_sym + ( + Col& eigval, + const SpBase& X, + const uword n_eigvals, + const char* form, + const typename T1::elem_type tol + ) + { + arma_extra_debug_sigprint(); + + eigs_opts opts; + opts.tol = tol; + + return eigs_sym(eigval, X, n_eigvals, form, opts); + } + + + +template +inline +typename enable_if2< is_real::value, bool >::result +eigs_sym + ( + Col& eigval, + const SpBase& X, + const uword n_eigvals, + const double sigma, + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + Mat eigvec; + + const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, T(sigma), opts); + + if(status == false) + { + eigval.soft_reset(); + arma_debug_warn_level(3, "eigs_sym(): decomposition failed"); } return status; @@ -86,7 +198,7 @@ //! eigenvalues and eigenvectors of symmetric real sparse matrix X template inline -bool +typename enable_if2< is_real::value, bool >::result eigs_sym ( Col& eigval, @@ -94,22 +206,80 @@ const SpBase& X, const uword n_eigvals, const char* form = "lm", - const typename T1::elem_type tol = 0.0, - const typename arma_real_only::result* junk = 0 + const eigs_opts opts = eigs_opts() ) { arma_extra_debug_sigprint(); - arma_ignore(junk); arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_sym(): parameter 'eigval' is an alias of parameter 'eigvec'" ); - const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, form, tol); + sp_auxlib::form_type form_val = sp_auxlib::interpret_form_str(form); + + const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, form_val, opts); + + if(status == false) + { + eigval.soft_reset(); + eigvec.soft_reset(); + arma_debug_warn_level(3, "eigs_sym(): decomposition failed"); + } + + return status; + } + + + +//! this form is deprecated; use eigs_sym(eigval, eigvec, X, n_eigvals, form, opts) instead +template +arma_deprecated +inline +typename enable_if2< is_real::value, bool >::result +eigs_sym + ( + Col& eigval, + Mat& eigvec, + const SpBase& X, + const uword n_eigvals, + const char* form, + const typename T1::elem_type tol + ) + { + arma_extra_debug_sigprint(); + + eigs_opts opts; + opts.tol = tol; + + return eigs_sym(eigval, eigvec, X, n_eigvals, form, opts); + } + + + +template +inline +typename enable_if2< is_real::value, bool >::result +eigs_sym + ( + Col& eigval, + Mat& eigvec, + const SpBase& X, + const uword n_eigvals, + const double sigma, + const eigs_opts opts = eigs_opts() + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_sym(): parameter 'eigval' is an alias of parameter 'eigvec'" ); + + const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, T(sigma), opts); if(status == false) { eigval.soft_reset(); eigvec.soft_reset(); - arma_debug_warn("eigs_sym(): decomposition failed"); + arma_debug_warn_level(3, "eigs_sym(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eig_sym.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eig_sym.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eig_sym.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eig_sym.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -30,15 +32,16 @@ { arma_extra_debug_sigprint(); - // unwrap_check not used as T1::elem_type and T1::pod_type may not be the same. - // furthermore, it doesn't matter if X is an alias of eigval, as auxlib::eig_sym() makes a copy of X + typedef typename T1::elem_type eT; + + Mat A(X.get_ref()); - const bool status = auxlib::eig_sym(eigval, X); + const bool status = auxlib::eig_sym(eigval, A); if(status == false) { eigval.soft_reset(); - arma_debug_warn("eig_sym(): decomposition failed"); + arma_debug_warn_level(3, "eig_sym(): decomposition failed"); } return status; @@ -58,16 +61,21 @@ { arma_extra_debug_sigprint(); - Col out; - const bool status = auxlib::eig_sym(out, X); + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + Col< T> eigval; + Mat A(X.get_ref()); + + const bool status = auxlib::eig_sym(eigval, A); if(status == false) { - out.soft_reset(); + eigval.reset(); arma_stop_runtime_error("eig_sym(): decomposition failed"); } - return out; + return eigval; } @@ -89,15 +97,15 @@ // if(auxlib::rudimentary_sym_check(X) == false) // { - // if(is_cx::no ) { arma_debug_warn(caller_sig, ": given matrix is not symmetric"); } - // if(is_cx::yes) { arma_debug_warn(caller_sig, ": given matrix is not hermitian"); } + // if(is_cx::no ) { arma_debug_warn_level(1, caller_sig, ": given matrix is not symmetric"); } + // if(is_cx::yes) { arma_debug_warn_level(1, caller_sig, ": given matrix is not hermitian"); } // return false; // } if((arma_config::debug) && (auxlib::rudimentary_sym_check(X) == false)) { - if(is_cx::no ) { arma_debug_warn(caller_sig, ": given matrix is not symmetric"); } - if(is_cx::yes) { arma_debug_warn(caller_sig, ": given matrix is not hermitian"); } + if(is_cx::no ) { arma_debug_warn_level(1, caller_sig, ": given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, caller_sig, ": given matrix is not hermitian"); } } bool status = false; @@ -127,7 +135,7 @@ typedef typename T1::elem_type eT; - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'd')), "eig_sym(): unknown method specified" ); arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eig_sym(): parameter 'eigval' is an alias of parameter 'eigvec'" ); @@ -145,7 +153,7 @@ { eigval.soft_reset(); eigvec.soft_reset(); - arma_debug_warn("eig_sym(): decomposition failed"); + arma_debug_warn_level(3, "eig_sym(): decomposition failed"); } else { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_elem.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_elem.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_elem.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_elem.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -436,7 +438,7 @@ arma_warn_unused arma_inline const eOpCube -abs(const BaseCube& X, const typename arma_not_cx::result* junk = 0) +abs(const BaseCube& X, const typename arma_not_cx::result* junk = nullptr) { arma_extra_debug_sigprint(); @@ -464,7 +466,7 @@ arma_warn_unused inline const mtOpCube -abs(const BaseCube< std::complex,T1>& X, const typename arma_cx_only::result* junk = 0) +abs(const BaseCube< std::complex,T1>& X, const typename arma_cx_only::result* junk = nullptr) { arma_extra_debug_sigprint(); @@ -479,7 +481,7 @@ arma_warn_unused arma_inline const SpOp -abs(const SpBase& X, const typename arma_not_cx::result* junk = 0) +abs(const SpBase& X, const typename arma_not_cx::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -493,7 +495,7 @@ arma_warn_unused arma_inline const mtSpOp -abs(const SpBase< std::complex, T1>& X, const typename arma_cx_only::result* junk = 0) +abs(const SpBase< std::complex, T1>& X, const typename arma_cx_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -524,7 +526,7 @@ arma_warn_unused arma_inline const eOpCube -arg(const BaseCube& X, const typename arma_not_cx::result* junk = 0) +arg(const BaseCube& X, const typename arma_not_cx::result* junk = nullptr) { arma_extra_debug_sigprint(); @@ -552,7 +554,7 @@ arma_warn_unused inline const mtOpCube -arg(const BaseCube< std::complex,T1>& X, const typename arma_cx_only::result* junk = 0) +arg(const BaseCube< std::complex,T1>& X, const typename arma_cx_only::result* junk = nullptr) { arma_extra_debug_sigprint(); @@ -567,7 +569,7 @@ arma_warn_unused arma_inline const SpOp -arg(const SpBase& X, const typename arma_not_cx::result* junk = 0) +arg(const SpBase& X, const typename arma_not_cx::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -581,7 +583,7 @@ arma_warn_unused arma_inline const mtSpOp -arg(const SpBase< std::complex, T1>& X, const typename arma_cx_only::result* junk = 0) +arg(const SpBase< std::complex, T1>& X, const typename arma_cx_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -1125,6 +1127,35 @@ } + +// +// tgamma + +template +arma_warn_unused +arma_inline +typename enable_if2< (is_arma_type::value && is_cx::no), const eOp >::result +tgamma(const T1& A) + { + arma_extra_debug_sigprint(); + + return eOp(A); + } + + + +template +arma_warn_unused +arma_inline +typename enable_if2< is_cx::no, const eOpCube >::result +tgamma(const BaseCube& A) + { + arma_extra_debug_sigprint(); + + return eOpCube(A.get_ref()); + } + + // the functions below are currently unused; reserved for potential future use diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eps.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eps.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eps.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eps.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -24,7 +26,7 @@ arma_warn_unused inline const eOp -eps(const Base& X, const typename arma_not_cx::result* junk = 0) +eps(const Base& X, const typename arma_not_cx::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -38,7 +40,7 @@ arma_warn_unused inline Mat< typename T1::pod_type > -eps(const Base< std::complex, T1>& X, const typename arma_cx_only::result* junk = 0) +eps(const Base< std::complex, T1>& X, const typename arma_cx_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -49,7 +51,7 @@ const unwrap tmp(X.get_ref()); const Mat& A = tmp.M; - Mat out(A.n_rows, A.n_cols); + Mat out(A.n_rows, A.n_cols, arma_nozeros_indicator()); T* out_mem = out.memptr(); const eT* A_mem = A.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_expmat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_expmat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_expmat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_expmat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -52,12 +54,11 @@ if(status == false) { - arma_debug_warn("expmat(): given matrix appears ill-conditioned"); B.soft_reset(); - return false; + arma_debug_warn_level(3, "expmat(): given matrix appears ill-conditioned"); } - return true; + return status; } @@ -91,7 +92,7 @@ if(status == false) { Y.soft_reset(); - arma_debug_warn("expmat_sym(): transformation failed"); + arma_debug_warn_level(3, "expmat_sym(): transformation failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eye.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eye.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_eye.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eye.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -47,7 +49,7 @@ arma_warn_unused arma_inline const Gen -eye(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = 0) +eye(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -71,7 +73,7 @@ arma_warn_unused arma_inline const Gen -eye(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = 0) +eye(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -85,7 +87,7 @@ arma_warn_unused inline obj_type -eye(const uword n_rows, const uword n_cols, const typename arma_SpMat_SpCol_SpRow_only::result* junk = NULL) +eye(const uword n_rows, const uword n_cols, const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -113,7 +115,7 @@ arma_warn_unused inline obj_type -eye(const SizeMat& s, const typename arma_SpMat_SpCol_SpRow_only::result* junk = NULL) +eye(const SizeMat& s, const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_fft2.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_fft2.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_fft2.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_fft2.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_fft.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_fft.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_fft.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_fft.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_find.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_find.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_find.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_find.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -45,7 +47,7 @@ { arma_extra_debug_sigprint(); - const char sig = (direction != NULL) ? direction[0] : char(0); + const char sig = (direction != nullptr) ? direction[0] : char(0); arma_debug_check ( @@ -162,7 +164,7 @@ const uword n_rows = P.get_n_rows(); const uword n_nz = P.get_n_nonzero(); - Mat tmp(n_nz,1); + Mat tmp(n_nz, 1, arma_nozeros_indicator()); uword* tmp_mem = tmp.memptr(); @@ -196,6 +198,10 @@ { arma_extra_debug_sigprint(); + arma_ignore(X); + arma_ignore(k); + arma_ignore(direction); + arma_check(true, "find(SpBase,k,direction): not implemented yet"); // TODO Col out; @@ -304,7 +310,7 @@ const uword n_rows = P.get_n_rows(); const uword n_nz = P.get_n_nonzero(); - Mat tmp(n_nz,1); + Mat tmp(n_nz, 1, arma_nozeros_indicator()); uword* tmp_mem = tmp.memptr(); @@ -348,7 +354,7 @@ const uword n_rows = P.get_n_rows(); const uword n_nz = P.get_n_nonzero(); - Mat tmp(n_nz,1); + Mat tmp(n_nz, 1, arma_nozeros_indicator()); uword* tmp_mem = tmp.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_find_unique.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_find_unique.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_find_unique.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_find_unique.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_flip.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_flip.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_flip.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_flip.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_hess.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_hess.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_hess.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_hess.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,7 +27,7 @@ ( Mat& H, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -48,7 +50,7 @@ if(status == false) { H.soft_reset(); - arma_debug_warn("hess(): decomposition failed"); + arma_debug_warn_level(3, "hess(): decomposition failed"); } return status; @@ -63,7 +65,7 @@ hess ( const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -103,7 +105,7 @@ Mat& U, Mat& H, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -161,7 +163,7 @@ { U.soft_reset(); H.soft_reset(); - arma_debug_warn("hess(): decomposition failed"); + arma_debug_warn_level(3, "hess(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_histc.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_histc.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_histc.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_histc.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_hist.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_hist.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_hist.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_hist.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_index_max.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_index_max.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_index_max.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_index_max.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_index_min.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_index_min.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_index_min.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_index_min.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_inplace_strans.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inplace_strans.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_inplace_strans.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inplace_strans.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -30,7 +32,7 @@ { arma_extra_debug_sigprint(); - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'l')), "inplace_strans(): unknown method specified" ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_inplace_trans.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inplace_trans.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_inplace_trans.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inplace_trans.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -56,7 +58,7 @@ { arma_extra_debug_sigprint(); - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'l')), "inplace_htrans(): unknown method specified" ); @@ -92,7 +94,7 @@ { arma_extra_debug_sigprint(); - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'l')), "inplace_trans(): unknown method specified" ); @@ -117,7 +119,7 @@ { arma_extra_debug_sigprint(); - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'l')), "inplace_trans(): unknown method specified" ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_interp1.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_interp1.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_interp1.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_interp1.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -198,8 +200,8 @@ arma_debug_check( (N_subset < 2), "interp1(): X must have at least two unique elements" ); - Mat X_sanitised(N_subset,1); - Mat Y_sanitised(N_subset,1); + Mat X_sanitised(N_subset, 1, arma_nozeros_indicator()); + Mat Y_sanitised(N_subset, 1, arma_nozeros_indicator()); eT* X_sanitised_mem = X_sanitised.memptr(); eT* Y_sanitised_mem = Y_sanitised.memptr(); @@ -296,7 +298,7 @@ uword sig = 0; - if(method != NULL ) + if(method != nullptr) if(method[0] != char(0)) if(method[1] != char(0)) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_interp2.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_interp2.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_interp2.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_interp2.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -193,7 +195,7 @@ typedef typename T1::elem_type eT; - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 'n') && (sig != 'l')), "interp2(): unsupported interpolation type" ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_intersect.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_intersect.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_intersect.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_intersect.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_inv.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inv.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_inv.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inv.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,102 +37,6 @@ -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Op >::result -inv - ( - const Base& X, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv(X,bool) is deprecated and will be removed; change to inv(X)"); - - return Op(X.get_ref()); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Op >::result -inv - ( - const Base& X, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv(X,char*) is deprecated and will be removed; change to inv(X)"); - - return Op(X.get_ref()); - } - - - -template -arma_warn_unused -arma_inline -typename enable_if2< is_supported_blas_type::value, const Op >::result -inv - ( - const Op& X - ) - { - arma_extra_debug_sigprint(); - - return Op(X.m, X.aux_uword_a, 0); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Op >::result -inv - ( - const Op& X, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv(X,bool) is deprecated and will be removed; change to inv(X)"); - - return Op(X.m, X.aux_uword_a, 0); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Op >::result -inv - ( - const Op& X, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv(X,char*) is deprecated and will be removed; change to inv(X)"); - - return Op(X.m, X.aux_uword_a, 0); - } - - - template inline typename enable_if2< is_supported_blas_type::value, bool >::result @@ -142,58 +48,15 @@ { arma_extra_debug_sigprint(); - try - { - out = inv(X); - } - catch(std::runtime_error&) + const bool status = op_inv::apply_direct(out, X.get_ref(), "inv()"); + + if(status == false) { - return false; + out.soft_reset(); + arma_debug_warn_level(3, "inv(): matrix is singular"); } - return true; - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, bool >::result -inv - ( - Mat& out, - const Base& X, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv(Y,X,bool) is deprecated and will be removed; change to inv(Y,X)"); - - return inv(out,X); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, bool >::result -inv - ( - Mat& out, - const Base& X, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv(Y,X,char*) is deprecated and will be removed; change to inv(Y,X)"); - - return inv(out,X); + return status; } @@ -214,46 +77,6 @@ -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Op >::result -inv_sympd - ( - const Base& X, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv_sympd(X,bool) is deprecated and will be removed; change to inv_sympd(X)"); - - return Op(X.get_ref()); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Op >::result -inv_sympd - ( - const Base& X, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv_sympd(X,char*) is deprecated and will be removed; change to inv_sympd(X)"); - - return Op(X.get_ref()); - } - - - template inline typename enable_if2< is_supported_blas_type::value, bool >::result @@ -265,58 +88,15 @@ { arma_extra_debug_sigprint(); - try - { - out = inv_sympd(X); - } - catch(std::runtime_error&) + const bool status = op_inv_sympd::apply_direct(out, X.get_ref()); + + if(status == false) { - return false; + out.soft_reset(); + arma_debug_warn_level(3, "inv_sympd(): matrix is singular or not positive definite"); } - return true; - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, bool >::result -inv_sympd - ( - Mat& out, - const Base& X, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv_sympd(Y,X,bool) is deprecated and will be removed; change to inv_sympd(Y,X)"); - - return inv_sympd(out,X); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, bool >::result -inv_sympd - ( - Mat& out, - const Base& X, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("inv_sympd(Y,X,char*) is deprecated and will be removed; change to inv_sympd(Y,X)"); - - return inv_sympd(out,X); + return status; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_join.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_join.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_join.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_join.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -258,7 +260,7 @@ arma_debug_assert_same_size(UA.M.n_rows, UA.M.n_cols, UB.M.n_rows, UB.M.n_cols, "join_slices(): incompatible dimensions"); - Cube out(UA.M.n_rows, UA.M.n_cols, 2); + Cube out(UA.M.n_rows, UA.M.n_cols, 2, arma_nozeros_indicator()); arrayops::copy(out.slice_memptr(0), UA.M.memptr(), UA.M.n_elem); arrayops::copy(out.slice_memptr(1), UB.M.memptr(), UB.M.n_elem); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_kmeans.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_kmeans.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_kmeans.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_kmeans.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -40,7 +42,7 @@ const bool status = model.kmeans_wrapper(means, data.get_ref(), k, seed_mode, n_iter, print_mode); - if(status == true) + if(status) { means = model.means; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_kron.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_kron.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_kron.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_kron.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_log_det.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_log_det.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_log_det.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_log_det.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,13 +24,13 @@ //! log determinant of mat template inline -void +bool log_det ( typename T1::elem_type& out_val, typename T1::pod_type& out_sign, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -37,28 +39,29 @@ typedef typename T1::elem_type eT; typedef typename T1::pod_type T; - const bool status = auxlib::log_det(out_val, out_sign, X); + const bool status = op_log_det::apply_direct(out_val, out_sign, X.get_ref()); if(status == false) { out_val = eT(Datum::nan); out_sign = T(0); - arma_warn("log_det(): failed to find determinant"); + arma_debug_warn_level(3, "log_det(): failed to find determinant"); } + + return status; } template inline -void +arma_warn_unused +std::complex log_det ( - typename T1::elem_type& out_val, - typename T1::pod_type& out_sign, - const Op& X, - const typename arma_blas_type_only::result* junk = 0 + const Base& X, + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -67,35 +70,55 @@ typedef typename T1::elem_type eT; typedef typename T1::pod_type T; - const diagmat_proxy A(X.m); - - arma_debug_check( (A.n_rows != A.n_cols), "log_det(): given matrix must be square sized" ); + eT out_val = eT(0); + T out_sign = T(0); - const uword N = (std::min)(A.n_rows, A.n_cols); + const bool status = op_log_det::apply_direct(out_val, out_sign, X.get_ref()); - if(N == 0) + if(status == false) { - out_val = eT(0); - out_sign = T(1); + out_val = eT(Datum::nan); + out_sign = T(0); - return; + arma_stop_runtime_error("log_det(): failed to find determinant"); } - eT x = A[0]; + return (out_sign >= T(1)) ? std::complex(out_val) : (out_val + std::complex(T(0),Datum::pi)); + } + + + +// + + + +template +inline +bool +log_det_sympd + ( + typename T1::pod_type& out_val, + const Base& X, + const typename arma_blas_type_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + typedef typename T1::pod_type T; + + out_val = T(0); - T sign = (is_cx::no) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1; - eT val = (is_cx::no) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x); + const bool status = op_log_det_sympd::apply_direct(out_val, X.get_ref()); - for(uword i=1; i::nan; - sign *= (is_cx::no) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1; - val += (is_cx::no) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x); + arma_debug_warn_level(3, "log_det_sympd(): given matrix is not symmetric positive definite"); } - out_val = val; - out_sign = sign; + return status; } @@ -103,25 +126,30 @@ template inline arma_warn_unused -std::complex -log_det +typename T1::pod_type +log_det_sympd ( const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); - typedef typename T1::elem_type eT; - typedef typename T1::pod_type T; + typedef typename T1::pod_type T; - eT out_val = eT(0); - T out_sign = T(0); + T out_val = T(0); - log_det(out_val, out_sign, X.get_ref()); + const bool status = op_log_det_sympd::apply_direct(out_val, X.get_ref()); - return (out_sign >= T(1)) ? std::complex(out_val) : (out_val + std::complex(T(0),Datum::pi)); + if(status == false) + { + out_val = Datum::nan; + + arma_stop_runtime_error("log_det_sympd(): given matrix is not symmetric positive definite"); + } + + return out_val; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_logmat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_logmat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_logmat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_logmat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -57,7 +59,7 @@ if(status == false) { Y.soft_reset(); - arma_debug_warn("logmat(): transformation failed"); + arma_debug_warn_level(3, "logmat(): transformation failed"); } return status; @@ -77,7 +79,7 @@ if(status == false) { Y.soft_reset(); - arma_debug_warn("logmat(): transformation failed"); + arma_debug_warn_level(3, "logmat(): transformation failed"); } return status; @@ -114,7 +116,7 @@ if(status == false) { Y.soft_reset(); - arma_debug_warn("logmat_sympd(): transformation failed"); + arma_debug_warn_level(3, "logmat_sympd(): transformation failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_log_normpdf.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_log_normpdf.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_log_normpdf.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_log_normpdf.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup fn_log_normpdf +//! @{ + + + +template +inline +typename enable_if2< (is_real::value), void >::result +log_normpdf_helper(Mat& out, const Base& X_expr, const Base& M_expr, const Base& S_expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + if(Proxy::use_at || Proxy::use_at || Proxy::use_at) + { + const quasi_unwrap UX(X_expr.get_ref()); + const quasi_unwrap UM(M_expr.get_ref()); + const quasi_unwrap US(S_expr.get_ref()); + + log_normpdf_helper(out, UX.M, UM.M, US.M); + + return; + } + + const Proxy PX(X_expr.get_ref()); + const Proxy PM(M_expr.get_ref()); + const Proxy PS(S_expr.get_ref()); + + arma_debug_check( ( (PX.get_n_rows() != PM.get_n_rows()) || (PX.get_n_cols() != PM.get_n_cols()) || (PM.get_n_rows() != PS.get_n_rows()) || (PM.get_n_cols() != PS.get_n_cols()) ), "log_normpdf(): size mismatch" ); + + out.set_size(PX.get_n_rows(), PX.get_n_cols()); + + eT* out_mem = out.memptr(); + + const uword N = PX.get_n_elem(); + + typename Proxy::ea_type X_ea = PX.get_ea(); + typename Proxy::ea_type M_ea = PM.get_ea(); + typename Proxy::ea_type S_ea = PS.get_ea(); + + const bool use_mp = arma_config::openmp && mp_gate::eval(N); + + if(use_mp) + { + #if defined(ARMA_USE_OPENMP) + { + const int n_threads = mp_thread_limit::get(); + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword i=0; i::log_sqrt2pi); + } + } + #endif + } + else + { + for(uword i=0; i::log_sqrt2pi); + } + } + } + + + +template +inline +arma_warn_unused +typename enable_if2< (is_real::value), eT >::result +log_normpdf(const eT x) + { + const eT out = (eT(-0.5) * (x*x)) - Datum::log_sqrt2pi; + + return out; + } + + + +template +inline +arma_warn_unused +typename enable_if2< (is_real::value), eT >::result +log_normpdf(const eT x, const eT mu, const eT sigma) + { + const eT tmp = (x - mu) / sigma; + + const eT out = (eT(-0.5) * (tmp*tmp)) - (std::log(sigma) + Datum::log_sqrt2pi); + + return out; + } + + + +template +inline +arma_warn_unused +typename enable_if2< (is_real::value), Mat >::result +log_normpdf(const eT x, const Base& M_expr, const Base& S_expr) + { + arma_extra_debug_sigprint(); + + const quasi_unwrap UM(M_expr.get_ref()); + const Mat& M = UM.M; + + Mat out; + + log_normpdf_helper(out, x*ones< Mat >(arma::size(M)), M, S_expr.get_ref()); + + return out; + } + + + +template +inline +arma_warn_unused +typename enable_if2< (is_real::value), Mat >::result +log_normpdf(const Base& X_expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const quasi_unwrap UX(X_expr.get_ref()); + const Mat& X = UX.M; + + Mat out; + + log_normpdf_helper(out, X, zeros< Mat >(arma::size(X)), ones< Mat >(arma::size(X))); + + return out; + } + + + +template +inline +arma_warn_unused +typename enable_if2< (is_real::value), Mat >::result +log_normpdf(const Base& X_expr, const typename T1::elem_type mu, const typename T1::elem_type sigma) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const quasi_unwrap UX(X_expr.get_ref()); + const Mat& X = UX.M; + + Mat out; + + log_normpdf_helper(out, X, mu*ones< Mat >(arma::size(X)), sigma*ones< Mat >(arma::size(X))); + + return out; + } + + + +template +inline +arma_warn_unused +typename enable_if2< (is_real::value), Mat >::result +log_normpdf(const Base& X_expr, const Base& M_expr, const Base& S_expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + Mat out; + + log_normpdf_helper(out, X_expr.get_ref(), M_expr.get_ref(), S_expr.get_ref()); + + return out; + } + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_lu.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_lu.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_lu.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_lu.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,13 +30,13 @@ Mat& L, Mat& U, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); - arma_debug_check( (&L == &U), "lu(): L and U are the same object"); + arma_debug_check( (&L == &U), "lu(): L and U are the same object" ); const bool status = auxlib::lu(L, U, X); @@ -42,7 +44,7 @@ { L.soft_reset(); U.soft_reset(); - arma_debug_warn("lu(): decomposition failed"); + arma_debug_warn_level(3, "lu(): decomposition failed"); } return status; @@ -60,13 +62,13 @@ Mat& U, Mat& P, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); - arma_debug_check( ( (&L == &U) || (&L == &P) || (&U == &P) ), "lu(): two or more output objects are the same object"); + arma_debug_check( ( (&L == &U) || (&L == &P) || (&U == &P) ), "lu(): two or more output objects are the same object" ); const bool status = auxlib::lu(L, U, P, X); @@ -75,7 +77,7 @@ L.soft_reset(); U.soft_reset(); P.soft_reset(); - arma_debug_warn("lu(): decomposition failed"); + arma_debug_warn_level(3, "lu(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_max.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_max.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_max.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_max.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_mean.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_mean.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_mean.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_mean.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_median.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_median.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_median.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_median.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_min.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_min.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_min.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_min.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_misc.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_misc.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_misc.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_misc.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -57,7 +59,7 @@ const uword num_m1 = num - 1; - if(is_non_integral::value == true) + if(is_non_integral::value) { const T delta = (end-start)/T(num_m1); @@ -167,7 +169,7 @@ } else { - return (log_a + arma_log1p(std::exp(negdelta))); + return (log_a + std::log1p(std::exp(negdelta))); } } @@ -190,7 +192,7 @@ arma_warn_unused arma_inline bool -is_finite(const eT x, const typename arma_scalar_only::result* junk = 0) +is_finite(const eT x, const typename arma_scalar_only::result* junk = nullptr) { arma_ignore(junk); @@ -241,22 +243,6 @@ -//! NOTE: don't use this function: it will be removed -template -arma_deprecated -inline -const T1& -sympd(const Base& X) - { - arma_extra_debug_sigprint(); - - arma_debug_warn("sympd() is deprecated and will be removed; change inv(sympd(X)) to inv_sympd(X)"); - - return X.get_ref(); - } - - - template inline void @@ -295,7 +281,7 @@ const uword row = i % s_n_rows; const uword col = i / s_n_rows; - uvec out(2); + uvec out(2, arma_nozeros_indicator()); uword* out_mem = out.memptr(); @@ -329,7 +315,7 @@ arma_debug_check( ((P_is_empty == false) && (P_is_vec == false)), "ind2sub(): parameter 'indices' must be a vector" ); - umat out(2,P_n_elem); + umat out(2, P_n_elem, arma_nozeros_indicator()); if(Proxy::use_at == false) { @@ -411,7 +397,7 @@ const uword row = j % s_n_rows; const uword col = j / s_n_rows; - uvec out(3); + uvec out(3, arma_nozeros_indicator()); uword* out_mem = out.memptr(); @@ -443,7 +429,7 @@ const uword U_n_elem = U.M.n_elem; const uword* U_mem = U.M.memptr(); - umat out(3,U_n_elem); + umat out(3, U_n_elem, arma_nozeros_indicator()); for(uword count=0; count < U_n_elem; ++count) { @@ -501,7 +487,7 @@ const uword U_M_n_cols = U.M.n_cols; - uvec out(U_M_n_cols); + uvec out(U_M_n_cols, arma_nozeros_indicator()); uword* out_mem = out.memptr(); const uword* U_M_mem = U.M.memptr(); @@ -558,7 +544,7 @@ const uword U_M_n_cols = U.M.n_cols; - uvec out(U_M_n_cols); + uvec out(U_M_n_cols, arma_nozeros_indicator()); uword* out_mem = out.memptr(); const uword* U_M_mem = U.M.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_mvnrnd.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_mvnrnd.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_mvnrnd.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_mvnrnd.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -56,7 +58,6 @@ template -arma_warn_unused inline typename enable_if2 @@ -72,17 +73,16 @@ if(status == false) { - arma_debug_warn("mvnrnd(): given covariance matrix is not symmetric positive semi-definite"); - return false; + out.soft_reset(); + arma_debug_warn_level(3, "mvnrnd(): given covariance matrix is not symmetric positive semi-definite"); } - return true; + return status; } template -arma_warn_unused inline typename enable_if2 @@ -98,11 +98,11 @@ if(status == false) { - arma_debug_warn("mvnrnd(): given covariance matrix is not symmetric positive semi-definite"); - return false; + out.soft_reset(); + arma_debug_warn_level(3, "mvnrnd(): given covariance matrix is not symmetric positive semi-definite"); } - return true; + return status; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_nonzeros.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_nonzeros.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_nonzeros.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_nonzeros.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_normalise.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normalise.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_normalise.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normalise.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -33,7 +35,7 @@ const T1& X, const uword p = uword(2), const arma_empty_class junk1 = arma_empty_class(), - const typename arma_real_or_cx_only::result* junk2 = 0 + const typename arma_real_or_cx_only::result* junk2 = nullptr ) { arma_extra_debug_sigprint(); @@ -59,7 +61,7 @@ const T1& X, const uword p = uword(2), const uword dim = 0, - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -79,7 +81,7 @@ const SpBase& expr, const uword p = uword(2), const uword dim = 0, - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -102,7 +104,7 @@ >::result normalise(const T& val) { - Col out(1); + Col out(1, arma_nozeros_indicator()); out[0] = (val != T(0)) ? T(val / (std::abs)(val)) : T(val); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_normcdf.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normcdf.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_normcdf.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normcdf.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,123 +28,96 @@ { arma_extra_debug_sigprint(); - #if !defined(ARMA_USE_CXX11) + typedef typename T1::elem_type eT; + + if(Proxy::use_at || Proxy::use_at || Proxy::use_at) { - arma_stop_logic_error("normcdf(): C++11 compiler required"); + const quasi_unwrap UX(X_expr.get_ref()); + const quasi_unwrap UM(M_expr.get_ref()); + const quasi_unwrap US(S_expr.get_ref()); + + normcdf_helper(out, UX.M, UM.M, US.M); return; } - #else + + const Proxy PX(X_expr.get_ref()); + const Proxy PM(M_expr.get_ref()); + const Proxy PS(S_expr.get_ref()); + + arma_debug_check( ( (PX.get_n_rows() != PM.get_n_rows()) || (PX.get_n_cols() != PM.get_n_cols()) || (PM.get_n_rows() != PS.get_n_rows()) || (PM.get_n_cols() != PS.get_n_cols()) ), "normcdf(): size mismatch" ); + + out.set_size(PX.get_n_rows(), PX.get_n_cols()); + + eT* out_mem = out.memptr(); + + const uword N = PX.get_n_elem(); + + typename Proxy::ea_type X_ea = PX.get_ea(); + typename Proxy::ea_type M_ea = PM.get_ea(); + typename Proxy::ea_type S_ea = PS.get_ea(); + + const bool use_mp = arma_config::openmp && mp_gate::eval(N); + + if(use_mp) { - typedef typename T1::elem_type eT; - - if(Proxy::use_at || Proxy::use_at || Proxy::use_at) - { - const quasi_unwrap UX(X_expr.get_ref()); - const quasi_unwrap UM(M_expr.get_ref()); - const quasi_unwrap US(S_expr.get_ref()); - - normcdf_helper(out, UX.M, UM.M, US.M); - - return; - } - - const Proxy PX(X_expr.get_ref()); - const Proxy PM(M_expr.get_ref()); - const Proxy PS(S_expr.get_ref()); - - arma_debug_check( ( (PX.get_n_rows() != PM.get_n_rows()) || (PX.get_n_cols() != PM.get_n_cols()) || (PM.get_n_rows() != PS.get_n_rows()) || (PM.get_n_cols() != PS.get_n_cols()) ), "normcdf(): size mismatch" ); - - out.set_size(PX.get_n_rows(), PX.get_n_cols()); - - eT* out_mem = out.memptr(); - - const uword N = PX.get_n_elem(); - - typename Proxy::ea_type X_ea = PX.get_ea(); - typename Proxy::ea_type M_ea = PM.get_ea(); - typename Proxy::ea_type S_ea = PS.get_ea(); - - const bool use_mp = arma_config::cxx11 && arma_config::openmp && mp_gate::eval(N); - - if(use_mp) - { - #if defined(ARMA_USE_OPENMP) - { - const int n_threads = mp_thread_limit::get(); - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword i=0; i::sqrt2)); - - out_mem[i] = 0.5 * std::erfc(tmp); - } - } - #endif - } - else + #if defined(ARMA_USE_OPENMP) { + const int n_threads = mp_thread_limit::get(); + #pragma omp parallel for schedule(static) num_threads(n_threads) for(uword i=0; i::sqrt2)); - out_mem[i] = 0.5 * std::erfc(tmp); + out_mem[i] = eT(0.5) * std::erfc(tmp); } } + #endif + } + else + { + for(uword i=0; i::sqrt2)); + + out_mem[i] = eT(0.5) * std::erfc(tmp); + } } - #endif } template -arma_inline +inline +arma_warn_unused typename enable_if2< (is_real::value), eT >::result normcdf(const eT x) { - #if !defined(ARMA_USE_CXX11) - { - arma_stop_logic_error("normcdf(): C++11 compiler required"); - - return eT(0); - } - #else - { - const eT out = 0.5 * std::erfc( x / (-Datum::sqrt2) ); - - return out; - } - #endif + const eT out = eT(0.5) * std::erfc( x / (-Datum::sqrt2) ); + + return out; } template inline +arma_warn_unused typename enable_if2< (is_real::value), eT >::result normcdf(const eT x, const eT mu, const eT sigma) { - #if !defined(ARMA_USE_CXX11) - { - arma_stop_logic_error("normcdf(): C++11 compiler required"); - - return eT(0); - } - #else - { - const eT tmp = (x - mu) / (sigma * (-Datum::sqrt2)); - - const eT out = 0.5 * std::erfc(tmp); - - return out; - } - #endif + const eT tmp = (x - mu) / (sigma * (-Datum::sqrt2)); + + const eT out = eT(0.5) * std::erfc(tmp); + + return out; } template inline +arma_warn_unused typename enable_if2< (is_real::value), Mat >::result normcdf(const eT x, const Base& M_expr, const Base& S_expr) { @@ -162,6 +137,7 @@ template inline +arma_warn_unused typename enable_if2< (is_real::value), Mat >::result normcdf(const Base& X_expr) { @@ -183,6 +159,7 @@ template inline +arma_warn_unused typename enable_if2< (is_real::value), Mat >::result normcdf(const Base& X_expr, const typename T1::elem_type mu, const typename T1::elem_type sigma) { @@ -204,6 +181,7 @@ template inline +arma_warn_unused typename enable_if2< (is_real::value), Mat >::result normcdf(const Base& X_expr, const Base& M_expr, const Base& S_expr) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_norm.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_norm.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_norm.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_norm.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,7 +29,7 @@ ( const T1& X, const uword k = uword(2), - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -37,51 +39,30 @@ const Proxy P(X); - if(P.get_n_elem() == 0) - { - return T(0); - } + if(P.get_n_elem() == 0) { return T(0); } - const bool is_vec = (T1::is_row) || (T1::is_col) || (P.get_n_rows() == 1) || (P.get_n_cols() == 1); + const bool is_vec = (T1::is_xvec) || (T1::is_row) || (T1::is_col) || (P.get_n_rows() == 1) || (P.get_n_cols() == 1); if(is_vec) { - switch(k) - { - case 1: - return op_norm::vec_norm_1(P); - break; - - case 2: - return op_norm::vec_norm_2(P); - break; - - default: - { - arma_debug_check( (k == 0), "norm(): k must be greater than zero" ); - return op_norm::vec_norm_k(P, int(k)); - } - } + if(k == uword(1)) { return op_norm::vec_norm_1(P); } + if(k == uword(2)) { return op_norm::vec_norm_2(P); } + + arma_debug_check( (k == 0), "norm(): k must be greater than zero" ); + + return op_norm::vec_norm_k(P, int(k)); } else { - switch(k) - { - case 1: - return op_norm::mat_norm_1(P); - break; - - case 2: - return op_norm::mat_norm_2(P); - break; + const quasi_unwrap::stored_type> U(P.Q); + + if(k == uword(1)) { return op_norm::mat_norm_1(U.M); } + if(k == uword(2)) { return op_norm::mat_norm_2(U.M); } - default: - arma_stop_logic_error("norm(): unsupported matrix norm type"); - return T(0); - } + arma_stop_logic_error("norm(): unsupported matrix norm type"); } - return T(0); // prevent erroneous compiler warnings + return T(0); } @@ -94,7 +75,7 @@ ( const T1& X, const char* method, - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -104,53 +85,81 @@ const Proxy P(X); - if(P.get_n_elem() == 0) - { - return T(0); - } + if(P.get_n_elem() == 0) { return T(0); } - const char sig = (method != NULL) ? method[0] : char(0); - const bool is_vec = (T1::is_row) || (T1::is_col) || (P.get_n_rows() == 1) || (P.get_n_cols() == 1); + const char sig = (method != nullptr) ? method[0] : char(0); + const bool is_vec = (T1::is_xvec) || (T1::is_row) || (T1::is_col) || (P.get_n_rows() == 1) || (P.get_n_cols() == 1); if(is_vec) { - if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // max norm - { - return op_norm::vec_norm_max(P); - } - else - if(sig == '-') // min norm - { - return op_norm::vec_norm_min(P); - } - else - if( (sig == 'f') || (sig == 'F') ) - { - return op_norm::vec_norm_2(P); - } - else - { - arma_stop_logic_error("norm(): unsupported vector norm type"); - return T(0); - } + if( (sig == 'i') || (sig == 'I') || (sig == '+') ) { return op_norm::vec_norm_max(P); } + if( (sig == '-') ) { return op_norm::vec_norm_min(P); } + if( (sig == 'f') || (sig == 'F') ) { return op_norm::vec_norm_2(P); } + + arma_stop_logic_error("norm(): unsupported vector norm type"); } else { if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // inf norm { - return op_norm::mat_norm_inf(P); + const quasi_unwrap::stored_type> U(P.Q); + + return op_norm::mat_norm_inf(U.M); } else if( (sig == 'f') || (sig == 'F') ) { return op_norm::vec_norm_2(P); } - else - { - arma_stop_logic_error("norm(): unsupported matrix norm type"); - return T(0); - } + + arma_stop_logic_error("norm(): unsupported matrix norm type"); } + + return T(0); + } + + + +template +inline +arma_warn_unused +typename enable_if2< is_arma_type::value, double >::result +norm + ( + const T1& X, + const uword k = uword(2), + const typename arma_integral_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + if(resolves_to_colvector::value) { return norm(conv_to< Col >::from(X), k); } + if(resolves_to_rowvector::value) { return norm(conv_to< Row >::from(X), k); } + + return norm(conv_to< Mat >::from(X), k); + } + + + +template +inline +arma_warn_unused +typename enable_if2< is_arma_type::value, double >::result +norm + ( + const T1& X, + const char* method, + const typename arma_integral_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + if(resolves_to_colvector::value) { return norm(conv_to< Col >::from(X), method); } + if(resolves_to_rowvector::value) { return norm(conv_to< Row >::from(X), method); } + + return norm(conv_to< Mat >::from(X), method); } @@ -165,9 +174,9 @@ typename enable_if2< is_arma_sparse_type::value, typename T1::pod_type >::result norm ( - const T1& X, + const T1& expr, const uword k = uword(2), - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -176,59 +185,36 @@ typedef typename T1::elem_type eT; typedef typename T1::pod_type T; - const SpProxy P(X); + const unwrap_spmat U(expr); + const SpMat& X = U.M; - if(P.get_n_nonzero() == 0) - { - return T(0); - } + if(X.n_nonzero == 0) { return T(0); } - const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1); + const bool is_vec = (T1::is_xvec) || (T1::is_row) || (T1::is_col) || (X.n_rows == 1) || (X.n_cols == 1); if(is_vec) { - const unwrap_spmat::stored_type> tmp(P.Q); - const SpMat& A = tmp.M; - // create a fake dense vector to allow reuse of code for dense vectors - Col fake_vector( access::rwp(A.values), A.n_nonzero, false ); + Col fake_vector( access::rwp(X.values), X.n_nonzero, false ); const Proxy< Col > P_fake_vector(fake_vector); - switch(k) - { - case 1: - return op_norm::vec_norm_1(P_fake_vector); - break; - - case 2: - return op_norm::vec_norm_2(P_fake_vector); - break; - - default: - { - arma_debug_check( (k == 0), "norm(): k must be greater than zero" ); - return op_norm::vec_norm_k(P_fake_vector, int(k)); - } - } + if(k == uword(1)) { return op_norm::vec_norm_1(P_fake_vector); } + if(k == uword(2)) { return op_norm::vec_norm_2(P_fake_vector); } + + arma_debug_check( (k == 0), "norm(): k must be greater than zero" ); + + return op_norm::vec_norm_k(P_fake_vector, int(k)); } else { - switch(k) - { - case 1: - return op_norm::mat_norm_1(P); - break; - - case 2: - return op_norm::mat_norm_2(P); - break; - - default: - arma_stop_logic_error("norm(): unsupported or unimplemented norm type for sparse matrices"); - return T(0); - } + if(k == uword(1)) { return spop_norm::mat_norm_1(X); } + if(k == uword(2)) { return spop_norm::mat_norm_2(X); } + + arma_stop_logic_error("norm(): unsupported or unimplemented norm type for sparse matrices"); } + + return T(0); } @@ -239,9 +225,9 @@ typename enable_if2< is_arma_sparse_type::value, typename T1::pod_type >::result norm ( - const T1& X, + const T1& expr, const char* method, - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -250,25 +236,19 @@ typedef typename T1::elem_type eT; typedef typename T1::pod_type T; - const SpProxy P(X); + const unwrap_spmat U(expr); + const SpMat& X = U.M; - if(P.get_n_nonzero() == 0) - { - return T(0); - } - - - const unwrap_spmat::stored_type> tmp(P.Q); - const SpMat& A = tmp.M; + if(X.n_nonzero == 0) { return T(0); } // create a fake dense vector to allow reuse of code for dense vectors - Col fake_vector( access::rwp(A.values), A.n_nonzero, false ); + Col fake_vector( access::rwp(X.values), X.n_nonzero, false ); const Proxy< Col > P_fake_vector(fake_vector); - const char sig = (method != NULL) ? method[0] : char(0); - const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1); // TODO: (T1::is_row) || (T1::is_col) || ... + const char sig = (method != nullptr) ? method[0] : char(0); + const bool is_vec = (T1::is_xvec) || (T1::is_row) || (T1::is_col) || (X.n_rows == 1) || (X.n_cols == 1); if(is_vec) { @@ -281,43 +261,32 @@ { const T val = op_norm::vec_norm_min(P_fake_vector); - if( P.get_n_nonzero() < P.get_n_elem() ) - { - return (std::min)(T(0), val); - } - else - { - return val; - } + return (X.n_nonzero < X.n_elem) ? T((std::min)(T(0), val)) : T(val); } else if( (sig == 'f') || (sig == 'F') ) { return op_norm::vec_norm_2(P_fake_vector); } - else - { - arma_stop_logic_error("norm(): unsupported vector norm type"); - return T(0); - } + + arma_stop_logic_error("norm(): unsupported vector norm type"); } else { if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // inf norm { - return op_norm::mat_norm_inf(P); + return spop_norm::mat_norm_inf(X); } else if( (sig == 'f') || (sig == 'F') ) { return op_norm::vec_norm_2(P_fake_vector); } - else - { - arma_stop_logic_error("norm(): unsupported matrix norm type"); - return T(0); - } + + arma_stop_logic_error("norm(): unsupported matrix norm type"); } + + return T(0); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_normpdf.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normpdf.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_normpdf.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normpdf.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -55,7 +57,7 @@ typename Proxy::ea_type M_ea = PM.get_ea(); typename Proxy::ea_type S_ea = PS.get_ea(); - const bool use_mp = arma_config::cxx11 && arma_config::openmp && mp_gate::eval(N); + const bool use_mp = arma_config::openmp && mp_gate::eval(N); if(use_mp) { @@ -90,7 +92,8 @@ template -arma_inline +inline +arma_warn_unused typename enable_if2< (is_real::value), eT >::result normpdf(const eT x) { @@ -103,6 +106,7 @@ template inline +arma_warn_unused typename enable_if2< (is_real::value), eT >::result normpdf(const eT x, const eT mu, const eT sigma) { @@ -117,6 +121,7 @@ template inline +arma_warn_unused typename enable_if2< (is_real::value), Mat >::result normpdf(const eT x, const Base& M_expr, const Base& S_expr) { @@ -136,6 +141,7 @@ template inline +arma_warn_unused typename enable_if2< (is_real::value), Mat >::result normpdf(const Base& X_expr) { @@ -157,6 +163,7 @@ template inline +arma_warn_unused typename enable_if2< (is_real::value), Mat >::result normpdf(const Base& X_expr, const typename T1::elem_type mu, const typename T1::elem_type sigma) { @@ -178,6 +185,7 @@ template inline +arma_warn_unused typename enable_if2< (is_real::value), Mat >::result normpdf(const Base& X_expr, const Base& M_expr, const Base& S_expr) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_numel.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_numel.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_numel.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_numel.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_n_unique.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_n_unique.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_n_unique.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_n_unique.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_ones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_ones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_ones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_ones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,7 +37,7 @@ arma_warn_unused arma_inline const Gen -ones(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = 0) +ones(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk1); @@ -81,7 +83,7 @@ arma_warn_unused inline const Gen -ones(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = 0) +ones(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -105,7 +107,7 @@ arma_warn_unused inline const Gen -ones(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = 0) +ones(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -143,7 +145,7 @@ arma_warn_unused arma_inline const GenCube -ones(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only::result* junk = 0) +ones(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -157,7 +159,7 @@ arma_warn_unused arma_inline const GenCube -ones(const SizeCube& s, const typename arma_Cube_only::result* junk = 0) +ones(const SizeCube& s, const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_orth_null.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_orth_null.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_orth_null.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_orth_null.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -45,7 +47,8 @@ if(status == false) { - arma_debug_warn("orth(): svd failed"); + out.soft_reset(); + arma_debug_warn_level(3, "orth(): svd failed"); } return status; @@ -83,7 +86,8 @@ if(status == false) { - arma_debug_warn("null(): svd failed"); + out.soft_reset(); + arma_debug_warn_level(3, "null(): svd failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_pinv.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_pinv.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_pinv.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_pinv.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,18 +29,26 @@ ( const Base& X, const typename T1::pod_type tol = 0.0, - const char* method = "dc" + const char* method = nullptr ) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const char sig = (method != NULL) ? method[0] : char(0); + uword method_id = 0; // default setting - arma_debug_check( ((sig != 's') && (sig != 'd')), "pinv(): unknown method specified" ); + if(method != nullptr) + { + const char sig = method[0]; + + arma_debug_check( ((sig != 's') && (sig != 'd')), "pinv(): unknown method specified" ); + + if(sig == 's') { method_id = 1; } + if(sig == 'd') { method_id = 2; } + } - return (sig == 'd') ? Op(X.get_ref(), eT(tol), 1, 0) : Op(X.get_ref(), eT(tol), 0, 0); + return Op(X.get_ref(), eT(tol), method_id, uword(0)); } @@ -51,22 +61,29 @@ Mat& out, const Base& X, const typename T1::pod_type tol = 0.0, - const char* method = "dc" + const char* method = nullptr ) { arma_extra_debug_sigprint(); - const char sig = (method != NULL) ? method[0] : char(0); + uword method_id = 0; // default setting - arma_debug_check( ((sig != 's') && (sig != 'd')), "pinv(): unknown method specified" ); - - const bool use_divide_and_conquer = (sig == 'd'); + if(method != nullptr) + { + const char sig = method[0]; + + arma_debug_check( ((sig != 's') && (sig != 'd')), "pinv(): unknown method specified" ); + + if(sig == 's') { method_id = 1; } + if(sig == 'd') { method_id = 2; } + } - const bool status = op_pinv::apply_direct(out, X.get_ref(), tol, use_divide_and_conquer); + const bool status = op_pinv::apply_direct(out, X.get_ref(), tol, method_id); if(status == false) { - arma_debug_warn("pinv(): svd failed"); + out.soft_reset(); + arma_debug_warn_level(3, "pinv(): svd failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_polyfit.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_polyfit.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_polyfit.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_polyfit.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -36,7 +38,7 @@ if(status == false) { out.soft_reset(); - arma_debug_warn("polyfit(): failed"); + arma_debug_warn_level(3, "polyfit(): failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_polyval.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_polyval.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_polyval.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_polyval.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_powmat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_powmat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_powmat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_powmat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup fn_powmat +//! @{ + + +template +arma_warn_unused +inline +typename enable_if2< is_supported_blas_type::value, const Op >::result +powmat(const Base& X, const int y) + { + arma_extra_debug_sigprint(); + + const uword aux_a = (y < int(0)) ? uword(-y) : uword(y); + const uword aux_b = (y < int(0)) ? uword(1) : uword(0); + + return Op(X.get_ref(), aux_a, aux_b); + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +powmat + ( + Mat& out, + const Base& X, + const int y + ) + { + arma_extra_debug_sigprint(); + + const uword y_val = (y < int(0)) ? uword(-y) : uword(y); + const bool y_neg = (y < int(0)); + + const bool status = op_powmat::apply_direct(out, X.get_ref(), y_val, y_neg); + + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "powmat(): transformation failed"); + } + + return status; + } + + + +template +arma_warn_unused +inline +typename enable_if2< is_supported_blas_type::value, const mtOp,T1,op_powmat_cx> >::result +powmat(const Base& X, const double y) + { + arma_extra_debug_sigprint(); + + typedef std::complex out_eT; + + return mtOp('j', X.get_ref(), out_eT(y)); + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +powmat + ( + Mat< std::complex >& out, + const Base& X, + const double y + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + const bool status = op_powmat_cx::apply_direct(out, X.get_ref(), T(y)); + + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "powmat(): transformation failed"); + } + + return status; + } + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_princomp.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_princomp.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_princomp.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_princomp.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,7 +37,7 @@ Col& latent_out, Col& tsquared_out, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -50,7 +52,7 @@ latent_out.soft_reset(); tsquared_out.soft_reset(); - arma_debug_warn("princomp(): decomposition failed"); + arma_debug_warn_level(3, "princomp(): decomposition failed"); } return status; @@ -72,7 +74,7 @@ Mat& score_out, Col& latent_out, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -86,7 +88,7 @@ score_out.soft_reset(); latent_out.soft_reset(); - arma_debug_warn("princomp(): decomposition failed"); + arma_debug_warn_level(3, "princomp(): decomposition failed"); } return status; @@ -106,7 +108,7 @@ Mat& coeff_out, Mat& score_out, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -119,7 +121,7 @@ coeff_out.soft_reset(); score_out.soft_reset(); - arma_debug_warn("princomp(): decomposition failed"); + arma_debug_warn_level(3, "princomp(): decomposition failed"); } return status; @@ -137,7 +139,7 @@ ( Mat& coeff_out, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -149,7 +151,7 @@ { coeff_out.soft_reset(); - arma_debug_warn("princomp(): decomposition failed"); + arma_debug_warn_level(3, "princomp(): decomposition failed"); } return status; @@ -164,7 +166,7 @@ princomp ( const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_prod.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_prod.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_prod.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_prod.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,8 +23,8 @@ //! \brief //! Delayed product of elements of a matrix along a specified dimension (either rows or columns). //! The result is stored in a dense matrix that has either one column or one row. -//! For dim = 0, find the sum of each column (i.e. traverse across rows) -//! For dim = 1, find the sum of each row (i.e. traverse across columns) +//! For dim = 0, find the sum of each column (ie. traverse across rows) +//! For dim = 1, find the sum of each row (ie. traverse across columns) //! The default is dim = 0. //! NOTE: this function works differently than in Matlab/Octave. diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_qr.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_qr.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_qr.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_qr.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,13 +30,13 @@ Mat& Q, Mat& R, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); - arma_debug_check( (&Q == &R), "qr(): Q and R are the same object"); + arma_debug_check( (&Q == &R), "qr(): Q and R are the same object" ); const bool status = auxlib::qr(Q, R, X); @@ -42,7 +44,7 @@ { Q.soft_reset(); R.soft_reset(); - arma_debug_warn("qr(): decomposition failed"); + arma_debug_warn_level(3, "qr(): decomposition failed"); } return status; @@ -59,13 +61,13 @@ Mat& Q, Mat& R, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); - arma_debug_check( (&Q == &R), "qr_econ(): Q and R are the same object"); + arma_debug_check( (&Q == &R), "qr_econ(): Q and R are the same object" ); const bool status = auxlib::qr_econ(Q, R, X); @@ -73,7 +75,66 @@ { Q.soft_reset(); R.soft_reset(); - arma_debug_warn("qr_econ(): decomposition failed"); + arma_debug_warn_level(3, "qr_econ(): decomposition failed"); + } + + return status; + } + + + +//! QR decomposition with pivoting +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +qr + ( + Mat& Q, + Mat& R, + Mat& P, + const Base& X, + const char* P_mode = "matrix" + ) + { + arma_extra_debug_sigprint(); + + arma_debug_check( (&Q == &R), "qr(): Q and R are the same object" ); + + const char sig = (P_mode != nullptr) ? P_mode[0] : char(0); + + arma_debug_check( ((sig != 'm') && (sig != 'v')), "qr(): argument 'P_mode' must be \"vector\" or \"matrix\"" ); + + bool status = false; + + if(sig == 'v') + { + status = auxlib::qr_pivot(Q, R, P, X); + } + else + if(sig == 'm') + { + Mat P_vec; + + status = auxlib::qr_pivot(Q, R, P_vec, X); + + if(status) + { + // construct P + + const uword N = P_vec.n_rows; + + P.zeros(N,N); + + for(uword row=0; row < N; ++row) { P.at(P_vec[row], row) = uword(1); } + } + } + + if(status == false) + { + Q.soft_reset(); + R.soft_reset(); + P.soft_reset(); + arma_debug_warn_level(3, "qr(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_quantile.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_quantile.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_quantile.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_quantile.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup fn_quantile +//! @{ + + +template +arma_warn_unused +arma_inline +typename +enable_if2 + < + is_arma_type::value && is_cx::no && is_real::value, + const mtGlue + >::result +quantile(const T1& X, const Base& P) + { + arma_extra_debug_sigprint(); + + return mtGlue(X, P.get_ref()); + } + + + +template +arma_warn_unused +arma_inline +typename +enable_if2 + < + is_arma_type::value && is_cx::no && is_real::value, + const mtGlue + >::result +quantile(const T1& X, const Base& P, const uword dim) + { + arma_extra_debug_sigprint(); + + return mtGlue(X, P.get_ref(), dim); + } + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_qz.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_qz.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_qz.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_qz.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -41,7 +43,7 @@ { arma_extra_debug_sigprint(); - const char sig = (select != NULL) ? select[0] : char(0); + const char sig = (select != nullptr) ? select[0] : char(0); arma_debug_check( ( (sig != 'n') && (sig != 'l') && (sig != 'r') && (sig != 'i') && (sig != 'o') ), "qz(): unknown select form" ); @@ -53,7 +55,7 @@ BB.soft_reset(); Q.soft_reset(); Z.soft_reset(); - arma_debug_warn("qz(): decomposition failed"); + arma_debug_warn_level(3, "qz(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randg.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randg.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randg.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randg.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,76 +25,50 @@ arma_warn_unused inline obj_type -randg(const uword n_rows, const uword n_cols, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = 0) +randg(const uword n_rows, const uword n_cols, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); - #if defined(ARMA_USE_CXX11) + typedef typename obj_type::elem_type eT; + + if(is_Col::value) + { + arma_debug_check( (n_cols != 1), "randg(): incompatible size" ); + } + else + if(is_Row::value) + { + arma_debug_check( (n_rows != 1), "randg(): incompatible size" ); + } + + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); + + double a; + double b; + + if(param.state == 0) { - if(is_Col::value) - { - arma_debug_check( (n_cols != 1), "randg(): incompatible size" ); - } - else - if(is_Row::value) - { - arma_debug_check( (n_rows != 1), "randg(): incompatible size" ); - } - - obj_type out(n_rows, n_cols); - - double a; - double b; - - if(param.state == 0) - { - a = double(1); - b = double(1); - } - else - if(param.state == 1) - { - a = double(param.a_int); - b = double(param.b_int); - } - else - { - a = param.a_double; - b = param.b_double; - } - - arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): a and b must be greater than zero" ); - - #if defined(ARMA_USE_EXTERN_CXX11_RNG) - { - arma_rng_cxx11_instance.randg_fill(out.memptr(), out.n_elem, a, b); - } - #else - { - arma_rng_cxx11 local_arma_rng_cxx11_instance; - - typedef typename arma_rng_cxx11::seed_type seed_type; - - local_arma_rng_cxx11_instance.set_seed( seed_type(arma_rng::randi()) ); - - local_arma_rng_cxx11_instance.randg_fill(out.memptr(), out.n_elem, a, b); - } - #endif - - return out; + a = double(1); + b = double(1); } - #else + else + if(param.state == 1) { - arma_ignore(n_rows); - arma_ignore(n_cols); - arma_ignore(param); - - arma_stop_logic_error("randg(): C++11 compiler required"); - - return obj_type(); + a = double(param.a_int); + b = double(param.b_int); } - #endif + else + { + a = param.a_double; + b = param.b_double; + } + + arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): a and b must be greater than zero" ); + + arma_rng::randg::fill(out.memptr(), out.n_elem, a, b); + + return out; } @@ -101,7 +77,7 @@ arma_warn_unused inline obj_type -randg(const SizeMat& s, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = 0) +randg(const SizeMat& s, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -115,20 +91,16 @@ arma_warn_unused inline obj_type -randg(const uword n_elem, const distr_param& param = distr_param(), const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = 0) +randg(const uword n_elem, const distr_param& param = distr_param(), const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk1); arma_ignore(junk2); - if(is_Row::value) - { - return randg(1, n_elem, param); - } - else - { - return randg(n_elem, 1, param); - } + const uword n_rows = (is_Row::value) ? uword(1) : n_elem; + const uword n_cols = (is_Row::value) ? n_elem : uword(1); + + return randg(n_rows, n_cols, param); } @@ -196,67 +168,40 @@ arma_warn_unused inline cube_type -randg(const uword n_rows, const uword n_cols, const uword n_slices, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = 0) +randg(const uword n_rows, const uword n_cols, const uword n_slices, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); - #if defined(ARMA_USE_CXX11) - { - cube_type out(n_rows, n_cols, n_slices); + typedef typename cube_type::elem_type eT; + + cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); - double a; - double b; - - if(param.state == 0) - { - a = double(1); - b = double(1); - } - else - if(param.state == 1) - { - a = double(param.a_int); - b = double(param.b_int); - } - else - { - a = param.a_double; - b = param.b_double; - } - - arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): a and b must be greater than zero" ); - - #if defined(ARMA_USE_EXTERN_CXX11_RNG) - { - arma_rng_cxx11_instance.randg_fill(out.memptr(), out.n_elem, a, b); - } - #else - { - arma_rng_cxx11 local_arma_rng_cxx11_instance; - - typedef typename arma_rng_cxx11::seed_type seed_type; - - local_arma_rng_cxx11_instance.set_seed( seed_type(arma_rng::randi()) ); - - local_arma_rng_cxx11_instance.randg_fill(out.memptr(), out.n_elem, a, b); - } - #endif - - return out; + double a; + double b; + + if(param.state == 0) + { + a = double(1); + b = double(1); } - #else + else + if(param.state == 1) { - arma_ignore(n_rows); - arma_ignore(n_cols); - arma_ignore(n_slices); - arma_ignore(param); - - arma_stop_logic_error("randg(): C++11 compiler required"); - - return cube_type(); + a = double(param.a_int); + b = double(param.b_int); } - #endif + else + { + a = param.a_double; + b = param.b_double; + } + + arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): a and b must be greater than zero" ); + + arma_rng::randg::fill(out.memptr(), out.n_elem, a, b); + + return out; } @@ -265,7 +210,7 @@ arma_warn_unused inline cube_type -randg(const SizeCube& s, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = 0) +randg(const SizeCube& s, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randi.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randi.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randi.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randi.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,7 +25,7 @@ arma_warn_unused inline obj_type -randi(const uword n_rows, const uword n_cols, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = 0) +randi(const uword n_rows, const uword n_cols, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -40,7 +42,7 @@ arma_debug_check( (n_rows != 1), "randi(): incompatible size" ); } - obj_type out(n_rows, n_cols); + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); int a; int b; @@ -75,7 +77,7 @@ arma_warn_unused inline obj_type -randi(const SizeMat& s, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = 0) +randi(const SizeMat& s, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -89,7 +91,7 @@ arma_warn_unused inline obj_type -randi(const uword n_elem, const distr_param& param = distr_param(), const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = 0) +randi(const uword n_elem, const distr_param& param = distr_param(), const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk1); @@ -189,14 +191,14 @@ arma_warn_unused inline cube_type -randi(const uword n_rows, const uword n_cols, const uword n_slices, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = 0) +randi(const uword n_rows, const uword n_cols, const uword n_slices, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); typedef typename cube_type::elem_type eT; - cube_type out(n_rows, n_cols, n_slices); + cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); int a; int b; @@ -231,7 +233,7 @@ arma_warn_unused inline cube_type -randi(const SizeCube& s, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = 0) +randi(const SizeCube& s, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randn.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randn.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randn.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randn.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -57,20 +59,16 @@ arma_warn_unused arma_inline const Gen -randn(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = 0) +randn(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk1); arma_ignore(junk2); - if(is_Row::value) - { - return Gen(1, n_elem); - } - else - { - return Gen(n_elem, 1); - } + const uword n_rows = (is_Row::value) ? uword(1) : n_elem; + const uword n_cols = (is_Row::value) ? n_elem : uword(1); + + return Gen(n_rows, n_cols); } @@ -104,7 +102,7 @@ arma_warn_unused arma_inline const Gen -randn(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = 0) +randn(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -128,7 +126,7 @@ arma_warn_unused arma_inline const Gen -randn(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = 0) +randn(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -166,7 +164,7 @@ arma_warn_unused arma_inline const GenCube -randn(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only::result* junk = 0) +randn(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -180,7 +178,7 @@ arma_warn_unused arma_inline const GenCube -randn(const SizeCube& s, const typename arma_Cube_only::result* junk = 0) +randn(const SizeCube& s, const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randperm.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randperm.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randperm.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randperm.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -118,7 +120,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (M > N), "randperm(): 'M' must be less than or equal to 'N'"); + arma_debug_check( (M > N), "randperm(): 'M' must be less than or equal to 'N'" ); obj_type x; @@ -136,7 +138,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (M > N), "randperm(): 'M' must be less than or equal to 'N'"); + arma_debug_check( (M > N), "randperm(): 'M' must be less than or equal to 'N'" ); uvec x; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randu.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randu.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_randu.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randu.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -57,20 +59,16 @@ arma_warn_unused arma_inline const Gen -randu(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = 0) +randu(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk1); arma_ignore(junk2); - if(is_Row::value) - { - return Gen(1, n_elem); - } - else - { - return Gen(n_elem, 1); - } + const uword n_rows = (is_Row::value) ? uword(1) : n_elem; + const uword n_cols = (is_Row::value) ? n_elem : uword(1); + + return Gen(n_rows, n_cols); } @@ -104,7 +102,7 @@ arma_warn_unused arma_inline const Gen -randu(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = 0) +randu(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -128,7 +126,7 @@ arma_warn_unused arma_inline const Gen -randu(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = 0) +randu(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -166,7 +164,7 @@ arma_warn_unused arma_inline const GenCube -randu(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only::result* junk = 0) +randu(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -180,7 +178,7 @@ arma_warn_unused arma_inline const GenCube -randu(const SizeCube& s, const typename arma_Cube_only::result* junk = 0) +randu(const SizeCube& s, const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_range.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_range.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_range.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_range.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_rank.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_rank.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_rank.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_rank.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,46 +24,32 @@ template arma_warn_unused inline -uword -rank - ( - const Base& X, - typename T1::pod_type tol = 0.0, - const typename arma_blas_type_only::result* junk = 0 - ) +typename enable_if2< is_supported_blas_type::value, uword >::result +rank(const Base& expr, const typename T1::pod_type tol = 0) { arma_extra_debug_sigprint(); - arma_ignore(junk); - - typedef typename T1::pod_type T; - - uword X_n_rows; - uword X_n_cols; - Col s; - const bool status = auxlib::svd_dc(s, X, X_n_rows, X_n_cols); + uword out = uword(0); - if(status == false) - { - arma_stop_runtime_error("rank(): svd failed"); - - return uword(0); - } + const bool status = op_rank::apply(out, expr.get_ref(), tol); - const uword s_n_elem = s.n_elem; - const T* s_mem = s.memptr(); + if(status == false) { arma_stop_runtime_error("rank(): failed"); return uword(0); } - // set tolerance to default if it hasn't been specified - if( (tol == T(0)) && (s_n_elem > 0) ) - { - tol = (std::max)(X_n_rows, X_n_cols) * s_mem[0] * std::numeric_limits::epsilon(); - } - - uword count = 0; + return out; + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +rank(uword& out, const Base& expr, const typename T1::pod_type tol = 0) + { + arma_extra_debug_sigprint(); - for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); } + out = uword(0); - return count; + return op_rank::apply(out, expr.get_ref(), tol); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_regspace.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_regspace.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_regspace.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_regspace.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_repelem.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_repelem.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_repelem.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_repelem.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_repmat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_repmat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_repmat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_repmat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_reshape.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_reshape.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_reshape.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_reshape.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,11 +25,11 @@ arma_warn_unused inline typename enable_if2< is_arma_type::value, const Op >::result -reshape(const T1& X, const uword in_n_rows, const uword in_n_cols) +reshape(const T1& X, const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - return Op(X, in_n_rows, in_n_cols); + return Op(X, new_n_rows, new_n_cols); } @@ -49,16 +51,16 @@ template arma_deprecated inline -const Op -reshape(const Base& X, const uword in_n_rows, const uword in_n_cols, const uword dim) //!< NOTE: don't use this form: it will be removed +const Op +reshape(const Base& X, const uword new_n_rows, const uword new_n_cols, const uword dim) //!< NOTE: don't use this form: it will be removed { arma_extra_debug_sigprint(); - arma_debug_check( (dim > 1), "reshape(): parameter 'dim' must be 0 or 1" ); + // arma_debug_warn_level(1, "this form of reshape() is deprecated and will be removed"); - // arma_debug_warn("this form of reshape() is deprecated and will be removed"); + arma_debug_check( (dim > 1), "reshape(): parameter 'dim' must be 0 or 1" ); - return Op(X.get_ref(), in_n_rows, in_n_cols, dim, 'j'); + return Op(X.get_ref(), new_n_rows, new_n_cols, dim, 'j'); } @@ -66,30 +68,12 @@ template arma_warn_unused inline -const OpCube -reshape(const BaseCube& X, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) +const OpCube +reshape(const BaseCube& X, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - return OpCube(X.get_ref(), in_n_rows, in_n_cols, in_n_slices, uword(0), 'j'); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -const OpCube -reshape(const BaseCube& X, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const uword dim) //!< NOTE: don't use this form: it will be removed - { - arma_extra_debug_sigprint(); - - arma_debug_check( (dim > 1), "reshape(): parameter 'dim' must be 0 or 1" ); - - // arma_debug_warn("this form of reshape() is deprecated and will be removed"); - - return OpCube(X.get_ref(), in_n_rows, in_n_cols, in_n_slices, dim, 'j'); + return OpCube(X.get_ref(), new_n_rows, new_n_cols, new_n_slices); } @@ -97,30 +81,12 @@ template arma_warn_unused inline -const OpCube +const OpCube reshape(const BaseCube& X, const SizeCube& s) { arma_extra_debug_sigprint(); - return OpCube(X.get_ref(), s.n_rows, s.n_cols, s.n_slices, uword(0), 'j'); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -const OpCube -reshape(const BaseCube& X, const SizeCube& s, const uword dim) //!< NOTE: don't use this form: it will be removed - { - arma_extra_debug_sigprint(); - - arma_debug_check( (dim > 1), "reshape(): parameter 'dim' must be 0 or 1" ); - - // arma_debug_warn("this form of reshape() is deprecated and will be removed"); - - return OpCube(X.get_ref(), s.n_rows, s.n_cols, s.n_slices, dim, 'j'); + return OpCube(X.get_ref(), s.n_rows, s.n_cols, s.n_slices); } @@ -129,11 +95,11 @@ arma_warn_unused inline const SpOp -reshape(const SpBase& X, const uword in_n_rows, const uword in_n_cols) +reshape(const SpBase& X, const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - return SpOp(X.get_ref(), in_n_rows, in_n_cols); + return SpOp(X.get_ref(), new_n_rows, new_n_cols); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_resize.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_resize.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_resize.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_resize.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_reverse.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_reverse.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_reverse.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_reverse.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_roots.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_roots.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_roots.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_roots.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -51,7 +53,11 @@ const bool status = op_roots::apply_direct(out, X.get_ref()); - if(status == false) { arma_debug_warn("roots(): eigen decomposition failed"); } + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "roots(): eigen decomposition failed"); + } return status; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_schur.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_schur.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_schur.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_schur.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,7 +27,7 @@ ( Mat& S, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -40,7 +42,7 @@ if(status == false) { S.soft_reset(); - arma_debug_warn("schur(): decomposition failed"); + arma_debug_warn_level(3, "schur(): decomposition failed"); } return status; @@ -55,7 +57,7 @@ schur ( const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -87,7 +89,7 @@ Mat& U, Mat& S, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -101,7 +103,7 @@ { U.soft_reset(); S.soft_reset(); - arma_debug_warn("schur(): decomposition failed"); + arma_debug_warn_level(3, "schur(): decomposition failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_shift.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_shift.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_shift.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_shift.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_shuffle.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_shuffle.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_shuffle.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_shuffle.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_size.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_size.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_size.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_size.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -88,6 +90,38 @@ +arma_warn_unused +inline +const SizeMat +size(const arma::span& row_span, const arma::span& col_span) + { + arma_extra_debug_sigprint(); + + uword n_rows = 0; + uword n_cols = 0; + + if(row_span.whole || col_span.whole) + { + arma_debug_check(true, "size(): span::all not supported"); + } + else + { + if((row_span.a > row_span.b) || (col_span.a > col_span.b)) + { + arma_debug_check_bounds(true, "size(): span indices incorrectly used"); + } + else + { + n_rows = row_span.b - row_span.a + 1; + n_cols = col_span.b - col_span.a + 1; + } + } + + return SizeMat(n_rows, n_cols); + } + + + template arma_warn_unused inline @@ -158,6 +192,40 @@ } + +arma_warn_unused +inline +const SizeCube +size(const arma::span& row_span, const arma::span& col_span, const arma::span& slice_span) + { + arma_extra_debug_sigprint(); + + uword n_rows = 0; + uword n_cols = 0; + uword n_slices = 0; + + if(row_span.whole || col_span.whole || slice_span.whole) + { + arma_debug_check(true, "size(): span::all not supported"); + } + else + { + if((row_span.a > row_span.b) || (col_span.a > col_span.b) || (slice_span.a > slice_span.b)) + { + arma_debug_check_bounds(true, "size(): span indices incorrectly used"); + } + else + { + n_rows = row_span.b - row_span.a + 1; + n_cols = col_span.b - col_span.a + 1; + n_slices = slice_span.b - slice_span.a + 1; + } + } + + return SizeCube(n_rows, n_cols, n_slices); + } + + template arma_warn_unused diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_solve.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_solve.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_solve.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_solve.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -41,48 +43,6 @@ -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Glue >::result -solve - ( - const Base& A, - const Base& B, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("solve(A,B,bool) is deprecated and will be removed; change to solve(A,B)"); - - return Glue(A.get_ref(), B.get_ref(), solve_opts::flag_none); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Glue >::result -solve - ( - const Base& A, - const Base& B, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("solve(A,B,char*) is deprecated and will be removed; change to solve(A,B)"); - - return Glue(A.get_ref(), B.get_ref(), solve_opts::flag_none); - } - - - template inline typename enable_if2< is_supported_blas_type::value, bool >::result @@ -96,51 +56,15 @@ { arma_extra_debug_sigprint(); - return glue_solve_gen::apply(out, A.get_ref(), B.get_ref(), opts.flags); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, bool >::result -solve - ( - Mat& out, - const Base& A, - const Base& B, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("solve(X,A,B,bool) is deprecated and will be removed; change to solve(X,A,B)"); - - return glue_solve_gen::apply(out, A.get_ref(), B.get_ref(), solve_opts::flag_none); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, bool >::result -solve - ( - Mat& out, - const Base& A, - const Base& B, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); + const bool status = glue_solve_gen::apply(out, A.get_ref(), B.get_ref(), opts.flags); - // arma_debug_warn("solve(X,A,B,char*) is deprecated and will be removed; change to solve(X,A,B)"); + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "solve(): solution not found"); + } - return glue_solve_gen::apply(out, A.get_ref(), B.get_ref(), solve_opts::flag_none); + return status; } @@ -194,58 +118,6 @@ -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Glue >::result -solve - ( - const Op& A, - const Base& B, - const bool // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("solve(A,B,bool) is deprecated and will be removed; change to solve(A,B)"); - - uword flags = uword(0); - - if(A.aux_uword_a == 0) { flags |= solve_opts::flag_triu; } - if(A.aux_uword_a == 1) { flags |= solve_opts::flag_tril; } - - return Glue(A.m, B.get_ref(), flags); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, const Glue >::result -solve - ( - const Op& A, - const Base& B, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("solve(A,B,char*) is deprecated and will be removed; change to solve(A,B)"); - - uword flags = uword(0); - - if(A.aux_uword_a == 0) { flags |= solve_opts::flag_triu; } - if(A.aux_uword_a == 1) { flags |= solve_opts::flag_tril; } - - return Glue(A.m, B.get_ref(), flags); - } - - - template inline typename enable_if2< is_supported_blas_type::value, bool >::result @@ -263,37 +135,20 @@ if(A.aux_uword_a == 0) { flags |= solve_opts::flag_triu; } if(A.aux_uword_a == 1) { flags |= solve_opts::flag_tril; } - return glue_solve_tri_default::apply(out, A.m, B.get_ref(), flags); - } - - - -template -inline -typename enable_if2< is_supported_blas_type::value, bool >::result -solve - ( - Mat& out, - const Op& A, - const Base& B, - const solve_opts::opts& opts - ) - { - arma_extra_debug_sigprint(); - - uword flags = opts.flags; + const bool status = glue_solve_tri_default::apply(out, A.m, B.get_ref(), flags); - if(A.aux_uword_a == 0) { flags |= solve_opts::flag_triu; } - if(A.aux_uword_a == 1) { flags |= solve_opts::flag_tril; } + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "solve(): solution not found"); + } - return glue_solve_tri::apply(out, A.m, B.get_ref(), flags); + return status; } -//! NOTE: don't use this form: it will be removed template -arma_deprecated inline typename enable_if2< is_supported_blas_type::value, bool >::result solve @@ -301,46 +156,25 @@ Mat& out, const Op& A, const Base& B, - const bool // argument kept only for compatibility with old user code + const solve_opts::opts& opts ) { arma_extra_debug_sigprint(); - // arma_debug_warn("solve(X,A,B,bool) is deprecated and will be removed; change to solve(X,A,B)"); - - uword flags = uword(0); + uword flags = opts.flags; if(A.aux_uword_a == 0) { flags |= solve_opts::flag_triu; } if(A.aux_uword_a == 1) { flags |= solve_opts::flag_tril; } - return glue_solve_tri_default::apply(out, A.m, B.get_ref(), flags); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename enable_if2< is_supported_blas_type::value, bool >::result -solve - ( - Mat& out, - const Op& A, - const Base& B, - const char* // argument kept only for compatibility with old user code - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("solve(X,A,B,char*) is deprecated and will be removed; change to solve(X,A,B)"); + const bool status = glue_solve_tri::apply(out, A.m, B.get_ref(), flags); - uword flags = uword(0); - - if(A.aux_uword_a == 0) { flags |= solve_opts::flag_triu; } - if(A.aux_uword_a == 1) { flags |= solve_opts::flag_tril; } + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "solve(): solution not found"); + } - return glue_solve_tri_default::apply(out, A.m, B.get_ref(), flags); + return status; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sort.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sort.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sort.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sort.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -61,82 +63,6 @@ -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename -enable_if2 - < - is_arma_type::value && resolves_to_vector::yes, - const Op - >::result -sort - ( - const T1& X, - const uword sort_type - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("sort(X,uword) is deprecated and will be removed; change to sort(X,sort_direction)"); - - return Op(X, sort_type, 0); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename -enable_if2 - < - is_arma_type::value && resolves_to_vector::no, - const Op - >::result -sort - ( - const T1& X, - const uword sort_type - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("sort(X,uword) is deprecated and will be removed; change to sort(X,sort_direction)"); - - return Op(X, sort_type, 0); - } - - - -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -typename -enable_if2 - < - (is_arma_type::value), - const Op - >::result -sort - ( - const T1& X, - const uword sort_type, - const uword dim - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("sort(X,uword,uword) is deprecated and will be removed; change to sort(X,sort_direction,dim)"); - - return Op(X, sort_type, dim); - } - - - template arma_warn_unused inline @@ -154,9 +80,9 @@ { arma_extra_debug_sigprint(); - const char sig = (sort_direction != NULL) ? sort_direction[0] : char(0); + const char sig = (sort_direction != nullptr) ? sort_direction[0] : char(0); - arma_debug_check( (sig != 'a') && (sig != 'd'), "sort(): unknown sort direction"); + arma_debug_check( (sig != 'a') && (sig != 'd'), "sort(): unknown sort direction" ); const uword sort_type = (sig == 'a') ? 0 : 1; @@ -182,9 +108,9 @@ { arma_extra_debug_sigprint(); - const char sig = (sort_direction != NULL) ? sort_direction[0] : char(0); + const char sig = (sort_direction != nullptr) ? sort_direction[0] : char(0); - arma_debug_check( (sig != 'a') && (sig != 'd'), "sort(): unknown sort direction"); + arma_debug_check( (sig != 'a') && (sig != 'd'), "sort(): unknown sort direction" ); const uword sort_type = (sig == 'a') ? 0 : 1; @@ -211,9 +137,9 @@ { arma_extra_debug_sigprint(); - const char sig = (sort_direction != NULL) ? sort_direction[0] : char(0); + const char sig = (sort_direction != nullptr) ? sort_direction[0] : char(0); - arma_debug_check( (sig != 'a') && (sig != 'd'), "sort(): unknown sort direction"); + arma_debug_check( (sig != 'a') && (sig != 'd'), "sort(): unknown sort direction" ); const uword sort_type = (sig == 'a') ? 0 : 1; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sort_index.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sort_index.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sort_index.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sort_index.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,35 +37,13 @@ -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -const mtOp -sort_index - ( - const Base& X, - const uword sort_type - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("sort_index(X,uword) is deprecated and will be removed; change to sort_index(X,sort_direction)"); - - arma_debug_check( (sort_type > 1), "sort_index(): parameter 'sort_type' must be 0 or 1" ); - - return mtOp(X.get_ref(), sort_type, uword(0)); - } - - - template arma_warn_unused inline typename enable_if2 < - ( (is_arma_type::value == true) && (is_same_type::value == true) ), + ( (is_arma_type::value) && (is_same_type::value) ), const mtOp >::result sort_index @@ -74,7 +54,7 @@ { arma_extra_debug_sigprint(); - const char sig = (sort_direction != NULL) ? sort_direction[0] : char(0); + const char sig = (sort_direction != nullptr) ? sort_direction[0] : char(0); arma_debug_check( ((sig != 'a') && (sig != 'd')), "sort_index(): unknown sort direction" ); @@ -103,35 +83,13 @@ -//! NOTE: don't use this form: it will be removed -template -arma_deprecated -inline -const mtOp -stable_sort_index - ( - const Base& X, - const uword sort_type - ) - { - arma_extra_debug_sigprint(); - - // arma_debug_warn("stable_sort_index(X,uword) is deprecated and will be removed; change to stable_sort_index(X,sort_direction)"); - - arma_debug_check( (sort_type > 1), "stable_sort_index(): parameter 'sort_type' must be 0 or 1" ); - - return mtOp(X.get_ref(), sort_type, uword(0)); - } - - - template arma_warn_unused inline typename enable_if2 < - ( (is_arma_type::value == true) && (is_same_type::value == true) ), + ( (is_arma_type::value) && (is_same_type::value) ), const mtOp >::result stable_sort_index @@ -142,7 +100,7 @@ { arma_extra_debug_sigprint(); - const char sig = (sort_direction != NULL) ? sort_direction[0] : char(0); + const char sig = (sort_direction != nullptr) ? sort_direction[0] : char(0); arma_debug_check( ((sig != 'a') && (sig != 'd')), "stable_sort_index(): unknown sort direction" ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_speye.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_speye.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_speye.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_speye.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -24,7 +26,7 @@ arma_warn_unused inline obj_type -speye(const uword n_rows, const uword n_cols, const typename arma_SpMat_SpCol_SpRow_only::result* junk = NULL) +speye(const uword n_rows, const uword n_cols, const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -52,7 +54,7 @@ arma_warn_unused inline obj_type -speye(const SizeMat& s, const typename arma_SpMat_SpCol_SpRow_only::result* junk = NULL) +speye(const SizeMat& s, const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_spones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_spones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_spones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_spones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sprandn.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sprandn.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sprandn.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sprandn.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -30,7 +32,7 @@ const uword n_rows, const uword n_cols, const double density, - const typename arma_SpMat_SpCol_SpRow_only::result* junk = 0 + const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -59,7 +61,7 @@ arma_warn_unused inline obj_type -sprandn(const SizeMat& s, const double density, const typename arma_SpMat_SpCol_SpRow_only::result* junk = 0) +sprandn(const SizeMat& s, const double density, const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sprandu.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sprandu.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sprandu.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sprandu.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -30,7 +32,7 @@ const uword n_rows, const uword n_cols, const double density, - const typename arma_SpMat_SpCol_SpRow_only::result* junk = 0 + const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -59,7 +61,7 @@ arma_warn_unused inline obj_type -sprandu(const SizeMat& s, const double density, const typename arma_SpMat_SpCol_SpRow_only::result* junk = 0) +sprandu(const SizeMat& s, const double density, const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_spsolve.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_spsolve.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_spsolve.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_spsolve.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -17,7 +19,7 @@ //! \addtogroup fn_spsolve //! @{ -//! Solve a system of linear equations, i.e., A*X = B, where X is unknown, +//! Solve a system of linear equations, A*X = B, where X is unknown, //! A is sparse, and B is dense. X will be dense too. template @@ -30,7 +32,7 @@ const Base& B, const char* solver, const spsolve_opts_base& settings, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -39,7 +41,7 @@ typedef typename T1::pod_type T; typedef typename T1::elem_type eT; - const char sig = (solver != NULL) ? solver[0] : char(0); + const char sig = (solver != nullptr) ? solver[0] : char(0); arma_debug_check( ((sig != 'l') && (sig != 's')), "spsolve(): unknown solver" ); @@ -54,7 +56,7 @@ const superlu_opts& opts = (settings.id == 1) ? static_cast(settings) : superlu_opts_default; - arma_debug_check( ( (opts.pivot_thresh < double(0)) || (opts.pivot_thresh > double(1)) ), "spsolve(): pivot_thresh out of bounds" ); + arma_debug_check( ( (opts.pivot_thresh < double(0)) || (opts.pivot_thresh > double(1)) ), "spsolve(): pivot_thresh must be in the [0,1] interval" ); if(sig == 's') // SuperLU solver { @@ -72,7 +74,7 @@ { if( (settings.id != 0) && ((opts.symmetric) || (opts.pivot_thresh != double(1))) ) { - arma_debug_warn("spsolve(): ignoring settings not applicable to LAPACK based solver"); + arma_debug_warn_level(1, "spsolve(): ignoring settings not applicable to LAPACK based solver"); } Mat AA; @@ -87,9 +89,9 @@ conversion_ok = true; } - catch(std::bad_alloc&) + catch(...) { - arma_debug_warn("spsolve(): not enough memory to use LAPACK based solver"); + arma_debug_warn_level(1, "spsolve(): not enough memory to use LAPACK based solver"); } if(conversion_ok) @@ -107,17 +109,14 @@ } - if(status == false) + if( (status == false) && (rcond > T(0)) ) { - if(rcond > T(0)) { arma_debug_warn("spsolve(): system seems singular (rcond: ", rcond, ")"); } - else { arma_debug_warn("spsolve(): system seems singular"); } - - out.soft_reset(); + arma_debug_warn_level(2, "spsolve(): system is singular (rcond: ", rcond, ")"); } if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(out)) ) { - arma_debug_warn("solve(): solution computed, but system seems singular to working precision (rcond: ", rcond, ")"); + arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); } return status; @@ -135,7 +134,7 @@ const Base& B, const char* solver = "superlu", const spsolve_opts_base& settings = spsolve_opts_none(), - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -143,6 +142,12 @@ const bool status = spsolve_helper(out, A.get_ref(), B.get_ref(), solver, settings); + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "spsolve(): solution not found"); + } + return status; } @@ -158,7 +163,7 @@ const Base& B, const char* solver = "superlu", const spsolve_opts_base& settings = spsolve_opts_none(), - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -172,6 +177,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("spsolve(): solution not found"); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sqrtmat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sqrtmat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sqrtmat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sqrtmat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -56,7 +58,7 @@ if(status == false) { - arma_debug_warn("sqrtmat(): given matrix seems singular; may not have a square root"); + arma_debug_warn_level(3, "sqrtmat(): given matrix is singular; may not have a square root"); } return status; @@ -75,7 +77,7 @@ if(status == false) { - arma_debug_warn("sqrtmat(): given matrix seems singular; may not have a square root"); + arma_debug_warn_level(3, "sqrtmat(): given matrix is singular; may not have a square root"); } return status; @@ -112,7 +114,7 @@ if(status == false) { Y.soft_reset(); - arma_debug_warn("sqrtmat_sympd(): transformation failed"); + arma_debug_warn_level(3, "sqrtmat_sympd(): transformation failed"); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_stddev.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_stddev.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_stddev.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_stddev.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -75,7 +77,7 @@ template arma_warn_unused -arma_inline +inline typename arma_scalar_only::result stddev(const T&) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_strans.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_strans.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_strans.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_strans.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,8 +28,8 @@ strans ( const T1& X, - const typename enable_if< is_arma_type::value == true >::result* junk1 = 0, - const typename arma_cx_only::result* junk2 = 0 + const typename enable_if< is_arma_type::value >::result* junk1 = nullptr, + const typename arma_cx_only::result* junk2 = nullptr ) { arma_extra_debug_sigprint(); @@ -48,8 +50,8 @@ strans ( const T1& X, - const typename enable_if< is_arma_type::value == true >::result* junk1 = 0, - const typename arma_not_cx::result* junk2 = 0 + const typename enable_if< is_arma_type::value >::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr ) { arma_extra_debug_sigprint(); @@ -72,8 +74,8 @@ strans ( const T1& X, - const typename enable_if< is_arma_sparse_type::value == true >::result* junk1 = 0, - const typename arma_cx_only::result* junk2 = 0 + const typename enable_if< is_arma_sparse_type::value >::result* junk1 = nullptr, + const typename arma_cx_only::result* junk2 = nullptr ) { arma_extra_debug_sigprint(); @@ -92,8 +94,8 @@ strans ( const T1& X, - const typename enable_if< is_arma_sparse_type::value == true >::result* junk1 = 0, - const typename arma_not_cx::result* junk2 = 0 + const typename enable_if< is_arma_sparse_type::value >::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr ) { arma_extra_debug_sigprint(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sum.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sum.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sum.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sum.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_svd.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_svd.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_svd.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_svd.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,20 +28,22 @@ ( Col& S, const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); - // it doesn't matter if X is an alias of S, as auxlib::svd() makes a copy of X + typedef typename T1::elem_type eT; + + Mat A(X.get_ref()); - const bool status = auxlib::svd_dc(S, X); + const bool status = auxlib::svd_dc(S, A); if(status == false) { S.soft_reset(); - arma_debug_warn("svd(): decomposition failed"); + arma_debug_warn_level(3, "svd(): decomposition failed"); } return status; @@ -54,15 +58,20 @@ svd ( const Base& X, - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); - Col out; + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + Col out; + + Mat A(X.get_ref()); - const bool status = auxlib::svd_dc(out, X); + const bool status = auxlib::svd_dc(out, A); if(status == false) { @@ -85,31 +94,34 @@ Mat& V, const Base& X, const char* method = "dc", - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); + typedef typename T1::elem_type eT; + arma_debug_check ( ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ), "svd(): two or more output objects are the same object" ); - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'd')), "svd(): unknown method specified" ); - // auxlib::svd() makes an internal copy of X - const bool status = (sig == 'd') ? auxlib::svd_dc(U, S, V, X) : auxlib::svd(U, S, V, X); + Mat A(X.get_ref()); + + const bool status = (sig == 'd') ? auxlib::svd_dc(U, S, V, A) : auxlib::svd(U, S, V, A); if(status == false) { U.soft_reset(); S.soft_reset(); V.soft_reset(); - arma_debug_warn("svd(): decomposition failed"); + arma_debug_warn_level(3, "svd(): decomposition failed"); } return status; @@ -128,12 +140,14 @@ const Base& X, const char mode, const char* method = "dc", - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); + typedef typename T1::elem_type eT; + arma_debug_check ( ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ), @@ -146,18 +160,20 @@ "svd_econ(): parameter 'mode' is incorrect" ); - const char sig = (method != NULL) ? method[0] : char(0); + const char sig = (method != nullptr) ? method[0] : char(0); arma_debug_check( ((sig != 's') && (sig != 'd')), "svd_econ(): unknown method specified" ); - const bool status = ((mode == 'b') && (sig == 'd')) ? auxlib::svd_dc_econ(U, S, V, X) : auxlib::svd_econ(U, S, V, X, mode); + Mat A(X.get_ref()); + + const bool status = ((mode == 'b') && (sig == 'd')) ? auxlib::svd_dc_econ(U, S, V, A) : auxlib::svd_econ(U, S, V, A, mode); if(status == false) { U.soft_reset(); S.soft_reset(); V.soft_reset(); - arma_debug_warn("svd(): decomposition failed"); + arma_debug_warn_level(3, "svd_econ(): decomposition failed"); } return status; @@ -176,13 +192,13 @@ const Base& X, const char* mode = "both", const char* method = "dc", - const typename arma_blas_type_only::result* junk = 0 + const typename arma_blas_type_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); arma_ignore(junk); - return svd_econ(U, S, V, X, ((mode != NULL) ? mode[0] : char(0)), method); + return svd_econ(U, S, V, X, ((mode != nullptr) ? mode[0] : char(0)), method); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_svds.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_svds.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_svds.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_svds.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -30,7 +32,7 @@ const uword k, const typename T1::pod_type tol, const bool calc_UV, - const typename arma_real_only::result* junk = 0 + const typename arma_real_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -81,7 +83,10 @@ Col eigval; Mat eigvec; - const bool status = sp_auxlib::eigs_sym(eigval, eigvec, C, kk, "la", (tol / Datum::sqrt2)); + eigs_opts opts; + opts.tol = (tol / Datum::sqrt2); + + const bool status = eigs_sym(eigval, eigvec, C, kk, "la", opts); if(status == false) { @@ -118,15 +123,15 @@ if(calc_UV) { - uvec U_row_indices(A.n_rows); for(uword i=0; i < A.n_rows; ++i) { U_row_indices[i] = i; } - uvec V_row_indices(A.n_cols); for(uword i=0; i < A.n_cols; ++i) { V_row_indices[i] = i + A.n_rows; } + uvec U_row_indices(A.n_rows, arma_nozeros_indicator()); for(uword i=0; i < A.n_rows; ++i) { U_row_indices[i] = i; } + uvec V_row_indices(A.n_cols, arma_nozeros_indicator()); for(uword i=0; i < A.n_cols; ++i) { V_row_indices[i] = i + A.n_rows; } U = Datum::sqrt2 * eigvec(U_row_indices, sorted_indices); V = Datum::sqrt2 * eigvec(V_row_indices, sorted_indices); } } - if(S.n_elem < k) { arma_debug_warn("svds(): found fewer singular values than specified"); } + if(S.n_elem < k) { arma_debug_warn_level(1, "svds(): found fewer singular values than specified"); } return true; } @@ -145,7 +150,7 @@ const uword k, const typename T1::pod_type tol, const bool calc_UV, - const typename arma_cx_only::result* junk = 0 + const typename arma_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -202,7 +207,10 @@ Col eigval_tmp; Mat eigvec; - const bool status = sp_auxlib::eigs_gen(eigval_tmp, eigvec, C, kk, "lr", (tol / Datum::sqrt2)); + eigs_opts opts; + opts.tol = (tol / Datum::sqrt2); + + const bool status = eigs_gen(eigval_tmp, eigvec, C, kk, "lr", opts); if(status == false) { @@ -241,15 +249,15 @@ if(calc_UV) { - uvec U_row_indices(A.n_rows); for(uword i=0; i < A.n_rows; ++i) { U_row_indices[i] = i; } - uvec V_row_indices(A.n_cols); for(uword i=0; i < A.n_cols; ++i) { V_row_indices[i] = i + A.n_rows; } + uvec U_row_indices(A.n_rows, arma_nozeros_indicator()); for(uword i=0; i < A.n_rows; ++i) { U_row_indices[i] = i; } + uvec V_row_indices(A.n_cols, arma_nozeros_indicator()); for(uword i=0; i < A.n_cols; ++i) { V_row_indices[i] = i + A.n_rows; } U = Datum::sqrt2 * eigvec(U_row_indices, sorted_indices); V = Datum::sqrt2 * eigvec(V_row_indices, sorted_indices); } } - if(S.n_elem < k) { arma_debug_warn("svds(): found fewer singular values than specified"); } + if(S.n_elem < k) { arma_debug_warn_level(1, "svds(): found fewer singular values than specified"); } return true; } @@ -268,7 +276,7 @@ const SpBase& X, const uword k, const typename T1::pod_type tol = 0.0, - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -276,7 +284,7 @@ const bool status = svds_helper(U, S, V, X.get_ref(), k, tol, true); - if(status == false) { arma_debug_warn("svds(): decomposition failed"); } + if(status == false) { arma_debug_warn_level(3, "svds(): decomposition failed"); } return status; } @@ -293,7 +301,7 @@ const SpBase& X, const uword k, const typename T1::pod_type tol = 0.0, - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -304,7 +312,7 @@ const bool status = svds_helper(U, S, V, X.get_ref(), k, tol, false); - if(status == false) { arma_debug_warn("svds(): decomposition failed"); } + if(status == false) { arma_debug_warn_level(3, "svds(): decomposition failed"); } return status; } @@ -321,7 +329,7 @@ const SpBase& X, const uword k, const typename T1::pod_type tol = 0.0, - const typename arma_real_or_cx_only::result* junk = 0 + const typename arma_real_or_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_syl_lyap.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_syl_lyap.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_syl_lyap.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_syl_lyap.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2008-2016 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -//! \addtogroup fn_syl_lyap -//! @{ - - -//! find the solution of the Sylvester equation AX + XB = C -template -inline -bool -syl - ( - Mat & out, - const Base& in_A, - const Base& in_B, - const Base& in_C, - const typename arma_blas_type_only::result* junk = 0 - ) - { - arma_extra_debug_sigprint(); - arma_ignore(junk); - - typedef typename T1::elem_type eT; - - const unwrap_check tmp_A(in_A.get_ref(), out); - const unwrap_check tmp_B(in_B.get_ref(), out); - const unwrap_check tmp_C(in_C.get_ref(), out); - - const Mat& A = tmp_A.M; - const Mat& B = tmp_B.M; - const Mat& C = tmp_C.M; - - const bool status = auxlib::syl(out, A, B, C); - - if(status == false) - { - out.soft_reset(); - arma_debug_warn("syl(): solution not found"); - } - - return status; - } - - - -template -arma_warn_unused -inline -Mat -syl - ( - const Base& in_A, - const Base& in_B, - const Base& in_C, - const typename arma_blas_type_only::result* junk = 0 - ) - { - arma_extra_debug_sigprint(); - arma_ignore(junk); - - typedef typename T1::elem_type eT; - - const unwrap tmp_A( in_A.get_ref() ); - const unwrap tmp_B( in_B.get_ref() ); - const unwrap tmp_C( in_C.get_ref() ); - - const Mat& A = tmp_A.M; - const Mat& B = tmp_B.M; - const Mat& C = tmp_C.M; - - Mat out; - - const bool status = auxlib::syl(out, A, B, C); - - if(status == false) - { - out.soft_reset(); - arma_stop_runtime_error("syl(): solution not found"); - } - - return out; - } - - - -//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sylvester.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sylvester.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_sylvester.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_sylvester.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup fn_syl_lyap +//! @{ + + +//! find the solution of the Sylvester equation AX + XB = C +template +inline +bool +syl + ( + Mat & out, + const Base& in_A, + const Base& in_B, + const Base& in_C, + const typename arma_blas_type_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + typedef typename T1::elem_type eT; + + const unwrap_check tmp_A(in_A.get_ref(), out); + const unwrap_check tmp_B(in_B.get_ref(), out); + const unwrap_check tmp_C(in_C.get_ref(), out); + + const Mat& A = tmp_A.M; + const Mat& B = tmp_B.M; + const Mat& C = tmp_C.M; + + const bool status = auxlib::syl(out, A, B, C); + + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "syl(): solution not found"); + } + + return status; + } + + + +template +inline +bool +sylvester + ( + Mat & out, + const Base& in_A, + const Base& in_B, + const Base& in_C, + const typename arma_blas_type_only::result* junk = nullptr + ) + { + arma_ignore(junk); + return syl(out, in_A, in_B, in_C); + } + + + +template +arma_warn_unused +inline +Mat +syl + ( + const Base& in_A, + const Base& in_B, + const Base& in_C, + const typename arma_blas_type_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + typedef typename T1::elem_type eT; + + const unwrap tmp_A( in_A.get_ref() ); + const unwrap tmp_B( in_B.get_ref() ); + const unwrap tmp_C( in_C.get_ref() ); + + const Mat& A = tmp_A.M; + const Mat& B = tmp_B.M; + const Mat& C = tmp_C.M; + + Mat out; + + const bool status = auxlib::syl(out, A, B, C); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("syl(): solution not found"); + } + + return out; + } + + + +template +arma_warn_unused +inline +Mat +sylvester + ( + const Base& in_A, + const Base& in_B, + const Base& in_C, + const typename arma_blas_type_only::result* junk = nullptr + ) + { + arma_ignore(junk); + return syl(in_A, in_B, in_C); + } + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_symmat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_symmat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_symmat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_symmat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,13 +23,13 @@ template arma_warn_unused arma_inline -typename enable_if2< is_cx::no, const Op >::result +typename enable_if2< is_cx::no, const Op >::result symmatu(const Base& X, const bool do_conj = false) { arma_extra_debug_sigprint(); arma_ignore(do_conj); - return Op(X.get_ref(), 0, 0); + return Op(X.get_ref()); } @@ -35,13 +37,13 @@ template arma_warn_unused arma_inline -typename enable_if2< is_cx::no, const Op >::result +typename enable_if2< is_cx::no, const Op >::result symmatl(const Base& X, const bool do_conj = false) { arma_extra_debug_sigprint(); arma_ignore(do_conj); - return Op(X.get_ref(), 1, 0); + return Op(X.get_ref()); } @@ -49,12 +51,12 @@ template arma_warn_unused arma_inline -typename enable_if2< is_cx::yes, const Op >::result +typename enable_if2< is_cx::yes, const Op >::result symmatu(const Base& X, const bool do_conj = true) { arma_extra_debug_sigprint(); - return Op(X.get_ref(), 0, (do_conj ? 1 : 0)); + return Op(X.get_ref(), 0, (do_conj ? 1 : 0)); } @@ -62,12 +64,12 @@ template arma_warn_unused arma_inline -typename enable_if2< is_cx::yes, const Op >::result +typename enable_if2< is_cx::yes, const Op >::result symmatl(const Base& X, const bool do_conj = true) { arma_extra_debug_sigprint(); - return Op(X.get_ref(), 1, (do_conj ? 1 : 0)); + return Op(X.get_ref(), 0, (do_conj ? 1 : 0)); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_toeplitz.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_toeplitz.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_toeplitz.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_toeplitz.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trace.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trace.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trace.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trace.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trans.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trans.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trans.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trans.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,7 +27,7 @@ trans ( const T1& X, - const typename enable_if< is_arma_type::value == true >::result* junk = 0 + const typename enable_if< is_arma_type::value >::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -43,7 +45,7 @@ htrans ( const T1& X, - const typename enable_if< is_arma_type::value == true >::result* junk = 0 + const typename enable_if< is_arma_type::value >::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -65,7 +67,7 @@ trans ( const T1& X, - const typename enable_if< is_arma_sparse_type::value == true >::result* junk = 0 + const typename enable_if< is_arma_sparse_type::value >::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -83,7 +85,7 @@ htrans ( const T1& X, - const typename enable_if< is_arma_sparse_type::value == true >::result* junk = 0 + const typename enable_if< is_arma_sparse_type::value >::result* junk = nullptr ) { arma_extra_debug_sigprint(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trapz.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trapz.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trapz.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trapz.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trig.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trig.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trig.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trig.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trimat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trimat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trimat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trimat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -106,37 +108,35 @@ -// // TODO: implement for sparse matrices -// template -// arma_warn_unused -// arma_inline -// const SpOp -// trimatu(const SpBase& X, const sword k) -// { -// arma_extra_debug_sigprint(); -// -// const uword row_offset = (k < 0) ? uword(-k) : uword(0); -// const uword col_offset = (k > 0) ? uword( k) : uword(0); -// -// return SpOp(X.get_ref(), row_offset, col_offset); -// } -// -// -// -// // TODO: implement for sparse matrices -// template -// arma_warn_unused -// arma_inline -// const SpOp -// trimatl(const SpBase& X, const sword k) -// { -// arma_extra_debug_sigprint(); -// -// const uword row_offset = (k < 0) ? uword(-k) : uword(0); -// const uword col_offset = (k > 0) ? uword( k) : uword(0); -// -// return SpOp(X.get_ref(), row_offset, col_offset); -// } +template +arma_warn_unused +arma_inline +const SpOp +trimatu(const SpBase& X, const sword k) + { + arma_extra_debug_sigprint(); + + const uword row_offset = (k < 0) ? uword(-k) : uword(0); + const uword col_offset = (k > 0) ? uword( k) : uword(0); + + return SpOp(X.get_ref(), row_offset, col_offset); + } + + + +template +arma_warn_unused +arma_inline +const SpOp +trimatl(const SpBase& X, const sword k) + { + arma_extra_debug_sigprint(); + + const uword row_offset = (k < 0) ? uword(-k) : uword(0); + const uword col_offset = (k > 0) ? uword( k) : uword(0); + + return SpOp(X.get_ref(), row_offset, col_offset); + } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trimat_ind.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trimat_ind.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_trimat_ind.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trimat_ind.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup fn_trimat_ind +//! @{ + + +arma_warn_unused +inline +uvec +trimatu_ind(const SizeMat& s, const sword k = 0) + { + arma_extra_debug_sigprint(); + + const uword n_rows = s.n_rows; + const uword n_cols = s.n_cols; + + const uword row_offset = (k < 0) ? uword(-k) : uword(0); + const uword col_offset = (k > 0) ? uword( k) : uword(0); + + arma_debug_check_bounds( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatu_ind(): requested diagonal is out of bounds" ); + + const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset); + + uvec tmp(n_rows * n_cols, arma_nozeros_indicator()); // worst case scenario + uword* tmp_mem = tmp.memptr(); + uword count = 0; + + for(uword i=0; i < n_cols; ++i) + { + const uword col = i + col_offset; + + if(i < N) + { + const uword end_row = i + row_offset; + + const uword index_offset = (n_rows * col); + + for(uword row=0; row <= end_row; ++row) + { + tmp_mem[count] = index_offset + row; + ++count; + } + } + else + { + if(col < n_cols) + { + const uword index_offset = (n_rows * col); + + for(uword row=0; row < n_rows; ++row) + { + tmp_mem[count] = index_offset + row; + ++count; + } + } + } + } + + uvec out; + + out.steal_mem_col(tmp, count); + + return out; + } + + + +arma_warn_unused +inline +uvec +trimatl_ind(const SizeMat& s, const sword k = 0) + { + arma_extra_debug_sigprint(); + + const uword n_rows = s.n_rows; + const uword n_cols = s.n_cols; + + const uword row_offset = (k < 0) ? uword(-k) : uword(0); + const uword col_offset = (k > 0) ? uword( k) : uword(0); + + arma_debug_check_bounds( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatl_ind(): requested diagonal is out of bounds" ); + + const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset); + + uvec tmp(n_rows * n_cols, arma_nozeros_indicator()); // worst case scenario + uword* tmp_mem = tmp.memptr(); + uword count = 0; + + for(uword col=0; col < col_offset; ++col) + { + const uword index_offset = (n_rows * col); + + for(uword row=0; row < n_rows; ++row) + { + tmp_mem[count] = index_offset + row; + ++count; + } + } + + for(uword i=0; i arma_warn_unused -arma_inline +inline typename arma_scalar_only::result var(const T&) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_vectorise.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_vectorise.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_vectorise.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_vectorise.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_wishrnd.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_wishrnd.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_wishrnd.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_wishrnd.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -72,17 +74,16 @@ if(status == false) { - arma_debug_warn("wishrnd(): given matrix is not symmetric positive definite"); - return false; + W.soft_reset(); + arma_debug_warn_level(3, "wishrnd(): given matrix is not symmetric positive definite"); } - return true; + return status; } template -arma_warn_unused inline typename enable_if2 @@ -95,7 +96,15 @@ arma_extra_debug_sigprint(); arma_ignore(S); - return op_wishrnd::apply_direct(W, D.get_ref(), df, uword(2)); + const bool status = op_wishrnd::apply_direct(W, D.get_ref(), df, uword(2)); + + if(status == false) + { + W.soft_reset(); + arma_debug_warn_level(3, "wishrnd(): problem with given 'D' matrix"); + } + + return status; } @@ -157,17 +166,16 @@ if(status == false) { - arma_debug_warn("iwishrnd(): given matrix is not symmetric positive definite and/or df is too low"); - return false; + W.soft_reset(); + arma_debug_warn_level(3, "iwishrnd(): given matrix is not symmetric positive definite and/or df is too low"); } - return true; + return status; } template -arma_warn_unused inline typename enable_if2 @@ -180,7 +188,15 @@ arma_extra_debug_sigprint(); arma_ignore(T); - return op_iwishrnd::apply_direct(W, Dinv.get_ref(), df, uword(2)); + const bool status = op_iwishrnd::apply_direct(W, Dinv.get_ref(), df, uword(2)); + + if(status == false) + { + W.soft_reset(); + arma_debug_warn_level(3, "wishrnd(): problem with given 'Dinv' matrix and/or df is too low"); + } + + return status; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/fn_zeros.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/fn_zeros.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/fn_zeros.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/fn_zeros.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,7 +37,7 @@ arma_warn_unused arma_inline const Gen -zeros(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = 0) +zeros(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only::result* junk2 = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk1); @@ -81,7 +83,7 @@ arma_warn_unused arma_inline const Gen -zeros(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = 0) +zeros(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -105,7 +107,7 @@ arma_warn_unused arma_inline const Gen -zeros(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = 0) +zeros(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -143,7 +145,7 @@ arma_warn_unused arma_inline const GenCube -zeros(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only::result* junk = 0) +zeros(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -157,7 +159,7 @@ arma_warn_unused arma_inline const GenCube -zeros(const SizeCube& s, const typename arma_Cube_only::result* junk = 0) +zeros(const SizeCube& s, const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); @@ -171,17 +173,17 @@ arma_warn_unused inline sp_obj_type -zeros(const uword n_rows, const uword n_cols, const typename arma_SpMat_SpCol_SpRow_only::result* junk = 0) +zeros(const uword n_rows, const uword n_cols, const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); - if(is_SpCol::value == true) + if(is_SpCol::value) { arma_debug_check( (n_cols != 1), "zeros(): incompatible size" ); } else - if(is_SpRow::value == true) + if(is_SpRow::value) { arma_debug_check( (n_rows != 1), "zeros(): incompatible size" ); } @@ -195,7 +197,7 @@ arma_warn_unused inline sp_obj_type -zeros(const SizeMat& s, const typename arma_SpMat_SpCol_SpRow_only::result* junk = 0) +zeros(const SizeMat& s, const typename arma_SpMat_SpCol_SpRow_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Gen_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Gen_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Gen_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Gen_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,7 +23,7 @@ //! support class for generator functions (eg. zeros, randu, randn, ...) template class Gen - : public Base > + : public Base< typename T1::elem_type, Gen > , public GenSpecialiser::yes, is_same_type::yes, is_same_type::yes, is_same_type::yes> { public: @@ -29,12 +31,12 @@ typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - static const bool use_at = (is_same_type::value); - static const bool is_simple = (is_same_type::value) || (is_same_type::value); + static constexpr bool use_at = (is_same_type::value); + static constexpr bool is_simple = (is_same_type::value) || (is_same_type::value); - static const bool is_row = T1::is_row; - static const bool is_col = T1::is_col; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T1::is_col; + static constexpr bool is_xvec = T1::is_xvec; arma_aligned const uword n_rows; arma_aligned const uword n_cols; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/GenCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/GenCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/GenCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/GenCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,7 +23,7 @@ //! support class for generator functions (eg. zeros, randu, randn, ...) template class GenCube - : public BaseCube > + : public BaseCube< eT, GenCube > , public GenSpecialiser::yes, is_same_type::yes, is_same_type::yes, is_same_type::yes> { public: @@ -29,8 +31,8 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool use_at = false; - static const bool is_simple = (is_same_type::value) || (is_same_type::value); + static constexpr bool use_at = false; + static constexpr bool is_simple = (is_same_type::value) || (is_same_type::value); arma_aligned const uword n_rows; arma_aligned const uword n_cols; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/GenCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/GenCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/GenCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/GenCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Gen_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Gen_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Gen_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Gen_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/GenSpecialiser.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/GenSpecialiser.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/GenSpecialiser.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/GenSpecialiser.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_affmul_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_affmul_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_affmul_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_affmul_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,9 +28,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_affmul_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_affmul_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_affmul_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_affmul_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -240,7 +242,7 @@ { if(B_n_cols == 1) { - Col tmp(N); + Col tmp(N, arma_nozeros_indicator()); eT* tmp_mem = tmp.memptr(); arrayops::copy(tmp_mem, B.memptr(), N-1); @@ -251,7 +253,7 @@ } else { - Mat tmp(N, B_n_cols); + Mat tmp(N, B_n_cols, arma_nozeros_indicator()); for(uword col=0; col < B_n_cols; ++col) { @@ -423,7 +425,7 @@ if(B_n_cols == 1) { - Col tmp(A_n_cols); + Col tmp(A_n_cols, arma_nozeros_indicator()); eT* tmp_mem = tmp.memptr(); arrayops::copy(tmp_mem, B.memptr(), A_n_cols-1); @@ -434,7 +436,7 @@ } else { - Mat tmp(A_n_cols, B_n_cols); + Mat tmp(A_n_cols, B_n_cols, arma_nozeros_indicator()); for(uword col=0; col < B_n_cols; ++col) { @@ -468,7 +470,7 @@ const uword B_n_rows = B.n_rows; const uword B_n_cols = B.n_cols; - Mat tmp(B_n_rows+1, B_n_cols); + Mat tmp(B_n_rows+1, B_n_cols, arma_nozeros_indicator()); for(uword col=0; col < B_n_cols; ++col) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_atan2_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_atan2_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_atan2_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_atan2_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_atan2_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_atan2_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_atan2_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_atan2_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -68,7 +70,7 @@ eT* out_mem = out.memptr(); - const bool use_mp = arma_config::cxx11 && arma_config::openmp && mp_gate::use_mp || Proxy::use_mp)>::eval(n_elem); + const bool use_mp = arma_config::openmp && mp_gate::use_mp || Proxy::use_mp)>::eval(n_elem); const bool use_at = Proxy::use_at || Proxy::use_at; if(use_at == false) @@ -170,7 +172,7 @@ eT* out_mem = out.memptr(); - const bool use_mp = arma_config::cxx11 && arma_config::openmp && mp_gate::use_mp || ProxyCube::use_mp)>::eval(n_elem); + const bool use_mp = arma_config::openmp && mp_gate::use_mp || ProxyCube::use_mp)>::eval(n_elem); const bool use_at = ProxyCube::use_at || ProxyCube::use_at; if(use_at == false) diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Glue_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Glue_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Glue_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Glue_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,33 +28,33 @@ template struct Glue_traits { - static const bool is_row = glue_type::template traits::is_row; - static const bool is_col = glue_type::template traits::is_col; - static const bool is_xvec = glue_type::template traits::is_xvec; + static constexpr bool is_row = glue_type::template traits::is_row; + static constexpr bool is_col = glue_type::template traits::is_col; + static constexpr bool is_xvec = glue_type::template traits::is_xvec; }; template struct Glue_traits { - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; }; template class Glue - : public Base > - , public Glue_traits::value > + : public Base< typename T1::elem_type, Glue > + , public Glue_traits::value> { public: typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - arma_inline Glue(const T1& in_A, const T2& in_B); - arma_inline Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword); - arma_inline ~Glue(); + 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(); const T1& A; //!< first operand; must be derived from Base const T2& B; //!< second operand; must be derived from Base diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_conv_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_conv_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_conv_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_conv_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T1::is_col; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T1::is_col; + static constexpr bool is_xvec = T1::is_xvec; }; template inline static void apply(Mat& out, const Mat& A, const Mat& B, const bool A_is_col); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_conv_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_conv_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_conv_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_conv_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -38,7 +40,7 @@ if( (h_n_elem == 0) || (x_n_elem == 0) ) { out.zeros(); return; } - Col hh(h_n_elem); // flipped version of h + Col hh(h_n_elem, arma_nozeros_indicator()); // flipped version of h const eT* h_mem = h.memptr(); eT* hh_mem = hh.memptr(); @@ -49,7 +51,7 @@ } - Col xx( (x_n_elem + 2*h_n_elem_m1), fill::zeros ); // zero padded version of x + Col xx( (x_n_elem + 2*h_n_elem_m1), arma_zeros_indicator() ); // zero padded version of x const eT* x_mem = x.memptr(); eT* xx_mem = xx.memptr(); @@ -90,7 +92,7 @@ // if( (h_n_elem == 0) || (x_n_elem == 0) ) { out.zeros(); return; } // // -// Col hh(h_n_elem); // flipped version of h +// Col hh(h_n_elem, arma_nozeros_indicator()); // flipped version of h // // const eT* h_mem = h.memptr(); // eT* hh_mem = hh.memptr(); @@ -106,7 +108,7 @@ // // const uword HH_n_rows = h_n_elem + (N_copies-1); // -// Mat HH(HH_n_rows, N_copies, fill::zeros); +// Mat HH(HH_n_rows, N_copies, arma_zeros_indicator()); // // for(uword i=0; i xx( (x_n_elem + 2*h_n_elem_m1), fill::zeros ); // zero padded version of x +// Col xx( (x_n_elem + 2*h_n_elem_m1), arma_zeros_indicator() ); // zero padded version of x // // const eT* x_mem = x.memptr(); // eT* xx_mem = xx.memptr(); @@ -181,7 +183,7 @@ arma_debug_check ( ( ((A.is_vec() == false) && (A.is_empty() == false)) || ((B.is_vec() == false) && (B.is_empty() == false)) ), - "conv(): given object is not a vector" + "conv(): given object must be a vector" ); const bool A_is_col = ((T1::is_col) || (A.n_cols == 1)); @@ -235,7 +237,7 @@ if(G.is_empty() || W.is_empty()) { out.zeros(); return; } - Mat H(G.n_rows, G.n_cols); // flipped filter coefficients + Mat H(G.n_rows, G.n_cols, arma_nozeros_indicator()); // flipped filter coefficients const uword H_n_rows = H.n_rows; const uword H_n_cols = H.n_cols; @@ -255,7 +257,7 @@ } - Mat X( (W.n_rows + 2*H_n_rows_m1), (W.n_cols + 2*H_n_cols_m1), fill::zeros ); + Mat X( (W.n_rows + 2*H_n_rows_m1), (W.n_cols + 2*H_n_cols_m1), arma_zeros_indicator() ); X( H_n_rows_m1, H_n_cols_m1, arma::size(W) ) = W; // zero padded version of 2D image diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cor_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cor_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cor_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cor_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = false; // T1::is_col; // TODO: check - static const bool is_col = false; // T2::is_col; // TODO: check - static const bool is_xvec = false; + static constexpr bool is_row = false; // T1::is_col; // TODO: check + static constexpr bool is_col = false; // T2::is_col; // TODO: check + static constexpr bool is_xvec = false; }; template inline static void apply(Mat& out, const Glue& X); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cor_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cor_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cor_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cor_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cov_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cov_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cov_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cov_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = false; // T1::is_col; // TODO: check - static const bool is_col = false; // T2::is_col; // TODO: check - static const bool is_xvec = false; + static constexpr bool is_row = false; // T1::is_col; // TODO: check + static constexpr bool is_col = false; // T2::is_col; // TODO: check + static constexpr bool is_xvec = false; }; template inline static void apply(Mat& out, const Glue& X); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cov_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cov_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cov_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cov_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cross_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cross_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cross_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cross_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T1::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T1::is_col; + static constexpr bool is_xvec = true; }; template inline static void apply(Mat& out, const Glue& X); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cross_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cross_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_cross_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_cross_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -32,12 +34,9 @@ const Proxy PA(X.A); const Proxy PB(X.B); - arma_debug_check( ((PA.get_n_elem() != 3) || (PB.get_n_elem() != 3)), "cross(): input vectors must have 3 elements" ); - - const uword PA_n_rows = Proxy::is_row ? 1 : PA.get_n_rows(); - const uword PA_n_cols = Proxy::is_col ? 1 : PA.get_n_cols(); + arma_debug_check( ((PA.get_n_elem() != 3) || (PB.get_n_elem() != 3)), "cross(): each vector must have 3 elements" ); - out.set_size(PA_n_rows, PA_n_cols); + out.set_size(PA.get_n_rows(), PA.get_n_cols()); eT* out_mem = out.memptr(); @@ -60,7 +59,7 @@ } else { - const bool PA_is_col = Proxy::is_col ? true : (PA_n_cols == 1); + const bool PA_is_col = Proxy::is_col ? true : (PA.get_n_cols() == 1); const bool PB_is_col = Proxy::is_col ? true : (PB.get_n_cols() == 1); const eT ax = PA.at(0,0); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/GlueCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/GlueCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/GlueCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/GlueCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,19 +23,18 @@ //! analog of the Glue class, intended for Cube objects template -class GlueCube : public BaseCube > +class GlueCube : public BaseCube< typename T1::elem_type, GlueCube > { public: typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - - arma_inline GlueCube(const BaseCube& in_A, const BaseCube& in_B); - arma_inline ~GlueCube(); + + inline GlueCube(const BaseCube& in_A, const BaseCube& in_B); + inline ~GlueCube(); const T1& A; //!< first operand; must be derived from BaseCube const T2& B; //!< second operand; must be derived from BaseCube - }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/GlueCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/GlueCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/GlueCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/GlueCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_hist_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_hist_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_hist_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_hist_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -39,9 +41,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T1::is_col; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T1::is_col; + static constexpr bool is_xvec = T1::is_xvec; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_histc_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_histc_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_histc_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_histc_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -39,9 +41,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T1::is_col; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T1::is_col; + static constexpr bool is_xvec = T1::is_xvec; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_histc_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_histc_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_histc_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_histc_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,7 +27,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ((B.is_vec() == false) && (B.is_empty() == false)), "histc(): parameter 'edges' is not a vector" ); + arma_debug_check( ((B.is_vec() == false) && (B.is_empty() == false)), "histc(): parameter 'edges' must be a vector" ); const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_hist_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_hist_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_hist_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_hist_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_hypot_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_hypot_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_hypot_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_hypot_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_hypot_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_hypot_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_hypot_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_hypot_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_intersect_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_intersect_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_intersect_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_intersect_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,9 +28,9 @@ template struct traits { - static const bool is_row = (T1::is_row && T2::is_row); - static const bool is_col = (T1::is_col || T2::is_col); - static const bool is_xvec = false; + static constexpr bool is_row = (T1::is_row && T2::is_row); + static constexpr bool is_col = (T1::is_col || T2::is_col); + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_intersect_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_intersect_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_intersect_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_intersect_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -76,7 +78,7 @@ const uword C_n_elem = A_uniq.n_elem + B_uniq.n_elem; - Col C(C_n_elem); + Col C(C_n_elem, arma_nozeros_indicator()); arrayops::copy(C.memptr(), A_uniq.memptr(), A_uniq.n_elem); arrayops::copy(C.memptr() + A_uniq.n_elem, B_uniq.memptr(), B_uniq.n_elem); @@ -96,7 +98,7 @@ const eT* C_sorted_mem = C_sorted.memptr(); - uvec jj(C_n_elem); // worst case length + uvec jj(C_n_elem, arma_nozeros_indicator()); // worst case length uword* jj_mem = jj.memptr(); uword jj_count = 0; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_join_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_join_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_join_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_join_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = (T1::is_col && T2::is_col); - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = (T1::is_col && T2::is_col); + static constexpr bool is_xvec = false; }; template @@ -54,9 +56,9 @@ template struct traits { - static const bool is_row = (T1::is_row && T2::is_row); - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = (T1::is_row && T2::is_row); + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_join_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_join_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_join_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_join_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -362,7 +364,7 @@ } else // we have aliasing { - Cube C(A.n_rows, A.n_cols, A.n_slices + B.n_slices); + Cube C(A.n_rows, A.n_cols, A.n_slices + B.n_slices, arma_nozeros_indicator()); C.slices(0, A.n_slices-1) = A; C.slices(A.n_slices, C.n_slices-1) = B; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_kron_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_kron_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_kron_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_kron_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = (T1::is_row && T2::is_row); - static const bool is_col = (T1::is_col && T2::is_col); - static const bool is_xvec = false; + static constexpr bool is_row = (T1::is_row && T2::is_row); + static constexpr bool is_col = (T1::is_col && T2::is_col); + static constexpr bool is_xvec = false; }; template inline static void direct_kron(Mat& out, const Mat& A, const Mat& B); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_kron_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_kron_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_kron_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_kron_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_max_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_max_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_max_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_max_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,18 +31,14 @@ template inline static void apply(Mat& out, const Glue& X); - template inline static void apply(Mat< eT >& out, const Proxy& PA, const Proxy& PB); - - template inline static void apply(Mat< std::complex >& out, const Proxy& PA, const Proxy& PB); + template inline static void apply(Mat& out, const Proxy& PA, const Proxy& PB); // cubes template inline static void apply(Cube& out, const GlueCube& X); - template inline static void apply(Cube< eT >& out, const ProxyCube& PA, const ProxyCube& PB); - - template inline static void apply(Cube< std::complex >& out, const ProxyCube& PA, const ProxyCube& PB); + template inline static void apply(Cube& out, const ProxyCube& PA, const ProxyCube& PB); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_max_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_max_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_max_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_max_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -58,51 +60,9 @@ 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); - - eT* out_mem = out.memptr(); - - if( (Proxy::use_at == false) && (Proxy::use_at == false) ) - { - typename Proxy::ea_type A = PA.get_ea(); - typename Proxy::ea_type B = PB.get_ea(); - - const uword N = PA.get_n_elem(); - - for(uword i=0; i -inline -void -glue_max::apply(Mat< std::complex >& out, const Proxy& PA, const Proxy& PB) - { - arma_extra_debug_sigprint(); - - typedef typename std::complex eT; - - 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"); + const arma_gt_comparator comparator; out.set_size(n_rows, n_cols); @@ -117,10 +77,10 @@ for(uword i=0; i std::abs(B_val) ) ? A_val : B_val; + out_mem[i] = comparator(Ai,Bi) ? Ai : Bi; } } else @@ -128,10 +88,10 @@ for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { - const eT A_val = PA.at(row,col); - const eT B_val = PB.at(row,col); + const eT Ai = PA.at(row,col); + const eT Bi = PB.at(row,col); - *out_mem = ( std::abs(A_val) > std::abs(B_val) ) ? A_val : B_val; + *out_mem = comparator(Ai,Bi) ? Ai : Bi; ++out_mem; } @@ -179,53 +139,9 @@ 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"); - - out.set_size(n_rows, n_cols, n_slices); - - eT* out_mem = out.memptr(); - - if( (ProxyCube::use_at == false) && (ProxyCube::use_at == false) ) - { - typename ProxyCube::ea_type A = PA.get_ea(); - typename ProxyCube::ea_type B = PB.get_ea(); - - const uword N = PA.get_n_elem(); - - for(uword i=0; i -inline -void -glue_max::apply(Cube< std::complex >& out, const ProxyCube& PA, const ProxyCube& PB) - { - arma_extra_debug_sigprint(); - - typedef typename std::complex eT; - - const uword n_rows = PA.get_n_rows(); - 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 max()"); - 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"); + const arma_gt_comparator comparator; out.set_size(n_rows, n_cols, n_slices); @@ -240,10 +156,10 @@ for(uword i=0; i std::abs(B_val) ) ? A_val : B_val; + out_mem[i] = comparator(Ai,Bi) ? Ai : Bi; } } else @@ -252,10 +168,10 @@ for(uword col=0; col < n_cols; ++col ) for(uword row=0; row < n_rows; ++row ) { - const eT A_val = PA.at(row,col,slice); - const eT B_val = PB.at(row,col,slice); + const eT Ai = PA.at(row,col,slice); + const eT Bi = PB.at(row,col,slice); - *out_mem = ( std::abs(A_val) > std::abs(B_val) ) ? A_val : B_val; + *out_mem = comparator(Ai,Bi) ? Ai : Bi; ++out_mem; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Glue_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Glue_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Glue_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Glue_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_min_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_min_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_min_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_min_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,18 +31,14 @@ template inline static void apply(Mat& out, const Glue& X); - template inline static void apply(Mat< eT >& out, const Proxy& PA, const Proxy& PB); - - template inline static void apply(Mat< std::complex >& out, const Proxy& PA, const Proxy& PB); + template inline static void apply(Mat& out, const Proxy& PA, const Proxy& PB); // cubes template inline static void apply(Cube& out, const GlueCube& X); - template inline static void apply(Cube< eT >& out, const ProxyCube& PA, const ProxyCube& PB); - - template inline static void apply(Cube< std::complex >& out, const ProxyCube& PA, const ProxyCube& PB); + template inline static void apply(Cube& out, const ProxyCube& PA, const ProxyCube& PB); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_min_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_min_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_min_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_min_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -58,51 +60,9 @@ 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); - - eT* out_mem = out.memptr(); - - if( (Proxy::use_at == false) && (Proxy::use_at == false) ) - { - typename Proxy::ea_type A = PA.get_ea(); - typename Proxy::ea_type B = PB.get_ea(); - - const uword N = PA.get_n_elem(); - - for(uword i=0; i -inline -void -glue_min::apply(Mat< std::complex >& out, const Proxy& PA, const Proxy& PB) - { - arma_extra_debug_sigprint(); - - typedef typename std::complex eT; - - 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"); + const arma_lt_comparator comparator; out.set_size(n_rows, n_cols); @@ -117,10 +77,10 @@ for(uword i=0; i::use_at == false) && (ProxyCube::use_at == false) ) - { - typename ProxyCube::ea_type A = PA.get_ea(); - typename ProxyCube::ea_type B = PB.get_ea(); - - const uword N = PA.get_n_elem(); - - for(uword i=0; i -inline -void -glue_min::apply(Cube< std::complex >& out, const ProxyCube& PA, const ProxyCube& PB) - { - arma_extra_debug_sigprint(); - - typedef typename std::complex eT; - - const uword n_rows = PA.get_n_rows(); - 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 min()"); - 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"); + const arma_lt_comparator comparator; out.set_size(n_rows, n_cols, n_slices); @@ -240,10 +156,10 @@ for(uword i=0; i struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_mixed_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_mixed_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_mixed_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_mixed_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -59,7 +61,7 @@ } else { - Mat tmp(out_n_rows, out_n_cols); + Mat tmp(out_n_rows, out_n_cols, arma_nozeros_indicator()); gemm_mixed::apply(tmp, A, B, alpha); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_mvnrnd_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_mvnrnd_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_mvnrnd_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_mvnrnd_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,9 +27,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_mvnrnd_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_mvnrnd_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_mvnrnd_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_mvnrnd_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -36,6 +38,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("mvnrnd(): given covariance matrix is not symmetric positive semi-definite"); } } @@ -53,6 +56,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("mvnrnd(): given covariance matrix is not symmetric positive semi-definite"); } } @@ -83,13 +87,13 @@ // if(auxlib::rudimentary_sym_check(UC.M) == false) // { - // arma_debug_warn("mvnrnd(): given matrix is not symmetric"); + // arma_debug_warn_level(1, "mvnrnd(): given matrix is not symmetric"); // return false; // } if((arma_config::debug) && (auxlib::rudimentary_sym_check(UC.M) == false)) { - arma_debug_warn("mvnrnd(): given matrix is not symmetric"); + arma_debug_warn_level(1, "mvnrnd(): given matrix is not symmetric"); } bool status = false; @@ -107,8 +111,6 @@ status = glue_mvnrnd::apply_noalias(out, UM.M, UC.M, N); } - if(status == false) { out.soft_reset(); } - return status; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_polyfit_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_polyfit_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_polyfit_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_polyfit_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; }; template inline static bool apply_noalias(Mat& out, const Col& X, const Col& Y, const uword N); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_polyfit_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_polyfit_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_polyfit_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_polyfit_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,7 +30,7 @@ // create Vandermonde matrix - Mat V(X.n_elem, N+1); + Mat V(X.n_elem, N+1, arma_nozeros_indicator()); V.tail_cols(1).ones(); @@ -76,7 +78,7 @@ arma_debug_check ( ( ((X.is_vec() == false) && (X.is_empty() == false)) || ((Y.is_vec() == false) && (Y.is_empty() == false)) ), - "polyfit(): given object is not a vector" + "polyfit(): given object must be a vector" ); arma_debug_check( (X.n_elem != Y.n_elem), "polyfit(): given vectors must have the same number of elements" ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_polyval_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_polyval_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_polyval_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_polyval_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = T2::is_row; - static const bool is_col = T2::is_col; - static const bool is_xvec = T2::is_xvec; + static constexpr bool is_row = T2::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = T2::is_xvec; }; template inline static void apply_noalias(Mat& out, const Mat& P, const Mat& X); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_polyval_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_polyval_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_polyval_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_polyval_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_quantile_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_quantile_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_quantile_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_quantile_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup glue_quantile +//! @{ + + +class glue_quantile + : public traits_glue_default + { + public: + + template + inline static void worker(eTb* out_mem, Col& Y, const Mat& P); + + + template + inline static void apply_noalias(Mat& out, const Mat& X, const Mat& P, const uword dim); + + template + inline static void apply(Mat& out, const mtGlue& expr); + }; + + + +class glue_quantile_default + { + public: + + template + struct traits + { + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T1::is_col; + static constexpr bool is_xvec = T1::is_xvec; + }; + + template + inline static void apply(Mat& out, const mtGlue& expr); + }; + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_quantile_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_quantile_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_quantile_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_quantile_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup glue_quantile +//! @{ + + +template +inline +void +glue_quantile::worker(eTb* out_mem, Col& Y, const Mat& P) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming out_mem is an array with P.n_elem elements + + // TODO: ignore non-finite values ? + + // algorithm based on "Definition 5" in: + // Rob J. Hyndman and Yanan Fan. + // Sample Quantiles in Statistical Packages. + // The American Statistician, Vol. 50, No. 4, pp. 361-365, 1996. + // http://doi.org/10.2307/2684934 + + const eTb* P_mem = P.memptr(); + const uword P_n_elem = P.n_elem; + + const eTb alpha = 0.5; + const eTb N = eTb(Y.n_elem); + const eTb P_min = (eTb(1) - alpha) / N; + const eTb P_max = (N - alpha) / N; + + for(uword i=0; i < P_n_elem; ++i) + { + const eTb P_i = P_mem[i]; + + eTb out_val = eTb(0); + + if(P_i < P_min) + { + out_val = (P_i < eTb(0)) ? eTb(-std::numeric_limits::infinity()) : eTb(Y.min()); + } + else + if(P_i > P_max) + { + out_val = (P_i > eTb(1)) ? eTb( std::numeric_limits::infinity()) : eTb(Y.max()); + } + else + { + const uword k = uword(std::floor(N * P_i + alpha)); + const eTb P_k = (eTb(k) - alpha) / N; + + const eTb w = (P_i - P_k) * N; + + eTa* Y_k_ptr = Y.begin() + uword(k); + std::nth_element( Y.begin(), Y_k_ptr, Y.end() ); + const eTa Y_k_val = (*Y_k_ptr); + + eTa* Y_km1_ptr = Y.begin() + uword(k-1); + // std::nth_element( Y.begin(), Y_km1_ptr, Y.end() ); + std::nth_element( Y.begin(), Y_km1_ptr, Y_k_ptr ); + const eTa Y_km1_val = (*Y_km1_ptr); + + out_val = ((eTb(1) - w) * Y_km1_val) + (w * Y_k_val); + } + + out_mem[i] = out_val; + } + } + + + +template +inline +void +glue_quantile::apply_noalias(Mat& out, const Mat& X, const Mat& P, const uword dim) + { + arma_extra_debug_sigprint(); + + arma_debug_check( ((P.is_vec() == false) && (P.is_empty() == false)), "quantile(): parameter 'P' must be a vector" ); + + if(X.is_empty()) { out.reset(); return; } + + const uword X_n_rows = X.n_rows; + const uword X_n_cols = X.n_cols; + + const uword P_n_elem = P.n_elem; + + if(dim == 0) + { + out.set_size(P_n_elem, X_n_cols); + + if(out.is_empty()) { return; } + + Col Y(X_n_rows, arma_nozeros_indicator()); + + if(X_n_cols == 1) + { + arrayops::copy(Y.memptr(), X.memptr(), X_n_rows); + + glue_quantile::worker(out.memptr(), Y, P); + } + else + { + for(uword col=0; col < X_n_cols; ++col) + { + arrayops::copy(Y.memptr(), X.colptr(col), X_n_rows); + + glue_quantile::worker(out.colptr(col), Y, P); + } + } + } + else + if(dim == 1) + { + out.set_size(X_n_rows, P_n_elem); + + if(out.is_empty()) { return; } + + Col Y(X_n_cols, arma_nozeros_indicator()); + + if(X_n_rows == 1) + { + arrayops::copy(Y.memptr(), X.memptr(), X_n_cols); + + glue_quantile::worker(out.memptr(), Y, P); + } + else + { + Col tmp(P_n_elem, arma_nozeros_indicator()); + + eTb* tmp_mem = tmp.memptr(); + + for(uword row=0; row < X_n_rows; ++row) + { + eTa* Y_mem = Y.memptr(); + + for(uword col=0; col < X_n_cols; ++col) { Y_mem[col] = X.at(row,col); } + + glue_quantile::worker(tmp_mem, Y, P); + + for(uword i=0; i < P_n_elem; ++i) { out.at(row,i) = tmp_mem[i]; } + } + } + } + } + + + +template +inline +void +glue_quantile::apply(Mat& out, const mtGlue& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T2::elem_type eTb; + + const uword dim = expr.aux_uword; + + arma_debug_check( (dim > 1), "quantile(): parameter 'dim' must be 0 or 1" ); + + const quasi_unwrap UA(expr.A); + const quasi_unwrap UB(expr.B); + + if(UA.is_alias(out) || UB.is_alias(out)) + { + Mat tmp; + + glue_quantile::apply_noalias(tmp, UA.M, UB.M, dim); + + out.steal_mem(tmp); + } + else + { + glue_quantile::apply_noalias(out, UA.M, UB.M, dim); + } + } + + + +template +inline +void +glue_quantile_default::apply(Mat& out, const mtGlue& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T2::elem_type eTb; + + const quasi_unwrap UA(expr.A); + const quasi_unwrap UB(expr.B); + + const uword dim = (T1::is_xvec) ? uword(UA.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0); + + if(UA.is_alias(out) || UB.is_alias(out)) + { + Mat tmp; + + glue_quantile::apply_noalias(tmp, UA.M, UB.M, dim); + + out.steal_mem(tmp); + } + else + { + glue_quantile::apply_noalias(out, UA.M, UB.M, dim); + } + } + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_relational_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_relational_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_relational_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_relational_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_relational_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_relational_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_relational_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_relational_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_solve_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_solve_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_solve_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_solve_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template inline static void apply(Mat& out, const Glue& X); @@ -46,9 +48,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template inline static void apply(Mat& out, const Glue& X); @@ -65,9 +67,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template inline static void apply(Mat& out, const Glue& X); @@ -105,18 +107,19 @@ // The values below (eg. 1u << 1) are for internal Armadillo use only. // The values can change without notice. - static const uword flag_none = uword(0 ); - static const uword flag_fast = uword(1u << 0); - static const uword flag_equilibrate = uword(1u << 1); - static const uword flag_no_approx = uword(1u << 2); - static const uword flag_triu = uword(1u << 3); - static const uword flag_tril = uword(1u << 4); - static const uword flag_no_band = uword(1u << 5); - static const uword flag_no_sympd = uword(1u << 6); - static const uword flag_allow_ugly = uword(1u << 7); - static const uword flag_likely_sympd = uword(1u << 8); - static const uword flag_refine = uword(1u << 9); - static const uword flag_no_trimat = uword(1u << 10); + static constexpr uword flag_none = uword(0 ); + static constexpr uword flag_fast = uword(1u << 0); + static constexpr uword flag_equilibrate = uword(1u << 1); + static constexpr uword flag_no_approx = uword(1u << 2); + static constexpr uword flag_triu = uword(1u << 3); + static constexpr uword flag_tril = uword(1u << 4); + static constexpr uword flag_no_band = uword(1u << 5); + static constexpr uword flag_no_sympd = uword(1u << 6); + static constexpr uword flag_allow_ugly = uword(1u << 7); + static constexpr uword flag_likely_sympd = uword(1u << 8); + static constexpr uword flag_refine = uword(1u << 9); + static constexpr uword flag_no_trimat = uword(1u << 10); + static constexpr uword flag_force_approx = uword(1u << 11); struct opts_none : public opts { inline opts_none() : opts(flag_none ) {} }; struct opts_fast : public opts { inline opts_fast() : opts(flag_fast ) {} }; @@ -130,6 +133,7 @@ struct opts_likely_sympd : public opts { inline opts_likely_sympd() : opts(flag_likely_sympd) {} }; struct opts_refine : public opts { inline opts_refine() : opts(flag_refine ) {} }; struct opts_no_trimat : public opts { inline opts_no_trimat() : opts(flag_no_trimat ) {} }; + struct opts_force_approx : public opts { inline opts_force_approx() : opts(flag_force_approx) {} }; static const opts_none none; static const opts_fast fast; @@ -143,6 +147,7 @@ static const opts_likely_sympd likely_sympd; static const opts_refine refine; static const opts_no_trimat no_trimat; + static const opts_force_approx force_approx; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_solve_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_solve_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_solve_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_solve_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -34,6 +36,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("solve(): solution not found"); } } @@ -58,6 +61,7 @@ const bool likely_sympd = bool(flags & solve_opts::flag_likely_sympd); const bool refine = bool(flags & solve_opts::flag_refine ); const bool no_trimat = bool(flags & solve_opts::flag_no_trimat ); + const bool force_approx = bool(flags & solve_opts::flag_force_approx); arma_extra_debug_print("glue_solve_gen::apply(): enabled flags:"); @@ -70,16 +74,31 @@ if(likely_sympd) { arma_extra_debug_print("likely_sympd"); } if(refine ) { arma_extra_debug_print("refine"); } if(no_trimat ) { arma_extra_debug_print("no_trimat"); } + if(force_approx) { arma_extra_debug_print("force_approx"); } arma_debug_check( (fast && equilibrate ), "solve(): options 'fast' and 'equilibrate' are mutually exclusive" ); arma_debug_check( (fast && refine ), "solve(): options 'fast' and 'refine' are mutually exclusive" ); arma_debug_check( (no_sympd && likely_sympd), "solve(): options 'no_sympd' and 'likely_sympd' are mutually exclusive" ); + Mat A = A_expr.get_ref(); + + if(force_approx) + { + arma_extra_debug_print("glue_solve_gen::apply(): forced approximate solution"); + + arma_debug_check( no_approx, "solve(): options 'no_approx' and 'force_approx' are mutually exclusive" ); + + if(fast) { arma_debug_warn_level(2, "solve(): option 'fast' ignored for forced approximate solution" ); } + if(equilibrate) { arma_debug_warn_level(2, "solve(): option 'equilibrate' ignored for forced approximate solution" ); } + if(refine) { arma_debug_warn_level(2, "solve(): option 'refine' ignored for forced approximate solution" ); } + if(likely_sympd) { arma_debug_warn_level(2, "solve(): option 'likely_sympd' ignored for forced approximate solution" ); } + + return auxlib::solve_approx_svd(out, A, B_expr.get_ref()); // A is overwritten + } + T rcond = T(0); bool status = false; - Mat A = A_expr.get_ref(); - if(A.n_rows == A.n_cols) { arma_extra_debug_print("glue_solve_gen::apply(): detected square system"); @@ -87,7 +106,7 @@ uword KL = 0; uword KU = 0; - #if defined(ARMA_OPTIMISE_SOLVE_BAND) + #if defined(ARMA_OPTIMISE_BAND) const bool is_band = (no_band || auxlib::crippled_lapack(A)) ? false : band_helper::is_band(KL, KU, A, uword(32)); #else const bool is_band = false; @@ -96,8 +115,8 @@ const bool is_triu = (no_trimat || refine || equilibrate || likely_sympd || is_band ) ? false : trimat_helper::is_triu(A); const bool is_tril = (no_trimat || refine || equilibrate || likely_sympd || is_band || is_triu) ? false : trimat_helper::is_tril(A); - #if defined(ARMA_OPTIMISE_SOLVE_SYMPD) - const bool try_sympd = (no_sympd || auxlib::crippled_lapack(A) || is_band || is_triu || is_tril) ? false : (likely_sympd ? true : sympd_helper::guess_sympd(A)); + #if defined(ARMA_OPTIMISE_SYMPD) + const bool try_sympd = (no_sympd || auxlib::crippled_lapack(A) || is_band || is_triu || is_tril) ? false : (likely_sympd ? true : sympd_helper::guess_sympd(A, uword(16))); #else const bool try_sympd = false; #endif @@ -238,7 +257,7 @@ if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(A)) ) { - arma_debug_warn("solve(): solution computed, but system seems singular to working precision (rcond: ", rcond, ")"); + arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); } @@ -248,11 +267,11 @@ if(rcond > T(0)) { - arma_debug_warn("solve(): system seems singular (rcond: ", rcond, "); attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); } else { - arma_debug_warn("solve(): system seems singular; attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); } // TODO: conditionally recreate A: have a separate state flag which indicates whether A was previously overwritten @@ -266,30 +285,44 @@ { arma_extra_debug_print("glue_solve_gen::apply(): detected non-square system"); - if(equilibrate) { arma_debug_warn( "solve(): option 'equilibrate' ignored for non-square matrix" ); } - if(refine) { arma_debug_warn( "solve(): option 'refine' ignored for non-square matrix" ); } - if(likely_sympd) { arma_debug_warn( "solve(): option 'likely_sympd' ignored for non-square matrix" ); } + if(equilibrate) { arma_debug_warn_level(2, "solve(): option 'equilibrate' ignored for non-square matrix" ); } + if(refine) { arma_debug_warn_level(2, "solve(): option 'refine' ignored for non-square matrix" ); } + if(likely_sympd) { arma_debug_warn_level(2, "solve(): option 'likely_sympd' ignored for non-square matrix" ); } if(fast) { - status = auxlib::solve_approx_fast(out, A, B_expr.get_ref()); // A is overwritten - - if(status == false) - { - A = A_expr.get_ref(); // as A was overwritten - - status = auxlib::solve_approx_svd(out, A, B_expr.get_ref()); // A is overwritten - } + status = auxlib::solve_rect_fast(out, A, B_expr.get_ref()); // A is overwritten } else { + status = auxlib::solve_rect_rcond(out, rcond, A, B_expr.get_ref(), allow_ugly); // A is overwritten + } + + if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(A)) ) + { + arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); + } + + if( (status == false) && (no_approx == false) ) + { + arma_extra_debug_print("glue_solve_gen::apply(): solving rank deficient system"); + + if(rcond > T(0)) + { + arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); + } + else + { + arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); + } + + A = A_expr.get_ref(); // as A was overwritten + status = auxlib::solve_approx_svd(out, A, B_expr.get_ref()); // A is overwritten } } - if(status == false) { out.soft_reset(); } - return status; } @@ -310,6 +343,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("solve(): solution not found"); } } @@ -352,7 +386,7 @@ if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(A)) ) { - arma_debug_warn("solve(): solution computed, but system seems singular to working precision (rcond: ", rcond, ")"); + arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); } @@ -362,11 +396,11 @@ if(rcond > T(0)) { - arma_debug_warn("solve(): system seems singular (rcond: ", rcond, "); attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); } else { - arma_debug_warn("solve(): system seems singular; attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); } Mat triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type @@ -375,8 +409,6 @@ } - if(status == false) { out.soft_reset(); } - if(is_alias) { actual_out.steal_mem(out); } return status; @@ -395,6 +427,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("solve(): solution not found"); } } @@ -419,6 +452,7 @@ const bool likely_sympd = bool(flags & solve_opts::flag_likely_sympd); const bool refine = bool(flags & solve_opts::flag_refine ); const bool no_trimat = bool(flags & solve_opts::flag_no_trimat ); + const bool force_approx = bool(flags & solve_opts::flag_force_approx); arma_extra_debug_print("glue_solve_tri::apply(): enabled flags:"); @@ -431,15 +465,16 @@ if(likely_sympd) { arma_extra_debug_print("likely_sympd"); } if(refine ) { arma_extra_debug_print("refine"); } if(no_trimat ) { arma_extra_debug_print("no_trimat"); } + if(force_approx) { arma_extra_debug_print("force_approx"); } - if(no_trimat || equilibrate || refine) + if(no_trimat || equilibrate || refine || force_approx) { const uword mask = ~(solve_opts::flag_triu | solve_opts::flag_tril); return glue_solve_gen::apply(actual_out, ((triu) ? trimatu(A_expr.get_ref()) : trimatl(A_expr.get_ref())), B_expr, (flags & mask)); } - if(likely_sympd) { arma_debug_warn("solve(): option 'likely_sympd' ignored for triangular matrix"); } + if(likely_sympd) { arma_debug_warn_level(2, "solve(): option 'likely_sympd' ignored for triangular matrix"); } const quasi_unwrap U(A_expr.get_ref()); const Mat& A = U.M; @@ -466,7 +501,7 @@ if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(A)) ) { - arma_debug_warn("solve(): solution computed, but system seems singular to working precision (rcond: ", rcond, ")"); + arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); } @@ -476,11 +511,11 @@ if(rcond > T(0)) { - arma_debug_warn("solve(): system seems singular (rcond: ", rcond, "); attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); } else { - arma_debug_warn("solve(): system seems singular; attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); } Mat triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type @@ -489,8 +524,6 @@ } - if(status == false) { out.soft_reset(); } - if(is_alias) { actual_out.steal_mem(out); } return status; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_times_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_times_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,18 +24,18 @@ //! \brief //! Template metaprogram depth_lhs //! calculates the number of Glue instances on the left hand side argument of Glue -//! i.e. it recursively expands each Tx, until the type of Tx is not "Glue<..,.., glue_type>" (i.e the "glue_type" changes) +//! ie. it recursively expands each Tx, until the type of Tx is not "Glue<..,.., glue_type>" (i.e the "glue_type" changes) template struct depth_lhs { - static const uword num = 0; + static constexpr uword num = 0; }; template struct depth_lhs< glue_type, Glue > { - static const uword num = 1 + depth_lhs::num; + static constexpr uword num = 1 + depth_lhs::num; }; @@ -113,9 +115,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template @@ -152,9 +154,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_times_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_times_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -81,7 +83,7 @@ typedef typename T1::elem_type eT; - if(strip_inv::do_inv == true) + if(strip_inv::do_inv) { // replace inv(A)*B with solve(A,B) @@ -97,8 +99,8 @@ { // if(auxlib::rudimentary_sym_check(A) == false) // { - // if(is_cx::no ) { arma_debug_warn("inv_sympd(): given matrix is not symmetric"); } - // if(is_cx::yes) { arma_debug_warn("inv_sympd(): given matrix is not hermitian"); } + // if(is_cx::no ) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not symmetric"); } + // if(is_cx::yes) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not hermitian"); } // // out.soft_reset(); // arma_stop_runtime_error("matrix multiplication: problem with matrix inverse; suggest to use solve() instead"); @@ -108,8 +110,8 @@ if( (arma_config::debug) && (auxlib::rudimentary_sym_check(A) == false) ) { - if(is_cx::no ) { arma_debug_warn("inv_sympd(): given matrix is not symmetric"); } - if(is_cx::yes) { arma_debug_warn("inv_sympd(): given matrix is not hermitian"); } + if(is_cx::no ) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not hermitian"); } } } @@ -118,7 +120,9 @@ arma_debug_assert_mul_size(A, B, "matrix multiplication"); - #if defined(ARMA_OPTIMISE_SOLVE_SYMPD) + // TODO: detect sympd via sympd_helper::guess_sympd(A) ? + + #if defined(ARMA_OPTIMISE_SYMPD) const bool status = (strip_inv::do_inv_sympd) ? auxlib::solve_sympd_fast(out, A, B) : auxlib::solve_square_fast(out, A, B); #else const bool status = auxlib::solve_square_fast(out, A, B); @@ -133,7 +137,7 @@ return; } - #if defined(ARMA_OPTIMISE_SOLVE_SYMPD) + #if defined(ARMA_OPTIMISE_SYMPD) { if(strip_inv::do_inv_sympd) { @@ -152,8 +156,8 @@ // if(auxlib::rudimentary_sym_check(B) == false) // { - // if(is_cx::no ) { arma_debug_warn("inv_sympd(): given matrix is not symmetric"); } - // if(is_cx::yes) { arma_debug_warn("inv_sympd(): given matrix is not hermitian"); } + // if(is_cx::no ) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not symmetric"); } + // if(is_cx::yes) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not hermitian"); } // // out.soft_reset(); // arma_stop_runtime_error("matrix multiplication: problem with matrix inverse; suggest to use solve() instead"); @@ -163,8 +167,8 @@ if( (arma_config::debug) && (auxlib::rudimentary_sym_check(B) == false) ) { - if(is_cx::no ) { arma_debug_warn("inv_sympd(): given matrix is not symmetric"); } - if(is_cx::yes) { arma_debug_warn("inv_sympd(): given matrix is not hermitian"); } + if(is_cx::no ) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not hermitian"); } } arma_debug_assert_mul_size(At.n_cols, At.n_rows, B.n_rows, B.n_cols, "matrix multiplication"); @@ -258,7 +262,7 @@ typedef typename T1::elem_type eT; - if(strip_inv::do_inv == true) + if(strip_inv::do_inv) { // replace inv(A)*B*C with solve(A,B*C); @@ -292,7 +296,9 @@ arma_debug_assert_mul_size(A, BC, "matrix multiplication"); - #if defined(ARMA_OPTIMISE_SOLVE_SYMPD) + // TODO: detect sympd via sympd_helper::guess_sympd(A) ? + + #if defined(ARMA_OPTIMISE_SYMPD) const bool status = (strip_inv::do_inv_sympd) ? auxlib::solve_sympd_fast(out, A, BC) : auxlib::solve_square_fast(out, A, BC); #else const bool status = auxlib::solve_square_fast(out, A, BC); @@ -308,7 +314,7 @@ } - if(strip_inv::do_inv == true) + if(strip_inv::do_inv) { // replace A*inv(B)*C with A*solve(B,C) @@ -327,7 +333,7 @@ Mat solve_result; - #if defined(ARMA_OPTIMISE_SOLVE_SYMPD) + #if defined(ARMA_OPTIMISE_SYMPD) const bool status = (strip_inv::do_inv_sympd) ? auxlib::solve_sympd_fast(solve_result, B, C) : auxlib::solve_square_fast(solve_result, B, C); #else const bool status = auxlib::solve_square_fast(solve_result, B, C); @@ -517,9 +523,9 @@ { arma_extra_debug_sigprint(); - const sword N_mat = 1 + depth_lhs< glue_times, Glue >::num; + constexpr uword N_mat = 1 + depth_lhs< glue_times, Glue >::num; - arma_extra_debug_print(arma_str::format("N_mat = %d") % N_mat); + arma_extra_debug_print(arma_str::format("N_mat = %u") % N_mat); glue_times_redirect::apply(out, X); } @@ -879,7 +885,7 @@ arma_hot inline void -glue_times_diag::apply(Mat& out, const Glue& X) +glue_times_diag::apply(Mat& actual_out, const Glue& X) { arma_extra_debug_sigprint(); @@ -895,10 +901,10 @@ { arma_extra_debug_print("glue_times_diag::apply(): diagmat(A) * B"); - const diagmat_proxy_check A(S1.M, out); + const diagmat_proxy A(S1.M); - const unwrap_check tmp(X.B, out); - const Mat& B = tmp.M; + const quasi_unwrap UB(X.B); + const Mat& B = UB.M; const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; @@ -909,6 +915,13 @@ arma_debug_assert_mul_size(A_n_rows, A_n_cols, B_n_rows, B_n_cols, "matrix multiplication"); + const bool is_alias = (A.is_alias(actual_out) || UB.is_alias(actual_out)); + + if(is_alias) { arma_extra_debug_print("glue_times_diag::apply(): aliasing detected"); } + + Mat tmp; + Mat& out = (is_alias) ? tmp : actual_out; + out.zeros(A_n_rows, B_n_cols); for(uword col=0; col < B_n_cols; ++col) @@ -916,21 +929,20 @@ eT* out_coldata = out.colptr(col); const eT* B_coldata = B.colptr(col); - for(uword i=0; i < A_length; ++i) - { - out_coldata[i] = A[i] * B_coldata[i]; - } + for(uword i=0; i < A_length; ++i) { out_coldata[i] = A[i] * B_coldata[i]; } } + + if(is_alias) { actual_out.steal_mem(tmp); } } else if( (strip_diagmat::do_diagmat == false) && (strip_diagmat::do_diagmat == true) ) { arma_extra_debug_print("glue_times_diag::apply(): A * diagmat(B)"); - const unwrap_check tmp(X.A, out); - const Mat& A = tmp.M; + const quasi_unwrap UA(X.A); + const Mat& A = UA.M; - const diagmat_proxy_check B(S2.M, out); + const diagmat_proxy B(S2.M); const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; @@ -941,6 +953,13 @@ arma_debug_assert_mul_size(A_n_rows, A_n_cols, B_n_rows, B_n_cols, "matrix multiplication"); + const bool is_alias = (UA.is_alias(actual_out) || B.is_alias(actual_out)); + + if(is_alias) { arma_extra_debug_print("glue_times_diag::apply(): aliasing detected"); } + + Mat tmp; + Mat& out = (is_alias) ? tmp : actual_out; + out.zeros(A_n_rows, B_n_cols); for(uword col=0; col < B_length; ++col) @@ -950,22 +969,28 @@ eT* out_coldata = out.colptr(col); const eT* A_coldata = A.colptr(col); - for(uword i=0; i < A_n_rows; ++i) - { - out_coldata[i] = A_coldata[i] * val; - } + for(uword i=0; i < A_n_rows; ++i) { out_coldata[i] = A_coldata[i] * val; } } + + if(is_alias) { actual_out.steal_mem(tmp); } } else if( (strip_diagmat::do_diagmat == true) && (strip_diagmat::do_diagmat == true) ) { arma_extra_debug_print("glue_times_diag::apply(): diagmat(A) * diagmat(B)"); - const diagmat_proxy_check A(S1.M, out); - const diagmat_proxy_check B(S2.M, out); + const diagmat_proxy A(S1.M); + const diagmat_proxy B(S2.M); arma_debug_assert_mul_size(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); + const bool is_alias = (A.is_alias(actual_out) || B.is_alias(actual_out)); + + if(is_alias) { arma_extra_debug_print("glue_times_diag::apply(): aliasing detected"); } + + Mat tmp; + Mat& out = (is_alias) ? tmp : actual_out; + out.zeros(A.n_rows, B.n_cols); const uword A_length = (std::min)(A.n_rows, A.n_cols); @@ -973,10 +998,9 @@ const uword N = (std::min)(A_length, B_length); - for(uword i=0; i < N; ++i) - { - out.at(i,i) = A[i] * B[i]; - } + for(uword i=0; i < N; ++i) { out.at(i,i) = A[i] * B[i]; } + + if(is_alias) { actual_out.steal_mem(tmp); } } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_toeplitz_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_toeplitz_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_toeplitz_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_toeplitz_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_toeplitz_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_toeplitz_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_toeplitz_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_toeplitz_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -38,7 +40,7 @@ arma_debug_check ( ( ((A.is_vec() == false) && (A.is_empty() == false)) || ((B.is_vec() == false) && (B.is_empty() == false)) ), - "toeplitz(): given object is not a vector" + "toeplitz(): given object must be a vector" ); const uword A_N = A.n_elem; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_trapz_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_trapz_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_trapz_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_trapz_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = true; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = true; }; template inline static void apply(Mat& out, const Glue& in); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/glue_trapz_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/glue_trapz_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/glue_trapz_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/glue_trapz_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_diag_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_diag_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_diag_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_diag_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -62,11 +64,11 @@ inline Col generate() const; inline Mat generate(const uword N) const; - template inline eT log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk2 = 0) const; - template inline eT log_p(const T1& expr, const uword gaus_id, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk2 = 0) const; + template inline eT log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk2 = nullptr) const; + template inline eT log_p(const T1& expr, const uword gaus_id, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk2 = nullptr) const; - template inline Row log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk2 = 0) const; - template inline Row log_p(const T1& expr, const uword gaus_id, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk2 = 0) const; + template inline Row log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk2 = nullptr) const; + template inline Row log_p(const T1& expr, const uword gaus_id, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk2 = nullptr) const; template inline eT sum_log_p(const Base& expr) const; template inline eT sum_log_p(const Base& expr, const uword gaus_id) const; @@ -74,8 +76,8 @@ template inline eT avg_log_p(const Base& expr) const; template inline eT avg_log_p(const Base& expr, const uword gaus_id) const; - template inline uword assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk = 0) const; - template inline urowvec assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk = 0) const; + template inline uword assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk = nullptr) const; + template inline urowvec assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk = nullptr) const; template inline urowvec raw_hist(const Base& expr, const gmm_dist_mode& dist_mode) const; template inline Row norm_hist(const Base& expr, const gmm_dist_mode& dist_mode) const; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_diag_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_diag_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_diag_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_diag_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -283,7 +285,7 @@ if( (status == false) || (Q.n_slices != 2) ) { reset(); - arma_debug_warn("gmm_diag::load(): problem with loading or incompatible format"); + arma_debug_warn_level(3, "gmm_diag::load(): problem with loading or incompatible format"); return false; } @@ -311,7 +313,7 @@ { arma_extra_debug_sigprint(); - Cube Q(means.n_rows + 1, means.n_cols, 2); + Cube Q(means.n_rows + 1, means.n_cols, 2, arma_nozeros_indicator()); if(Q.n_elem > 0) { @@ -643,7 +645,7 @@ if(acc == eT(0)) { acc = eT(1); } - Row out(hist_n_elem); + Row out(hist_n_elem, arma_nozeros_indicator()); eT* out_mem = out.memptr(); @@ -688,8 +690,8 @@ const unwrap tmp_X(data.get_ref()); const Mat& X = tmp_X.M; - if(X.is_empty() ) { arma_debug_warn("gmm_diag::learn(): given matrix is empty" ); return false; } - if(X.is_finite() == false) { arma_debug_warn("gmm_diag::learn(): given matrix has non-finite values"); return false; } + if(X.is_empty() ) { arma_debug_warn_level(3, "gmm_diag::learn(): given matrix is empty" ); return false; } + if(X.is_finite() == false) { arma_debug_warn_level(3, "gmm_diag::learn(): given matrix has non-finite values"); return false; } if(N_gaus == 0) { reset(); return true; } @@ -718,14 +720,14 @@ if(seed_mode == keep_existing) { - if(means.is_empty() ) { arma_debug_warn("gmm_diag::learn(): no existing means" ); return false; } - if(X.n_rows != means.n_rows) { arma_debug_warn("gmm_diag::learn(): dimensionality mismatch"); return false; } + if(means.is_empty() ) { arma_debug_warn_level(3, "gmm_diag::learn(): no existing means" ); return false; } + if(X.n_rows != means.n_rows) { arma_debug_warn_level(3, "gmm_diag::learn(): dimensionality mismatch"); return false; } // TODO: also check for number of vectors? } else { - if(X.n_cols < N_gaus) { arma_debug_warn("gmm_diag::learn(): number of vectors is less than number of gaussians"); return false; } + if(X.n_cols < N_gaus) { arma_debug_warn_level(3, "gmm_diag::learn(): number of vectors is less than number of gaussians"); return false; } reset(X.n_rows, N_gaus); @@ -749,7 +751,7 @@ stream_state.restore(get_cout_stream()); - if(status == false) { arma_debug_warn("gmm_diag::learn(): k-means algorithm failed; not enough data, or too many gaussians requested"); init(orig); return false; } + if(status == false) { arma_debug_warn_level(3, "gmm_diag::learn(): k-means algorithm failed; not enough data, or too many gaussians requested"); init(orig); return false; } } @@ -776,7 +778,7 @@ stream_state.restore(get_cout_stream()); - if(status == false) { arma_debug_warn("gmm_diag::learn(): EM algorithm failed"); init(orig); return false; } + if(status == false) { arma_debug_warn_level(3, "gmm_diag::learn(): EM algorithm failed"); init(orig); return false; } } mah_aux.reset(); @@ -816,8 +818,8 @@ const unwrap tmp_X(data.get_ref()); const Mat& X = tmp_X.M; - if(X.is_empty() ) { arma_debug_warn("kmeans(): given matrix is empty" ); return false; } - if(X.is_finite() == false) { arma_debug_warn("kmeans(): given matrix has non-finite values"); return false; } + if(X.is_empty() ) { arma_debug_warn_level(3, "kmeans(): given matrix is empty" ); return false; } + if(X.is_finite() == false) { arma_debug_warn_level(3, "kmeans(): given matrix has non-finite values"); return false; } if(N_gaus == 0) { reset(); return true; } @@ -828,14 +830,14 @@ { access::rw(means) = user_means; - if(means.is_empty() ) { arma_debug_warn("kmeans(): no existing means" ); return false; } - if(X.n_rows != means.n_rows) { arma_debug_warn("kmeans(): dimensionality mismatch"); return false; } + if(means.is_empty() ) { arma_debug_warn_level(3, "kmeans(): no existing means" ); return false; } + if(X.n_rows != means.n_rows) { arma_debug_warn_level(3, "kmeans(): dimensionality mismatch"); return false; } // TODO: also check for number of vectors? } else { - if(X.n_cols < N_gaus) { arma_debug_warn("kmeans(): number of vectors is less than number of means"); return false; } + if(X.n_cols < N_gaus) { arma_debug_warn_level(3, "kmeans(): number of vectors is less than number of means"); return false; } access::rw(means).zeros(X.n_rows, N_gaus); @@ -857,7 +859,7 @@ stream_state.restore(get_cout_stream()); - if(status == false) { arma_debug_warn("kmeans(): clustering failed; not enough data, or too many means requested"); return false; } + if(status == false) { arma_debug_warn_level(3, "kmeans(): clustering failed; not enough data, or too many means requested"); return false; } } return true; @@ -970,7 +972,7 @@ // - const eT tmp = (eT(N_dims)/eT(2)) * std::log(eT(2) * Datum::pi); + const eT tmp = (eT(N_dims)/eT(2)) * std::log(Datum::tau); log_det_etc.set_size(N_gaus); @@ -1013,12 +1015,12 @@ const uword n_threads_avail = (omp_in_parallel()) ? uword(1) : uword(omp_get_max_threads()); const uword n_threads = (n_threads_avail > 0) ? ( (n_threads_avail <= N) ? n_threads_avail : 1 ) : 1; #else - static const uword n_threads = 1; + static constexpr uword n_threads = 1; #endif // get_cout_stream() << "gmm_diag::internal_gen_boundaries(): n_threads: " << n_threads << '\n'; - umat boundaries(2, n_threads); + umat boundaries(2, n_threads, arma_nozeros_indicator()); if(N > 0) { @@ -1135,7 +1137,7 @@ const uword N = X.n_cols; - Row out(N); + Row out(N, arma_nozeros_indicator()); if(N > 0) { @@ -1188,7 +1190,7 @@ const uword N = X.n_cols; - Row out(N); + Row out(N, arma_nozeros_indicator()); if(N > 0) { @@ -1249,7 +1251,7 @@ const uword n_threads = boundaries.n_cols; - Col t_accs(n_threads, fill::zeros); + Col t_accs(n_threads, arma_zeros_indicator()); #pragma omp parallel for schedule(static) for(uword t=0; t < n_threads; ++t) @@ -1306,7 +1308,7 @@ const uword n_threads = boundaries.n_cols; - Col t_accs(n_threads, fill::zeros); + Col t_accs(n_threads, arma_zeros_indicator()); #pragma omp parallel for schedule(static) for(uword t=0; t < n_threads; ++t) @@ -1911,10 +1913,10 @@ // as the covariances are calculated via accumulators, // the means also need to be calculated via accumulators to ensure numerical consistency - Mat acc_means(N_dims, N_gaus, fill::zeros); - Mat acc_dcovs(N_dims, N_gaus, fill::zeros); + Mat acc_means(N_dims, N_gaus, arma_zeros_indicator()); + Mat acc_dcovs(N_dims, N_gaus, arma_zeros_indicator()); - Row acc_hefts(N_gaus, fill::zeros); + Row acc_hefts(N_gaus, arma_zeros_indicator()); uword* acc_hefts_mem = acc_hefts.memptr(); @@ -2072,9 +2074,9 @@ const eT* mah_aux_mem = mah_aux.memptr(); - Mat acc_means(N_dims, N_gaus, fill::zeros); - Row acc_hefts(N_gaus, fill::zeros); - Row last_indx(N_gaus, fill::zeros); + Mat acc_means(N_dims, N_gaus, arma_zeros_indicator()); + Row acc_hefts( N_gaus, arma_zeros_indicator()); + Row last_indx( N_gaus, arma_zeros_indicator()); Mat new_means = means; Mat old_means = means; @@ -2314,7 +2316,7 @@ field< Col > t_acc_norm_lhoods(n_threads); field< Col > t_gaus_log_lhoods(n_threads); - Col t_progress_log_lhood(n_threads); + Col t_progress_log_lhood(n_threads, arma_nozeros_indicator()); for(uword t=0; t generate() const; inline Mat generate(const uword N) const; - template inline eT log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk2 = 0) const; - template inline eT log_p(const T1& expr, const uword gaus_id, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk2 = 0) const; + template inline eT log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk2 = nullptr) const; + template inline eT log_p(const T1& expr, const uword gaus_id, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk2 = nullptr) const; - template inline Row log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk2 = 0) const; - template inline Row log_p(const T1& expr, const uword gaus_id, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk2 = 0) const; + template inline Row log_p(const T1& expr, const gmm_empty_arg& junk1 = gmm_empty_arg(), typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk2 = nullptr) const; + template inline Row log_p(const T1& expr, const uword gaus_id, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk2 = nullptr) const; template inline eT sum_log_p(const Base& expr) const; template inline eT sum_log_p(const Base& expr, const uword gaus_id) const; @@ -74,8 +76,8 @@ template inline eT avg_log_p(const Base& expr) const; template inline eT avg_log_p(const Base& expr, const uword gaus_id) const; - template inline uword assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk = 0) const; - template inline urowvec assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk = 0) const; + template inline uword assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == true ))>::result* junk = nullptr) const; + template inline urowvec assign(const T1& expr, const gmm_dist_mode& dist, typename enable_if<((is_arma_type::value) && (resolves_to_colvector::value == false))>::result* junk = nullptr) const; template inline urowvec raw_hist(const Base& expr, const gmm_dist_mode& dist_mode) const; template inline Row norm_hist(const Base& expr, const gmm_dist_mode& dist_mode) const; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_full_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_full_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_full_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_full_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -291,7 +293,7 @@ if( (status == false) || (storage.n_elem < 2) ) { reset(); - arma_debug_warn("gmm_full::load(): problem with loading or incompatible format"); + arma_debug_warn_level(3, "gmm_full::load(): problem with loading or incompatible format"); return false; } @@ -306,7 +308,7 @@ if( (storage.n_elem != (N_gaus + 2)) || (storage_hefts.n_rows != 1) || (storage_hefts.n_cols != N_gaus) ) { reset(); - arma_debug_warn("gmm_full::load(): incompatible format"); + arma_debug_warn_level(3, "gmm_full::load(): incompatible format"); return false; } @@ -322,7 +324,7 @@ if( (storage_fcov.n_rows != N_dims) || (storage_fcov.n_cols != N_dims) ) { reset(); - arma_debug_warn("gmm_full::load(): incompatible format"); + arma_debug_warn_level(3, "gmm_full::load(): incompatible format"); return false; } @@ -374,8 +376,8 @@ const uword N_dims = means.n_rows; const uword N_gaus = means.n_cols; - Col out( (N_gaus > 0) ? N_dims : uword(0) ); - Col tmp( (N_gaus > 0) ? N_dims : uword(0), fill::randn ); + Col out( (N_gaus > 0) ? N_dims : uword(0), arma_nozeros_indicator() ); + Col tmp( (N_gaus > 0) ? N_dims : uword(0), fill::randn ); if(N_gaus > 0) { @@ -410,8 +412,8 @@ const uword N_dims = means.n_rows; const uword N_gaus = means.n_cols; - Mat out( ( (N_gaus > 0) ? N_dims : uword(0) ), N_vec ); - Mat tmp( ( (N_gaus > 0) ? N_dims : uword(0) ), N_vec, fill::randn ); + Mat out( ( (N_gaus > 0) ? N_dims : uword(0) ), N_vec, arma_nozeros_indicator() ); + Mat tmp( ( (N_gaus > 0) ? N_dims : uword(0) ), N_vec, fill::randn ); if(N_gaus > 0) { @@ -682,7 +684,7 @@ if(acc == eT(0)) { acc = eT(1); } - Row out(hist_n_elem); + Row out(hist_n_elem, arma_nozeros_indicator()); eT* out_mem = out.memptr(); @@ -727,8 +729,8 @@ const unwrap tmp_X(data.get_ref()); const Mat& X = tmp_X.M; - if(X.is_empty() ) { arma_debug_warn("gmm_full::learn(): given matrix is empty" ); return false; } - if(X.is_finite() == false) { arma_debug_warn("gmm_full::learn(): given matrix has non-finite values"); return false; } + if(X.is_empty() ) { arma_debug_warn_level(3, "gmm_full::learn(): given matrix is empty" ); return false; } + if(X.is_finite() == false) { arma_debug_warn_level(3, "gmm_full::learn(): given matrix has non-finite values"); return false; } if(N_gaus == 0) { reset(); return true; } @@ -757,14 +759,14 @@ if(seed_mode == keep_existing) { - if(means.is_empty() ) { arma_debug_warn("gmm_full::learn(): no existing means" ); return false; } - if(X.n_rows != means.n_rows) { arma_debug_warn("gmm_full::learn(): dimensionality mismatch"); return false; } + if(means.is_empty() ) { arma_debug_warn_level(3, "gmm_full::learn(): no existing means" ); return false; } + if(X.n_rows != means.n_rows) { arma_debug_warn_level(3, "gmm_full::learn(): dimensionality mismatch"); return false; } // TODO: also check for number of vectors? } else { - if(X.n_cols < N_gaus) { arma_debug_warn("gmm_full::learn(): number of vectors is less than number of gaussians"); return false; } + if(X.n_cols < N_gaus) { arma_debug_warn_level(3, "gmm_full::learn(): number of vectors is less than number of gaussians"); return false; } reset(X.n_rows, N_gaus); @@ -788,7 +790,7 @@ stream_state.restore(get_cout_stream()); - if(status == false) { arma_debug_warn("gmm_full::learn(): k-means algorithm failed; not enough data, or too many gaussians requested"); init(orig); return false; } + if(status == false) { arma_debug_warn_level(3, "gmm_full::learn(): k-means algorithm failed; not enough data, or too many gaussians requested"); init(orig); return false; } } @@ -815,7 +817,7 @@ stream_state.restore(get_cout_stream()); - if(status == false) { arma_debug_warn("gmm_full::learn(): EM algorithm failed"); init(orig); return false; } + if(status == false) { arma_debug_warn_level(3, "gmm_full::learn(): EM algorithm failed"); init(orig); return false; } } mah_aux.reset(); @@ -920,7 +922,7 @@ const uword N_dims = means.n_rows; const uword N_gaus = means.n_cols; - const eT tmp = (eT(N_dims)/eT(2)) * std::log(eT(2) * Datum::pi); + const eT tmp = (eT(N_dims)/eT(2)) * std::log(Datum::tau); // @@ -940,9 +942,9 @@ eT log_det_val = eT(0); eT log_det_sign = eT(0); - log_det(log_det_val, log_det_sign, fcov); + const bool log_det_status = log_det(log_det_val, log_det_sign, fcov); - const bool log_det_ok = ( (arma_isfinite(log_det_val)) && (log_det_sign > eT(0)) ); + const bool log_det_ok = ( log_det_status && (arma_isfinite(log_det_val)) && (log_det_sign > eT(0)) ); if(inv_ok && log_det_ok) { @@ -1030,12 +1032,12 @@ const uword n_threads_avail = uword(omp_get_max_threads()); const uword n_threads = (n_threads_avail > 0) ? ( (n_threads_avail <= N) ? n_threads_avail : 1 ) : 1; #else - static const uword n_threads = 1; + static constexpr uword n_threads = 1; #endif // get_cout_stream() << "gmm_full::internal_gen_boundaries(): n_threads: " << n_threads << '\n'; - umat boundaries(2, n_threads); + umat boundaries(2, n_threads, arma_nozeros_indicator()); if(N > 0) { @@ -1143,7 +1145,7 @@ arma_debug_check( (X.n_rows != N_dims), "gmm_full::log_p(): incompatible dimensions" ); - Row out(N_samples); + Row out(N_samples, arma_nozeros_indicator()); if(N_samples > 0) { @@ -1197,7 +1199,7 @@ arma_debug_check( (X.n_rows != N_dims), "gmm_full::log_p(): incompatible dimensions" ); arma_debug_check( (gaus_id >= means.n_cols), "gmm_full::log_p(): specified gaussian is out of range" ); - Row out(N_samples); + Row out(N_samples, arma_nozeros_indicator()); if(N_samples > 0) { @@ -1258,7 +1260,7 @@ const uword n_threads = boundaries.n_cols; - Col t_accs(n_threads, fill::zeros); + Col t_accs(n_threads, arma_zeros_indicator()); #pragma omp parallel for schedule(static) for(uword t=0; t < n_threads; ++t) @@ -1315,7 +1317,7 @@ const uword n_threads = boundaries.n_cols; - Col t_accs(n_threads, fill::zeros); + Col t_accs(n_threads, arma_zeros_indicator()); #pragma omp parallel for schedule(static) for(uword t=0; t < n_threads; ++t) @@ -1938,10 +1940,10 @@ // as the covariances are calculated via accumulators, // the means also need to be calculated via accumulators to ensure numerical consistency - Mat acc_means(N_dims, N_gaus, fill::zeros); - Mat acc_dcovs(N_dims, N_gaus, fill::zeros); + Mat acc_means(N_dims, N_gaus); + Mat acc_dcovs(N_dims, N_gaus); - Row acc_hefts(N_gaus, fill::zeros); + Row acc_hefts(N_gaus, arma_zeros_indicator()); uword* acc_hefts_mem = acc_hefts.memptr(); @@ -2101,9 +2103,9 @@ const eT* mah_aux_mem = mah_aux.memptr(); - Mat acc_means(N_dims, N_gaus, fill::zeros); - Row acc_hefts(N_gaus, fill::zeros); - Row last_indx(N_gaus, fill::zeros); + Mat acc_means(N_dims, N_gaus, arma_zeros_indicator()); + Row acc_hefts( N_gaus, arma_zeros_indicator()); + Row last_indx( N_gaus, arma_zeros_indicator()); Mat new_means = means; Mat old_means = means; @@ -2341,7 +2343,7 @@ field< Col > t_acc_norm_lhoods(n_threads); field< Col > t_gaus_log_lhoods(n_threads); - Col t_progress_log_lhood(n_threads); + Col t_progress_log_lhood(n_threads, arma_nozeros_indicator()); for(uword t=0; t mean_outer(N_dims, N_dims); + Mat mean_outer(N_dims, N_dims, arma_nozeros_indicator()); //// update each component without sanity checking @@ -2540,9 +2542,9 @@ eT log_det_val = eT(0); eT log_det_sign = eT(0); - log_det(log_det_val, log_det_sign, acc_fcov); + const bool log_det_status = log_det(log_det_val, log_det_sign, acc_fcov); - const bool log_det_ok = ( (arma_isfinite(log_det_val)) && (log_det_sign > eT(0)) ); + const bool log_det_ok = ( log_det_status && (arma_isfinite(log_det_val)) && (log_det_sign > eT(0)) ); const bool inv_ok = (log_det_ok) ? bool(auxlib::inv_sympd(mean_outer, acc_fcov)) : bool(false); // mean_outer is used as a junk matrix diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_misc_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_misc_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_misc_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_misc_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -99,7 +101,7 @@ template struct distance { - arma_inline arma_hot static eT eval(const uword N, const eT* A, const eT* B, const eT*); + arma_inline static eT eval(const uword N, const eT* A, const eT* B, const eT*); }; @@ -107,7 +109,7 @@ template struct distance { - arma_inline arma_hot static eT eval(const uword N, const eT* A, const eT* B, const eT* C); + arma_inline static eT eval(const uword N, const eT* A, const eT* B, const eT* C); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_misc_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_misc_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/gmm_misc_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_misc_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -124,7 +126,6 @@ template arma_inline -arma_hot eT distance::eval(const uword N, const eT* A, const eT* B, const eT*) { @@ -158,7 +159,6 @@ template arma_inline -arma_hot eT distance::eval(const uword N, const eT* A, const eT* B, const eT* C) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/hdf5_misc.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/hdf5_misc.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/hdf5_misc.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/hdf5_misc.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -103,25 +105,21 @@ return arma_H5Tcopy(arma_H5T_NATIVE_ULONG); } +template<> +inline +hid_t +get_hdf5_type< long long >() + { + return arma_H5Tcopy(arma_H5T_NATIVE_LLONG); + } -#if defined(ARMA_USE_U64S64) && defined(ULLONG_MAX) - template<> - inline - hid_t - get_hdf5_type< long long >() - { - return arma_H5Tcopy(arma_H5T_NATIVE_LLONG); - } - - template<> - inline - hid_t - get_hdf5_type< unsigned long long >() - { - return arma_H5Tcopy(arma_H5T_NATIVE_ULLONG); - } -#endif - +template<> +inline +hid_t +get_hdf5_type< unsigned long long >() + { + return arma_H5Tcopy(arma_H5T_NATIVE_ULLONG); + } template<> inline @@ -196,22 +194,22 @@ search_type = get_hdf5_type(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } search_type = get_hdf5_type< std::complex >(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } search_type = get_hdf5_type(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } search_type = get_hdf5_type< std::complex >(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } // remaining supported types: u8, s8, u16, s16, u32, s32, u64, s64, ulng_t, slng_t @@ -219,60 +217,52 @@ search_type = get_hdf5_type(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } search_type = get_hdf5_type(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } search_type = get_hdf5_type(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } search_type = get_hdf5_type(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } search_type = get_hdf5_type(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } search_type = get_hdf5_type(); is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); arma_H5Tclose(search_type); - if (is_equal) { return true; } + if(is_equal) { return true; } - #if defined(ARMA_USE_U64S64) - { - search_type = get_hdf5_type(); - is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); - arma_H5Tclose(search_type); - if (is_equal) { return true; } - - search_type = get_hdf5_type(); - is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); - arma_H5Tclose(search_type); - if (is_equal) { return true; } - } - #endif - - #if defined(ARMA_ALLOW_LONG) - { - search_type = get_hdf5_type(); - is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); - arma_H5Tclose(search_type); - if (is_equal) { return true; } - - search_type = get_hdf5_type(); - is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); - arma_H5Tclose(search_type); - if (is_equal) { return true; } - } - #endif + search_type = get_hdf5_type(); + is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); + arma_H5Tclose(search_type); + if(is_equal) { return true; } + + search_type = get_hdf5_type(); + is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); + arma_H5Tclose(search_type); + if(is_equal) { return true; } + + search_type = get_hdf5_type(); + is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); + arma_H5Tclose(search_type); + if(is_equal) { return true; } + + search_type = get_hdf5_type(); + is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); + arma_H5Tclose(search_type); + if(is_equal) { return true; } return false; } @@ -304,7 +294,7 @@ hdf5_search_info* search_info = (hdf5_search_info*) operator_data; // We are looking for datasets. - if (info->type == H5O_TYPE_DATASET) + if(info->type == H5O_TYPE_DATASET) { // Check type of dataset to see if we could even load it. hid_t dataset = arma_H5Dopen(loc_id, name, H5P_DEFAULT); @@ -323,7 +313,7 @@ // Now we have to check against our set of names. // Only check names which could be better. - for (size_t string_pos = 0; string_pos < search_info->best_match_position; ++string_pos) + for(size_t string_pos = 0; string_pos < search_info->best_match_position; ++string_pos) { // name is the full path (/path/to/dataset); names[string_pos] may be // "dataset", "/to/dataset", or "/path/to/dataset". @@ -333,26 +323,26 @@ // Count the number of forward slashes in names[string_pos]. uword name_count = 0; - for (uword i = 0; i < search_info->names[string_pos].length(); ++i) + for(uword i = 0; i < search_info->names[string_pos].length(); ++i) { - if ((search_info->names[string_pos])[i] == '/') { ++name_count; } + if((search_info->names[string_pos])[i] == '/') { ++name_count; } } // Count the number of forward slashes in the full name. uword count = 0; const std::string str = std::string(name); - for (uword i = 0; i < str.length(); ++i) + for(uword i = 0; i < str.length(); ++i) { - if (str[i] == '/') { ++count; } + if(str[i] == '/') { ++count; } } // Is the full string the same? - if (str == search_info->names[string_pos]) + if(str == search_info->names[string_pos]) { // We found it exactly. hid_t match_candidate = arma_H5Dopen(loc_id, name, H5P_DEFAULT); - if (match_candidate < 0) + if(match_candidate < 0) { return -1; } @@ -361,11 +351,11 @@ hid_t filespace = arma_H5Dget_space(match_candidate); int num_dims = arma_H5Sget_simple_extent_ndims(filespace); - if (num_dims <= search_info->num_dims) + if(num_dims <= search_info->num_dims) { // Valid dataset -- we'll keep it. // If we already have an existing match we have to close it. - if (search_info->best_match != -1) + if(search_info->best_match != -1) { arma_H5Dclose(search_info->best_match); } @@ -382,16 +372,16 @@ // If we are asking for more slashes than we have, this can't be a match. // Skip to below, where we decide whether or not to keep it anyway based // on the exactness condition of the search. - if (count <= name_count) + if(count <= name_count) { size_t start_pos = (count == 0) ? 0 : std::string::npos; - while (count > 0) + while(count > 0) { // Move pointer to previous slash. start_pos = str.rfind('/', start_pos); // Break if we've run out of slashes. - if (start_pos == std::string::npos) { break; } + if(start_pos == std::string::npos) { break; } --count; } @@ -400,7 +390,7 @@ const std::string substring = str.substr(start_pos); // Are they the same? - if (substring == search_info->names[string_pos]) + if(substring == search_info->names[string_pos]) { // We have found the object; it must be better than our existing match. hid_t match_candidate = arma_H5Dopen(loc_id, name, H5P_DEFAULT); @@ -417,11 +407,11 @@ hid_t filespace = arma_H5Dget_space(match_candidate); int num_dims = arma_H5Sget_simple_extent_ndims(filespace); - if (num_dims <= search_info->num_dims) + if(num_dims <= search_info->num_dims) { // Valid dataset -- we'll keep it. // If we already have an existing match we have to close it. - if (search_info->best_match != -1) + if(search_info->best_match != -1) { arma_H5Dclose(search_info->best_match); } @@ -436,7 +426,7 @@ // If they are not the same, but we have not found anything and we don't need an exact match, take this. - if ((search_info->exact == false) && (search_info->best_match == -1)) + if((search_info->exact == false) && (search_info->best_match == -1)) { hid_t match_candidate = arma_H5Dopen(loc_id, name, H5P_DEFAULT); @@ -449,7 +439,7 @@ hid_t filespace = arma_H5Dget_space(match_candidate); int num_dims = arma_H5Sget_simple_extent_ndims(filespace); - if (num_dims <= search_info->num_dims) + if(num_dims <= search_info->num_dims) { // Valid dataset -- we'll keep it. search_info->best_match = arma_H5Dopen(loc_id, name, H5P_DEFAULT); @@ -523,7 +513,7 @@ if(is_equal) { - Col v(n_elem); + Col v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); @@ -538,7 +528,7 @@ if(is_equal) { - Col v(n_elem); + Col v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); @@ -553,7 +543,7 @@ if(is_equal) { - Col v(n_elem); + Col v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); @@ -568,7 +558,7 @@ if(is_equal) { - Col v(n_elem); + Col v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); @@ -583,7 +573,7 @@ if(is_equal) { - Col v(n_elem); + Col v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); @@ -598,7 +588,7 @@ if(is_equal) { - Col v(n_elem); + Col v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); @@ -606,72 +596,64 @@ } - #if defined(ARMA_USE_U64S64) + // u64 + search_type = get_hdf5_type(); + is_equal = (arma_H5Tequal(datatype, search_type) > 0); + arma_H5Tclose(search_type); + + if(is_equal) { - // u64 - search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); - - if(is_equal) - { - Col v(n_elem); - hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); - arrayops::convert(dest, v.memptr(), n_elem); + Col v(n_elem, arma_nozeros_indicator()); + hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); + arrayops::convert(dest, v.memptr(), n_elem); - return status; - } - - - // s64 - search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); - - if(is_equal) - { - Col v(n_elem); - hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); - arrayops::convert(dest, v.memptr(), n_elem); + return status; + } + + + // s64 + search_type = get_hdf5_type(); + is_equal = (arma_H5Tequal(datatype, search_type) > 0); + arma_H5Tclose(search_type); + + if(is_equal) + { + Col v(n_elem, arma_nozeros_indicator()); + hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); + arrayops::convert(dest, v.memptr(), n_elem); - return status; - } + return status; } - #endif - #if defined(ARMA_ALLOW_LONG) + // ulng_t + search_type = get_hdf5_type(); + is_equal = (arma_H5Tequal(datatype, search_type) > 0); + arma_H5Tclose(search_type); + + if(is_equal) { - // ulng_t - search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); - - if(is_equal) - { - Col v(n_elem); - hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); - arrayops::convert(dest, v.memptr(), n_elem); + Col v(n_elem, arma_nozeros_indicator()); + hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); + arrayops::convert(dest, v.memptr(), n_elem); - return status; - } - - - // slng_t - search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); - - if(is_equal) - { - Col v(n_elem); - hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); - arrayops::convert(dest, v.memptr(), n_elem); + return status; + } + + + // slng_t + search_type = get_hdf5_type(); + is_equal = (arma_H5Tequal(datatype, search_type) > 0); + arma_H5Tclose(search_type); + + if(is_equal) + { + Col v(n_elem, arma_nozeros_indicator()); + hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); + arrayops::convert(dest, v.memptr(), n_elem); - return status; - } + return status; } - #endif // float @@ -681,7 +663,7 @@ if(is_equal) { - Col v(n_elem); + Col v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); @@ -696,7 +678,7 @@ if(is_equal) { - Col v(n_elem); + Col v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); @@ -716,7 +698,7 @@ return -1; // can't read complex data into non-complex matrix/cube } - Col< std::complex > v(n_elem); + Col< std::complex > v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert_cx(dest, v.memptr(), n_elem); @@ -736,7 +718,7 @@ return -1; // can't read complex data into non-complex matrix/cube } - Col< std::complex > v(n_elem); + Col< std::complex > v(n_elem, arma_nozeros_indicator()); hid_t status = arma_H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert_cx(dest, v.memptr(), n_elem); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/hdf5_name.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/hdf5_name.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/hdf5_name.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/hdf5_name.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup diskio +//! @{ + + +namespace hdf5_opts + { + typedef unsigned int flag_type; + + struct opts + { + const flag_type flags; + + inline explicit opts(const flag_type in_flags); + + inline const opts operator+(const opts& rhs) const; + }; + + inline + opts::opts(const flag_type in_flags) + : flags(in_flags) + {} + + inline + const opts + opts::operator+(const opts& rhs) const + { + const opts result( flags | rhs.flags ); + + return result; + } + + // The values below (eg. 1u << 0) are for internal Armadillo use only. + // The values can change without notice. + + static const flag_type flag_none = flag_type(0 ); + static const flag_type flag_trans = flag_type(1u << 0); + static const flag_type flag_append = flag_type(1u << 1); + static const flag_type flag_replace = flag_type(1u << 2); + + struct opts_none : public opts { inline opts_none() : opts(flag_none ) {} }; + struct opts_trans : public opts { inline opts_trans() : opts(flag_trans ) {} }; + struct opts_append : public opts { inline opts_append() : opts(flag_append ) {} }; + struct opts_replace : public opts { inline opts_replace() : opts(flag_replace) {} }; + + static const opts_none none; + static const opts_trans trans; + static const opts_append append; + static const opts_replace replace; + } + + +struct hdf5_name + { + const std::string filename; + const std::string dsname; + const hdf5_opts::opts opts; + + inline + hdf5_name(const std::string& in_filename) + : filename(in_filename ) + , dsname (std::string() ) + , opts (hdf5_opts::none) + {} + + inline + hdf5_name(const std::string& in_filename, const std::string& in_dsname, const hdf5_opts::opts& in_opts = hdf5_opts::none) + : filename(in_filename) + , dsname (in_dsname ) + , opts (in_opts ) + {} + }; + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/include_atlas.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/include_atlas.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/include_atlas.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/include_atlas.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/include_hdf5.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/include_hdf5.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/include_hdf5.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/include_hdf5.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -15,6 +17,10 @@ #if defined(ARMA_USE_HDF5) + + #undef H5_USE_110_API + #define H5_USE_110_API + #if !defined(ARMA_HDF5_INCLUDE_DIR) #include #else diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/include_superlu.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/include_superlu.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/include_superlu.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/include_superlu.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/injector_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/injector_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/injector_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/injector_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -24,9 +26,9 @@ { public: - inline mat_injector_row(); + arma_cold inline mat_injector_row(); - inline void insert(const eT val) const; + arma_cold inline void insert(const eT val) const; mutable uword n_cols; mutable podarray A; @@ -42,15 +44,15 @@ typedef typename T1::elem_type elem_type; - inline void insert(const elem_type val) const; - inline void end_of_row() const; - inline ~mat_injector(); + arma_cold inline void insert(const elem_type val) const; + arma_cold inline void end_of_row() const; + arma_cold inline ~mat_injector(); private: - inline mat_injector(T1& in_X, const elem_type val); - inline mat_injector(T1& in_X, const injector_end_of_row<>& x); + arma_cold inline mat_injector(T1& in_X, const elem_type val); + arma_cold inline mat_injector(T1& in_X, const injector_end_of_row<>& x); T1& X; mutable uword n_rows; @@ -74,10 +76,10 @@ { public: - inline field_injector_row(); - inline ~field_injector_row(); + arma_cold inline field_injector_row(); + arma_cold inline ~field_injector_row(); - inline void insert(const oT& val) const; + arma_cold inline void insert(const oT& val) const; mutable uword n_cols; mutable field* AA; @@ -93,15 +95,15 @@ typedef typename T1::object_type object_type; - inline void insert(const object_type& val) const; - inline void end_of_row() const; - inline ~field_injector(); + arma_cold inline void insert(const object_type& val) const; + arma_cold inline void end_of_row() const; + arma_cold inline ~field_injector(); private: - inline field_injector(T1& in_X, const object_type& val); - inline field_injector(T1& in_X, const injector_end_of_row<>& x); + arma_cold inline field_injector(T1& in_X, const object_type& val); + arma_cold inline field_injector(T1& in_X, const injector_end_of_row<>& x); T1& X; mutable uword n_rows; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/injector_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/injector_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/injector_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/injector_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,6 +22,7 @@ template +arma_cold inline mat_injector_row::mat_injector_row() : n_cols(0) @@ -32,6 +35,7 @@ template +arma_cold inline void mat_injector_row::insert(const eT val) const @@ -66,6 +70,7 @@ template +arma_cold inline mat_injector::mat_injector(T1& in_X, const typename mat_injector::elem_type val) : X(in_X) @@ -93,6 +98,7 @@ template +arma_cold inline mat_injector::mat_injector(T1& in_X, const injector_end_of_row<>& x) : X(in_X) @@ -121,6 +127,7 @@ template +arma_cold inline mat_injector::~mat_injector() { @@ -146,7 +153,7 @@ const uword max_n_rows = ((*(A[n_rows-1])).n_cols == 0) ? n_rows-1 : n_rows; - if(is_Mat_only::value == true) + if(is_Mat_only::value) { X.set_size(max_n_rows, max_n_cols); @@ -166,7 +173,7 @@ } } else - if(is_Row::value == true) + if(is_Row::value) { arma_debug_check( (max_n_rows > 1), "matrix initialisation: incompatible dimensions" ); @@ -177,7 +184,7 @@ arrayops::copy( X.memptr(), (*(A[0])).A.memptr(), n_cols ); } else - if(is_Col::value == true) + if(is_Col::value) { const bool is_vec = ( (max_n_rows == 1) || (max_n_cols == 1) ); @@ -219,6 +226,7 @@ template +arma_cold inline void mat_injector::insert(const typename mat_injector::elem_type val) const @@ -236,6 +244,7 @@ template +arma_cold inline void mat_injector::end_of_row() const @@ -264,7 +273,7 @@ template -arma_inline +arma_cold const mat_injector& operator<<(const mat_injector& ref, const typename mat_injector::elem_type val) { @@ -278,7 +287,7 @@ template -arma_inline +arma_cold const mat_injector& operator<<(const mat_injector& ref, const injector_end_of_row<>& x) { @@ -293,7 +302,7 @@ //// using a mixture of operator << and , doesn't work yet -//// e.g. A << 1, 2, 3 << endr +//// eg. A << 1, 2, 3 << endr //// in the above "3 << endr" requires special handling. //// similarly, special handling is necessary for "endr << 3" //// @@ -334,6 +343,7 @@ template +arma_cold inline field_injector_row::field_injector_row() : n_cols(0) @@ -351,6 +361,7 @@ template +arma_cold inline field_injector_row::~field_injector_row() { @@ -363,6 +374,7 @@ template +arma_cold inline void field_injector_row::insert(const oT& val) const @@ -401,6 +413,7 @@ template +arma_cold inline field_injector::field_injector(T1& in_X, const typename field_injector::object_type& val) : X(in_X) @@ -428,6 +441,7 @@ template +arma_cold inline field_injector::field_injector(T1& in_X, const injector_end_of_row<>& x) : X(in_X) @@ -456,6 +470,7 @@ template +arma_cold inline field_injector::~field_injector() { @@ -513,6 +528,7 @@ template +arma_cold inline void field_injector::insert(const typename field_injector::object_type& val) const @@ -530,6 +546,7 @@ template +arma_cold inline void field_injector::end_of_row() const @@ -561,7 +578,7 @@ template -arma_inline +arma_cold const field_injector& operator<<(const field_injector& ref, const typename field_injector::object_type& val) { @@ -575,7 +592,7 @@ template -arma_inline +arma_cold const field_injector& operator<<(const field_injector& ref, const injector_end_of_row<>& x) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/MapMat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/MapMat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/MapMat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/MapMat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,9 +30,9 @@ typedef eT elem_type; //!< the type of elements stored in the matrix typedef typename get_pod_type::result pod_type; //!< if eT is std::complex, pod_type is T; otherwise pod_type is eT - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; const uword n_rows; //!< number of rows (read-only) const uword n_cols; //!< number of columns (read-only) @@ -58,10 +60,8 @@ inline explicit MapMat(const SpMat& x); inline void operator=(const SpMat& x); - #if defined(ARMA_USE_CXX11) inline MapMat(MapMat&& x); inline void operator=(MapMat&& x); - #endif inline void reset(); inline void set_size(const uword in_n_rows); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/MapMat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/MapMat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/MapMat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/MapMat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,7 +30,7 @@ if(map_ptr) { (*map_ptr).clear(); delete map_ptr; } // try to expose buggy user code that accesses deleted objects - if(arma_config::debug) { map_ptr = NULL; } + if(arma_config::debug) { map_ptr = nullptr; } arma_type_check(( is_supported_elem_type::value == false )); } @@ -41,7 +43,7 @@ : n_rows (0) , n_cols (0) , n_elem (0) - , map_ptr(NULL) + , map_ptr(nullptr) { arma_extra_debug_sigprint_this(this); @@ -56,7 +58,7 @@ : n_rows (in_n_rows) , n_cols (in_n_cols) , n_elem (in_n_rows * in_n_cols) - , map_ptr(NULL) + , map_ptr(nullptr) { arma_extra_debug_sigprint_this(this); @@ -71,7 +73,7 @@ : n_rows (s.n_rows) , n_cols (s.n_cols) , n_elem (s.n_rows * s.n_cols) - , map_ptr(NULL) + , map_ptr(nullptr) { arma_extra_debug_sigprint_this(this); @@ -86,7 +88,7 @@ : n_rows (0) , n_cols (0) , n_elem (0) - , map_ptr(NULL) + , map_ptr(nullptr) { arma_extra_debug_sigprint_this(this); @@ -121,7 +123,7 @@ : n_rows (0) , n_cols (0) , n_elem (0) - , map_ptr(NULL) + , map_ptr(nullptr) { arma_extra_debug_sigprint_this(this); @@ -164,60 +166,52 @@ const uword index = (x_n_rows * col) + row; - #if defined(ARMA_USE_CXX11) - map_ref.emplace_hint(map_ref.cend(), index, val); - #else - map_ref.operator[](index) = val; - #endif + map_ref.emplace_hint(map_ref.cend(), index, val); } } } -#if defined(ARMA_USE_CXX11) +template +inline +MapMat::MapMat(MapMat&& x) + : n_rows (x.n_rows ) + , n_cols (x.n_cols ) + , n_elem (x.n_elem ) + , map_ptr(x.map_ptr) + { + arma_extra_debug_sigprint_this(this); + + access::rw(x.n_rows) = 0; + access::rw(x.n_cols) = 0; + access::rw(x.n_elem) = 0; + access::rw(x.map_ptr) = nullptr; + } + + - template - inline - MapMat::MapMat(MapMat&& x) - : n_rows (x.n_rows ) - , n_cols (x.n_cols ) - , n_elem (x.n_elem ) - , map_ptr(x.map_ptr) - { - arma_extra_debug_sigprint_this(this); - - access::rw(x.n_rows) = 0; - access::rw(x.n_cols) = 0; - access::rw(x.n_elem) = 0; - access::rw(x.map_ptr) = NULL; - } +template +inline +void +MapMat::operator=(MapMat&& x) + { + arma_extra_debug_sigprint(); + reset(); + if(map_ptr) { delete map_ptr; } - template - inline - void - MapMat::operator=(MapMat&& x) - { - arma_extra_debug_sigprint(); - - reset(); - - if(map_ptr) { delete map_ptr; } - - access::rw(n_rows) = x.n_rows; - access::rw(n_cols) = x.n_cols; - access::rw(n_elem) = x.n_elem; - access::rw(map_ptr) = x.map_ptr; - - access::rw(x.n_rows) = 0; - access::rw(x.n_cols) = 0; - access::rw(x.n_elem) = 0; - access::rw(x.map_ptr) = NULL; - } - -#endif + access::rw(n_rows) = x.n_rows; + access::rw(n_cols) = x.n_cols; + access::rw(n_elem) = x.n_elem; + access::rw(map_ptr) = x.map_ptr; + + access::rw(x.n_rows) = 0; + access::rw(x.n_cols) = 0; + access::rw(x.n_elem) = 0; + access::rw(x.map_ptr) = nullptr; + } @@ -356,11 +350,7 @@ { const uword index = (in_n_rows * i) + i; - #if defined(ARMA_USE_CXX11) - map_ref.emplace_hint(map_ref.cend(), index, eT(1)); - #else - map_ref.operator[](index) = eT(1); - #endif + map_ref.emplace_hint(map_ref.cend(), index, eT(1)); } } @@ -447,7 +437,7 @@ MapMat_val MapMat::operator()(const uword index) { - arma_debug_check( (index >= n_elem), "MapMat::operator(): index out of bounds" ); + arma_debug_check_bounds( (index >= n_elem), "MapMat::operator(): index out of bounds" ); return MapMat_val(*this, index); } @@ -460,7 +450,7 @@ eT MapMat::operator()(const uword index) const { - arma_debug_check( (index >= n_elem), "MapMat::operator(): index out of bounds" ); + arma_debug_check_bounds( (index >= n_elem), "MapMat::operator(): index out of bounds" ); map_type& map_ref = (*map_ptr); @@ -509,7 +499,7 @@ MapMat_val MapMat::operator()(const uword in_row, const uword in_col) { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" ); const uword index = (n_rows * in_col) + in_row; @@ -524,7 +514,7 @@ eT MapMat::operator()(const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" ); const uword index = (n_rows * in_col) + in_row; @@ -619,11 +609,7 @@ const uword index = indx_mem[i]; const eT val = vals_mem[i]; - #if defined(ARMA_USE_CXX11) - map_ref.emplace_hint(map_ref.cend(), index, val); - #else - map_ref.operator[](index) = val; - #endif + map_ref.emplace_hint(map_ref.cend(), index, val); } } @@ -744,10 +730,10 @@ // ensure that n_elem can hold the result of (n_rows * n_cols) - #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD)) + #if defined(ARMA_64BIT_WORD) const char* error_message = "MapMat(): requested size is too large"; #else - const char* error_message = "MapMat(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD"; + const char* error_message = "MapMat(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_check @@ -762,7 +748,7 @@ map_ptr = new (std::nothrow) map_type; - arma_check_bad_alloc( (map_ptr == NULL), "MapMat(): out of memory" ); + arma_check_bad_alloc( (map_ptr == nullptr), "MapMat(): out of memory" ); } @@ -778,10 +764,10 @@ // ensure that n_elem can hold the result of (n_rows * n_cols) - #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD)) + #if defined(ARMA_64BIT_WORD) const char* error_message = "MapMat(): requested size is too large"; #else - const char* error_message = "MapMat(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD"; + const char* error_message = "MapMat(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_check @@ -814,24 +800,16 @@ if(in_val != eT(0)) { - #if defined(ARMA_USE_CXX11) + map_type& map_ref = (*map_ptr); + + if( (map_ref.empty() == false) && (index > uword(map_ref.crbegin()->first)) ) { - map_type& map_ref = (*map_ptr); - - if( (map_ref.empty() == false) && (index > uword(map_ref.crbegin()->first)) ) - { - map_ref.emplace_hint(map_ref.cend(), index, in_val); - } - else - { - map_ref.operator[](index) = in_val; - } + map_ref.emplace_hint(map_ref.cend(), index, in_val); } - #else + else { - (*map_ptr).operator[](index) = in_val; + map_ref.operator[](index) = in_val; } - #endif } else { @@ -1204,7 +1182,7 @@ (*this).set(in_val); } } - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { s_parent.cache_mutex.lock(); @@ -1239,7 +1217,7 @@ (*this).add(in_val); } } - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { s_parent.cache_mutex.lock(); @@ -1274,7 +1252,7 @@ (*this).sub(in_val); } } - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { s_parent.cache_mutex.lock(); @@ -1307,7 +1285,7 @@ (*this).mul(in_val); } } - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { s_parent.cache_mutex.lock(); @@ -1340,7 +1318,7 @@ (*this).div(in_val); } } - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { s_parent.cache_mutex.lock(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Mat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Mat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Mat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Mat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,9 +31,10 @@ typedef eT elem_type; //!< the type of elements stored in the matrix typedef typename get_pod_type::result pod_type; //!< if eT is std::complex, pod_type is T; otherwise pod_type is eT - 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) + 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) + const uword n_alloc; //!< number of allocated elements (read-only); NOTE: n_alloc can be 0, even if n_elem > 0 const uhword vec_state; //!< 0: matrix layout; 1: column vector layout; 2: row vector layout const uhword mem_state; @@ -50,18 +53,24 @@ public: - static const bool is_col = false; - static const bool is_row = false; - static const bool is_xvec = false; + static constexpr bool is_col = false; + static constexpr bool is_row = false; + static constexpr bool is_xvec = false; inline ~Mat(); inline Mat(); - inline explicit Mat(const uword in_rows, const uword in_cols); + inline explicit Mat(const uword in_n_rows, const uword in_n_cols); inline explicit Mat(const SizeMat& s); - template inline Mat(const uword in_rows, const uword in_cols, const fill::fill_class& f); - template inline Mat(const SizeMat& s, const fill::fill_class& f); + template inline explicit Mat(const uword in_n_rows, const uword in_n_cols, const arma_initmode_indicator&); + template inline explicit Mat(const SizeMat& s, const arma_initmode_indicator&); + + template inline Mat(const uword in_n_rows, const uword in_n_cols, const fill::fill_class& f); + template inline Mat(const SizeMat& s, const fill::fill_class& f); + + inline Mat(const uword in_n_rows, const uword in_n_cols, const fill::scalar_holder f); + inline Mat(const SizeMat& s, const fill::scalar_holder f); inline arma_cold Mat(const char* text); inline arma_cold Mat& operator=(const char* text); @@ -72,7 +81,6 @@ inline Mat(const std::vector& x); inline Mat& operator=(const std::vector& x); - #if defined(ARMA_USE_CXX11) inline Mat(const std::initializer_list& list); inline Mat& operator=(const std::initializer_list& list); @@ -81,19 +89,18 @@ inline Mat(Mat&& m); inline Mat& operator=(Mat&& m); - #endif inline Mat( eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem = true, const bool strict = false); inline Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols); - inline Mat& operator=(const eT val); + inline Mat& operator= (const eT val); inline Mat& operator+=(const eT val); inline Mat& operator-=(const eT val); inline Mat& operator*=(const eT val); inline Mat& operator/=(const eT val); inline Mat(const Mat& m); - inline Mat& operator=(const Mat& m); + inline Mat& operator= (const Mat& m); inline Mat& operator+=(const Mat& m); inline Mat& operator-=(const Mat& m); inline Mat& operator*=(const Mat& m); @@ -101,7 +108,7 @@ inline Mat& operator/=(const Mat& m); template inline Mat(const BaseCube& X); - template inline Mat& operator=(const BaseCube& X); + template inline Mat& operator= (const BaseCube& X); template inline Mat& operator+=(const BaseCube& X); template inline Mat& operator-=(const BaseCube& X); template inline Mat& operator*=(const BaseCube& X); @@ -114,7 +121,7 @@ inline explicit Mat(const subview& X, const bool use_colmem); // only to be used by the quasi_unwrap class inline Mat(const subview& X); - inline Mat& operator=(const subview& X); + inline Mat& operator= (const subview& X); inline Mat& operator+=(const subview& X); inline Mat& operator-=(const subview& X); inline Mat& operator*=(const subview& X); @@ -129,7 +136,7 @@ inline Mat(const xtrans_mat& X); // xtrans_mat can only be generated by the Proxy class inline Mat(const subview_cube& X); - inline Mat& operator=(const subview_cube& X); + inline Mat& operator= (const subview_cube& X); inline Mat& operator+=(const subview_cube& X); inline Mat& operator-=(const subview_cube& X); inline Mat& operator*=(const subview_cube& X); @@ -137,7 +144,7 @@ inline Mat& operator/=(const subview_cube& X); inline Mat(const diagview& X); - inline Mat& operator=(const diagview& X); + inline Mat& operator= (const diagview& X); inline Mat& operator+=(const diagview& X); inline Mat& operator-=(const diagview& X); inline Mat& operator*=(const diagview& X); @@ -162,15 +169,18 @@ // Operators on sparse matrices (and subviews) template inline explicit Mat(const SpBase& m); - template inline Mat& operator=(const SpBase& m); + template inline Mat& operator= (const SpBase& m); template inline Mat& operator+=(const SpBase& m); template inline Mat& operator-=(const SpBase& m); template inline Mat& operator*=(const SpBase& m); template inline Mat& operator%=(const SpBase& m); template inline Mat& operator/=(const SpBase& m); + inline explicit Mat(const SpSubview& X); + inline Mat& operator= (const SpSubview& X); + inline explicit Mat(const spdiagview& X); - inline Mat& operator=(const spdiagview& X); + inline Mat& operator= (const spdiagview& X); inline Mat& operator+=(const spdiagview& X); inline Mat& operator-=(const spdiagview& X); inline Mat& operator*=(const spdiagview& X); @@ -178,8 +188,8 @@ inline Mat& operator/=(const spdiagview& X); - inline mat_injector operator<<(const eT val); - inline mat_injector operator<<(const injector_end_of_row<>& x); + arma_cold inline mat_injector operator<<(const eT val); + arma_cold inline mat_injector operator<<(const injector_end_of_row<>& x); arma_inline subview_row row(const uword row_num); @@ -199,17 +209,17 @@ inline const Col unsafe_col(const uword col_num) const; - arma_inline subview rows(const uword in_row1, const uword in_row2); - arma_inline const subview rows(const uword in_row1, const uword in_row2) const; + arma_inline subview rows(const uword in_row1, const uword in_row2); + arma_inline const subview rows(const uword in_row1, const uword in_row2) const; - arma_inline subview cols(const uword in_col1, const uword in_col2); - arma_inline const subview cols(const uword in_col1, const uword in_col2) const; + arma_inline subview_cols cols(const uword in_col1, const uword in_col2); + arma_inline const subview_cols cols(const uword in_col1, const uword in_col2) const; - inline subview rows(const span& row_span); - inline const subview rows(const span& row_span) const; + inline subview rows(const span& row_span); + inline const subview rows(const span& row_span) const; - arma_inline subview cols(const span& col_span); - arma_inline const subview cols(const span& col_span) const; + arma_inline subview_cols cols(const span& col_span); + arma_inline const subview_cols cols(const span& col_span) const; arma_inline subview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2); @@ -233,11 +243,11 @@ inline subview tail_rows(const uword N); inline const subview tail_rows(const uword N) const; - inline subview head_cols(const uword N); - inline const subview head_cols(const uword N) const; + inline subview_cols head_cols(const uword N); + inline const subview_cols head_cols(const uword N) const; - inline subview tail_cols(const uword N); - inline const subview tail_cols(const uword N) const; + inline subview_cols tail_cols(const uword N); + inline const subview_cols tail_cols(const uword N) const; template arma_inline subview_elem1 elem(const Base& a); template arma_inline const subview_elem1 elem(const Base& a) const; @@ -275,13 +285,11 @@ template inline const subview_each2< Mat, 0, T1 > each_col(const Base& indices) const; template inline const subview_each2< Mat, 1, T1 > each_row(const Base& indices) const; - #if defined(ARMA_USE_CXX11) inline const Mat& each_col(const std::function< void( Col&) >& F); inline const Mat& each_col(const std::function< void(const Col&) >& F) const; inline const Mat& each_row(const std::function< void( Row&) >& F); inline const Mat& each_row(const std::function< void(const Row&) >& F) const; - #endif arma_inline diagview diag(const sword in_id = 0); @@ -308,7 +316,7 @@ template inline Mat(const Gen& X); - template inline Mat& operator=(const Gen& X); + template inline Mat& operator= (const Gen& X); template inline Mat& operator+=(const Gen& X); template inline Mat& operator-=(const Gen& X); template inline Mat& operator*=(const Gen& X); @@ -316,7 +324,7 @@ template inline Mat& operator/=(const Gen& X); template inline Mat(const Op& X); - template inline Mat& operator=(const Op& X); + template inline Mat& operator= (const Op& X); template inline Mat& operator+=(const Op& X); template inline Mat& operator-=(const Op& X); template inline Mat& operator*=(const Op& X); @@ -324,7 +332,7 @@ template inline Mat& operator/=(const Op& X); template inline Mat(const eOp& X); - template inline Mat& operator=(const eOp& X); + template inline Mat& operator= (const eOp& X); template inline Mat& operator+=(const eOp& X); template inline Mat& operator-=(const eOp& X); template inline Mat& operator*=(const eOp& X); @@ -332,7 +340,7 @@ template inline Mat& operator/=(const eOp& X); template inline Mat(const mtOp& X); - template inline Mat& operator=(const mtOp& X); + template inline Mat& operator= (const mtOp& X); template inline Mat& operator+=(const mtOp& X); template inline Mat& operator-=(const mtOp& X); template inline Mat& operator*=(const mtOp& X); @@ -340,7 +348,7 @@ template inline Mat& operator/=(const mtOp& X); template inline Mat(const CubeToMatOp& X); - template inline Mat& operator=(const CubeToMatOp& X); + template inline Mat& operator= (const CubeToMatOp& X); template inline Mat& operator+=(const CubeToMatOp& X); template inline Mat& operator-=(const CubeToMatOp& X); template inline Mat& operator*=(const CubeToMatOp& X); @@ -348,7 +356,7 @@ template inline Mat& operator/=(const CubeToMatOp& X); template inline Mat(const SpToDOp& X); - template inline Mat& operator=(const SpToDOp& X); + template inline Mat& operator= (const SpToDOp& X); template inline Mat& operator+=(const SpToDOp& X); template inline Mat& operator-=(const SpToDOp& X); template inline Mat& operator*=(const SpToDOp& X); @@ -356,7 +364,7 @@ template inline Mat& operator/=(const SpToDOp& X); template inline Mat(const Glue& X); - template inline Mat& operator=(const Glue& X); + template inline Mat& operator= (const Glue& X); template inline Mat& operator+=(const Glue& X); template inline Mat& operator-=(const Glue& X); template inline Mat& operator*=(const Glue& X); @@ -367,7 +375,7 @@ template inline Mat& operator-=(const Glue& X); template inline Mat(const eGlue& X); - template inline Mat& operator=(const eGlue& X); + template inline Mat& operator= (const eGlue& X); template inline Mat& operator+=(const eGlue& X); template inline Mat& operator-=(const eGlue& X); template inline Mat& operator*=(const eGlue& X); @@ -375,7 +383,7 @@ template inline Mat& operator/=(const eGlue& X); template inline Mat(const mtGlue& X); - template inline Mat& operator=(const mtGlue& X); + template inline Mat& operator= (const mtGlue& X); template inline Mat& operator+=(const mtGlue& X); template inline Mat& operator-=(const mtGlue& X); template inline Mat& operator*=(const mtGlue& X); @@ -436,28 +444,21 @@ arma_inline arma_warn_unused const eT* memptr() const; - arma_cold inline void impl_print( const std::string& extra_text) const; - arma_cold inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const; - - arma_cold inline void impl_raw_print( const std::string& extra_text) const; - arma_cold inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const; - - template inline void copy_size(const Base& X); - inline void set_size(const uword in_elem); - inline void set_size(const uword in_rows, const uword in_cols); + inline void set_size(const uword new_n_elem); + inline void set_size(const uword new_n_rows, const uword new_n_cols); inline void set_size(const SizeMat& s); - inline void resize(const uword in_elem); - inline void resize(const uword in_rows, const uword in_cols); + inline void resize(const uword new_n_elem); + inline void resize(const uword new_n_rows, const uword new_n_cols); inline void resize(const SizeMat& s); - inline void reshape(const uword in_rows, const uword in_cols); + inline void reshape(const uword new_n_rows, const uword new_n_cols); inline void reshape(const SizeMat& s); - arma_deprecated inline void reshape(const uword in_rows, const uword in_cols, const uword dim); //!< NOTE: don't use this form: it will be removed + arma_deprecated inline void reshape(const uword new_n_rows, const uword new_n_cols, const uword dim); //!< NOTE: don't use this form: it will be removed template inline const Mat& for_each(functor F); @@ -471,33 +472,35 @@ inline const Mat& clean(const pod_type threshold); + inline const Mat& clamp(const eT min_val, const eT max_val); + inline const Mat& fill(const eT val); template inline const Mat& fill(const fill::fill_class& f); inline const Mat& zeros(); - inline const Mat& zeros(const uword in_elem); - inline const Mat& zeros(const uword in_rows, const uword in_cols); + inline const Mat& zeros(const uword new_n_elem); + inline const Mat& zeros(const uword new_n_rows, const uword new_n_cols); inline const Mat& zeros(const SizeMat& s); inline const Mat& ones(); - inline const Mat& ones(const uword in_elem); - inline const Mat& ones(const uword in_rows, const uword in_cols); + inline const Mat& ones(const uword new_n_elem); + inline const Mat& ones(const uword new_n_rows, const uword new_n_cols); inline const Mat& ones(const SizeMat& s); inline const Mat& randu(); - inline const Mat& randu(const uword in_elem); - inline const Mat& randu(const uword in_rows, const uword in_cols); + inline const Mat& randu(const uword new_n_elem); + inline const Mat& randu(const uword new_n_rows, const uword new_n_cols); inline const Mat& randu(const SizeMat& s); inline const Mat& randn(); - inline const Mat& randn(const uword in_elem); - inline const Mat& randn(const uword in_rows, const uword in_cols); + inline const Mat& randn(const uword new_n_elem); + inline const Mat& randn(const uword new_n_rows, const uword new_n_cols); inline const Mat& randn(const SizeMat& s); inline const Mat& eye(); - inline const Mat& eye(const uword in_rows, const uword in_cols); + inline const Mat& eye(const uword new_n_rows, const uword new_n_cols); inline const Mat& eye(const SizeMat& s); inline arma_cold void reset(); @@ -518,20 +521,24 @@ inline eT max(uword& row_of_max_val, uword& col_of_max_val) const; - inline arma_cold bool save(const std::string name, const file_type type = arma_binary, const bool print_status = true) const; - inline arma_cold bool save(const hdf5_name& spec, const file_type type = hdf5_binary, const bool print_status = true) const; - inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary, const bool print_status = true) const; - - inline arma_cold bool load(const std::string name, const file_type type = auto_detect, const bool print_status = true); - inline arma_cold bool load(const hdf5_name& spec, const file_type type = hdf5_binary, const bool print_status = true); - inline arma_cold bool load( std::istream& is, const file_type type = auto_detect, const bool print_status = true); + inline arma_cold bool save(const std::string name, const file_type type = arma_binary) const; + inline arma_cold bool save(const hdf5_name& spec, const file_type type = hdf5_binary) const; + inline arma_cold bool save(const csv_name& spec, const file_type type = csv_ascii) const; + inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary) const; + + inline arma_cold bool load(const std::string name, const file_type type = auto_detect); + inline arma_cold bool load(const hdf5_name& spec, const file_type type = hdf5_binary); + inline arma_cold bool load(const csv_name& spec, const file_type type = csv_ascii); + inline arma_cold bool load( std::istream& is, const file_type type = auto_detect); inline arma_cold bool quiet_save(const std::string name, const file_type type = arma_binary) const; inline arma_cold bool quiet_save(const hdf5_name& spec, const file_type type = hdf5_binary) const; + inline arma_cold bool quiet_save(const csv_name& spec, const file_type type = csv_ascii) const; inline arma_cold bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; inline arma_cold bool quiet_load(const std::string name, const file_type type = auto_detect); inline arma_cold bool quiet_load(const hdf5_name& spec, const file_type type = hdf5_binary); + inline arma_cold bool quiet_load(const csv_name& spec, const file_type type = csv_ascii); inline arma_cold bool quiet_load( std::istream& is, const file_type type = auto_detect); @@ -724,11 +731,11 @@ inline bool empty() const; inline uword size() const; - inline eT& front(); - inline const eT& front() const; + inline arma_warn_unused eT& front(); + inline arma_warn_unused const eT& front() const; - inline eT& back(); - inline const eT& back() const; + inline arma_warn_unused eT& back(); + inline arma_warn_unused const eT& back() const; inline void swap(Mat& B); @@ -743,14 +750,12 @@ protected: inline void init_cold(); - inline void init_warm(uword in_rows, uword in_cols); + inline void init_warm(uword in_n_rows, uword in_n_cols); inline arma_cold void init(const std::string& text); - #if defined(ARMA_USE_CXX11) - inline void init(const std::initializer_list& list); - inline void init(const std::initializer_list< std::initializer_list >& list); - #endif + inline void init(const std::initializer_list& list); + inline void init(const std::initializer_list< std::initializer_list >& list); template inline void init(const Base& A, const Base& B); @@ -789,8 +794,8 @@ { private: - static const uword fixed_n_elem = fixed_n_rows * fixed_n_cols; - static const bool use_extra = (fixed_n_elem > arma_config::mat_prealloc); + static constexpr uword fixed_n_elem = fixed_n_rows * fixed_n_cols; + static constexpr bool use_extra = (fixed_n_elem > arma_config::mat_prealloc); arma_align_mem eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ]; @@ -802,9 +807,9 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_col = (fixed_n_cols == 1); - static const bool is_row = (fixed_n_rows == 1); - static const bool is_xvec = false; + static constexpr bool is_col = (fixed_n_cols == 1); + static constexpr bool is_row = (fixed_n_rows == 1); + static constexpr bool is_xvec = false; static const uword n_rows; // value provided below the class definition static const uword n_cols; // value provided below the class definition @@ -813,6 +818,7 @@ arma_inline fixed(); arma_inline fixed(const fixed& X); + inline fixed(const fill::scalar_holder f); template inline fixed(const fill::fill_class& f); template inline fixed(const Base& A); template inline fixed(const Base& A, const Base& B); @@ -825,13 +831,11 @@ using Mat::operator=; using Mat::operator(); - #if defined(ARMA_USE_CXX11) - inline fixed(const std::initializer_list& list); - inline Mat& operator=(const std::initializer_list& list); - - inline fixed(const std::initializer_list< std::initializer_list >& list); - inline Mat& operator=(const std::initializer_list< std::initializer_list >& list); - #endif + inline fixed(const std::initializer_list& list); + inline Mat& operator=(const std::initializer_list& list); + + inline fixed(const std::initializer_list< std::initializer_list >& list); + inline Mat& operator=(const std::initializer_list< std::initializer_list >& list); arma_inline Mat& operator=(const fixed& X); @@ -840,9 +844,9 @@ template inline Mat& operator=(const eGlue& X); #endif - arma_inline const Op< Mat_fixed_type, op_htrans > t() const; - arma_inline const Op< Mat_fixed_type, op_htrans > ht() const; - arma_inline const Op< Mat_fixed_type, op_strans > st() const; + arma_inline arma_warn_unused const Op< Mat_fixed_type, op_htrans > t() const; + arma_inline arma_warn_unused const Op< Mat_fixed_type, op_htrans > ht() const; + arma_inline arma_warn_unused const Op< Mat_fixed_type, op_strans > st() const; arma_inline arma_warn_unused const eT& at_alt (const uword i) const; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Mat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Mat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Mat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Mat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -24,13 +26,14 @@ { arma_extra_debug_sigprint_this(this); - if( (mem_state == 0) && (n_elem > arma_config::mat_prealloc) ) + if(n_alloc > 0) { + arma_extra_debug_print("Mat::destructor: releasing memory"); memory::release( access::rw(mem) ); } // try to expose buggy user code that accesses deleted objects - if(arma_config::debug) { access::rw(mem) = 0; } + if(arma_config::debug) { access::rw(mem) = nullptr; } arma_type_check(( is_supported_elem_type::value == false )); } @@ -43,6 +46,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -59,6 +63,7 @@ : n_rows(in_n_rows) , n_cols(in_n_cols) , n_elem(in_n_rows*in_n_cols) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -66,6 +71,13 @@ arma_extra_debug_sigprint_this(this); init_cold(); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Mat::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } + #endif } @@ -76,6 +88,60 @@ : n_rows(s.n_rows) , n_cols(s.n_cols) , n_elem(s.n_rows*s.n_cols) + , n_alloc() + , vec_state(0) + , mem_state(0) + , mem() + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Mat::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } + #endif + } + + + +//! internal use only +template +template +inline +Mat::Mat(const uword in_n_rows, const uword in_n_cols, const arma_initmode_indicator&) + : n_rows(in_n_rows) + , n_cols(in_n_cols) + , n_elem(in_n_rows*in_n_cols) + , n_alloc() + , vec_state(0) + , mem_state(0) + , mem() + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + + if(do_zeros) + { + arma_extra_debug_print("Mat::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } + } + + + +//! internal use only +template +template +inline +Mat::Mat(const SizeMat& s, const arma_initmode_indicator&) + : n_rows(s.n_rows) + , n_cols(s.n_cols) + , n_elem(s.n_rows*s.n_cols) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -83,6 +149,12 @@ arma_extra_debug_sigprint_this(this); init_cold(); + + if(do_zeros) + { + arma_extra_debug_print("Mat::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } } @@ -95,6 +167,7 @@ : n_rows(in_n_rows) , n_cols(in_n_cols) , n_elem(in_n_rows*in_n_cols) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -115,6 +188,7 @@ : n_rows(s.n_rows) , n_cols(s.n_cols) , n_elem(s.n_rows*s.n_cols) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -128,6 +202,47 @@ +//! construct the matrix to have user specified dimensions and fill with specified value +template +inline +Mat::Mat(const uword in_n_rows, const uword in_n_cols, const fill::scalar_holder f) + : n_rows(in_n_rows) + , n_cols(in_n_cols) + , n_elem(in_n_rows*in_n_cols) + , n_alloc() + , vec_state(0) + , mem_state(0) + , mem() + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + + (*this).fill(f.scalar); + } + + + +template +inline +Mat::Mat(const SizeMat& s, const fill::scalar_holder f) + : n_rows(s.n_rows) + , n_cols(s.n_cols) + , n_elem(s.n_rows*s.n_cols) + , n_alloc() + , vec_state(0) + , mem_state(0) + , mem() + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + + (*this).fill(f.scalar); + } + + + //! constructor used by Row and Col classes template inline @@ -135,6 +250,7 @@ : n_rows( (in_vec_state == 2) ? 1 : 0 ) , n_cols( (in_vec_state == 1) ? 1 : 0 ) , n_elem(0) + , n_alloc(0) , vec_state(in_vec_state) , mem_state(0) , mem() @@ -151,6 +267,7 @@ : n_rows(in_n_rows) , n_cols(in_n_cols) , n_elem(in_n_rows*in_n_cols) + , n_alloc() , vec_state(in_vec_state) , mem_state(0) , mem() @@ -168,6 +285,7 @@ : n_rows (in_n_rows) , n_cols (in_n_cols) , n_elem (in_n_rows*in_n_cols) + , n_alloc (0) , vec_state (in_vec_state) , mem_state (3) , mem (in_mem) @@ -186,10 +304,10 @@ // ensure that n_elem can hold the result of (n_rows * n_cols) - #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD)) + #if defined(ARMA_64BIT_WORD) const char* error_message = "Mat::init(): requested size is too large"; #else - const char* error_message = "Mat::init(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD"; + const char* error_message = "Mat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_check @@ -204,20 +322,17 @@ if(n_elem <= arma_config::mat_prealloc) { - if(n_elem == 0) - { - access::rw(mem) = NULL; - } - else - { - arma_extra_debug_print("Mat::init(): using local memory"); - access::rw(mem) = mem_local; - } + if(n_elem > 0) { arma_extra_debug_print("Mat::init(): using local memory"); } + + access::rw(mem) = (n_elem == 0) ? nullptr : mem_local; + access::rw(n_alloc) = 0; } else { arma_extra_debug_print("Mat::init(): acquiring memory"); - access::rw(mem) = memory::acquire(n_elem); + + access::rw(mem) = memory::acquire(n_elem); + access::rw(n_alloc) = n_elem; } } @@ -233,7 +348,7 @@ if( (n_rows == in_n_rows) && (n_cols == in_n_cols) ) { return; } bool err_state = false; - char* err_msg = 0; + char* err_msg = nullptr; const uhword t_vec_state = vec_state; const uhword t_mem_state = mem_state; @@ -256,10 +371,10 @@ // ensure that n_elem can hold the result of (n_rows * n_cols) - #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD)) + #if defined(ARMA_64BIT_WORD) const char* error_message = "Mat::init(): requested size is too large"; #else - const char* error_message = "Mat::init(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD"; + const char* error_message = "Mat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_set_error @@ -284,62 +399,55 @@ arma_extra_debug_print("Mat::init(): reusing memory"); access::rw(n_rows) = in_n_rows; access::rw(n_cols) = in_n_cols; + return; } - else // condition: old_n_elem != new_n_elem + + arma_debug_check( (t_mem_state == 2), "Mat::init(): mismatch between size of auxiliary memory and requested size" ); + + if(new_n_elem <= arma_config::mat_prealloc) { - arma_debug_check( (t_mem_state == 2), "Mat::init(): mismatch between size of auxiliary memory and requested size" ); - - if(new_n_elem < old_n_elem) // reuse existing memory if possible + if(n_alloc > 0) { - if( (t_mem_state == 0) && (new_n_elem <= arma_config::mat_prealloc) ) - { - if(old_n_elem > arma_config::mat_prealloc) - { - arma_extra_debug_print("Mat::init(): releasing memory"); - memory::release( access::rw(mem) ); - } - - if(new_n_elem == 0) - { - access::rw(mem) = NULL; - } - else - { - arma_extra_debug_print("Mat::init(): using local memory"); - access::rw(mem) = mem_local; - } - } - else - { - arma_extra_debug_print("Mat::init(): reusing memory"); - } + arma_extra_debug_print("Mat::init(): releasing memory"); + memory::release( access::rw(mem) ); } - else // condition: new_n_elem > old_n_elem + + if(new_n_elem > 0) { arma_extra_debug_print("Mat::init(): using local memory"); } + + access::rw(mem) = (new_n_elem == 0) ? nullptr : mem_local; + access::rw(n_alloc) = 0; + } + else // condition: new_n_elem > arma_config::mat_prealloc + { + if(new_n_elem > n_alloc) { - if( (t_mem_state == 0) && (old_n_elem > arma_config::mat_prealloc) ) + if(n_alloc > 0) { arma_extra_debug_print("Mat::init(): releasing memory"); memory::release( access::rw(mem) ); + + // in case memory::acquire() throws an exception + access::rw(mem) = nullptr; + access::rw(n_rows) = 0; + access::rw(n_cols) = 0; + access::rw(n_elem) = 0; + access::rw(n_alloc) = 0; } - if(new_n_elem <= arma_config::mat_prealloc) - { - arma_extra_debug_print("Mat::init(): using local memory"); - access::rw(mem) = mem_local; - } - else - { - arma_extra_debug_print("Mat::init(): acquiring memory"); - access::rw(mem) = memory::acquire(new_n_elem); - } - - access::rw(mem_state) = 0; + arma_extra_debug_print("Mat::init(): acquiring memory"); + access::rw(mem) = memory::acquire(new_n_elem); + access::rw(n_alloc) = new_n_elem; + } + else // condition: new_n_elem <= n_alloc + { + arma_extra_debug_print("Mat::init(): reusing memory"); } - - access::rw(n_rows) = in_n_rows; - access::rw(n_cols) = in_n_cols; - access::rw(n_elem) = new_n_elem; } + + access::rw(n_rows) = in_n_rows; + access::rw(n_cols) = in_n_cols; + access::rw(n_elem) = new_n_elem; + access::rw(mem_state) = 0; } @@ -352,6 +460,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -373,6 +482,7 @@ arma_extra_debug_sigprint(); init( std::string(text) ); + return *this; } @@ -386,6 +496,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -407,6 +518,7 @@ arma_extra_debug_sigprint(); init(text); + return *this; } @@ -537,6 +649,7 @@ : n_rows(uword(x.size())) , n_cols(1) , n_elem(uword(x.size())) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -545,10 +658,7 @@ init_cold(); - if(n_elem > 0) - { - arrayops::copy( memptr(), &(x[0]), n_elem ); - } + if(n_elem > 0) { arrayops::copy( memptr(), &(x[0]), n_elem ); } } @@ -563,143 +673,140 @@ init_warm(uword(x.size()), 1); - if(x.size() > 0) - { - arrayops::copy( memptr(), &(x[0]), uword(x.size()) ); - } + if(x.size() > 0) { arrayops::copy( memptr(), &(x[0]), uword(x.size()) ); } return *this; } -#if defined(ARMA_USE_CXX11) +template +inline +Mat::Mat(const std::initializer_list& list) + : n_rows(0) + , n_cols(0) + , n_elem(0) + , n_alloc(0) + , vec_state(0) + , mem_state(0) + , mem() + { + arma_extra_debug_sigprint_this(this); - template - inline - Mat::Mat(const std::initializer_list& list) - : n_rows(0) - , n_cols(0) - , n_elem(0) - , vec_state(0) - , mem_state(0) - , mem() - { - arma_extra_debug_sigprint_this(this); - - init(list); - } + init(list); + } + + + +template +inline +Mat& +Mat::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + init(list); + return *this; + } + + + +template +inline +Mat::Mat(const std::initializer_list< std::initializer_list >& list) + : n_rows(0) + , n_cols(0) + , n_elem(0) + , n_alloc(0) + , vec_state(0) + , mem_state(0) + , mem() + { + arma_extra_debug_sigprint_this(this); - template - inline - Mat& - Mat::operator=(const std::initializer_list& list) - { - arma_extra_debug_sigprint(); - - init(list); - - return *this; - } + init(list); + } + + + +template +inline +Mat& +Mat::operator=(const std::initializer_list< std::initializer_list >& list) + { + arma_extra_debug_sigprint(); + init(list); + return *this; + } + + + +template +inline +Mat::Mat(Mat&& X) + : n_rows (X.n_rows ) + , n_cols (X.n_cols ) + , n_elem (X.n_elem ) + , n_alloc (X.n_alloc) + , vec_state(0 ) + , mem_state(0 ) + , mem ( ) + { + arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - template - inline - Mat::Mat(const std::initializer_list< std::initializer_list >& list) - : n_rows(0) - , n_cols(0) - , n_elem(0) - , vec_state(0) - , mem_state(0) - , mem() + if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) ) { - arma_extra_debug_sigprint_this(this); + access::rw(mem_state) = X.mem_state; + access::rw(mem) = X.mem; - init(list); + access::rw(X.n_rows) = 0; + 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; } - - - - template - inline - Mat& - Mat::operator=(const std::initializer_list< std::initializer_list >& list) + else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3) { - arma_extra_debug_sigprint(); + init_cold(); - init(list); + arrayops::copy( memptr(), X.mem, X.n_elem ); - return *this; + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) + { + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 0; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; + } } + } - template - inline - Mat::Mat(Mat&& X) - : n_rows (X.n_rows) - , n_cols (X.n_cols) - , n_elem (X.n_elem) - , vec_state(0 ) - , mem_state(0 ) - , mem ( ) - { - arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - - if( ((X.mem_state == 0) && (X.n_elem > arma_config::mat_prealloc)) || (X.mem_state == 1) || (X.mem_state == 2) ) - { - access::rw(mem_state) = X.mem_state; - access::rw(mem) = X.mem; - - access::rw(X.n_rows) = 0; - access::rw(X.n_cols) = 0; - access::rw(X.n_elem) = 0; - access::rw(X.mem_state) = 0; - access::rw(X.mem) = 0; - } - else - { - init_cold(); - - arrayops::copy( memptr(), X.mem, X.n_elem ); - - if( (X.mem_state == 0) && (X.n_elem <= arma_config::mat_prealloc) ) - { - access::rw(X.n_rows) = 0; - access::rw(X.n_cols) = 0; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = 0; - } - } - } - +template +inline +Mat& +Mat::operator=(Mat&& X) + { + arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); + (*this).steal_mem(X); - template - inline - Mat& - Mat::operator=(Mat&& X) + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) && (this != &X) ) { - arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - - (*this).steal_mem(X); - - if( (X.mem_state == 0) && (X.n_elem <= arma_config::mat_prealloc) && (this != &X) ) - { - access::rw(X.n_rows) = 0; - access::rw(X.n_cols) = 0; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = 0; - } - - return *this; + access::rw(X.n_rows) = 0; + access::rw(X.n_cols) = 0; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; } -#endif - + return *this; + } + //! Set the matrix to be equal to the specified scalar. @@ -712,7 +819,9 @@ arma_extra_debug_sigprint(); init_warm(1,1); + access::rw(mem[0]) = val; + return *this; } @@ -785,6 +894,7 @@ : n_rows(in_mat.n_rows) , n_cols(in_mat.n_cols) , n_elem(in_mat.n_elem) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -818,86 +928,74 @@ -#if defined(ARMA_USE_CXX11) +template +inline +void +Mat::init(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); - template - inline - void - Mat::init(const std::initializer_list& list) + const uword N = uword(list.size()); + + set_size(1, N); + + arrayops::copy( memptr(), list.begin(), N ); + } + + + +template +inline +void +Mat::init(const std::initializer_list< std::initializer_list >& list) + { + arma_extra_debug_sigprint(); + + uword x_n_rows = uword(list.size()); + uword x_n_cols = 0; + + auto it = list.begin(); + auto it_end = list.end(); + + for(; it != it_end; ++it) { x_n_cols = (std::max)(x_n_cols, uword((*it).size())); } + + Mat& t = (*this); + + if(t.mem_state == 3) { - arma_extra_debug_sigprint(); - - const uword N = uword(list.size()); - - set_size(1, N); - - arrayops::copy( memptr(), list.begin(), N ); + arma_debug_check( ((x_n_rows != t.n_rows) || (x_n_cols != t.n_cols)), "Mat::init(): size mismatch between fixed size matrix and initialiser list" ); + } + else + { + t.set_size(x_n_rows, x_n_cols); } + uword row_num = 0; + auto row_it = list.begin(); + auto row_it_end = list.end(); - template - inline - void - Mat::init(const std::initializer_list< std::initializer_list >& list) + for(; row_it != row_it_end; ++row_it) { - arma_extra_debug_sigprint(); - - uword x_n_rows = uword(list.size()); - uword x_n_cols = 0; + uword col_num = 0; - bool x_n_cols_found = false; + auto col_it = (*row_it).begin(); + auto col_it_end = (*row_it).end(); - auto it = list.begin(); - auto it_end = list.end(); - - for(; it != it_end; ++it) + for(; col_it != col_it_end; ++col_it) { - if(x_n_cols_found == false) - { - x_n_cols = uword((*it).size()); - x_n_cols_found = true; - } - else - { - arma_check( (uword((*it).size()) != x_n_cols), "Mat::init(): inconsistent number of columns in initialiser list" ); - } + t.at(row_num, col_num) = (*col_it); + ++col_num; } - Mat& t = (*this); - - if(t.mem_state == 3) - { - arma_debug_check( ((x_n_rows != t.n_rows) || (x_n_cols != t.n_cols)), "Mat::init(): size mismatch between fixed size matrix and initialiser list" ); - } - else + for(uword c=col_num; c < x_n_cols; ++c) { - t.set_size(x_n_rows, x_n_cols); + t.at(row_num, c) = eT(0); } - uword row_num = 0; - - auto row_it = list.begin(); - auto row_it_end = list.end(); - - for(; row_it != row_it_end; ++row_it) - { - uword col_num = 0; - - auto col_it = (*row_it).begin(); - auto col_it_end = (*row_it).end(); - - for(; col_it != col_it_end; ++col_it) - { - t.at(row_num, col_num) = (*col_it); - ++col_num; - } - - ++row_num; - } + ++row_num; } - -#endif + } @@ -998,8 +1096,8 @@ const uword A_n_elem = A.n_elem; const uword B_n_elem = B.n_elem; - const bool A_use_local_mem = (A_n_elem <= arma_config::mat_prealloc); - const bool B_use_local_mem = (B_n_elem <= arma_config::mat_prealloc); + const bool A_use_local_mem = (A.n_alloc <= arma_config::mat_prealloc); + const bool B_use_local_mem = (B.n_alloc <= arma_config::mat_prealloc); if( (A_use_local_mem == false) && (B_use_local_mem == false) ) { @@ -1041,9 +1139,10 @@ access::rw(A.mem) = A_mem_local; } - std::swap( access::rw(A.n_rows), access::rw(B.n_rows) ); - std::swap( access::rw(A.n_cols), access::rw(B.n_cols) ); - std::swap( access::rw(A.n_elem), access::rw(B.n_elem) ); + std::swap( access::rw(A.n_rows), access::rw(B.n_rows) ); + std::swap( access::rw(A.n_cols), access::rw(B.n_cols) ); + std::swap( access::rw(A.n_elem), access::rw(B.n_elem) ); + std::swap( access::rw(A.n_alloc), access::rw(B.n_alloc) ); } else if( (A_mem_state <= 2) && (B_mem_state <= 2) && (A.n_elem == B.n_elem) && layout_ok ) @@ -1105,40 +1204,32 @@ const uword x_n_rows = x.n_rows; const uword x_n_cols = x.n_cols; const uword x_n_elem = x.n_elem; + const uword x_n_alloc = x.n_alloc; const uhword x_vec_state = x.vec_state; const uhword x_mem_state = x.mem_state; const uhword t_vec_state = vec_state; const uhword t_mem_state = mem_state; - bool layout_ok = false; - - if(t_vec_state == x_vec_state) - { - layout_ok = true; - } - else - { - if( (t_vec_state == 1) && (x_n_cols == 1) ) { layout_ok = true; } - if( (t_vec_state == 2) && (x_n_rows == 1) ) { layout_ok = true; } - } - + const bool layout_ok = (t_vec_state == x_vec_state) || ((t_vec_state == 1) && (x_n_cols == 1)) || ((t_vec_state == 2) && (x_n_rows == 1)); - if( (t_mem_state <= 1) && ( ((x_mem_state == 0) && (x_n_elem > arma_config::mat_prealloc)) || (x_mem_state == 1) ) && layout_ok ) + if( layout_ok && (t_mem_state <= 1) && ((x_n_alloc > arma_config::mat_prealloc) || (x_mem_state == 1)) ) { reset(); access::rw(n_rows) = x_n_rows; access::rw(n_cols) = x_n_cols; access::rw(n_elem) = x_n_elem; + access::rw(n_alloc) = x_n_alloc; access::rw(mem_state) = x_mem_state; access::rw(mem) = x.mem; access::rw(x.n_rows) = 0; 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) = 0; + access::rw(x.mem) = nullptr; } else { @@ -1156,6 +1247,7 @@ arma_extra_debug_sigprint(); const uword x_n_elem = x.n_elem; + const uword x_n_alloc = x.n_alloc; const uhword x_mem_state = x.mem_state; const uhword t_vec_state = vec_state; @@ -1172,7 +1264,7 @@ if( (this != &x) && (t_vec_state <= 1) && (t_mem_state <= 1) && (x_mem_state <= 1) ) { - if( (x_mem_state == 0) && ((x_n_elem <= arma_config::mat_prealloc) || (alt_n_rows <= arma_config::mat_prealloc)) ) + if( (x_mem_state == 0) && ((x_n_alloc <= arma_config::mat_prealloc) || (alt_n_rows <= arma_config::mat_prealloc)) ) { (*this).set_size(alt_n_rows, uword(1)); @@ -1185,19 +1277,21 @@ access::rw(n_rows) = alt_n_rows; access::rw(n_cols) = 1; access::rw(n_elem) = alt_n_rows; + access::rw(n_alloc) = x_n_alloc; access::rw(mem_state) = x_mem_state; access::rw(mem) = x.mem; access::rw(x.n_rows) = 0; 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) = 0; + access::rw(x.mem) = nullptr; } } else { - Mat tmp(alt_n_rows, 1); + Mat tmp(alt_n_rows, 1, arma_nozeros_indicator()); arrayops::copy( tmp.memptr(), x.memptr(), alt_n_rows ); @@ -1218,9 +1312,10 @@ : n_rows ( aux_n_rows ) , n_cols ( aux_n_cols ) , n_elem ( aux_n_rows*aux_n_cols ) + , n_alloc ( 0 ) , vec_state( 0 ) , mem_state( copy_aux_mem ? 0 : ( strict ? 2 : 1 ) ) - , mem ( copy_aux_mem ? 0 : aux_mem ) + , mem ( copy_aux_mem ? nullptr : aux_mem ) { arma_extra_debug_sigprint_this(this); @@ -1242,6 +1337,7 @@ : n_rows(aux_n_rows) , n_cols(aux_n_cols) , n_elem(aux_n_rows*aux_n_cols) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -1265,11 +1361,13 @@ : n_rows (aux_n_rows ) , n_cols (aux_n_cols ) , n_elem (aux_n_rows*aux_n_cols) + , n_alloc (0 ) , vec_state(0 ) , mem_state(3 ) , mem (aux_mem ) { arma_extra_debug_sigprint_this(this); + arma_ignore(junk); } @@ -1365,6 +1463,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -1816,6 +1915,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -1833,9 +1933,10 @@ : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(X.n_elem) + , n_alloc(0) , vec_state(0) , mem_state(use_colmem ? 3 : 0) - , mem (use_colmem ? X.colptr(0) : NULL) + , mem (use_colmem ? X.colptr(0) : nullptr) { arma_extra_debug_sigprint_this(this); @@ -1853,13 +1954,14 @@ -//! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation) +//! construct a matrix from subview (eg. construct a matrix from a delayed submatrix operation) template inline Mat::Mat(const subview& X) : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(X.n_elem) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -1873,7 +1975,7 @@ -//! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation) +//! construct a matrix from subview (eg. construct a matrix from a delayed submatrix operation) template inline Mat& @@ -1980,6 +2082,7 @@ : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(X.n_elem) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -1999,6 +2102,7 @@ : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(X.n_elem) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -2018,6 +2122,7 @@ : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(X.n_elem) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -2038,6 +2143,7 @@ : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(X.n_elem) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -2058,6 +2164,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -2123,6 +2230,7 @@ arma_extra_debug_sigprint(); const Mat tmp(X); + glue_times::apply_inplace(*this, tmp); return *this; @@ -2160,13 +2268,14 @@ -//! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation) +//! construct a matrix from diagview (eg. construct a matrix from a delayed diag operation) template inline Mat::Mat(const diagview& X) : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(X.n_elem) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -2180,7 +2289,7 @@ -//! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation) +//! construct a matrix from diagview (eg. construct a matrix from a delayed diag operation) template inline Mat& @@ -2290,6 +2399,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -2398,6 +2508,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -2506,6 +2617,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -2525,46 +2637,28 @@ { arma_extra_debug_sigprint(); - if( (is_SpMat::value) || (is_SpMat::stored_type>::value) ) + const unwrap_spmat U(m.get_ref()); + const SpMat& x = U.M; + + const uword x_n_cols = x.n_cols; + + (*this).zeros(x.n_rows, x_n_cols); + + const eT* x_values = x.values; + const uword* x_row_indices = x.row_indices; + const uword* x_col_ptrs = x.col_ptrs; + + for(uword x_col = 0; x_col < x_n_cols; ++x_col) { - const unwrap_spmat U(m.get_ref()); - const SpMat& x = U.M; + const uword start = x_col_ptrs[x_col ]; + const uword end = x_col_ptrs[x_col + 1]; - const uword x_n_cols = x.n_cols; - - (*this).zeros(x.n_rows, x_n_cols); - - const eT* x_values = x.values; - const uword* x_row_indices = x.row_indices; - const uword* x_col_ptrs = x.col_ptrs; - - for(uword x_col = 0; x_col < x_n_cols; ++x_col) + for(uword i = start; i < end; ++i) { - const uword start = x_col_ptrs[x_col ]; - const uword end = x_col_ptrs[x_col + 1]; + const uword x_row = x_row_indices[i]; + const eT x_val = x_values[i]; - for(uword i = start; i < end; ++i) - { - const uword x_row = x_row_indices[i]; - const eT x_val = x_values[i]; - - at(x_row, x_col) = x_val; - } - } - } - else - { - const SpProxy p(m.get_ref()); - - (*this).zeros(p.get_n_rows(), p.get_n_cols()); - - typename SpProxy::const_iterator_type it = p.begin(); - typename SpProxy::const_iterator_type it_end = p.end(); - - while(it != it_end) - { - at(it.row(), it.col()) = (*it); - ++it; + at(x_row, x_col) = x_val; } } @@ -2588,11 +2682,7 @@ typename SpProxy::const_iterator_type it = p.begin(); typename SpProxy::const_iterator_type it_end = p.end(); - while(it != it_end) - { - at(it.row(), it.col()) += (*it); - ++it; - } + for(; it != it_end; ++it) { at(it.row(), it.col()) += (*it); } return *this; } @@ -2614,11 +2704,7 @@ typename SpProxy::const_iterator_type it = p.begin(); typename SpProxy::const_iterator_type it_end = p.end(); - while(it != it_end) - { - at(it.row(), it.col()) -= (*it); - ++it; - } + for(; it != it_end; ++it) { at(it.row(), it.col()) -= (*it); } return *this; } @@ -2688,16 +2774,81 @@ { arma_extra_debug_sigprint(); + // NOTE: use of this function is not advised; it is implemented only for completeness + const SpProxy 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) { - at(r, c) /= p.at(r, c); + at(r, c) /= p.at(r, c); + } + + return *this; + } + + + +template +inline +Mat::Mat(const SpSubview& X) + : n_rows(0) + , n_cols(0) + , n_elem(0) + , n_alloc(0) + , vec_state(0) + , mem_state(0) + , mem() + { + arma_extra_debug_sigprint_this(this); + + (*this).operator=(X); + } + + + +template +inline +Mat& +Mat::operator=(const SpSubview& X) + { + arma_extra_debug_sigprint(); + + (*this).zeros(X.n_rows, X.n_cols); + + if(X.n_rows == X.m.n_rows) + { + const uword sv_col_start = X.aux_col1; + const uword sv_col_end = X.aux_col1 + X.n_cols - 1; + + const eT* m_values = X.m.values; + const uword* m_row_indices = X.m.row_indices; + const uword* m_col_ptrs = X.m.col_ptrs; + + for(uword m_col = sv_col_start; m_col <= sv_col_end; ++m_col) + { + const uword m_col_adjusted = m_col - sv_col_start; + + const uword start = m_col_ptrs[m_col ]; + const uword end = m_col_ptrs[m_col + 1]; + + for(uword ii = start; ii < end; ++ii) + { + const uword m_row = m_row_indices[ii]; + const eT m_val = m_values[ii]; + + at(m_row, m_col_adjusted) = m_val; + } + } + } + else + { + typename SpSubview::const_iterator it = X.begin(); + typename SpSubview::const_iterator it_end = X.end(); + + for(; it != it_end; ++it) { at(it.row(), it.col()) = (*it); } } return *this; @@ -2711,6 +2862,7 @@ : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(X.n_elem) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -2821,6 +2973,7 @@ template +arma_cold inline mat_injector< Mat > Mat::operator<<(const eT val) @@ -2831,6 +2984,7 @@ template +arma_cold inline mat_injector< Mat > Mat::operator<<(const injector_end_of_row<>& x) @@ -2848,7 +3002,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( row_num >= n_rows, "Mat::row(): index out of bounds" ); + arma_debug_check_bounds( row_num >= n_rows, "Mat::row(): index out of bounds" ); return subview_row(*this, row_num); } @@ -2863,7 +3017,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( row_num >= n_rows, "Mat::row(): index out of bounds" ); + arma_debug_check_bounds( row_num >= n_rows, "Mat::row(): index out of bounds" ); return subview_row(*this, row_num); } @@ -2885,7 +3039,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( (row_num >= n_rows) || @@ -2914,7 +3068,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( (row_num >= n_rows) || @@ -2936,7 +3090,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "Mat::col(): index out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "Mat::col(): index out of bounds" ); return subview_col(*this, col_num); } @@ -2951,7 +3105,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "Mat::col(): index out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "Mat::col(): index out of bounds" ); return subview_col(*this, col_num); } @@ -2973,7 +3127,7 @@ const uword in_row2 = row_span.b; const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; - arma_debug_check + arma_debug_check_bounds ( (col_num >= n_cols) || @@ -3002,7 +3156,7 @@ const uword in_row2 = row_span.b; const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; - arma_debug_check + arma_debug_check_bounds ( (col_num >= n_cols) || @@ -3028,7 +3182,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds" ); return Col(colptr(col_num), n_rows, false, true); } @@ -3047,7 +3201,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds" ); typedef const Col out_type; @@ -3064,7 +3218,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "Mat::rows(): indices out of bounds or incorrectly used" @@ -3085,7 +3239,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "Mat::rows(): indices out of bounds or incorrectly used" @@ -3101,12 +3255,12 @@ //! creation of subview (submatrix comprised of specified column vectors) template arma_inline -subview +subview_cols Mat::cols(const uword in_col1, const uword in_col2) { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "Mat::cols(): indices out of bounds or incorrectly used" @@ -3114,7 +3268,7 @@ const uword subview_n_cols = in_col2 - in_col1 + 1; - return subview(*this, 0, in_col1, n_rows, subview_n_cols); + return subview_cols(*this, in_col1, subview_n_cols); } @@ -3122,12 +3276,12 @@ //! creation of subview (submatrix comprised of specified column vectors) template arma_inline -const subview +const subview_cols Mat::cols(const uword in_col1, const uword in_col2) const { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "Mat::cols(): indices out of bounds or incorrectly used" @@ -3135,7 +3289,7 @@ const uword subview_n_cols = in_col2 - in_col1 + 1; - return subview(*this, 0, in_col1, n_rows, subview_n_cols); + return subview_cols(*this, in_col1, subview_n_cols); } @@ -3156,7 +3310,7 @@ const uword in_row2 = row_span.b; const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) , @@ -3184,7 +3338,7 @@ const uword in_row2 = row_span.b; const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) , @@ -3199,7 +3353,7 @@ //! creation of subview (submatrix comprised of specified column vectors) template arma_inline -subview +subview_cols Mat::cols(const span& col_span) { arma_extra_debug_sigprint(); @@ -3212,14 +3366,14 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) , "Mat::cols(): indices out of bounds or incorrectly used" ); - return subview(*this, 0, in_col1, n_rows, submat_n_cols); + return subview_cols(*this, in_col1, submat_n_cols); } @@ -3227,7 +3381,7 @@ //! creation of subview (submatrix comprised of specified column vectors) template arma_inline -const subview +const subview_cols Mat::cols(const span& col_span) const { arma_extra_debug_sigprint(); @@ -3240,14 +3394,14 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) , "Mat::cols(): indices out of bounds or incorrectly used" ); - return subview(*this, 0, in_col1, n_rows, submat_n_cols); + return subview_cols(*this, in_col1, submat_n_cols); } @@ -3260,7 +3414,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "Mat::submat(): indices out of bounds or incorrectly used" @@ -3282,7 +3436,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "Mat::submat(): indices out of bounds or incorrectly used" @@ -3310,7 +3464,7 @@ const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)), "Mat::submat(): indices or size out of bounds" @@ -3335,7 +3489,7 @@ const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)), "Mat::submat(): indices or size out of bounds" @@ -3368,7 +3522,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -3404,7 +3558,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -3473,7 +3627,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_rows), "Mat::head_rows(): size out of bounds"); + arma_debug_check_bounds( (N > n_rows), "Mat::head_rows(): size out of bounds" ); return subview(*this, 0, 0, N, n_cols); } @@ -3487,7 +3641,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_rows), "Mat::head_rows(): size out of bounds"); + arma_debug_check_bounds( (N > n_rows), "Mat::head_rows(): size out of bounds" ); return subview(*this, 0, 0, N, n_cols); } @@ -3501,7 +3655,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_rows), "Mat::tail_rows(): size out of bounds"); + arma_debug_check_bounds( (N > n_rows), "Mat::tail_rows(): size out of bounds" ); const uword start_row = n_rows - N; @@ -3517,7 +3671,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_rows), "Mat::tail_rows(): size out of bounds"); + arma_debug_check_bounds( (N > n_rows), "Mat::tail_rows(): size out of bounds" ); const uword start_row = n_rows - N; @@ -3528,60 +3682,60 @@ template inline -subview +subview_cols Mat::head_cols(const uword N) { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_cols), "Mat::head_cols(): size out of bounds"); + arma_debug_check_bounds( (N > n_cols), "Mat::head_cols(): size out of bounds" ); - return subview(*this, 0, 0, n_rows, N); + return subview_cols(*this, 0, N); } template inline -const subview +const subview_cols Mat::head_cols(const uword N) const { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_cols), "Mat::head_cols(): size out of bounds"); + arma_debug_check_bounds( (N > n_cols), "Mat::head_cols(): size out of bounds" ); - return subview(*this, 0, 0, n_rows, N); + return subview_cols(*this, 0, N); } template inline -subview +subview_cols Mat::tail_cols(const uword N) { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_cols), "Mat::tail_cols(): size out of bounds"); + arma_debug_check_bounds( (N > n_cols), "Mat::tail_cols(): size out of bounds" ); const uword start_col = n_cols - N; - return subview(*this, 0, start_col, n_rows, N); + return subview_cols(*this, start_col, N); } template inline -const subview +const subview_cols Mat::tail_cols(const uword N) const { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_cols), "Mat::tail_cols(): size out of bounds"); + arma_debug_check_bounds( (N > n_cols), "Mat::tail_cols(): size out of bounds" ); const uword start_col = n_cols - N; - return subview(*this, 0, start_col, n_rows, N); + return subview_cols(*this, start_col, N); } @@ -3868,143 +4022,139 @@ -#if defined(ARMA_USE_CXX11) +//! apply a lambda function to each column, where each column is interpreted as a column vector +template +inline +const Mat& +Mat::each_col(const std::function< void(Col&) >& F) + { + arma_extra_debug_sigprint(); - //! apply a lambda function to each column, where each column is interpreted as a column vector - template - inline - const Mat& - Mat::each_col(const std::function< void(Col&) >& F) + for(uword ii=0; ii < n_cols; ++ii) { - arma_extra_debug_sigprint(); - - for(uword ii=0; ii < n_cols; ++ii) - { - Col tmp(colptr(ii), n_rows, false, true); - F(tmp); - } - - return *this; + Col tmp(colptr(ii), n_rows, false, true); + F(tmp); } + return *this; + } + + + +template +inline +const Mat& +Mat::each_col(const std::function< void(const Col&) >& F) const + { + arma_extra_debug_sigprint(); - - template - inline - const Mat& - Mat::each_col(const std::function< void(const Col&) >& F) const + for(uword ii=0; ii < n_cols; ++ii) { - arma_extra_debug_sigprint(); - - for(uword ii=0; ii < n_cols; ++ii) - { - const Col tmp(const_cast(colptr(ii)), n_rows, false, true); - F(tmp); - } - - return *this; + const Col tmp(const_cast(colptr(ii)), n_rows, false, true); + F(tmp); } + return *this; + } + + + +//! apply a lambda function to each row, where each row is interpreted as a row vector +template +inline +const Mat& +Mat::each_row(const std::function< void(Row&) >& F) + { + arma_extra_debug_sigprint(); + + podarray array1(n_cols); + podarray array2(n_cols); + Row tmp1( array1.memptr(), n_cols, false, true ); + Row tmp2( array2.memptr(), n_cols, false, true ); - //! apply a lambda function to each row, where each row is interpreted as a row vector - template - inline - const Mat& - Mat::each_row(const std::function< void(Row&) >& F) + eT* tmp1_mem = tmp1.memptr(); + eT* tmp2_mem = tmp2.memptr(); + + uword ii, jj; + + for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2) { - arma_extra_debug_sigprint(); - - podarray array1(n_cols); - podarray array2(n_cols); - - Row tmp1( array1.memptr(), n_cols, false, true ); - Row tmp2( array2.memptr(), n_cols, false, true ); - - eT* tmp1_mem = tmp1.memptr(); - eT* tmp2_mem = tmp2.memptr(); - - uword ii, jj; - - for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2) + for(uword col_id = 0; col_id < n_cols; ++col_id) { - for(uword col_id = 0; col_id < n_cols; ++col_id) - { - const eT* col_mem = colptr(col_id); - - tmp1_mem[col_id] = col_mem[ii]; - tmp2_mem[col_id] = col_mem[jj]; - } + const eT* col_mem = colptr(col_id); - F(tmp1); - F(tmp2); - - for(uword col_id = 0; col_id < n_cols; ++col_id) - { - eT* col_mem = colptr(col_id); - - col_mem[ii] = tmp1_mem[col_id]; - col_mem[jj] = tmp2_mem[col_id]; - } + tmp1_mem[col_id] = col_mem[ii]; + tmp2_mem[col_id] = col_mem[jj]; } - if(ii < n_rows) + F(tmp1); + F(tmp2); + + for(uword col_id = 0; col_id < n_cols; ++col_id) { - tmp1 = (*this).row(ii); - - F(tmp1); + eT* col_mem = colptr(col_id); - (*this).row(ii) = tmp1; + col_mem[ii] = tmp1_mem[col_id]; + col_mem[jj] = tmp2_mem[col_id]; } + } + + if(ii < n_rows) + { + tmp1 = (*this).row(ii); - return *this; + F(tmp1); + + (*this).row(ii) = tmp1; } + return *this; + } + + + +template +inline +const Mat& +Mat::each_row(const std::function< void(const Row&) >& F) const + { + arma_extra_debug_sigprint(); + + podarray array1(n_cols); + podarray array2(n_cols); + Row tmp1( array1.memptr(), n_cols, false, true ); + Row tmp2( array2.memptr(), n_cols, false, true ); - template - inline - const Mat& - Mat::each_row(const std::function< void(const Row&) >& F) const + eT* tmp1_mem = tmp1.memptr(); + eT* tmp2_mem = tmp2.memptr(); + + uword ii, jj; + + for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2) { - arma_extra_debug_sigprint(); - - podarray array1(n_cols); - podarray array2(n_cols); - - Row tmp1( array1.memptr(), n_cols, false, true ); - Row tmp2( array2.memptr(), n_cols, false, true ); - - eT* tmp1_mem = tmp1.memptr(); - eT* tmp2_mem = tmp2.memptr(); - - uword ii, jj; - - for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2) + for(uword col_id = 0; col_id < n_cols; ++col_id) { - for(uword col_id = 0; col_id < n_cols; ++col_id) - { - const eT* col_mem = colptr(col_id); - - tmp1_mem[col_id] = col_mem[ii]; - tmp2_mem[col_id] = col_mem[jj]; - } + const eT* col_mem = colptr(col_id); - F(tmp1); - F(tmp2); + tmp1_mem[col_id] = col_mem[ii]; + tmp2_mem[col_id] = col_mem[jj]; } - if(ii < n_rows) - { - tmp1 = (*this).row(ii); - - F(tmp1); - } + F(tmp1); + F(tmp2); + } + + if(ii < n_rows) + { + tmp1 = (*this).row(ii); - return *this; + F(tmp1); } -#endif + return *this; + } @@ -4019,7 +4169,7 @@ const uword row_offset = (in_id < 0) ? uword(-in_id) : 0; const uword col_offset = (in_id > 0) ? uword( in_id) : 0; - arma_debug_check + arma_debug_check_bounds ( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "Mat::diag(): requested diagonal out of bounds" @@ -4043,7 +4193,7 @@ const uword row_offset = uword( (in_id < 0) ? -in_id : 0 ); const uword col_offset = uword( (in_id > 0) ? in_id : 0 ); - arma_debug_check + arma_debug_check_bounds ( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "Mat::diag(): requested diagonal out of bounds" @@ -4066,7 +4216,7 @@ const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; - arma_debug_check + arma_debug_check_bounds ( (in_row1 >= local_n_rows) || (in_row2 >= local_n_rows), "Mat::swap_rows(): index out of bounds" @@ -4097,7 +4247,7 @@ const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; - arma_debug_check + arma_debug_check_bounds ( (in_colA >= local_n_cols) || (in_colB >= local_n_cols), "Mat::swap_cols(): index out of bounds" @@ -4141,7 +4291,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( row_num >= n_rows, "Mat::shed_row(): index out of bounds"); + arma_debug_check_bounds( row_num >= n_rows, "Mat::shed_row(): index out of bounds" ); shed_rows(row_num, row_num); } @@ -4156,7 +4306,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "Mat::shed_col(): index out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "Mat::shed_col(): index out of bounds" ); shed_cols(col_num, col_num); } @@ -4171,7 +4321,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "Mat::shed_rows(): indices out of bounds or incorrectly used" @@ -4180,7 +4330,7 @@ const uword n_keep_front = in_row1; const uword n_keep_back = n_rows - (in_row2 + 1); - Mat X(n_keep_front + n_keep_back, n_cols); + Mat X(n_keep_front + n_keep_back, n_cols, arma_nozeros_indicator()); if(n_keep_front > 0) { @@ -4205,7 +4355,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "Mat::shed_cols(): indices out of bounds or incorrectly used" @@ -4214,7 +4364,7 @@ const uword n_keep_front = in_col1; const uword n_keep_back = n_cols - (in_col2 + 1); - Mat X(n_rows, n_keep_front + n_keep_back); + Mat X(n_rows, n_keep_front + n_keep_back, arma_nozeros_indicator()); if(n_keep_front > 0) { @@ -4245,7 +4395,7 @@ arma_debug_check( ((tmp1.is_vec() == false) && (tmp1.is_empty() == false)), "Mat::shed_rows(): list of indices must be a vector" ); - if(tmp1.is_empty()) { return; } + if(tmp1.is_empty()) { return; } const Col tmp2(const_cast(tmp1.memptr()), tmp1.n_elem, false, false); @@ -4260,11 +4410,11 @@ { for(uword i=0; i= n_rows), "Mat::shed_rows(): indices out of bounds" ); + arma_debug_check_bounds( (rows_to_shed_mem[i] >= n_rows), "Mat::shed_rows(): indices out of bounds" ); } } - Col tmp3(n_rows); + Col tmp3(n_rows, arma_nozeros_indicator()); uword* tmp3_mem = tmp3.memptr(); @@ -4315,7 +4465,7 @@ arma_debug_check( ((tmp1.is_vec() == false) && (tmp1.is_empty() == false)), "Mat::shed_cols(): list of indices must be a vector" ); - if(tmp1.is_empty()) { return; } + if(tmp1.is_empty()) { return; } const Col tmp2(const_cast(tmp1.memptr()), tmp1.n_elem, false, false); @@ -4330,11 +4480,11 @@ { for(uword i=0; i= n_cols), "Mat::shed_cols(): indices out of bounds" ); + arma_debug_check_bounds( (cols_to_shed_mem[i] >= n_cols), "Mat::shed_cols(): indices out of bounds" ); } } - Col tmp3(n_cols); + Col tmp3(n_cols, arma_nozeros_indicator()); uword* tmp3_mem = tmp3.memptr(); @@ -4387,11 +4537,11 @@ const uword B_n_rows = t_n_rows - row_num; // insertion at row_num == n_rows is in effect an append operation - arma_debug_check( (row_num > t_n_rows), "Mat::insert_rows(): index out of bounds"); + arma_debug_check_bounds( (row_num > t_n_rows), "Mat::insert_rows(): index out of bounds" ); if(N > 0) { - Mat out(t_n_rows + N, t_n_cols); + Mat out(t_n_rows + N, t_n_cols, arma_nozeros_indicator()); if(A_n_rows > 0) { @@ -4430,11 +4580,11 @@ const uword B_n_cols = t_n_cols - col_num; // insertion at col_num == n_cols is in effect an append operation - arma_debug_check( (col_num > t_n_cols), "Mat::insert_cols(): index out of bounds"); + arma_debug_check_bounds( (col_num > t_n_cols), "Mat::insert_cols(): index out of bounds" ); if(N > 0) { - Mat out(t_n_rows, t_n_cols + N); + Mat out(t_n_rows, t_n_cols + N, arma_nozeros_indicator()); if(A_n_cols > 0) { @@ -4480,7 +4630,7 @@ const uword B_n_rows = t_n_rows - row_num; bool err_state = false; - char* err_msg = 0; + char* err_msg = nullptr; // insertion at row_num == n_rows is in effect an append operation @@ -4500,11 +4650,11 @@ "Mat::insert_rows(): given object has an incompatible number of columns" ); - arma_debug_check(err_state, err_msg); + arma_debug_check_bounds(err_state, err_msg); if(C_n_rows > 0) { - Mat out( t_n_rows + C_n_rows, (std::max)(t_n_cols, C_n_cols) ); + Mat out( t_n_rows + C_n_rows, (std::max)(t_n_cols, C_n_cols), arma_nozeros_indicator() ); if(t_n_cols > 0) { @@ -4553,7 +4703,7 @@ const uword B_n_cols = t_n_cols - col_num; bool err_state = false; - char* err_msg = 0; + char* err_msg = nullptr; // insertion at col_num == n_cols is in effect an append operation @@ -4573,11 +4723,11 @@ "Mat::insert_cols(): given object has an incompatible number of rows" ); - arma_debug_check(err_state, err_msg); + arma_debug_check_bounds(err_state, err_msg); if(C_n_cols > 0) { - Mat out( (std::max)(t_n_rows, C_n_rows), t_n_cols + C_n_cols ); + Mat out( (std::max)(t_n_rows, C_n_rows), t_n_cols + C_n_cols, arma_nozeros_indicator() ); if(t_n_rows > 0) { @@ -4610,6 +4760,7 @@ : n_rows(X.n_rows) , n_cols(X.n_cols) , n_elem(n_rows*n_cols) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -4729,7 +4880,7 @@ -//! create a matrix from Op, i.e. run the previously delayed unary operations +//! create a matrix from Op, ie. run the previously delayed unary operations template template inline @@ -4737,6 +4888,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -4750,7 +4902,7 @@ -//! create a matrix from Op, i.e. run the previously delayed unary operations +//! create a matrix from Op, ie. run the previously delayed unary operations template template inline @@ -4858,7 +5010,7 @@ -//! create a matrix from eOp, i.e. run the previously delayed unary operations +//! create a matrix from eOp, ie. run the previously delayed unary operations template template inline @@ -4866,6 +5018,7 @@ : n_rows(X.get_n_rows()) , n_cols(X.get_n_cols()) , n_elem(X.get_n_elem()) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -4881,7 +5034,7 @@ -//! create a matrix from eOp, i.e. run the previously delayed unary operations +//! create a matrix from eOp, ie. run the previously delayed unary operations template template inline @@ -5006,6 +5159,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -5114,6 +5268,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -5236,6 +5391,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -5249,7 +5405,7 @@ -//! create a matrix from an SpToDOp, i.e. run the previously delayed unary operations +//! create a matrix from an SpToDOp, ie. run the previously delayed unary operations template template inline @@ -5357,7 +5513,7 @@ -//! create a matrix from Glue, i.e. run the previously delayed binary operations +//! create a matrix from Glue, ie. run the previously delayed binary operations template template inline @@ -5365,6 +5521,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -5379,7 +5536,7 @@ -//! create a matrix from Glue, i.e. run the previously delayed binary operations +//! create a matrix from Glue, ie. run the previously delayed binary operations template template inline @@ -5523,7 +5680,7 @@ -//! create a matrix from eGlue, i.e. run the previously delayed binary operations +//! create a matrix from eGlue, ie. run the previously delayed binary operations template template inline @@ -5531,6 +5688,7 @@ : n_rows(X.get_n_rows()) , n_cols(X.get_n_cols()) , n_elem(X.get_n_elem()) + , n_alloc() , vec_state(0) , mem_state(0) , mem() @@ -5547,7 +5705,7 @@ -//! create a matrix from eGlue, i.e. run the previously delayed binary operations +//! create a matrix from eGlue, ie. run the previously delayed binary operations template template inline @@ -5636,6 +5794,7 @@ arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); glue_times::apply_inplace(*this, X); + return *this; } @@ -5653,6 +5812,7 @@ arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); eglue_type::apply_inplace_schur(*this, X); + return *this; } @@ -5670,6 +5830,7 @@ arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); eglue_type::apply_inplace_div(*this, X); + return *this; } @@ -5682,6 +5843,7 @@ : n_rows(0) , n_cols(0) , n_elem(0) + , n_alloc(0) , vec_state(0) , mem_state(0) , mem() @@ -5793,6 +5955,7 @@ Mat::at_alt(const uword ii) const { const eT* mem_aligned = mem; + memory::mark_as_aligned(mem_aligned); return mem_aligned[ii]; @@ -5807,7 +5970,8 @@ eT& Mat::operator() (const uword ii) { - arma_debug_check( (ii >= n_elem), "Mat::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= n_elem), "Mat::operator(): index out of bounds" ); + return access::rw(mem[ii]); } @@ -5820,7 +5984,8 @@ const eT& Mat::operator() (const uword ii) const { - arma_debug_check( (ii >= n_elem), "Mat::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= n_elem), "Mat::operator(): index out of bounds" ); + return mem[ii]; } @@ -5880,7 +6045,8 @@ eT& Mat::operator() (const uword in_row, const uword in_col) { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds" ); + return access::rw(mem[in_row + in_col*n_rows]); } @@ -5893,7 +6059,8 @@ const eT& Mat::operator() (const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds" ); + return mem[in_row + in_col*n_rows]; } @@ -5930,6 +6097,7 @@ Mat::operator++() { Mat_aux::prefix_pp(*this); + return *this; } @@ -5953,6 +6121,7 @@ Mat::operator--() { Mat_aux::prefix_mm(*this); + return *this; } @@ -6088,7 +6257,7 @@ { arma_extra_debug_sigprint(); - const char sig1 = (direction != NULL) ? direction[0] : char(0); + const char sig1 = (direction != nullptr) ? direction[0] : char(0); // direction is one of: // "ascend" @@ -6410,127 +6579,24 @@ -//! print contents of the matrix (to the cout stream), -//! optionally preceding with a user specified line of text. -//! the precision and cell width are modified. -//! on return, the stream's state are restored to their original values. -template -arma_cold -inline -void -Mat::impl_print(const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = get_cout_stream().width(); - - get_cout_stream() << extra_text << '\n'; - - get_cout_stream().width(orig_width); - } - - arma_ostream::print(get_cout_stream(), *this, true); - } - - - -//! print contents of the matrix to a user specified stream, -//! optionally preceding with a user specified line of text. -//! the precision and cell width are modified. -//! on return, the stream's state are restored to their original values. -template -arma_cold -inline -void -Mat::impl_print(std::ostream& user_stream, const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = user_stream.width(); - - user_stream << extra_text << '\n'; - - user_stream.width(orig_width); - } - - arma_ostream::print(user_stream, *this, true); - } - - - -//! print contents of the matrix (to the cout stream), -//! optionally preceding with a user specified line of text. -//! the stream's state are used as is and are not modified -//! (i.e. the precision and cell width are not modified). -template -arma_cold -inline -void -Mat::impl_raw_print(const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = get_cout_stream().width(); - - get_cout_stream() << extra_text << '\n'; - - get_cout_stream().width(orig_width); - } - - arma_ostream::print(get_cout_stream(), *this, false); - } - - - -//! print contents of the matrix to a user specified stream, -//! optionally preceding with a user specified line of text. -//! the stream's state are used as is and are not modified. -//! (i.e. the precision and cell width are not modified). -template -arma_cold -inline -void -Mat::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = user_stream.width(); - - user_stream << extra_text << '\n'; - - user_stream.width(orig_width); - } - - arma_ostream::print(user_stream, *this, false); - } - - - //! change the matrix to have user specified dimensions (data is not preserved) template inline void -Mat::set_size(const uword in_elem) +Mat::set_size(const uword new_n_elem) { arma_extra_debug_sigprint(); switch(vec_state) { case 0: + // fallthrough case 1: - init_warm(in_elem, 1); + init_warm(new_n_elem, 1); break; case 2: - init_warm(1, in_elem); + init_warm(1, new_n_elem); break; default: @@ -6544,11 +6610,11 @@ template inline void -Mat::set_size(const uword in_rows, const uword in_cols) +Mat::set_size(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - init_warm(in_rows, in_cols); + init_warm(new_n_rows, new_n_cols); } @@ -6569,19 +6635,20 @@ template inline void -Mat::resize(const uword in_elem) +Mat::resize(const uword new_n_elem) { arma_extra_debug_sigprint(); switch(vec_state) { case 0: + // fallthrough case 1: - (*this).resize(in_elem, 1); + (*this).resize(new_n_elem, 1); break; case 2: - (*this).resize(1, in_elem); + (*this).resize(1, new_n_elem); break; default: @@ -6595,11 +6662,11 @@ template inline void -Mat::resize(const uword in_rows, const uword in_cols) +Mat::resize(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - *this = arma::resize(*this, in_rows, in_cols); + op_resize::apply_mat_inplace((*this), new_n_rows, new_n_cols); } @@ -6611,7 +6678,7 @@ { arma_extra_debug_sigprint(); - *this = arma::resize(*this, s.n_rows, s.n_cols); + op_resize::apply_mat_inplace((*this), s.n_rows, s.n_cols); } @@ -6620,11 +6687,11 @@ template inline void -Mat::reshape(const uword in_rows, const uword in_cols) +Mat::reshape(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - *this = arma::reshape(*this, in_rows, in_cols); + op_reshape::apply_mat_inplace((*this), new_n_rows, new_n_cols); } @@ -6636,7 +6703,7 @@ { arma_extra_debug_sigprint(); - *this = arma::reshape(*this, s.n_rows, s.n_cols); + op_reshape::apply_mat_inplace((*this), s.n_rows, s.n_cols); } @@ -6646,11 +6713,15 @@ arma_deprecated inline void -Mat::reshape(const uword in_rows, const uword in_cols, const uword dim) +Mat::reshape(const uword new_n_rows, const uword new_n_cols, const uword dim) { arma_extra_debug_sigprint(); - *this = arma::reshape(*this, in_rows, in_cols, dim); + // arma_debug_warn_level(1, "this form of reshape() is deprecated and will be removed"); + + arma_debug_check( (dim > 1), "reshape(): parameter 'dim' must be 0 or 1" ); + + op_reshape_old::apply_mat_inplace((*this), new_n_rows, new_n_cols, dim); } @@ -6834,6 +6905,30 @@ +template +inline +const Mat& +Mat::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + if(is_cx::no) + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): min_val must be less than max_val" ); + } + else + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" ); + } + + arrayops::clamp(memptr(), n_elem, min_val, max_val); + + return *this; + } + + + //! fill the matrix with the specified value template inline @@ -6849,7 +6944,7 @@ -//! fill the matrix with the specified value +//! fill the matrix with the specified pattern template template inline @@ -6858,11 +6953,11 @@ { arma_extra_debug_sigprint(); - if(is_same_type::yes) (*this).zeros(); - if(is_same_type::yes) (*this).ones(); - if(is_same_type::yes) (*this).eye(); - if(is_same_type::yes) (*this).randu(); - if(is_same_type::yes) (*this).randn(); + if(is_same_type::yes) { (*this).zeros(); } + if(is_same_type::yes) { (*this).ones(); } + if(is_same_type::yes) { (*this).eye(); } + if(is_same_type::yes) { (*this).randu(); } + if(is_same_type::yes) { (*this).randn(); } return *this; } @@ -6886,11 +6981,11 @@ template inline const Mat& -Mat::zeros(const uword in_elem) +Mat::zeros(const uword new_n_elem) { arma_extra_debug_sigprint(); - set_size(in_elem); + set_size(new_n_elem); return (*this).zeros(); } @@ -6900,11 +6995,11 @@ template inline const Mat& -Mat::zeros(const uword in_n_rows, const uword in_n_cols) +Mat::zeros(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - set_size(in_n_rows, in_n_cols); + set_size(new_n_rows, new_n_cols); return (*this).zeros(); } @@ -6938,11 +7033,11 @@ template inline const Mat& -Mat::ones(const uword in_elem) +Mat::ones(const uword new_n_elem) { arma_extra_debug_sigprint(); - set_size(in_elem); + set_size(new_n_elem); return fill(eT(1)); } @@ -6952,11 +7047,11 @@ template inline const Mat& -Mat::ones(const uword in_rows, const uword in_cols) +Mat::ones(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - set_size(in_rows, in_cols); + set_size(new_n_rows, new_n_cols); return fill(eT(1)); } @@ -6992,11 +7087,11 @@ template inline const Mat& -Mat::randu(const uword in_elem) +Mat::randu(const uword new_n_elem) { arma_extra_debug_sigprint(); - set_size(in_elem); + set_size(new_n_elem); return (*this).randu(); } @@ -7006,11 +7101,11 @@ template inline const Mat& -Mat::randu(const uword in_rows, const uword in_cols) +Mat::randu(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - set_size(in_rows, in_cols); + set_size(new_n_rows, new_n_cols); return (*this).randu(); } @@ -7046,11 +7141,11 @@ template inline const Mat& -Mat::randn(const uword in_elem) +Mat::randn(const uword new_n_elem) { arma_extra_debug_sigprint(); - set_size(in_elem); + set_size(new_n_elem); return (*this).randn(); } @@ -7060,11 +7155,11 @@ template inline const Mat& -Mat::randn(const uword in_rows, const uword in_cols) +Mat::randn(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - set_size(in_rows, in_cols); + set_size(new_n_rows, new_n_cols); return (*this).randn(); } @@ -7094,10 +7189,7 @@ const uword N = (std::min)(n_rows, n_cols); - for(uword ii=0; ii inline const Mat& -Mat::eye(const uword in_rows, const uword in_cols) +Mat::eye(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); - set_size(in_rows, in_cols); + set_size(new_n_rows, new_n_cols); return (*this).eye(); } @@ -7138,20 +7230,10 @@ { arma_extra_debug_sigprint(); - switch(vec_state) - { - default: - init_warm(0, 0); - break; - - case 1: - init_warm(0, 1); - break; - - case 2: - init_warm(1, 0); - break; - } + const uword new_n_rows = (vec_state == 2) ? 1 : 0; + const uword new_n_cols = (vec_state == 1) ? 1 : 0; + + init_warm(new_n_rows, new_n_cols); } @@ -7171,7 +7253,7 @@ } else { - fill(Datum::nan); + zeros(); } } @@ -7348,7 +7430,7 @@ inline arma_cold bool -Mat::save(const std::string name, const file_type type, const bool print_status) const +Mat::save(const std::string name, const file_type type) const { arma_extra_debug_sigprint(); @@ -7364,8 +7446,16 @@ save_okay = diskio::save_arma_ascii(*this, name); break; - case csv_ascii: - save_okay = diskio::save_csv_ascii(*this, name); + case csv_ascii: + return (*this).save(csv_name(name), type); + break; + + case ssv_ascii: + return (*this).save(csv_name(name), type); + break; + + case coord_ascii: + save_okay = diskio::save_coord_ascii(*this, name); break; case raw_binary: @@ -7389,11 +7479,11 @@ break; default: - if(print_status) { arma_debug_warn("Mat::save(): unsupported file type"); } + arma_debug_warn_level(1, "Mat::save(): unsupported file type"); save_okay = false; } - if(print_status && (save_okay == false)) { arma_debug_warn("Mat::save(): couldn't write to ", name); } + if(save_okay == false) { arma_debug_warn_level(3, "Mat::save(): couldn't write; file: ", name); } return save_okay; } @@ -7404,7 +7494,7 @@ inline arma_cold bool -Mat::save(const hdf5_name& spec, const file_type type, const bool print_status) const +Mat::save(const hdf5_name& spec, const file_type type) const { arma_extra_debug_sigprint(); @@ -7412,7 +7502,7 @@ if( (type != hdf5_binary) && (type != hdf5_binary_trans) ) { - arma_debug_check(true, "Mat::save(): unsupported file type for hdf5_name()"); + arma_stop_runtime_error("Mat::save(): unsupported file type for hdf5_name()"); return false; } @@ -7422,11 +7512,12 @@ if(append && replace) { - arma_debug_check(true, "Mat::save(): only one of 'append' or 'replace' options can be used"); + arma_stop_runtime_error("Mat::save(): only one of 'append' or 'replace' options can be used"); return false; } bool save_okay = false; + std::string err_msg; if(do_trans) @@ -7442,18 +7533,96 @@ save_okay = diskio::save_hdf5_binary(*this, spec, err_msg); } - if((print_status == true) && (save_okay == false)) + if(save_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("Mat::save(): ", err_msg, spec.filename); + arma_debug_warn_level(3, "Mat::save(): ", err_msg, "; file: ", spec.filename); } else { - arma_debug_warn("Mat::save(): couldn't write to ", spec.filename); + arma_debug_warn_level(3, "Mat::save(): couldn't write; file: ", spec.filename); + } + } + + return save_okay; + } + + + +template +inline +arma_cold +bool +Mat::save(const csv_name& spec, const file_type type) const + { + arma_extra_debug_sigprint(); + + if( (type != csv_ascii) && (type != ssv_ascii) ) + { + arma_stop_runtime_error("Mat::save(): unsupported file type for csv_name()"); + return false; + } + + const bool do_trans = bool(spec.opts.flags & csv_opts::flag_trans ); + const bool no_header = bool(spec.opts.flags & csv_opts::flag_no_header ); + bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header); + const bool use_semicolon = bool(spec.opts.flags & csv_opts::flag_semicolon ) || (type == ssv_ascii); + + arma_extra_debug_print("Mat::save(csv_name): enabled flags:"); + + if(do_trans ) { arma_extra_debug_print("trans"); } + if(no_header ) { arma_extra_debug_print("no_header"); } + if(with_header ) { arma_extra_debug_print("with_header"); } + if(use_semicolon) { arma_extra_debug_print("semicolon"); } + + const char separator = (use_semicolon) ? char(';') : char(','); + + if(no_header) { with_header = false; } + + if(with_header) + { + if( (spec.header_ro.n_cols != 1) && (spec.header_ro.n_rows != 1) ) + { + arma_debug_warn_level(1, "Mat::save(): given header must have a vector layout"); + return false; + } + + for(uword i=0; i < spec.header_ro.n_elem; ++i) + { + const std::string& token = spec.header_ro.at(i); + + if(token.find(separator) != std::string::npos) + { + arma_debug_warn_level(1, "Mat::save(): token within the header contains the separator character: '", token, "'"); + return false; + } + } + + const uword save_n_cols = (do_trans) ? (*this).n_rows : (*this).n_cols; + + if(spec.header_ro.n_elem != save_n_cols) + { + arma_debug_warn_level(1, "Mat::save(): size mistmach between header and matrix"); + return false; } } + bool save_okay = false; + + if(do_trans) + { + const Mat tmp = (*this).st(); + + save_okay = diskio::save_csv_ascii(tmp, spec.filename, spec.header_ro, with_header, separator); + } + else + { + save_okay = diskio::save_csv_ascii(*this, spec.filename, spec.header_ro, with_header, separator); + } + + if(save_okay == false) { arma_debug_warn_level(3, "Mat::save(): couldn't write; file: ", spec.filename); } + return save_okay; } @@ -7464,7 +7633,7 @@ inline arma_cold bool -Mat::save(std::ostream& os, const file_type type, const bool print_status) const +Mat::save(std::ostream& os, const file_type type) const { arma_extra_debug_sigprint(); @@ -7481,7 +7650,15 @@ break; case csv_ascii: - save_okay = diskio::save_csv_ascii(*this, os); + save_okay = diskio::save_csv_ascii(*this, os, char(',')); + break; + + case ssv_ascii: + save_okay = diskio::save_csv_ascii(*this, os, char(';')); + break; + + case coord_ascii: + save_okay = diskio::save_coord_ascii(*this, os); break; case raw_binary: @@ -7497,11 +7674,11 @@ break; default: - if(print_status) { arma_debug_warn("Mat::save(): unsupported file type"); } + arma_debug_warn_level(1, "Mat::save(): unsupported file type"); save_okay = false; } - if(print_status && (save_okay == false)) { arma_debug_warn("Mat::save(): couldn't write to the given stream"); } + if(save_okay == false) { arma_debug_warn_level(3, "Mat::save(): couldn't write to stream"); } return save_okay; } @@ -7513,7 +7690,7 @@ inline arma_cold bool -Mat::load(const std::string name, const file_type type, const bool print_status) +Mat::load(const std::string name, const file_type type) { arma_extra_debug_sigprint(); @@ -7535,7 +7712,15 @@ break; case csv_ascii: - load_okay = diskio::load_csv_ascii(*this, name, err_msg); + return (*this).load(csv_name(name), type); + break; + + case ssv_ascii: + return (*this).load(csv_name(name), type); + break; + + case coord_ascii: + load_okay = diskio::load_coord_ascii(*this, name, err_msg); break; case raw_binary: @@ -7559,26 +7744,23 @@ break; default: - if(print_status) { arma_debug_warn("Mat::load(): unsupported file type"); } + arma_debug_warn_level(1, "Mat::load(): unsupported file type"); load_okay = false; } - if( (print_status == true) && (load_okay == false) ) + if(load_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("Mat::load(): ", err_msg, name); + arma_debug_warn_level(3, "Mat::load(): ", err_msg, "; file: ", name); } else { - arma_debug_warn("Mat::load(): couldn't read ", name); + arma_debug_warn_level(3, "Mat::load(): couldn't read; file: ", name); } } - if(load_okay == false) - { - (*this).soft_reset(); - } + if(load_okay == false) { (*this).soft_reset(); } return load_okay; } @@ -7589,14 +7771,13 @@ inline arma_cold bool -Mat::load(const hdf5_name& spec, const file_type type, const bool print_status) +Mat::load(const hdf5_name& spec, const file_type type) { arma_extra_debug_sigprint(); if( (type != hdf5_binary) && (type != hdf5_binary_trans) ) { - if(print_status) { arma_debug_warn("Mat::load(): unsupported file type for hdf5_name()"); } - (*this).soft_reset(); + arma_stop_runtime_error("Mat::load(): unsupported file type for hdf5_name()"); return false; } @@ -7619,21 +7800,106 @@ } - if( (print_status == true) && (load_okay == false) ) + if(load_okay == false) + { + if(err_msg.length() > 0) + { + arma_debug_warn_level(3, "Mat::load(): ", err_msg, "; file: ", spec.filename); + } + else + { + arma_debug_warn_level(3, "Mat::load(): couldn't read; file: ", spec.filename); + } + } + + if(load_okay == false) { (*this).soft_reset(); } + + return load_okay; + } + + + +template +inline +arma_cold +bool +Mat::load(const csv_name& spec, const file_type type) + { + arma_extra_debug_sigprint(); + + if( (type != csv_ascii) && (type != ssv_ascii) ) + { + arma_stop_runtime_error("Mat::load(): unsupported file type for csv_name()"); + return false; + } + + const bool do_trans = bool(spec.opts.flags & csv_opts::flag_trans ); + const bool no_header = bool(spec.opts.flags & csv_opts::flag_no_header ); + bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header); + const bool use_semicolon = bool(spec.opts.flags & csv_opts::flag_semicolon ) || (type == ssv_ascii); + + arma_extra_debug_print("Mat::load(csv_name): enabled flags:"); + + if(do_trans ) { arma_extra_debug_print("trans"); } + if(no_header ) { arma_extra_debug_print("no_header"); } + if(with_header ) { arma_extra_debug_print("with_header"); } + if(use_semicolon) { arma_extra_debug_print("semicolon"); } + + const char separator = (use_semicolon) ? char(';') : char(','); + + if(no_header) { with_header = false; } + + bool load_okay = false; + std::string err_msg; + + if(do_trans) + { + Mat tmp_mat; + + load_okay = diskio::load_csv_ascii(tmp_mat, spec.filename, err_msg, spec.header_rw, with_header, separator); + + if(load_okay) + { + (*this) = tmp_mat.st(); + + if(with_header) + { + // field::set_size() preserves data if the number of elements hasn't changed + spec.header_rw.set_size(spec.header_rw.n_elem, 1); + } + } + } + else + { + load_okay = diskio::load_csv_ascii(*this, spec.filename, err_msg, spec.header_rw, with_header, separator); + } + + if(load_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("Mat::load(): ", err_msg, spec.filename); + arma_debug_warn_level(3, "Mat::load(): ", err_msg, "; file: ", spec.filename); } else { - arma_debug_warn("Mat::load(): couldn't read ", spec.filename); + arma_debug_warn_level(3, "Mat::load(): couldn't read; file: ", spec.filename); + } + } + else + { + const uword load_n_cols = (do_trans) ? (*this).n_rows : (*this).n_cols; + + if(with_header && (spec.header_rw.n_elem != load_n_cols)) + { + arma_debug_warn_level(3, "Mat::load(): size mistmach between header and matrix"); } } if(load_okay == false) { (*this).soft_reset(); + + if(with_header) { spec.header_rw.reset(); } } return load_okay; @@ -7646,7 +7912,7 @@ inline arma_cold bool -Mat::load(std::istream& is, const file_type type, const bool print_status) +Mat::load(std::istream& is, const file_type type) { arma_extra_debug_sigprint(); @@ -7668,7 +7934,15 @@ break; case csv_ascii: - load_okay = diskio::load_csv_ascii(*this, is, err_msg); + load_okay = diskio::load_csv_ascii(*this, is, err_msg, char(',')); + break; + + case ssv_ascii: + load_okay = diskio::load_csv_ascii(*this, is, err_msg, char(';')); + break; + + case coord_ascii: + load_okay = diskio::load_coord_ascii(*this, is, err_msg); break; case raw_binary: @@ -7684,26 +7958,23 @@ break; default: - if(print_status) { arma_debug_warn("Mat::load(): unsupported file type"); } + arma_debug_warn_level(1, "Mat::load(): unsupported file type"); load_okay = false; } - if( (print_status == true) && (load_okay == false) ) + if(load_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("Mat::load(): ", err_msg, "the given stream"); + arma_debug_warn_level(3, "Mat::load(): ", err_msg); } else { - arma_debug_warn("Mat::load(): couldn't load from the given stream"); + arma_debug_warn_level(3, "Mat::load(): couldn't load from stream"); } } - if(load_okay == false) - { - (*this).soft_reset(); - } + if(load_okay == false) { (*this).soft_reset(); } return load_okay; } @@ -7719,7 +7990,7 @@ { arma_extra_debug_sigprint(); - return (*this).save(name, type, false); + return (*this).save(name, type); } @@ -7732,7 +8003,20 @@ { arma_extra_debug_sigprint(); - return (*this).save(spec, type, false); + return (*this).save(spec, type); + } + + + +template +inline +arma_cold +bool +Mat::quiet_save(const csv_name& spec, const file_type type) const + { + arma_extra_debug_sigprint(); + + return (*this).save(spec, type); } @@ -7746,7 +8030,7 @@ { arma_extra_debug_sigprint(); - return (*this).save(os, type, false); + return (*this).save(os, type); } @@ -7760,7 +8044,7 @@ { arma_extra_debug_sigprint(); - return (*this).load(name, type, false); + return (*this).load(name, type); } @@ -7773,7 +8057,20 @@ { arma_extra_debug_sigprint(); - return (*this).load(spec, type, false); + return (*this).load(spec, type); + } + + + +template +inline +arma_cold +bool +Mat::quiet_load(const csv_name& spec, const file_type type) + { + arma_extra_debug_sigprint(); + + return (*this).load(spec, type); } @@ -7787,7 +8084,7 @@ { arma_extra_debug_sigprint(); - return (*this).load(is, type, false); + return (*this).load(is, type); } @@ -7795,12 +8092,13 @@ template inline Mat::row_iterator::row_iterator() - : M (NULL) + : M (nullptr) , current_row(0 ) , current_col(0 ) { arma_extra_debug_sigprint(); - // Technically this iterator is invalid (it does not point to a valid element) + + // NOTE: this instance of row_iterator is invalid (it does not point to a valid element) } @@ -7958,12 +8256,13 @@ template inline Mat::const_row_iterator::const_row_iterator() - : M (NULL) + : M (nullptr) , current_row(0 ) , current_col(0 ) { arma_extra_debug_sigprint(); - // Technically this iterator is invalid (it does not point to a valid element) + + // NOTE: this instance of const_row_iterator is invalid (it does not point to a valid element) } @@ -8133,8 +8432,8 @@ template inline Mat::row_col_iterator::row_col_iterator() - : M (NULL) - , current_ptr(NULL) + : M (nullptr) + , current_ptr(nullptr) , current_col(0 ) , current_row(0 ) { @@ -8325,8 +8624,8 @@ template inline Mat::const_row_col_iterator::const_row_col_iterator() - : M (NULL) - , current_ptr(NULL) + : M (nullptr) + , current_ptr(nullptr) , current_col(0 ) , current_row(0 ) { @@ -8607,7 +8906,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (col_num >= n_cols), "Mat::begin_col(): index out of bounds"); + arma_debug_check_bounds( (col_num >= n_cols), "Mat::begin_col(): index out of bounds" ); return colptr(col_num); } @@ -8621,7 +8920,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (col_num >= n_cols), "Mat::begin_col(): index out of bounds"); + arma_debug_check_bounds( (col_num >= n_cols), "Mat::begin_col(): index out of bounds" ); return colptr(col_num); } @@ -8635,7 +8934,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (col_num >= n_cols), "Mat::end_col(): index out of bounds"); + arma_debug_check_bounds( (col_num >= n_cols), "Mat::end_col(): index out of bounds" ); return colptr(col_num) + n_rows; } @@ -8649,7 +8948,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (col_num >= n_cols), "Mat::end_col(): index out of bounds"); + arma_debug_check_bounds( (col_num >= n_cols), "Mat::end_col(): index out of bounds" ); return colptr(col_num) + n_rows; } @@ -8663,7 +8962,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" ); + arma_debug_check_bounds( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" ); return typename Mat::row_iterator(*this, row_num, uword(0)); } @@ -8677,7 +8976,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" ); + arma_debug_check_bounds( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" ); return typename Mat::const_row_iterator(*this, row_num, uword(0)); } @@ -8691,7 +8990,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" ); + arma_debug_check_bounds( (row_num >= n_rows), "Mat::end_row(): index out of bounds" ); return typename Mat::row_iterator(*this, (row_num + uword(1)), 0); } @@ -8705,7 +9004,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" ); + arma_debug_check_bounds( (row_num >= n_rows), "Mat::end_row(): index out of bounds" ); return typename Mat::const_row_iterator(*this, (row_num + uword(1)), 0); } @@ -8785,6 +9084,7 @@ template inline +arma_warn_unused eT& Mat::front() { @@ -8797,6 +9097,7 @@ template inline +arma_warn_unused const eT& Mat::front() const { @@ -8809,6 +9110,7 @@ template inline +arma_warn_unused eT& Mat::back() { @@ -8821,6 +9123,7 @@ template inline +arma_warn_unused const eT& Mat::back() const { @@ -8838,6 +9141,16 @@ : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat::mem_local) ) { arma_extra_debug_sigprint_this(this); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Mat::fixed::constructor: zeroing memory"); + + eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]); + + arrayops::inplace_set_fixed( mem_use, eT(0) ); + } + #endif } @@ -8860,6 +9173,19 @@ template template +inline +Mat::fixed::fixed(const fill::scalar_holder f) + : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat::mem_local) ) + { + arma_extra_debug_sigprint_this(this); + + (*this).fill(f.scalar); + } + + + +template +template template inline Mat::fixed::fixed(const fill::fill_class&) @@ -8867,11 +9193,11 @@ { arma_extra_debug_sigprint_this(this); - if(is_same_type::yes) (*this).zeros(); - if(is_same_type::yes) (*this).ones(); - if(is_same_type::yes) (*this).eye(); - if(is_same_type::yes) (*this).randu(); - if(is_same_type::yes) (*this).randn(); + if(is_same_type::yes) { (*this).zeros(); } + if(is_same_type::yes) { (*this).ones(); } + if(is_same_type::yes) { (*this).eye(); } + if(is_same_type::yes) { (*this).randu(); } + if(is_same_type::yes) { (*this).randn(); } } @@ -8945,71 +9271,67 @@ -#if defined(ARMA_USE_CXX11) - - template - template - inline - Mat::fixed::fixed(const std::initializer_list& list) - : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat::mem_local) ) - { - arma_extra_debug_sigprint_this(this); - - (*this).operator=(list); - } +template +template +inline +Mat::fixed::fixed(const std::initializer_list& list) + : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat::mem_local) ) + { + arma_extra_debug_sigprint_this(this); + (*this).operator=(list); + } + + + +template +template +inline +Mat& +Mat::fixed::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + const uword N = uword(list.size()); - template - template - inline - Mat& - Mat::fixed::operator=(const std::initializer_list& list) - { - arma_extra_debug_sigprint(); - - const uword N = uword(list.size()); - - arma_debug_check( (N > fixed_n_elem), "Mat::fixed: initialiser list is too long" ); - - eT* this_mem = (*this).memptr(); - - arrayops::copy( this_mem, list.begin(), N ); - - for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); } - - return *this; - } + arma_debug_check( (N > fixed_n_elem), "Mat::fixed: initialiser list is too long" ); + eT* this_mem = (*this).memptr(); + arrayops::copy( this_mem, list.begin(), N ); - template - template - inline - Mat::fixed::fixed(const std::initializer_list< std::initializer_list >& list) - : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat::mem_local) ) - { - arma_extra_debug_sigprint_this(this); - - Mat::init(list); - } + for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); } + return *this; + } + + + +template +template +inline +Mat::fixed::fixed(const std::initializer_list< std::initializer_list >& list) + : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : Mat::mem_local) ) + { + arma_extra_debug_sigprint_this(this); + Mat::init(list); + } + + + +template +template +inline +Mat& +Mat::fixed::operator=(const std::initializer_list< std::initializer_list >& list) + { + arma_extra_debug_sigprint(); - template - template - inline - Mat& - Mat::fixed::operator=(const std::initializer_list< std::initializer_list >& list) - { - arma_extra_debug_sigprint(); - - Mat::init(list); - - return *this; - } + Mat::init(list); -#endif + return *this; + } @@ -9113,6 +9435,7 @@ template template arma_inline +arma_warn_unused const Op< typename Mat::template fixed::Mat_fixed_type, op_htrans > Mat::fixed::t() const { @@ -9124,6 +9447,7 @@ template template arma_inline +arma_warn_unused const Op< typename Mat::template fixed::Mat_fixed_type, op_htrans > Mat::fixed::ht() const { @@ -9135,6 +9459,7 @@ template template arma_inline +arma_warn_unused const Op< typename Mat::template fixed::Mat_fixed_type, op_strans > Mat::fixed::st() const { @@ -9220,7 +9545,7 @@ eT& Mat::fixed::operator() (const uword ii) { - arma_debug_check( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; } @@ -9234,7 +9559,7 @@ const eT& Mat::fixed::operator() (const uword ii) const { - arma_debug_check( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; } @@ -9276,7 +9601,7 @@ eT& Mat::fixed::operator() (const uword in_row, const uword in_col) { - arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds" ); const uword iq = in_row + in_col*fixed_n_rows; @@ -9292,7 +9617,7 @@ const eT& Mat::fixed::operator() (const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds" ); const uword iq = in_row + in_col*fixed_n_rows; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/memory.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/memory.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/memory.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/memory.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,10 +24,7 @@ { public: - inline arma_deprecated static uword enlarge_to_mult_of_chunksize(const uword n_elem); - - template inline arma_malloc static eT* acquire(const uword n_elem); - template inline arma_deprecated static eT* acquire_chunked(const uword n_elem); + template inline arma_malloc static eT* acquire(const uword n_elem); template arma_inline static void release(eT* mem); @@ -36,24 +35,13 @@ -//! no longer used; this function will be removed -inline -arma_deprecated -uword -memory::enlarge_to_mult_of_chunksize(const uword n_elem) - { - return n_elem; - } - - - template inline arma_malloc eT* memory::acquire(const uword n_elem) { - if(n_elem == 0) { return NULL; } + if(n_elem == 0) { return nullptr; } arma_debug_check ( @@ -63,7 +51,11 @@ eT* out_memptr; - #if defined(ARMA_USE_TBB_ALLOC) + #if defined(ARMA_ALIEN_MEM_ALLOC_FUNCTION) + { + out_memptr = (eT *) ARMA_ALIEN_MEM_ALLOC_FUNCTION(sizeof(eT)*n_elem); + } + #elif defined(ARMA_USE_TBB_ALLOC) { out_memptr = (eT *) scalable_malloc(sizeof(eT)*n_elem); } @@ -73,7 +65,7 @@ } #elif defined(ARMA_HAVE_POSIX_MEMALIGN) { - eT* memptr = NULL; + eT* memptr = nullptr; const size_t n_bytes = sizeof(eT)*size_t(n_elem); const size_t alignment = (n_bytes >= size_t(1024)) ? size_t(32) : size_t(16); @@ -81,7 +73,7 @@ // TODO: investigate apparent memory leak when using alignment >= 64 (as shown on Fedora 28, glibc 2.27) int status = posix_memalign((void **)&memptr, ( (alignment >= sizeof(void*)) ? alignment : sizeof(void*) ), n_bytes); - out_memptr = (status == 0) ? memptr : NULL; + out_memptr = (status == 0) ? memptr : nullptr; } #elif defined(_MSC_VER) { @@ -102,33 +94,25 @@ // TODO: for mingw, use __mingw_aligned_malloc - arma_check_bad_alloc( (out_memptr == NULL), "arma::memory::acquire(): out of memory" ); + arma_check_bad_alloc( (out_memptr == nullptr), "arma::memory::acquire(): out of memory" ); return out_memptr; } -//! no longer used; this function will be removed; replace with call to memory::acquire() -template -inline -arma_deprecated -eT* -memory::acquire_chunked(const uword n_elem) - { - return memory::acquire(n_elem); - } - - - template arma_inline void memory::release(eT* mem) { - if(mem == NULL) { return; } + if(mem == nullptr) { return; } - #if defined(ARMA_USE_TBB_ALLOC) + #if defined(ARMA_ALIEN_MEM_FREE_FUNCTION) + { + ARMA_ALIEN_MEM_FREE_FUNCTION( (void *)(mem) ); + } + #elif defined(ARMA_USE_TBB_ALLOC) { scalable_free( (void *)(mem) ); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mp_misc.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mp_misc.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mp_misc.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mp_misc.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtGlue_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtGlue_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtGlue_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtGlue_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,16 +22,16 @@ template -class mtGlue : public Base > +class mtGlue : public Base< out_eT, mtGlue > { public: typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = glue_type::template traits::is_row; - static const bool is_col = glue_type::template traits::is_col; - static const bool is_xvec = glue_type::template traits::is_xvec; + static constexpr bool is_row = glue_type::template traits::is_row; + static constexpr bool is_col = glue_type::template traits::is_col; + static constexpr bool is_xvec = glue_type::template traits::is_xvec; 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); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtGlueCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtGlueCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtGlueCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtGlueCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,7 +22,7 @@ template -class mtGlueCube : public BaseCube > +class mtGlueCube : public BaseCube< out_eT, mtGlueCube > { public: diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtGlueCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtGlueCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtGlueCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtGlueCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtGlue_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtGlue_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtGlue_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtGlue_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtOp_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtOp_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtOp_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtOp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,7 +24,7 @@ template -class mtOp : public Base > +class mtOp : public Base< out_eT, mtOp > { public: @@ -31,9 +33,9 @@ typedef typename T1::elem_type in_eT; - static const bool is_row = op_type::template traits::is_row; - static const bool is_col = op_type::template traits::is_col; - static const bool is_xvec = op_type::template traits::is_xvec; + static constexpr bool is_row = op_type::template traits::is_row; + static constexpr bool is_col = op_type::template traits::is_col; + static constexpr bool is_xvec = op_type::template traits::is_xvec; inline explicit mtOp(const T1& in_m); inline mtOp(const T1& in_m, const in_eT in_aux); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtOpCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtOpCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtOpCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtOpCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,15 +25,15 @@ template -class mtOpCube : public BaseCube > +class mtOpCube : public BaseCube< out_eT, mtOpCube > { public: typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; - + typedef typename T1::elem_type in_eT; - + 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); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtOpCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtOpCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtOpCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtOpCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtOp_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtOp_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtOp_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtOp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtSpGlue_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtSpGlue_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtSpGlue_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtSpGlue_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,16 +22,16 @@ template -class mtSpGlue : public SpBase > +class mtSpGlue : public SpBase< out_eT, mtSpGlue > { public: typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = spglue_type::template traits::is_row; - static const bool is_col = spglue_type::template traits::is_col; - static const bool is_xvec = spglue_type::template traits::is_xvec; + static constexpr bool is_row = spglue_type::template traits::is_row; + static constexpr bool is_col = spglue_type::template traits::is_col; + static constexpr bool is_xvec = spglue_type::template traits::is_xvec; inline mtSpGlue(const T1& in_A, const T2& in_B); inline ~mtSpGlue(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtSpGlue_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtSpGlue_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtSpGlue_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtSpGlue_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtSpOp_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtSpOp_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtSpOp_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtSpOp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,7 +25,7 @@ template -class mtSpOp : public SpBase > +class mtSpOp : public SpBase< out_eT, mtSpOp > { public: @@ -32,9 +34,9 @@ typedef typename T1::elem_type in_eT; - static const bool is_row = spop_type::template traits::is_row; - static const bool is_col = spop_type::template traits::is_col; - static const bool is_xvec = spop_type::template traits::is_xvec; + static constexpr bool is_row = spop_type::template traits::is_row; + static constexpr bool is_col = spop_type::template traits::is_col; + static constexpr bool is_xvec = spop_type::template traits::is_xvec; inline explicit mtSpOp(const T1& in_m); inline mtSpOp(const T1& in_m, const uword aux_uword_a, const uword aux_uword_b); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mtSpOp_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mtSpOp_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mtSpOp_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mtSpOp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mul_gemm.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemm.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mul_gemm.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemm.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -189,7 +191,7 @@ const TB& B, const eT alpha = eT(1), const eT beta = eT(0), - const typename arma_not_cx::result* junk = 0 + const typename arma_not_cx::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -212,7 +214,7 @@ const Mat& B, const eT alpha = eT(1), const eT beta = eT(0), - const typename arma_cx_only::result* junk = 0 + const typename arma_cx_only::result* junk = nullptr ) { arma_extra_debug_sigprint(); @@ -238,7 +240,7 @@ //! \brief //! Wrapper for ATLAS/BLAS dgemm function, using template arguments to control the arguments passed to dgemm. -//! Matrix 'C' is assumed to have been set to the correct size (i.e. taking into account transposes) +//! Matrix 'C' is assumed to have been set to the correct size (ie. taking into account transposes) template class gemm @@ -261,7 +263,7 @@ } else { - Mat BB(B.n_rows, B.n_rows); + Mat BB(B.n_rows, B.n_rows, arma_nozeros_indicator()); op_strans::apply_mat_noalias_tinysq(BB, B); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mul_gemm_mixed.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemm_mixed.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mul_gemm_mixed.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemm_mixed.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,7 +24,7 @@ //! \brief //! Matrix multplication where the matrices have differing element types. //! Uses caching for speedup. -//! Matrix 'C' is assumed to have been set to the correct size (i.e. taking into account transposes) +//! Matrix 'C' is assumed to have been set to the correct size (ie. taking into account transposes) template class gemm_mixed_large diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mul_gemv.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemv.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mul_gemv.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemv.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,9 +31,9 @@ template struct pos { - static const uword n2 = (do_trans_A == false) ? (row + col*2) : (col + row*2); - static const uword n3 = (do_trans_A == false) ? (row + col*3) : (col + row*3); - static const uword n4 = (do_trans_A == false) ? (row + col*4) : (col + row*4); + static constexpr uword n2 = (do_trans_A == false) ? (row + col*2) : (col + row*2); + static constexpr uword n3 = (do_trans_A == false) ? (row + col*3) : (col + row*3); + static constexpr uword n4 = (do_trans_A == false) ? (row + col*4) : (col + row*4); }; @@ -208,7 +210,7 @@ //! \brief //! Partial emulation of ATLAS/BLAS gemv(). -//! 'y' is assumed to have been set to the correct size (i.e. taking into account the transpose) +//! 'y' is assumed to have been set to the correct size (ie. taking into account the transpose) template class gemv_emul @@ -292,7 +294,7 @@ //! \brief //! Wrapper for ATLAS/BLAS gemv function, using template arguments to control the arguments passed to gemv. -//! 'y' is assumed to have been set to the correct size (i.e. taking into account the transpose) +//! 'y' is assumed to have been set to the correct size (ie. taking into account the transpose) template class gemv diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mul_herk.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mul_herk.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mul_herk.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mul_herk.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -316,7 +318,7 @@ inline static void - apply_blas_type( Mat >& C, const TA& A, const T alpha = T(1), const T beta = T(0) ) + apply_blas_type( Mat>& C, const TA& A, const T alpha = T(1), const T beta = T(0) ) { arma_extra_debug_sigprint(); @@ -345,7 +347,7 @@ typedef typename std::complex eT; // use a temporary matrix, as we can't assume that matrix C is already symmetric - Mat D(C.n_rows, C.n_cols); + Mat D(C.n_rows, C.n_cols, arma_nozeros_indicator()); herk::apply_blas_type(D,A,alpha); @@ -379,7 +381,7 @@ typedef typename std::complex eT; // use a temporary matrix, as we can't assume that matrix C is already symmetric - Mat D(C.n_rows, C.n_cols); + Mat D(C.n_rows, C.n_cols, arma_nozeros_indicator()); herk::apply_blas_type(D,A,alpha); @@ -436,7 +438,7 @@ inline static void - apply( Mat& C, const TA& A, const eT alpha = eT(1), const eT beta = eT(0), const typename arma_not_cx::result* junk = 0 ) + apply( Mat& C, const TA& A, const eT alpha = eT(1), const eT beta = eT(0), const typename arma_not_cx::result* junk = nullptr ) { arma_ignore(C); arma_ignore(A); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/mul_syrk.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/mul_syrk.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/mul_syrk.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/mul_syrk.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -304,7 +306,7 @@ if(use_beta == true) { // use a temporary matrix, as we can't assume that matrix C is already symmetric - Mat D(C.n_rows, C.n_cols); + Mat D(C.n_rows, C.n_cols, arma_nozeros_indicator()); syrk::apply_blas_type(D,A,alpha); @@ -336,7 +338,7 @@ if(use_beta == true) { // use a temporary matrix, as we can't assume that matrix C is already symmetric - Mat D(C.n_rows, C.n_cols); + Mat D(C.n_rows, C.n_cols, arma_nozeros_indicator()); syrk::apply_blas_type(D,A,alpha); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_cx_attrib.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_cx_attrib.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_cx_attrib.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_cx_attrib.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_DenseGenMatProd_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_DenseGenMatProd_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_DenseGenMatProd_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_DenseGenMatProd_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_DenseGenMatProd_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_DenseGenMatProd_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_DenseGenMatProd_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_DenseGenMatProd_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_DoubleShiftQR_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_DoubleShiftQR_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_DoubleShiftQR_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_DoubleShiftQR_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_DoubleShiftQR_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_DoubleShiftQR_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_DoubleShiftQR_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_DoubleShiftQR_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -123,7 +125,7 @@ // Apply the first reflector apply_PX(mat_H, il, il, 3, n - il, il); - apply_XP(mat_H, 0, il, il + std::min(bsize, uword(4)), 3, il); + apply_XP(mat_H, 0, il, il + (std::min)(bsize, uword(4)), 3, il); // Calculate the following reflectors // If entering this loop, block size is at least 4. @@ -132,7 +134,7 @@ compute_reflector(mat_H.colptr(il + i - 1) + il + i, il + i); // Apply the reflector to X apply_PX(mat_H, il + i, il + i - 1, 3, n + 1 - il - i, il + i); - apply_XP(mat_H, 0, il + i, il + std::min(bsize, uword(i + 4)), 3, il + i); + apply_XP(mat_H, 0, il + i, il + (std::min)(bsize, uword(i + 4)), 3, il + i); } // The last reflector diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_EigsSelect.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_EigsSelect.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_EigsSelect.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_EigsSelect.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_GenEigsSolver_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_GenEigsSolver_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_GenEigsSolver_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_GenEigsSolver_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -24,7 +26,7 @@ { protected: - const OpType& op; // object to conduct matrix operation, e.g. matrix-vector product + const OpType& op; // object to conduct matrix operation, eg. matrix-vector product const uword nev; // number of eigenvalues requested Col< std::complex > ritz_val; // ritz values @@ -46,7 +48,7 @@ Col< std::complex > ritz_est; // last row of ritz_vec std::vector ritz_conv; // indicator of the convergence of ritz values const eT eps; // the machine precision - // e.g. ~= 1e-16 for double type + // eg. ~= 1e-16 for double type const eT approx0; // a number that is approximately zero // approx0 = eps^(2/3) // used to test the orthogonality of vectors, diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_GenEigsSolver_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_GenEigsSolver_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_GenEigsSolver_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_GenEigsSolver_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,7 +31,7 @@ fac_f = fk; - Col w(dim_n); + Col w(dim_n, arma_zeros_indicator()); eT beta = norm(fac_f); // Keep the upperleft k x k submatrix of H and set other elements to 0 fac_H.tail_cols(ncv - from_k).zeros(); @@ -151,10 +153,11 @@ fac_H.diag() += ritz_val(i).real(); } } + // V -> VQ // Q has some elements being zero // The first (ncv - k + i) elements of the i-th column of Q are non-zero - Mat Vs(dim_n, k + 1); + Mat Vs(dim_n, k + 1, arma_nozeros_indicator()); uword nnz; for(uword i = 0; i < k; i++) { @@ -186,7 +189,7 @@ const eT f_norm = arma::norm(fac_f); for(uword i = 0; i < nev; i++) { - eT thresh = tol * std::max(approx0, std::abs(ritz_val(i))); + eT thresh = tol * (std::max)(approx0, std::abs(ritz_val(i))); eT resid = std::abs(ritz_est(i)) * f_norm; ritz_conv[i] = (resid < thresh); } @@ -210,7 +213,7 @@ if(std::abs(ritz_est(i)) < eps) { nev_new++; } } // Adjust nev_new again, according to dnaup2.f line 660~674 in ARPACK - nev_new += std::min(nconv, (ncv - nev_new) / 2); + nev_new += (std::min)(nconv, (ncv - nev_new) / 2); if(nev_new == 1 && ncv >= 6) { nev_new = ncv / 2; @@ -278,8 +281,8 @@ std::vector ind = sorting.index(); - Col< std::complex > new_ritz_val(ncv); - Mat< std::complex > new_ritz_vec(ncv, nev); + Col< std::complex > new_ritz_val(ncv, arma_zeros_indicator() ); + Mat< std::complex > new_ritz_vec(ncv, nev, arma_nozeros_indicator()); std::vector new_ritz_conv(nev); for(uword i = 0; i < nev; i++) @@ -342,7 +345,7 @@ arma_check( (rnorm < eps), "newarp::GenEigsSolver::init(): initial residual vector cannot be zero" ); v = r / rnorm; - Col w(dim_n); + Col w(dim_n, arma_zeros_indicator()); op.perform_op(v.memptr(), w.memptr()); nmatop++; @@ -394,7 +397,7 @@ niter = i + 1; - return std::min(nev, nconv); + return (std::min)(nev, nconv); } @@ -407,7 +410,7 @@ arma_extra_debug_sigprint(); uword nconv = std::count(ritz_conv.begin(), ritz_conv.end(), true); - Col< std::complex > res(nconv); + Col< std::complex > res(nconv, arma_zeros_indicator()); if(nconv > 0) { @@ -435,12 +438,12 @@ arma_extra_debug_sigprint(); uword nconv = std::count(ritz_conv.begin(), ritz_conv.end(), true); - nvec = std::min(nvec, nconv); + nvec = (std::min)(nvec, nconv); Mat< std::complex > res(dim_n, nvec); if(nvec > 0) { - Mat< std::complex > ritz_vec_conv(ncv, nvec); + Mat< std::complex > ritz_vec_conv(ncv, nvec, arma_zeros_indicator()); uword j = 0; for(uword i = 0; (i < nev) && (j < nvec); i++) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SortEigenvalue.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SortEigenvalue.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SortEigenvalue.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SortEigenvalue.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +namespace newarp +{ + + +//! Define matrix operations on existing matrix objects +template +class SparseGenRealShiftSolve + { + private: + + #if defined(ARMA_USE_SUPERLU) + // The following objects are read-only in perform_op() + mutable superlu_supermatrix_wrangler l; + mutable superlu_supermatrix_wrangler u; + mutable superlu_array_wrangler perm_c; + mutable superlu_array_wrangler perm_r; + #endif + + + public: + + bool valid = false; + + const uword n_rows; // number of rows of the underlying matrix + const uword n_cols; // number of columns of the underlying matrix + + inline SparseGenRealShiftSolve(const SpMat& mat_obj, const eT shift); + + inline void perform_op(eT* x_in, eT* y_out) const; + }; + + +} // namespace newarp diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +namespace newarp +{ + + +template +inline +SparseGenRealShiftSolve::SparseGenRealShiftSolve(const SpMat& mat_obj, const eT shift) + #if defined(ARMA_USE_SUPERLU) + : perm_c(mat_obj.n_cols + 1) + , perm_r(mat_obj.n_rows + 1) + , n_rows(mat_obj.n_rows) + , n_cols(mat_obj.n_cols) + #endif + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_SUPERLU) + { + // Derived from sp_auxlib::run_aupd_shiftinvert() + superlu_opts superlu_opts_default; + superlu::superlu_options_t options; + sp_auxlib::set_superlu_opts(options, superlu_opts_default); + + superlu::GlobalLU_t Glu; + arrayops::fill_zeros(reinterpret_cast(&Glu), sizeof(superlu::GlobalLU_t)); + + superlu_supermatrix_wrangler x; + superlu_supermatrix_wrangler xC; + superlu_array_wrangler etree(mat_obj.n_cols+1); + + // Copy A-shift*I to x + const bool status_x = sp_auxlib::copy_to_supermatrix_with_shift(x.get_ref(), mat_obj, shift); + + if(status_x == false) { arma_stop_runtime_error("newarp::SparseGenRealShiftSolve::SparseGenRealShiftSolve(): could not construct SuperLU matrix"); return; } + + int panel_size = superlu::sp_ispec_environ(1); + int relax = superlu::sp_ispec_environ(2); + int slu_info = 0; // Return code + int lwork = 0; // lwork = 0: allocate space internally by system malloc + + superlu_stat_wrangler stat; + + arma_extra_debug_print("superlu::gstrf()"); + superlu::get_permutation_c(options.ColPerm, x.get_ptr(), perm_c.get_ptr()); + superlu::sp_preorder_mat(&options, x.get_ptr(), perm_c.get_ptr(), etree.get_ptr(), xC.get_ptr()); + superlu::gstrf(&options, xC.get_ptr(), relax, panel_size, etree.get_ptr(), NULL, lwork, perm_c.get_ptr(), perm_r.get_ptr(), l.get_ptr(), u.get_ptr(), &Glu, stat.get_ptr(), &slu_info); + + if(slu_info != 0) + { + arma_debug_warn_level(2, "matrix is singular to working precision"); + return; + } + + eT x_norm_val = sp_auxlib::norm1(x.get_ptr()); + eT x_rcond = sp_auxlib::lu_rcond(l.get_ptr(), u.get_ptr(), x_norm_val); + + if( (x_rcond < std::numeric_limits::epsilon()) || arma_isnan(x_rcond) ) + { + if(x_rcond > eT(0)) { arma_debug_warn_level(2, "matrix is singular to working precision (rcond: ", x_rcond, ")"); } + else { arma_debug_warn_level(2, "matrix is singular to working precision"); } + return; + } + + valid = true; + } + #else + { + arma_ignore(mat_obj); + arma_ignore(shift); + } + #endif + } + + + +// Perform the shift-solve operation \f$y=(A-\sigma I)^{-1}x\f$. +// y_out = inv(A - sigma * I) * x_in +template +inline +void +SparseGenRealShiftSolve::perform_op(eT* x_in, eT* y_out) const + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_SUPERLU) + { + const Col x(x_in , n_cols, false, true); + Col y(y_out, n_rows, false, true); + + // Derived from sp_auxlib::run_aupd_shiftinvert() + y = x; + superlu_supermatrix_wrangler out_slu; + + const bool status_out_slu = sp_auxlib::wrap_to_supermatrix(out_slu.get_ref(), y); + + if(status_out_slu == false) { arma_stop_runtime_error("newarp::SparseGenRealShiftSolve::perform_op(): could not construct SuperLU matrix"); return; } + + superlu_stat_wrangler stat; + int info = 0; + + arma_extra_debug_print("superlu::gstrs()"); + superlu::gstrs(superlu::NOTRANS, l.get_ptr(), u.get_ptr(), perm_c.get_ptr(), perm_r.get_ptr(), out_slu.get_ptr(), stat.get_ptr(), &info); + + if(info != 0) { arma_stop_runtime_error("newarp::SparseGenRealShiftSolve::perform_op(): could not solve linear equation"); return; } + + // No need to modify memory further since it was all done in-place. + } + #else + { + arma_ignore(x_in); + arma_ignore(y_out); + } + #endif + } + + +} // namespace newarp diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SymEigsShiftSolver_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsShiftSolver_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SymEigsShiftSolver_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsShiftSolver_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +namespace newarp +{ + + +//! This class implements the eigen solver for real symmetric matrices in the shift-and-invert mode. +template +class SymEigsShiftSolver : public SymEigsSolver + { + private: + + const eT sigma; + + // Sort the first nev Ritz pairs in ascending algebraic order + // This is used to return the final results + void sort_ritzpair(); + + + public: + + //! Constructor to create a solver object. + inline SymEigsShiftSolver(const OpType& op_, uword nev_, uword ncv_, const eT sigma_); + }; + + +} // namespace newarp diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SymEigsShiftSolver_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsShiftSolver_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SymEigsShiftSolver_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsShiftSolver_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +namespace newarp +{ + + +template +inline +void +SymEigsShiftSolver::sort_ritzpair() + { + arma_extra_debug_sigprint(); + + // First transform back the Ritz values, and then sort + for(uword i = 0; i < this->nev; i++) + { + this->ritz_val(i) = eT(1.0) / this->ritz_val(i) + sigma; + } + SymEigsSolver::sort_ritzpair(); + } + + + +template +inline +SymEigsShiftSolver::SymEigsShiftSolver(const OpType& op_, uword nev_, uword ncv_, const eT sigma_) + : SymEigsSolver::SymEigsSolver(op_, nev_, ncv_) + , sigma(sigma_) + { + arma_extra_debug_sigprint(); + } + + +} // namespace newarp diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SymEigsSolver_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsSolver_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SymEigsSolver_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsSolver_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -24,11 +26,11 @@ { protected: - const OpType& op; // object to conduct matrix operation, e.g. matrix-vector product + const OpType& op; // object to conduct matrix operation, eg. matrix-vector product const uword nev; // number of eigenvalues requested Col ritz_val; // ritz values - // Sort the first nev Ritz pairs in decreasing magnitude order + // Sort the first nev Ritz pairs in ascending algebraic order // This is used to return the final results virtual void sort_ritzpair(); @@ -46,12 +48,10 @@ Col ritz_est; // last row of ritz_vec std::vector ritz_conv; // indicator of the convergence of ritz values const eT eps; // the machine precision - // e.g. ~= 1e-16 for double type - const eT approx0; // a number that is approximately zero - // approx0 = eps^(2/3) - // used to test the orthogonality of vectors, - // and in convergence test, tol*approx0 is - // the absolute tolerance + // eg. ~= 1e-16 for double type + const eT eps23; // eps^(2/3), used in convergence test + // tol*eps23 is the absolute tolerance + const eT near0; // a very small value, but 1/near0 does not overflow // Arnoldi factorisation starting from step-k inline void factorise_from(uword from_k, uword to_m, const Col& fk); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SymEigsSolver_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsSolver_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_SymEigsSolver_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsSolver_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,8 +31,11 @@ fac_f = fk; - Col w(dim_n); - eT beta = norm(fac_f), Hii = 0.0; + Col w(dim_n, arma_zeros_indicator()); + // Norm of f + eT beta = norm(fac_f); + // Used to test beta~=0 + const eT beta_thresh = eps * eop_aux::sqrt(dim_n); // Keep the upperleft k x k submatrix of H and set other elements to 0 fac_H.tail_cols(ncv - from_k).zeros(); fac_H.submat(span(from_k, ncv - 1), span(0, from_k - 1)).zeros(); @@ -40,7 +45,7 @@ // If beta = 0, then the next V is not full rank // We need to generate a new residual vector that is orthogonal // to the current V, which we call a restart - if(beta < eps) + if(beta < near0) { // Generate new random vector for fac_f blas_int idist = 2; @@ -63,14 +68,14 @@ v = fac_f / beta; // Note that H[i+1, i] equals to the unrestarted beta - if(restart) { fac_H(i, i - 1) = 0.0; } else { fac_H(i, i - 1) = beta; } + fac_H(i, i - 1) = restart ? eT(0) : beta; // w <- A * v, v = fac_V.col(i) op.perform_op(v.memptr(), w.memptr()); nmatop++; - Hii = dot(v, w); fac_H(i - 1, i) = fac_H(i, i - 1); // Due to symmetry + eT Hii = dot(v, w); fac_H(i, i) = Hii; // f <- w - V * V' * w = w - H[i+1, i] * V{i} - H[i+1, i+1] * V{i+1} @@ -90,10 +95,23 @@ // whether V' * (f/||f||) ~= 0 Mat Vs(fac_V.memptr(), dim_n, i + 1, false); // First i+1 columns Col Vf = Vs.t() * fac_f; + eT ortho_err = abs(Vf).max(); // If not, iteratively correct the residual uword count = 0; - while(count < 5 && abs(Vf).max() > approx0 * beta) + while(count < 5 && ortho_err > eps * beta) { + // There is an edge case: when beta=||f|| is close to zero, f mostly consists + // of rounding errors, so the test [ortho_err < eps * beta] is very + // likely to fail. In particular, if beta=0, then the test is ensured to fail. + // Hence when this happens, we force f to be zero, and then restart in the + // next iteration. + if(beta < beta_thresh) + { + fac_f.zeros(); + beta = eT(0); + break; + } + // f <- f - V * Vf fac_f -= Vs * Vf; // h <- h + Vf @@ -104,6 +122,7 @@ beta = norm(fac_f); Vf = Vs.t() * fac_f; + ortho_err = abs(Vf).max(); count++; } } @@ -121,7 +140,7 @@ if(k >= ncv) { return; } TridiagQR decomp; - Mat Q = eye< Mat >(ncv, ncv); + Mat Q(ncv, ncv, fill::eye); for(uword i = k; i < ncv; i++) { @@ -142,22 +161,27 @@ // V -> VQ, only need to update the first k+1 columns // Q has some elements being zero // The first (ncv - k + i) elements of the i-th column of Q are non-zero - Mat Vs(dim_n, k + 1); + Mat Vs(dim_n, k + 1, arma_nozeros_indicator()); uword nnz; for(uword i = 0; i < k; i++) { nnz = ncv - k + i + 1; Mat V(fac_V.memptr(), dim_n, nnz, false); Col q(Q.colptr(i), nnz, false); - Vs.col(i) = V * q; + // OLD CODE: + // Vs.col(i) = V * q; + // NEW CODE: + Col v(Vs.colptr(i), dim_n, false, true); + v = V * q; } + Vs.col(k) = fac_V * Q.col(k); fac_V.head_cols(k + 1) = Vs; Col fk = fac_f * Q(ncv - 1, k - 1) + fac_V.col(k) * fac_H(k, k - 1); factorise_from(k, ncv, fk); retrieve_ritzpair(); -} + } @@ -172,7 +196,7 @@ const eT f_norm = norm(fac_f); for(uword i = 0; i < nev; i++) { - eT thresh = tol * std::max(approx0, std::abs(ritz_val(i))); + eT thresh = tol * (std::max)(eps23, std::abs(ritz_val(i))); eT resid = std::abs(ritz_est(i)) * f_norm; ritz_conv[i] = (resid < thresh); } @@ -192,11 +216,11 @@ uword nev_new = nev; for(uword i = nev; i < ncv; i++) { - if(std::abs(ritz_est(i)) < eps) { nev_new++; } + if(std::abs(ritz_est(i)) < near0) { nev_new++; } } // Adjust nev_new, according to dsaup2.f line 677~684 in ARPACK - nev_new += std::min(nconv, (ncv - nev_new) / 2); + nev_new += (std::min)(nconv, (ncv - nev_new) / 2); if(nev_new >= ncv) { nev_new = ncv - 1; } if(nev_new == 1 && ncv >= 6) { @@ -269,13 +293,13 @@ // SortEigenvalue sorting(ritz_val.memptr(), nev); - // sort Ritz values in ascending algebraic, to be consistent with ARPACK + // Sort Ritz values in ascending algebraic, to be consistent with ARPACK SortEigenvalue sorting(ritz_val.memptr(), nev); std::vector ind = sorting.index(); - Col new_ritz_val(ncv); - Mat new_ritz_vec(ncv, nev); + Col new_ritz_val(ncv, arma_zeros_indicator() ); + Mat new_ritz_vec(ncv, nev, arma_nozeros_indicator()); std::vector new_ritz_conv(nev); for(uword i = 0; i < nev; i++) @@ -302,7 +326,8 @@ , nmatop(0) , niter(0) , eps(std::numeric_limits::epsilon()) - , approx0(std::pow(eps, eT(2.0) / 3)) + , eps23(std::pow(eps, eT(2.0) / 3)) + , near0(std::numeric_limits::min() * eT(10)) { arma_extra_debug_sigprint(); @@ -335,15 +360,19 @@ // The first column of fac_V Col v(fac_V.colptr(0), dim_n, false); eT rnorm = norm(r); - arma_check( (rnorm < eps), "newarp::SymEigsSolver::init(): initial residual vector cannot be zero" ); + arma_check( (rnorm < near0), "newarp::SymEigsSolver::init(): initial residual vector cannot be zero" ); v = r / rnorm; - Col w(dim_n); + Col w(dim_n, arma_zeros_indicator()); op.perform_op(v.memptr(), w.memptr()); nmatop++; fac_H(0, 0) = dot(v, w); fac_f = w - v * fac_H(0, 0); + + // In some cases f is zero in exact arithmetics, but due to rounding errors + // it may contain tiny fluctuations. When this happens, we force f to be zero + if(abs(fac_f).max() < eps) { fac_f.zeros(); } } @@ -390,7 +419,7 @@ niter = i + 1; - return std::min(nev, nconv); + return (std::min)(nev, nconv); } @@ -403,7 +432,7 @@ arma_extra_debug_sigprint(); uword nconv = std::count(ritz_conv.begin(), ritz_conv.end(), true); - Col res(nconv); + Col res(nconv, arma_zeros_indicator()); if(nconv > 0) { @@ -431,12 +460,12 @@ arma_extra_debug_sigprint(); uword nconv = std::count(ritz_conv.begin(), ritz_conv.end(), true); - nvec = std::min(nvec, nconv); + nvec = (std::min)(nvec, nconv); Mat res(dim_n, nvec); if(nvec > 0) { - Mat ritz_vec_conv(ncv, nvec); + Mat ritz_vec_conv(ncv, nvec, arma_zeros_indicator()); uword j = 0; for(uword i = 0; i < nev && j < nvec; i++) diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_TridiagEigen_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_TridiagEigen_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_TridiagEigen_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_TridiagEigen_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_TridiagEigen_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_TridiagEigen_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_TridiagEigen_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_TridiagEigen_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -122,7 +124,7 @@ arma_debug_check( (computed == false), "newarp::UpperHessenbergEigen::eigenvectors(): need to call compute() first" ); // Lapack will set the imaginary parts of real eigenvalues to be exact zero - Mat< std::complex > evecs(n, n); + Mat< std::complex > evecs(n, n, arma_zeros_indicator()); std::complex* col_ptr = evecs.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_UpperHessenbergQR_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergQR_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_UpperHessenbergQR_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergQR_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_UpperHessenbergQR_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergQR_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/newarp_UpperHessenbergQR_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergQR_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -273,7 +275,7 @@ arma_debug_check( (this->computed == false), "newarp::TridiagQR::matrix_RQ(): need to call compute() first" ); // Make a copy of the R matrix - Mat RQ(this->n, this->n, fill::zeros); + Mat RQ(this->n, this->n, arma_zeros_indicator()); RQ.diag() = this->mat_T.diag(); RQ.diag(1) = this->mat_T.diag(1); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_all_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_all_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_all_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_all_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -46,8 +48,8 @@ all_vec_helper ( const mtOp& X, - const typename arma_op_rel_only::result junk1 = 0, - const typename arma_not_cx::result junk2 = 0 + const typename arma_op_rel_only::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr ); @@ -56,9 +58,9 @@ all_vec_helper ( const mtGlue& X, - const typename arma_glue_rel_only::result junk1 = 0, - const typename arma_not_cx::result junk2 = 0, - const typename arma_not_cx::result junk3 = 0 + const typename arma_glue_rel_only::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr, + const typename arma_not_cx::result* junk3 = nullptr ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_all_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_all_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_all_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_all_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -117,8 +119,8 @@ op_all::all_vec_helper ( const mtOp& X, - const typename arma_op_rel_only::result junk1, - const typename arma_not_cx::result junk2 + const typename arma_op_rel_only::result* junk1, + const typename arma_not_cx::result* junk2 ) { arma_extra_debug_sigprint(); @@ -189,9 +191,9 @@ op_all::all_vec_helper ( const mtGlue& X, - const typename arma_glue_rel_only::result junk1, - const typename arma_not_cx::result junk2, - const typename arma_not_cx::result junk3 + const typename arma_glue_rel_only::result* junk1, + const typename arma_not_cx::result* junk2, + const typename arma_not_cx::result* junk3 ) { arma_extra_debug_sigprint(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_any_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_any_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_any_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_any_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -46,8 +48,8 @@ any_vec_helper ( const mtOp& X, - const typename arma_op_rel_only::result junk1 = 0, - const typename arma_not_cx::result junk2 = 0 + const typename arma_op_rel_only::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr ); @@ -56,9 +58,9 @@ any_vec_helper ( const mtGlue& X, - const typename arma_glue_rel_only::result junk1 = 0, - const typename arma_not_cx::result junk2 = 0, - const typename arma_not_cx::result junk3 = 0 + const typename arma_glue_rel_only::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr, + const typename arma_not_cx::result* junk3 = nullptr ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_any_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_any_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_any_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_any_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -112,8 +114,8 @@ op_any::any_vec_helper ( const mtOp& X, - const typename arma_op_rel_only::result junk1, - const typename arma_not_cx::result junk2 + const typename arma_op_rel_only::result* junk1, + const typename arma_not_cx::result* junk2 ) { arma_extra_debug_sigprint(); @@ -183,9 +185,9 @@ op_any::any_vec_helper ( const mtGlue& X, - const typename arma_glue_rel_only::result junk1, - const typename arma_not_cx::result junk2, - const typename arma_not_cx::result junk3 + const typename arma_glue_rel_only::result* junk1, + const typename arma_not_cx::result* junk2, + const typename arma_not_cx::result* junk3 ) { arma_extra_debug_sigprint(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Op_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Op_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Op_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Op_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,24 +28,24 @@ template struct Op_traits { - static const bool is_row = op_type::template traits::is_row; - static const bool is_col = op_type::template traits::is_col; - static const bool is_xvec = op_type::template traits::is_xvec; + static constexpr bool is_row = op_type::template traits::is_row; + static constexpr bool is_col = op_type::template traits::is_col; + static constexpr bool is_xvec = op_type::template traits::is_xvec; }; template struct Op_traits { - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; }; template class Op - : public Base > - , public Op_traits::value > + : public Base< typename T1::elem_type, Op > + , public Op_traits::value> { public: diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_chi2rnd_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_chi2rnd_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_chi2rnd_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_chi2rnd_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,8 +37,6 @@ -#if defined(ARMA_USE_CXX11) - template class op_chi2rnd_varying_df { @@ -50,7 +50,5 @@ inline eT operator()(const eT df); }; -#endif - //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_chi2rnd_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_chi2rnd_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_chi2rnd_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_chi2rnd_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -53,46 +55,36 @@ { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_CXX11) + typedef typename T1::elem_type eT; + + op_chi2rnd_varying_df generator; + + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); + + out.set_size(n_rows, n_cols); + + eT* out_mem = out.memptr(); + + if(Proxy::use_at == false) { - typedef typename T1::elem_type eT; - - op_chi2rnd_varying_df generator; + const uword N = P.get_n_elem(); - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); + typename Proxy::ea_type Pea = P.get_ea(); - out.set_size(n_rows, n_cols); - - eT* out_mem = out.memptr(); - - if(Proxy::use_at == false) + for(uword i=0; i::ea_type Pea = P.get_ea(); - - for(uword i=0; i eT(0)) { - if(df > eT(0)) - { - typedef std::mt19937_64 motor_type; - typedef std::mt19937_64::result_type seed_type; - typedef std::chi_squared_distribution distr_type; - - motor_type motor; motor.seed( seed_type(arma_rng::randi()) ); - distr_type distr(df); - - const uword N = out.n_elem; - - eT* out_mem = out.memptr(); - - for(uword i=0; i distr_type; + + motor_type motor; motor.seed( seed_type(arma_rng::randi()) ); + distr_type distr(df); + + const uword N = out.n_elem; + + eT* out_mem = out.memptr(); + + for(uword i=0; i::nan ); + out_mem[i] = eT( distr(motor) ); } } - #else + else { - out.reset(); - arma_ignore(df); - - arma_stop_logic_error("chi2rnd(): C++11 compiler required"); + out.fill( Datum::nan ); } - #endif } @@ -145,8 +126,6 @@ -#if defined(ARMA_USE_CXX11) - template inline op_chi2rnd_varying_df::~op_chi2rnd_varying_df() @@ -192,8 +171,6 @@ } } -#endif - //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_chol_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_chol_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_chol_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_chol_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_chol_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_chol_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_chol_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_chol_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -54,20 +56,24 @@ // if(auxlib::rudimentary_sym_check(out) == false) // { - // if(is_cx::no ) { arma_debug_warn("chol(): given matrix is not symmetric"); } - // if(is_cx::yes) { arma_debug_warn("chol(): given matrix is not hermitian"); } + // if(is_cx::no ) { arma_debug_warn_level(1, "chol(): given matrix is not symmetric"); } + // if(is_cx::yes) { arma_debug_warn_level(1, "chol(): given matrix is not hermitian"); } // return false; // } if((arma_config::debug) && (auxlib::rudimentary_sym_check(out) == false)) { - if(is_cx::no ) { arma_debug_warn("chol(): given matrix is not symmetric"); } - if(is_cx::yes) { arma_debug_warn("chol(): given matrix is not hermitian"); } + if(is_cx::no ) { arma_debug_warn_level(1, "chol(): given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, "chol(): given matrix is not hermitian"); } } uword KD = 0; - const bool is_band = (auxlib::crippled_lapack(out)) ? false : ((layout == 0) ? band_helper::is_band_upper(KD, out, uword(32)) : band_helper::is_band_lower(KD, out, uword(32))); + #if defined(ARMA_OPTIMISE_BAND) + const bool is_band = (auxlib::crippled_lapack(out)) ? false : ((layout == 0) ? band_helper::is_band_upper(KD, out, uword(32)) : band_helper::is_band_lower(KD, out, uword(32))); + #else + const bool is_band = false; + #endif const bool status = (is_band) ? auxlib::chol_band(out, KD, layout) : auxlib::chol(out, layout); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_clamp_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_clamp_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_clamp_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_clamp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,17 +31,42 @@ template inline static void apply(Mat& out, const mtOp& in); - template inline static void apply_proxy_noalias(Mat& out, const Proxy& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val); - template inline static void apply_direct(Mat& out, const Mat& X, const eT min_val, const eT max_val); + template inline static void apply_proxy_noalias(Mat& out, const Proxy& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val); + // cubes template inline static void apply(Cube& out, const mtOpCube& in); + template inline static void apply_direct(Cube& out, const Cube& X, const eT min_val, const eT max_val); + template inline static void apply_proxy_noalias(Cube& out, const ProxyCube& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val); + }; + + + +class op_clamp_cx + : public traits_op_passthru + { + public: + + // matrices + + template inline static void apply(Mat& out, const mtOp& in); + + template inline static void apply_direct(Mat& out, const Mat& X, const eT min_val, const eT max_val); + + template inline static void apply_proxy_noalias(Mat& out, const Proxy& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val); + + + // cubes + + template inline static void apply(Cube& out, const mtOpCube& in); template inline static void apply_direct(Cube& out, const Cube& X, const eT min_val, const eT max_val); + + template inline static void apply_proxy_noalias(Cube& out, const ProxyCube& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_clamp_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_clamp_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_clamp_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_clamp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,17 +29,68 @@ { arma_extra_debug_sigprint(); - const Proxy P(in.m); + typedef typename T1::elem_type eT; + + const eT min_val = in.aux; + const eT max_val = in.aux_out_eT; + + arma_debug_check( (min_val > max_val), "clamp(): min_val must be less than max_val" ); - if(is_Mat::stored_type>::value || P.is_alias(out)) + if(is_Mat::value) + { + const unwrap U(in.m); + + op_clamp::apply_direct(out, U.M, min_val, max_val); + } + else { - const unwrap::stored_type> U(P.Q); + const Proxy P(in.m); + + if(P.is_alias(out)) + { + Mat tmp; + + op_clamp::apply_proxy_noalias(tmp, P, min_val, max_val); + + out.steal_mem(tmp); + } + else + { + op_clamp::apply_proxy_noalias(out, P, min_val, max_val); + } + } + } + + + +template +inline +void +op_clamp::apply_direct(Mat& out, const Mat& X, const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + if(&out != &X) + { + out.set_size(X.n_rows, X.n_cols); + + const uword N = out.n_elem; - op_clamp::apply_direct(out, U.M, in.aux, in.aux_out_eT); + const eT* X_mem = X.memptr(); + eT* out_mem = out.memptr(); + + for(uword i=0; i max_val) ? max_val : val); + } } else { - op_clamp::apply_proxy_noalias(out, P, in.aux, in.aux_out_eT); + arma_extra_debug_print("op_clamp::apply_direct(): inplace operation"); + + arrayops::clamp(out.memptr(), out.n_elem, min_val, max_val); } } @@ -65,40 +118,68 @@ typename Proxy::ea_type A = P.get_ea(); - uword j; - for(j=1; j max_val) ? max_val : val_i); - val_j = (val_j < min_val) ? min_val : ((val_j > max_val) ? max_val : val_j); + const eT val = A[i]; - (*out_mem) = val_i; out_mem++; - (*out_mem) = val_j; out_mem++; + out_mem[i] = (val < min_val) ? min_val : ((val > max_val) ? max_val : val); } - - const uword i = j-1; - - if(i < N) + } + else + { + for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) { - eT val_i = A[i]; + const eT val = P.at(row,col); - val_i = (val_i < min_val) ? min_val : ((val_i > max_val) ? max_val : val_i); + (*out_mem) = (val < min_val) ? min_val : ((val > max_val) ? max_val : val); - (*out_mem) = val_i; + out_mem++; } } + } + + + +// + + + +template +inline +void +op_clamp::apply(Cube& out, const mtOpCube& in) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const eT min_val = in.aux; + const eT max_val = in.aux_out_eT; + + arma_debug_check( (min_val > max_val), "clamp(): min_val must be less than max_val" ); + + if(is_Cube::value) + { + const unwrap_cube U(in.m); + + op_clamp::apply_direct(out, U.M, min_val, max_val); + } else { - for(uword col=0; col P(in.m); + + if(P.is_alias(out)) { - eT val = P.at(row,col); + Cube tmp; - val = (val < min_val) ? min_val : ((val > max_val) ? max_val : val); + op_clamp::apply_proxy_noalias(tmp, P, min_val, max_val); - (*out_mem) = val; out_mem++; + out.steal_mem(tmp); + } + else + { + op_clamp::apply_proxy_noalias(out, P, min_val, max_val); } } } @@ -108,29 +189,77 @@ template inline void -op_clamp::apply_direct(Mat& out, const Mat& X, const eT min_val, const eT max_val) +op_clamp::apply_direct(Cube& out, const Cube& X, const eT min_val, const eT max_val) { arma_extra_debug_sigprint(); if(&out != &X) { - const Proxy< Mat > P(X); + out.set_size(X.n_rows, X.n_cols, X.n_slices); + + const uword N = out.n_elem; + + const eT* X_mem = X.memptr(); + eT* out_mem = out.memptr(); - op_clamp::apply_proxy_noalias(out, P, min_val, max_val); + for(uword i=0; i max_val) ? max_val : val); + } } else { - arma_extra_debug_print("inplace operation"); + arma_extra_debug_print("op_clamp::apply_direct(): inplace operation"); - const uword N = out.n_elem; + arrayops::clamp(out.memptr(), out.n_elem, min_val, max_val); + } + } + + + +template +inline +void +op_clamp::apply_proxy_noalias(Cube& out, const ProxyCube& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); + const uword n_slices = P.get_n_slices(); + + out.set_size(n_rows, n_cols, n_slices); + + eT* out_mem = out.memptr(); + + if(ProxyCube::use_at == false) + { + const uword N = P.get_n_elem(); - eT* out_mem = out.memptr(); + typename ProxyCube::ea_type A = P.get_ea(); for(uword i=0; i max_val) ? max_val : out_val ); + out_mem[i] = (val < min_val) ? min_val : ((val > max_val) ? max_val : val); + } + } + else + { + for(uword s=0; s < n_slices; ++s) + for(uword c=0; c < n_cols; ++c) + for(uword r=0; r < n_rows; ++r) + { + const eT val = P.at(r,c,s); + + (*out_mem) = (val < min_val) ? min_val : ((val > max_val) ? max_val : val); + + out_mem++; } } } @@ -144,21 +273,84 @@ template inline void -op_clamp::apply(Cube& out, const mtOpCube& in) +op_clamp_cx::apply(Mat& out, const mtOp& in) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + if(is_Mat::value) + { + const unwrap U(in.m); + + op_clamp_cx::apply_direct(out, U.M, in.aux, in.aux_out_eT); + } + else + { + const Proxy P(in.m); + + if(P.is_alias(out)) + { + Mat tmp; + + op_clamp_cx::apply_proxy_noalias(tmp, P, in.aux, in.aux_out_eT); + + out.steal_mem(tmp); + } + else + { + op_clamp_cx::apply_proxy_noalias(out, P, in.aux, in.aux_out_eT); + } + } + } + + + +template +inline +void +op_clamp_cx::apply_direct(Mat& out, const Mat& X, const eT min_val, const eT max_val) { arma_extra_debug_sigprint(); - const ProxyCube P(in.m); + typedef typename get_pod_type::result T; + + const T min_val_real = std::real(min_val); + const T min_val_imag = std::imag(min_val); + + const T max_val_real = std::real(max_val); + const T max_val_imag = std::imag(max_val); - if((is_Cube::stored_type>::value) || P.is_alias(out)) + arma_debug_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" ); + + if(&out != &X) { - const unwrap_cube::stored_type> U(P.Q); + out.set_size(X.n_rows, X.n_cols); + + const uword N = out.n_elem; - op_clamp::apply_direct(out, U.M, in.aux, in.aux_out_eT); + const eT* X_mem = X.memptr(); + eT* out_mem = out.memptr(); + + for(uword i=0; i max_val_real) ? max_val_real : val_real); + val_imag = (val_imag < min_val_imag) ? min_val_imag : ((val_imag > max_val_imag) ? max_val_imag : val_imag); + + out_mem[i] = std::complex(val_real,val_imag); + } } else { - op_clamp::apply_proxy_noalias(out, P, in.aux, in.aux_out_eT); + arma_extra_debug_print("op_clamp_cx::apply_direct(): inplace operation"); + + arrayops::clamp(out.memptr(), out.n_elem, min_val, max_val); } } @@ -167,61 +359,100 @@ template inline void -op_clamp::apply_proxy_noalias(Cube& out, const ProxyCube& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val) +op_clamp_cx::apply_proxy_noalias(Mat& out, const Proxy& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); - const uword n_slices = P.get_n_slices(); + const T min_val_real = std::real(min_val); + const T min_val_imag = std::imag(min_val); - out.set_size(n_rows, n_cols, n_slices); + const T max_val_real = std::real(max_val); + const T max_val_imag = std::imag(max_val); + + arma_debug_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (min_val_imag > max_val_imag), "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(); + + out.set_size(n_rows, n_cols); eT* out_mem = out.memptr(); - if(ProxyCube::use_at == false) + if(Proxy::use_at == false) { const uword N = P.get_n_elem(); - typename ProxyCube::ea_type A = P.get_ea(); + typename Proxy::ea_type A = P.get_ea(); - uword j; - for(j=1; j max_val) ? max_val : val_i); - val_j = (val_j < min_val) ? min_val : ((val_j > max_val) ? max_val : val_j); + val_real = (val_real < min_val_real) ? min_val_real : ((val_real > max_val_real) ? max_val_real : val_real); + val_imag = (val_imag < min_val_imag) ? min_val_imag : ((val_imag > max_val_imag) ? max_val_imag : val_imag); - (*out_mem) = val_i; out_mem++; - (*out_mem) = val_j; out_mem++; + out_mem[i] = std::complex(val_real,val_imag); } - - const uword i = j-1; - - if(i < N) + } + else + { + for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) { - eT val_i = A[i]; + const eT val = P.at(row,col); - val_i = (val_i < min_val) ? min_val : ((val_i > max_val) ? max_val : val_i); + T val_real = std::real(val); + T val_imag = std::imag(val); - (*out_mem) = val_i; + val_real = (val_real < min_val_real) ? min_val_real : ((val_real > max_val_real) ? max_val_real : val_real); + val_imag = (val_imag < min_val_imag) ? min_val_imag : ((val_imag > max_val_imag) ? max_val_imag : val_imag); + + (*out_mem) = std::complex(val_real,val_imag); out_mem++; } } + } + + + +// + + + +template +inline +void +op_clamp_cx::apply(Cube& out, const mtOpCube& in) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + if(is_Cube::value) + { + const unwrap_cube U(in.m); + + op_clamp_cx::apply_direct(out, U.M, in.aux, in.aux_out_eT); + } else { - for(uword k=0; k < n_slices; ++k) - for(uword j=0; j < n_cols; ++j) - for(uword i=0; i < n_rows; ++i) + const ProxyCube P(in.m); + + if(P.is_alias(out)) { - eT val = P.at(i,j,k); + Cube tmp; - val = (val < min_val) ? min_val : ((val > max_val) ? max_val : val); + op_clamp_cx::apply_proxy_noalias(tmp, P, in.aux, in.aux_out_eT); - (*out_mem) = val; out_mem++; + out.steal_mem(tmp); + } + else + { + op_clamp_cx::apply_proxy_noalias(out, P, in.aux, in.aux_out_eT); } } } @@ -231,29 +462,112 @@ template inline void -op_clamp::apply_direct(Cube& out, const Cube& X, const eT min_val, const eT max_val) +op_clamp_cx::apply_direct(Cube& out, const Cube& X, const eT min_val, const eT max_val) { arma_extra_debug_sigprint(); + typedef typename get_pod_type::result T; + + const T min_val_real = std::real(min_val); + const T min_val_imag = std::imag(min_val); + + const T max_val_real = std::real(max_val); + const T max_val_imag = std::imag(max_val); + + arma_debug_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" ); + if(&out != &X) { - const ProxyCube< Cube > P(X); + out.set_size(X.n_rows, X.n_cols, X.n_slices); - op_clamp::apply_proxy_noalias(out, P, min_val, max_val); + const uword N = out.n_elem; + + const eT* X_mem = X.memptr(); + eT* out_mem = out.memptr(); + + for(uword i=0; i max_val_real) ? max_val_real : val_real); + val_imag = (val_imag < min_val_imag) ? min_val_imag : ((val_imag > max_val_imag) ? max_val_imag : val_imag); + + out_mem[i] = std::complex(val_real,val_imag); + } } else { - arma_extra_debug_print("inplace operation"); + arma_extra_debug_print("op_clamp_cx::apply_direct(): inplace operation"); - const uword N = out.n_elem; + arrayops::clamp(out.memptr(), out.n_elem, min_val, max_val); + } + } + + + +template +inline +void +op_clamp_cx::apply_proxy_noalias(Cube& out, const ProxyCube& P, const typename T1::elem_type min_val, const typename T1::elem_type max_val) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + const T min_val_real = std::real(min_val); + const T min_val_imag = std::imag(min_val); + + const T max_val_real = std::real(max_val); + const T max_val_imag = std::imag(max_val); + + arma_debug_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (min_val_imag > max_val_imag), "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(); + const uword n_slices = P.get_n_slices(); + + out.set_size(n_rows, n_cols, n_slices); + + eT* out_mem = out.memptr(); + + if(ProxyCube::use_at == false) + { + const uword N = P.get_n_elem(); - eT* out_mem = out.memptr(); + typename ProxyCube::ea_type A = P.get_ea(); for(uword i=0; i max_val_real) ? max_val_real : val_real); + val_imag = (val_imag < min_val_imag) ? min_val_imag : ((val_imag > max_val_imag) ? max_val_imag : val_imag); + + out_mem[i] = std::complex(val_real,val_imag); + } + } + else + { + for(uword s=0; s < n_slices; ++s) + for(uword c=0; c < n_cols; ++c) + for(uword r=0; r < n_rows; ++r) + { + const eT val = P.at(r,c,s); + + T val_real = std::real(val); + T val_imag = std::imag(val); + + val_real = (val_real < min_val_real) ? min_val_real : ((val_real > max_val_real) ? max_val_real : val_real); + val_imag = (val_imag < min_val_imag) ? min_val_imag : ((val_imag > max_val_imag) ? max_val_imag : val_imag); - out_val = (out_val < min_val) ? min_val : ( (out_val > max_val) ? max_val : out_val ); + (*out_mem) = std::complex(val_real,val_imag); out_mem++; } } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cond_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cond_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cond_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cond_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cond_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cond_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cond_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cond_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,15 +28,18 @@ { arma_extra_debug_sigprint(); - typedef typename T1::pod_type T; + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + Mat A(X.get_ref()); Col S; - const bool status = auxlib::svd_dc(S, X); + const bool status = auxlib::svd_dc(S, A); if(status == false) { - arma_debug_warn("cond(): svd failed"); + arma_debug_warn_level(3, "cond(): svd failed"); return T(0); } @@ -56,13 +61,15 @@ if(strip_trimat::do_trimat) { - const strip_trimat T(X.get_ref()); + const strip_trimat S(X.get_ref()); - arma_debug_check( (T.M.is_square() == false), "rcond(): matrix must be square sized" ); + const quasi_unwrap::stored_type> U(S.M); - const uword layout = (T.do_triu) ? uword(0) : uword(1); + arma_debug_check( (U.M.is_square() == false), "rcond(): matrix must be square sized" ); - return auxlib::rcond_trimat(T.M, layout); + const uword layout = (S.do_triu) ? uword(0) : uword(1); + + return auxlib::rcond_trimat(U.M, layout); } Mat A = X.get_ref(); @@ -81,16 +88,24 @@ return auxlib::rcond_trimat(A, layout); } - const bool try_sympd = auxlib::crippled_lapack(A) ? false : sympd_helper::guess_sympd(A); + #if defined(ARMA_OPTIMISE_SYMPD) + const bool try_sympd = auxlib::crippled_lapack(A) ? false : sympd_helper::guess_sympd(A); + #else + const bool try_sympd = false; + #endif if(try_sympd) { + arma_extra_debug_print("op_cond::rcond(): attempting sympd optimisation"); + bool calc_ok = false; const T out_val = auxlib::rcond_sympd(A, calc_ok); if(calc_ok) { return out_val; } + arma_extra_debug_print("op_cond::rcond(): sympd optimisation failed"); + // auxlib::rcond_sympd() may have failed because A isn't really sympd // restore A, as auxlib::rcond_sympd() may have destroyed it A = X.get_ref(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cor_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cor_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cor_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cor_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cor_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cor_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cor_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cor_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cov_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cov_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cov_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cov_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cov_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cov_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cov_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cov_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/OpCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/OpCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/OpCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/OpCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,7 +23,7 @@ //! Analog of the Op class, intended for cubes template -class OpCube : public BaseCube > +class OpCube : public BaseCube< typename T1::elem_type, OpCube > { public: diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/OpCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/OpCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/OpCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/OpCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cumprod_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cumprod_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cumprod_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cumprod_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cumprod_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cumprod_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cumprod_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cumprod_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cumsum_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cumsum_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cumsum_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cumsum_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cumsum_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cumsum_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cumsum_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cumsum_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cx_scalar_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cx_scalar_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cx_scalar_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cx_scalar_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_cx_scalar_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_cx_scalar_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_cx_scalar_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_cx_scalar_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_det_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_det_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_det_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_det_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup op_det +//! @{ + + + +class op_det + : public traits_op_default + { + public: + + template + struct pos + { + static constexpr uword n2 = row + col*2; + static constexpr uword n3 = row + col*3; + static constexpr uword n4 = row + col*4; + }; + + template + inline static bool apply_direct(typename T1::elem_type& out_val, const Base& expr); + + template + inline static typename T1::elem_type apply_diagmat(const Base& expr); + + template + inline static typename T1::elem_type apply_trimat(const Base& expr); + + template + arma_cold inline static eT apply_tiny(const Mat& X); + }; + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_det_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_det_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_det_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_det_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup op_det +//! @{ + + + +template +inline +bool +op_det::apply_direct(typename T1::elem_type& out_val, const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + if(strip_diagmat::do_diagmat) + { + const strip_diagmat strip(expr.get_ref()); + + out_val = op_det::apply_diagmat(strip.M); + + return true; + } + + if(strip_trimat::do_trimat) + { + const strip_trimat strip(expr.get_ref()); + + out_val = op_det::apply_trimat(strip.M); + + return true; + } + + Mat A(expr.get_ref()); + + arma_debug_check( (A.is_square() == false), "det(): given matrix must be square sized" ); + + if((A.n_rows <= 4) && is_cx::no) + { + constexpr T det_min = std::numeric_limits::epsilon(); + constexpr T det_max = T(1) / std::numeric_limits::epsilon(); + + const eT det_val = op_det::apply_tiny(A); + const T abs_det_val = std::abs(det_val); + + if((abs_det_val > det_min) && (abs_det_val < det_max)) { out_val = det_val; return true; } + + // fallthrough if det_val is suspect + } + + if(A.is_diagmat()) { out_val = op_det::apply_diagmat(A); return true; } + + const bool is_triu = trimat_helper::is_triu(A); + const bool is_tril = is_triu ? false : trimat_helper::is_tril(A); + + if(is_triu || is_tril) { out_val = op_det::apply_trimat(A); return true; } + + return auxlib::det(out_val, A); + } + + + +template +inline +typename T1::elem_type +op_det::apply_diagmat(const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const diagmat_proxy A(expr.get_ref()); + + arma_debug_check( (A.n_rows != A.n_cols), "det(): given matrix must be square sized" ); + + const uword N = (std::min)(A.n_rows, A.n_cols); + + eT val = eT(1); + + for(uword i=0; i +inline +typename T1::elem_type +op_det::apply_trimat(const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const Proxy P(expr.get_ref()); + + const uword N = P.get_n_rows(); + + arma_debug_check( (N != P.get_n_cols()), "det(): given matrix must be square sized" ); + + eT val = eT(1); + + for(uword i=0; i +arma_cold +inline +eT +op_det::apply_tiny(const Mat& X) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming matrix X is square sized + + const uword N = X.n_rows; + const eT* Xm = X.memptr(); + + if(N == 0) { return eT(1); } + + if(N == 1) { return Xm[0]; } + + if(N == 2) + { + return ( Xm[pos<0,0>::n2]*Xm[pos<1,1>::n2] - Xm[pos<0,1>::n2]*Xm[pos<1,0>::n2] ); + } + + if(N == 3) + { + // const double tmp1 = X.at(0,0) * X.at(1,1) * X.at(2,2); + // const double tmp2 = X.at(0,1) * X.at(1,2) * X.at(2,0); + // const double tmp3 = X.at(0,2) * X.at(1,0) * X.at(2,1); + // const double tmp4 = X.at(2,0) * X.at(1,1) * X.at(0,2); + // const double tmp5 = X.at(2,1) * X.at(1,2) * X.at(0,0); + // const double tmp6 = X.at(2,2) * X.at(1,0) * X.at(0,1); + // return (tmp1+tmp2+tmp3) - (tmp4+tmp5+tmp6); + + const eT val1 = Xm[pos<0,0>::n3]*(Xm[pos<2,2>::n3]*Xm[pos<1,1>::n3] - Xm[pos<2,1>::n3]*Xm[pos<1,2>::n3]); + const eT val2 = Xm[pos<1,0>::n3]*(Xm[pos<2,2>::n3]*Xm[pos<0,1>::n3] - Xm[pos<2,1>::n3]*Xm[pos<0,2>::n3]); + const eT val3 = Xm[pos<2,0>::n3]*(Xm[pos<1,2>::n3]*Xm[pos<0,1>::n3] - Xm[pos<1,1>::n3]*Xm[pos<0,2>::n3]); + + return ( val1 - val2 + val3 ); + } + + if(N == 4) + { + const eT val_03_12 = Xm[pos<0,3>::n4] * Xm[pos<1,2>::n4]; + const eT val_02_13 = Xm[pos<0,2>::n4] * Xm[pos<1,3>::n4]; + const eT val_03_11 = Xm[pos<0,3>::n4] * Xm[pos<1,1>::n4]; + + const eT val_01_13 = Xm[pos<0,1>::n4] * Xm[pos<1,3>::n4]; + const eT val_02_11 = Xm[pos<0,2>::n4] * Xm[pos<1,1>::n4]; + const eT val_01_12 = Xm[pos<0,1>::n4] * Xm[pos<1,2>::n4]; + + const eT val_03_10 = Xm[pos<0,3>::n4] * Xm[pos<1,0>::n4]; + const eT val_00_13 = Xm[pos<0,0>::n4] * Xm[pos<1,3>::n4]; + const eT val_02_10 = Xm[pos<0,2>::n4] * Xm[pos<1,0>::n4]; + const eT val_00_12 = Xm[pos<0,0>::n4] * Xm[pos<1,2>::n4]; + + const eT val_01_10 = Xm[pos<0,1>::n4] * Xm[pos<1,0>::n4]; + const eT val_00_11 = Xm[pos<0,0>::n4] * Xm[pos<1,1>::n4]; + + const eT val_21_30 = Xm[pos<2,1>::n4] * Xm[pos<3,0>::n4]; + const eT val_22_30 = Xm[pos<2,2>::n4] * Xm[pos<3,0>::n4]; + const eT val_23_30 = Xm[pos<2,3>::n4] * Xm[pos<3,0>::n4]; + + const eT val_20_31 = Xm[pos<2,0>::n4] * Xm[pos<3,1>::n4]; + const eT val_22_31 = Xm[pos<2,2>::n4] * Xm[pos<3,1>::n4]; + const eT val_23_31 = Xm[pos<2,3>::n4] * Xm[pos<3,1>::n4]; + + const eT val_20_32 = Xm[pos<2,0>::n4] * Xm[pos<3,2>::n4]; + const eT val_21_32 = Xm[pos<2,1>::n4] * Xm[pos<3,2>::n4]; + const eT val_23_32 = Xm[pos<2,3>::n4] * Xm[pos<3,2>::n4]; + + const eT val_20_33 = Xm[pos<2,0>::n4] * Xm[pos<3,3>::n4]; + const eT val_21_33 = Xm[pos<2,1>::n4] * Xm[pos<3,3>::n4]; + const eT val_22_33 = Xm[pos<2,2>::n4] * Xm[pos<3,3>::n4]; + + const eT val = \ + val_03_12 * val_21_30 \ + - val_02_13 * val_21_30 \ + - val_03_11 * val_22_30 \ + + val_01_13 * val_22_30 \ + + val_02_11 * val_23_30 \ + - val_01_12 * val_23_30 \ + - val_03_12 * val_20_31 \ + + val_02_13 * val_20_31 \ + + val_03_10 * val_22_31 \ + - val_00_13 * val_22_31 \ + - val_02_10 * val_23_31 \ + + val_00_12 * val_23_31 \ + + val_03_11 * val_20_32 \ + - val_01_13 * val_20_32 \ + - val_03_10 * val_21_32 \ + + val_00_13 * val_21_32 \ + + val_01_10 * val_23_32 \ + - val_00_11 * val_23_32 \ + - val_02_11 * val_20_33 \ + + val_01_12 * val_20_33 \ + + val_02_10 * val_21_33 \ + - val_00_12 * val_21_33 \ + - val_01_10 * val_22_33 \ + + val_00_11 * val_22_33 \ + ; + + return val; + } + + return eT(0); + } + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_diagmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_diagmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_diagmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_diagmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,7 +29,17 @@ template inline static void apply(Mat& out, const Op& X); - // TODO: implement specialised handling of Op,op_diagmat> + template + inline static void apply(Mat& out, const Proxy& P); + + template + inline static void apply(Mat& out, const Op< Glue, op_diagmat>& X); + + template + inline static void apply_times(Mat& out, const T1& X, const T2& Y, const typename arma_not_cx::result* junk = nullptr); + + template + inline static void apply_times(Mat& out, const T1& X, const T2& Y, const typename arma_cx_only::result* junk = nullptr); }; @@ -38,10 +50,10 @@ public: template - inline static void apply(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset); + inline static void apply(Mat& out, const Op& X); template - inline static void apply(Mat& out, const Op& X); + inline static void apply(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_diagmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_diagmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_diagmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_diagmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,184 +30,647 @@ typedef typename T1::elem_type eT; - const Proxy P(X.m); + if(is_Mat::value) + { + // allow detection of in-place operation + + const unwrap U(X.m); + const Mat& A = U.M; + + if(&out != &A) // no aliasing + { + const Proxy< Mat > P(A); + + op_diagmat::apply(out, P); + } + else // we have aliasing + { + const uword n_rows = out.n_rows; + const uword n_cols = out.n_cols; + + if((n_rows == 1) || (n_cols == 1)) // create diagonal matrix from vector + { + const eT* out_mem = out.memptr(); + const uword N = out.n_elem; + + Mat tmp(N,N, arma_zeros_indicator()); + + for(uword i=0; i P(X.m); + + if(P.is_alias(out)) + { + Mat tmp; + + op_diagmat::apply(tmp, P); + + out.steal_mem(tmp); + } + else + { + op_diagmat::apply(out, P); + } + } + } + + + +template +inline +void +op_diagmat::apply(Mat& out, const Proxy& P) + { + arma_extra_debug_sigprint(); const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); + const uword n_elem = P.get_n_elem(); - const bool P_is_vec = (n_rows == 1) || (n_cols == 1); + if(n_elem == 0) { out.reset(); return; } + const bool P_is_vec = (T1::is_row) || (T1::is_col) || (n_rows == 1) || (n_cols == 1); - if(P.is_alias(out) == false) + if(P_is_vec) { - if(P_is_vec) // generate a diagonal matrix out of a vector + out.zeros(n_elem, n_elem); + + if(Proxy::use_at == false) { - const uword N = (n_rows == 1) ? n_cols : n_rows; - - out.zeros(N, N); + typename Proxy::ea_type Pea = P.get_ea(); - if(Proxy::use_at == false) + for(uword i=0; i < n_elem; ++i) { out.at(i,i) = Pea[i]; } + } + else + { + if(n_rows == 1) { - typename Proxy::ea_type P_ea = P.get_ea(); - - for(uword i=0; i < N; ++i) { out.at(i,i) = P_ea[i]; } + for(uword i=0; i < n_elem; ++i) { out.at(i,i) = P.at(0,i); } } else { - if(n_rows == 1) - { - for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(0,i); } - } - else - { - for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(i,0); } - } + for(uword i=0; i < n_elem; ++i) { out.at(i,i) = P.at(i,0); } } } - else // generate a diagonal matrix out of a matrix + } + else // P represents a matrix + { + out.zeros(n_rows, n_cols); + + const uword N = (std::min)(n_rows, n_cols); + + for(uword i=0; i +inline +void +op_diagmat::apply(Mat& out, const Op< Glue, op_diagmat>& X) + { + arma_extra_debug_sigprint(); + + op_diagmat::apply_times(out, X.m.A, X.m.B); + } + + + +template +inline +void +op_diagmat::apply_times(Mat& actual_out, const T1& X, const T2& Y, const typename arma_not_cx::result* junk) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + typedef typename T1::elem_type eT; + + const partial_unwrap UA(X); + const partial_unwrap UB(Y); + + const typename partial_unwrap::stored_type& A = UA.M; + const typename partial_unwrap::stored_type& B = UB.M; + + arma_debug_assert_trans_mul_size< partial_unwrap::do_trans, partial_unwrap::do_trans >(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); + + const bool use_alpha = partial_unwrap::do_times || partial_unwrap::do_times; + const eT alpha = use_alpha ? (UA.get_val() * UB.get_val()) : eT(0); + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + + const uword B_n_rows = B.n_rows; + const uword B_n_cols = B.n_cols; + + // check if the multiplication results in a vector + + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == false) ) + { + if((A_n_rows == 1) || (B_n_cols == 1)) + { + arma_extra_debug_print("trans_A = false; trans_B = false; vector result"); + + const Mat C = A*B; + const eT* C_mem = C.memptr(); + const uword N = C.n_elem; + + actual_out.zeros(N,N); + + for(uword i=0; i::do_trans == true ) && (partial_unwrap::do_trans == false) ) + { + if((A_n_cols == 1) || (B_n_cols == 1)) + { + arma_extra_debug_print("trans_A = true; trans_B = false; vector result"); + + const Mat C = trans(A)*B; + const eT* C_mem = C.memptr(); + const uword N = C.n_elem; + + actual_out.zeros(N,N); + + for(uword i=0; i::do_trans == false) && (partial_unwrap::do_trans == true ) ) + { + if((A_n_rows == 1) || (B_n_rows == 1)) + { + arma_extra_debug_print("trans_A = false; trans_B = true; vector result"); + + const Mat C = A*trans(B); + const eT* C_mem = C.memptr(); + const uword N = C.n_elem; + + actual_out.zeros(N,N); + + for(uword i=0; i::do_trans == true ) && (partial_unwrap::do_trans == true ) ) + { + if((A_n_cols == 1) || (B_n_rows == 1)) { - out.zeros(n_rows, n_cols); + arma_extra_debug_print("trans_A = true; trans_B = true; vector result"); + + const Mat C = trans(A)*trans(B); + const eT* C_mem = C.memptr(); + const uword N = C.n_elem; - const uword N = (std::min)(n_rows, n_cols); + actual_out.zeros(N,N); - for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(i,i); } + for(uword i=0; i tmp; + Mat& out = (is_alias) ? tmp : actual_out; + + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == false) ) { - if(P_is_vec) // generate a diagonal matrix out of a vector + arma_extra_debug_print("trans_A = false; trans_B = false; matrix result"); + + out.zeros(A_n_rows, B_n_cols); + + const uword N = (std::min)(A_n_rows, B_n_cols); + + for(uword k=0; k < N; ++k) { - const uword N = (n_rows == 1) ? n_cols : n_rows; + eT acc1 = eT(0); + eT acc2 = eT(0); + + const eT* B_colptr = B.colptr(k); - podarray tmp(N); - eT* tmp_mem = tmp.memptr(); + // condition: A_n_cols = B_n_rows - if(Proxy::use_at == false) + uword j; + + for(j=1; j < A_n_cols; j+=2) { - typename Proxy::ea_type P_ea = P.get_ea(); + const uword i = (j-1); + + const eT tmp_i = B_colptr[i]; + const eT tmp_j = B_colptr[j]; - for(uword i=0; i < N; ++i) { tmp_mem[i] = P_ea[i]; } + acc1 += A.at(k, i) * tmp_i; + acc2 += A.at(k, j) * tmp_j; } - else + + const uword i = (j-1); + + if(i < A_n_cols) { - if(n_rows == 1) - { - for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(0,i); } - } - else - { - for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(i,0); } - } + acc1 += A.at(k, i) * B_colptr[i]; } - out.zeros(N, N); + const eT acc = acc1 + acc2; + + out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc); + } + } + else + if( (partial_unwrap::do_trans == true ) && (partial_unwrap::do_trans == false) ) + { + arma_extra_debug_print("trans_A = true; trans_B = false; matrix result"); + + out.zeros(A_n_cols, B_n_cols); + + const uword N = (std::min)(A_n_cols, B_n_cols); + + for(uword k=0; k < N; ++k) + { + const eT* A_colptr = A.colptr(k); + const eT* B_colptr = B.colptr(k); + + // condition: A_n_rows = B_n_rows + + const eT acc = op_dot::direct_dot(A_n_rows, A_colptr, B_colptr); - for(uword i=0; i < N; ++i) { out.at(i,i) = tmp_mem[i]; } + out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc); } - else // generate a diagonal matrix out of a matrix + } + else + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == true ) ) + { + arma_extra_debug_print("trans_A = false; trans_B = true; matrix result"); + + out.zeros(A_n_rows, B_n_rows); + + const uword N = (std::min)(A_n_rows, B_n_rows); + + for(uword k=0; k < N; ++k) { - const uword N = (std::min)(n_rows, n_cols); + eT acc = eT(0); + + // condition: A_n_cols = B_n_cols - if( (Proxy::has_subview == false) && (Proxy::fake_mat == false) ) + for(uword i=0; i < A_n_cols; ++i) { - // NOTE: we have aliasing and it's not due to a subview, hence we're assuming that the output matrix already has the correct size - - for(uword i=0; i < n_cols; ++i) - { - if(i < N) - { - const eT val = P.at(i,i); - - arrayops::fill_zeros(out.colptr(i), n_rows); - - out.at(i,i) = val; - } - else - { - arrayops::fill_zeros(out.colptr(i), n_rows); - } - } + acc += A.at(k,i) * B.at(k,i); } - else + + out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc); + } + } + else + if( (partial_unwrap::do_trans == true ) && (partial_unwrap::do_trans == true ) ) + { + arma_extra_debug_print("trans_A = true; trans_B = true; matrix result"); + + out.zeros(A_n_cols, B_n_rows); + + const uword N = (std::min)(A_n_cols, B_n_rows); + + for(uword k=0; k < N; ++k) + { + eT acc = eT(0); + + const eT* A_colptr = A.colptr(k); + + // condition: A_n_rows = B_n_cols + + for(uword i=0; i < A_n_rows; ++i) { - podarray tmp(N); - eT* tmp_mem = tmp.memptr(); - - for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(i,i); } - - out.zeros(n_rows, n_cols); - - for(uword i=0; i < N; ++i) { out.at(i,i) = tmp_mem[i]; } + acc += A_colptr[i] * B.at(k,i); } + + out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc); } } + + if(is_alias) { actual_out.steal_mem(tmp); } } -template +template inline void -op_diagmat2::apply(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset) +op_diagmat::apply_times(Mat& actual_out, const T1& X, const T2& Y, const typename arma_cx_only::result* junk) { arma_extra_debug_sigprint(); + arma_ignore(junk); - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); - const uword n_elem = P.get_n_elem(); + typedef typename T1::pod_type T; + typedef typename T1::elem_type eT; - if(n_elem == 0) { out.reset(); return; } + const partial_unwrap UA(X); + const partial_unwrap UB(Y); - const bool P_is_vec = (T1::is_row) || (T1::is_col) || (n_rows == 1) || (n_cols == 1); + const typename partial_unwrap::stored_type& A = UA.M; + const typename partial_unwrap::stored_type& B = UB.M; - if(P_is_vec) + arma_debug_assert_trans_mul_size< partial_unwrap::do_trans, partial_unwrap::do_trans >(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); + + const bool use_alpha = partial_unwrap::do_times || partial_unwrap::do_times; + const eT alpha = use_alpha ? (UA.get_val() * UB.get_val()) : eT(0); + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + + const uword B_n_rows = B.n_rows; + const uword B_n_cols = B.n_cols; + + // check if the multiplication results in a vector + + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == false) ) { - const uword n_pad = (std::max)(row_offset, col_offset); + if((A_n_rows == 1) || (B_n_cols == 1)) + { + arma_extra_debug_print("trans_A = false; trans_B = false; vector result"); + + const Mat C = A*B; + const eT* C_mem = C.memptr(); + const uword N = C.n_elem; + + actual_out.zeros(N,N); + + for(uword i=0; i::do_trans == true ) && (partial_unwrap::do_trans == false) ) + { + if((A_n_cols == 1) || (B_n_cols == 1)) + { + arma_extra_debug_print("trans_A = true; trans_B = false; vector result"); + + const Mat C = trans(A)*B; + const eT* C_mem = C.memptr(); + const uword N = C.n_elem; + + actual_out.zeros(N,N); + + for(uword i=0; i::do_trans == false) && (partial_unwrap::do_trans == true ) ) + { + if((A_n_rows == 1) || (B_n_rows == 1)) + { + arma_extra_debug_print("trans_A = false; trans_B = true; vector result"); + + const Mat C = A*trans(B); + const eT* C_mem = C.memptr(); + const uword N = C.n_elem; + + actual_out.zeros(N,N); + + for(uword i=0; i::do_trans == true ) && (partial_unwrap::do_trans == true ) ) + { + if((A_n_cols == 1) || (B_n_rows == 1)) + { + arma_extra_debug_print("trans_A = true; trans_B = true; vector result"); + + const Mat C = trans(A)*trans(B); + const eT* C_mem = C.memptr(); + const uword N = C.n_elem; + + actual_out.zeros(N,N); + + for(uword i=0; i tmp; + Mat& out = (is_alias) ? tmp : actual_out; + + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == false) ) + { + arma_extra_debug_print("trans_A = false; trans_B = false; matrix result"); - out.zeros(n_elem + n_pad, n_elem + n_pad); + out.zeros(A_n_rows, B_n_cols); - if(Proxy::use_at == false) + const uword N = (std::min)(A_n_rows, B_n_cols); + + for(uword k=0; k < N; ++k) { - typename Proxy::ea_type Pea = P.get_ea(); + T acc_real = T(0); + T acc_imag = T(0); + + const eT* B_colptr = B.colptr(k); - for(uword i=0; i < n_elem; ++i) + // condition: A_n_cols = B_n_rows + + for(uword i=0; i < A_n_cols; ++i) { - out.at(row_offset + i, col_offset + i) = Pea[i]; + // acc += A.at(k, i) * B_colptr[i]; + + const std::complex& xx = A.at(k, i); + const std::complex& yy = B_colptr[i]; + + const T a = xx.real(); + const T b = xx.imag(); + + const T c = yy.real(); + const T d = yy.imag(); + + acc_real += (a*c) - (b*d); + acc_imag += (a*d) + (b*c); } + + const eT acc = std::complex(acc_real, acc_imag); + + out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc); } - else + } + else + if( (partial_unwrap::do_trans == true) && (partial_unwrap::do_trans == false) ) + { + arma_extra_debug_print("trans_A = true; trans_B = false; matrix result"); + + out.zeros(A_n_cols, B_n_cols); + + const uword N = (std::min)(A_n_cols, B_n_cols); + + for(uword k=0; k < N; ++k) { - const unwrap::stored_type> U(P.Q); + T acc_real = T(0); + T acc_imag = T(0); + + const eT* A_colptr = A.colptr(k); + const eT* B_colptr = B.colptr(k); + + // condition: A_n_rows = B_n_rows + + for(uword i=0; i < A_n_rows; ++i) + { + // acc += std::conj(A_colptr[i]) * B_colptr[i]; + + const std::complex& xx = A_colptr[i]; + const std::complex& yy = B_colptr[i]; + + const T a = xx.real(); + const T b = xx.imag(); + + const T c = yy.real(); + const T d = yy.imag(); + + // take into account the complex conjugate of xx + + acc_real += (a*c) + (b*d); + acc_imag += (a*d) - (b*c); + } - const Proxy::stored_type>::stored_type> PP(U.M); + const eT acc = std::complex(acc_real, acc_imag); - op_diagmat2::apply(out, PP, row_offset, col_offset); + out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc); } } - else // P represents a matrix + else + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == true) ) { - arma_debug_check - ( - ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), - "diagmat(): requested diagonal out of bounds" - ); + arma_extra_debug_print("trans_A = false; trans_B = true; matrix result"); - out.zeros(n_rows, n_cols); + out.zeros(A_n_rows, B_n_rows); - const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset); + const uword N = (std::min)(A_n_rows, B_n_rows); - for(uword i=0; i& xx = A.at(k, i); + const std::complex& yy = B.at(k, i); + + const T a = xx.real(); + const T b = xx.imag(); + + const T c = yy.real(); + const T d = -yy.imag(); // take the conjugate + + acc_real += (a*c) - (b*d); + acc_imag += (a*d) + (b*c); + } + + const eT acc = std::complex(acc_real, acc_imag); + + out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc); + } + } + else + if( (partial_unwrap::do_trans == true) && (partial_unwrap::do_trans == true) ) + { + arma_extra_debug_print("trans_A = true; trans_B = true; matrix result"); + + out.zeros(A_n_cols, B_n_rows); + + const uword N = (std::min)(A_n_cols, B_n_rows); + + for(uword k=0; k < N; ++k) + { + T acc_real = T(0); + T acc_imag = T(0); + + const eT* A_colptr = A.colptr(k); + + // condition: A_n_rows = B_n_cols + + for(uword i=0; i < A_n_rows; ++i) + { + // acc += std::conj(A_colptr[i]) * std::conj(B.at(k,i)); + + const std::complex& xx = A_colptr[i]; + const std::complex& yy = B.at(k, i); + + const T a = xx.real(); + const T b = -xx.imag(); // take the conjugate + + const T c = yy.real(); + const T d = -yy.imag(); // take the conjugate + + acc_real += (a*c) - (b*d); + acc_imag += (a*d) + (b*c); + } + + const eT acc = std::complex(acc_real, acc_imag); + + out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc); } } + + if(is_alias) { actual_out.steal_mem(tmp); } } +// +// +// + + + template inline void @@ -234,6 +699,69 @@ } } + + +template +inline +void +op_diagmat2::apply(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset) + { + arma_extra_debug_sigprint(); + + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); + const uword n_elem = P.get_n_elem(); + + if(n_elem == 0) { out.reset(); return; } + + const bool P_is_vec = (T1::is_row) || (T1::is_col) || (n_rows == 1) || (n_cols == 1); + + if(P_is_vec) + { + const uword n_pad = (std::max)(row_offset, col_offset); + + out.zeros(n_elem + n_pad, n_elem + n_pad); + + if(Proxy::use_at == false) + { + typename Proxy::ea_type Pea = P.get_ea(); + + for(uword i=0; i < n_elem; ++i) { out.at(row_offset + i, col_offset + i) = Pea[i]; } + } + else + { + if(n_rows == 1) + { + for(uword i=0; i < n_elem; ++i) { out.at(row_offset + i, col_offset + i) = P.at(0,i); } + } + else + { + for(uword i=0; i < n_elem; ++i) { out.at(row_offset + i, col_offset + i) = P.at(i,0); } + } + } + } + else // P represents a matrix + { + arma_debug_check_bounds + ( + ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), + "diagmat(): requested diagonal out of bounds" + ); + + out.zeros(n_rows, n_cols); + + const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset); + + for(uword i=0; i& out, const Op& X); template - arma_hot inline static void apply_unwrap(Mat& out, const T1& X, const uword row_offset, const uword col_offset, const uword len); + inline static void apply_proxy(Mat& out, const Proxy& P); + + template + inline static void apply(Mat& out, const Op< Glue, op_diagvec>& X, const typename arma_not_cx::result* junk = nullptr); + + template + inline static void apply(Mat& out, const Op< Glue, op_diagvec>& X, const typename arma_cx_only::result* junk = nullptr); + }; + + + +class op_diagvec2 + : public traits_op_col + { + public: + + template + inline static void apply(Mat& out, const Op& X); template - arma_hot inline static void apply_proxy(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset, const uword len); + inline static void apply_proxy(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_diagvec_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_diagvec_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_diagvec_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_diagvec_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,93 +30,487 @@ typedef typename T1::elem_type eT; - const uword a = X.aux_uword_a; - const uword b = X.aux_uword_b; + const Proxy P(X.m); - const uword row_offset = (b > 0) ? a : 0; - const uword col_offset = (b == 0) ? a : 0; + if(P.is_alias(out) == false) + { + op_diagvec::apply_proxy(out, P); + } + else + { + Mat tmp; + + op_diagvec::apply_proxy(tmp, P); + + out.steal_mem(tmp); + } + } + + + +template +inline +void +op_diagvec::apply_proxy(Mat& out, const Proxy& P) + { + arma_extra_debug_sigprint(); - const Proxy P(X.m); + typedef typename T1::elem_type eT; const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); - arma_debug_check - ( - ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), - "diagvec(): requested diagonal is out of bounds" - ); + const uword len = (std::min)(n_rows, n_cols); - const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset); + out.set_size(len, 1); + + eT* out_mem = out.memptr(); + + uword i,j; + for(i=0, j=1; j < len; i+=2, j+=2) + { + const eT tmp_i = P.at(i, i); + const eT tmp_j = P.at(j, j); + + out_mem[i] = tmp_i; + out_mem[j] = tmp_j; + } - if( (is_Mat::stored_type>::value) && (Proxy::fake_mat == false) ) + if(i < len) { - op_diagvec::apply_unwrap(out, P.Q, row_offset, col_offset, len); + out_mem[i] = P.at(i, i); + } + } + + + +template +inline +void +op_diagvec::apply(Mat& actual_out, const Op< Glue, op_diagvec>& X, const typename arma_not_cx::result* junk) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + typedef typename T1::elem_type eT; + + const partial_unwrap UA(X.m.A); + const partial_unwrap UB(X.m.B); + + const typename partial_unwrap::stored_type& A = UA.M; + const typename partial_unwrap::stored_type& B = UB.M; + + arma_debug_assert_trans_mul_size< partial_unwrap::do_trans, partial_unwrap::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; } + + const bool use_alpha = partial_unwrap::do_times || partial_unwrap::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 tmp; + Mat& out = (is_alias) ? tmp : actual_out; + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + + const uword B_n_rows = B.n_rows; + const uword B_n_cols = B.n_cols; + + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == false) ) + { + arma_extra_debug_print("trans_A = false; trans_B = false;"); + + const uword N = (std::min)(A_n_rows, B_n_cols); + + out.set_size(N,1); + + eT* out_mem = out.memptr(); + + for(uword k=0; k < N; ++k) + { + eT acc1 = eT(0); + eT acc2 = eT(0); + + const eT* B_colptr = B.colptr(k); + + // condition: A_n_cols = B_n_rows + + uword j; + + for(j=1; j < A_n_cols; j+=2) + { + const uword i = (j-1); + + const eT tmp_i = B_colptr[i]; + const eT tmp_j = B_colptr[j]; + + acc1 += A.at(k, i) * tmp_i; + acc2 += A.at(k, j) * tmp_j; + } + + const uword i = (j-1); + + if(i < A_n_cols) + { + acc1 += A.at(k, i) * B_colptr[i]; + } + + const eT acc = acc1 + acc2; + + out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc); + } + } + else + if( (partial_unwrap::do_trans == true ) && (partial_unwrap::do_trans == false) ) + { + arma_extra_debug_print("trans_A = true; trans_B = false;"); + + const uword N = (std::min)(A_n_cols, B_n_cols); + + out.set_size(N,1); + + eT* out_mem = out.memptr(); + + for(uword k=0; k < N; ++k) + { + const eT* A_colptr = A.colptr(k); + const eT* B_colptr = B.colptr(k); + + // condition: A_n_rows = B_n_rows + + const eT acc = op_dot::direct_dot(A_n_rows, A_colptr, B_colptr); + + out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc); + } } else + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == true ) ) { - if(P.is_alias(out) == false) + arma_extra_debug_print("trans_A = false; trans_B = true;"); + + const uword N = (std::min)(A_n_rows, B_n_rows); + + out.set_size(N,1); + + eT* out_mem = out.memptr(); + + for(uword k=0; k < N; ++k) { - op_diagvec::apply_proxy(out, P, row_offset, col_offset, len); + eT acc = eT(0); + + // condition: A_n_cols = B_n_cols + + for(uword i=0; i < A_n_cols; ++i) + { + acc += A.at(k,i) * B.at(k,i); + } + + out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc); } - else + } + else + if( (partial_unwrap::do_trans == true ) && (partial_unwrap::do_trans == true ) ) + { + arma_extra_debug_print("trans_A = true; trans_B = true;"); + + const uword N = (std::min)(A_n_cols, B_n_rows); + + out.set_size(N,1); + + eT* out_mem = out.memptr(); + + for(uword k=0; k < N; ++k) { - Mat tmp; + eT acc = eT(0); + + const eT* A_colptr = A.colptr(k); + + // condition: A_n_rows = B_n_cols - op_diagvec::apply_proxy(tmp, P, row_offset, col_offset, len); + for(uword i=0; i < A_n_rows; ++i) + { + acc += A_colptr[i] * B.at(k,i); + } - out.steal_mem(tmp); + out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc); } } + + if(is_alias) { actual_out.steal_mem(tmp); } } -template -arma_hot +template inline void -op_diagvec::apply_unwrap(Mat& out, const T1& X, const uword row_offset, const uword col_offset, const uword len) +op_diagvec::apply(Mat& actual_out, const Op< Glue, op_diagvec>& X, const typename arma_cx_only::result* junk) { arma_extra_debug_sigprint(); + arma_ignore(junk); + typedef typename T1::pod_type T; typedef typename T1::elem_type eT; - const unwrap_check tmp_A(X, out); - const Mat& A = tmp_A.M; + const partial_unwrap UA(X.m.A); + const partial_unwrap UB(X.m.B); - out.set_size(len, 1); + const typename partial_unwrap::stored_type& A = UA.M; + const typename partial_unwrap::stored_type& B = UB.M; - eT* out_mem = out.memptr(); + arma_debug_assert_trans_mul_size< partial_unwrap::do_trans, partial_unwrap::do_trans >(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); - uword i,j; - for(i=0, j=1; j < len; i+=2, j+=2) + if( (A.n_elem == 0) || (B.n_elem == 0) ) { actual_out.reset(); return; } + + const bool use_alpha = partial_unwrap::do_times || partial_unwrap::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 tmp; + Mat& out = (is_alias) ? tmp : actual_out; + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + + const uword B_n_rows = B.n_rows; + const uword B_n_cols = B.n_cols; + + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == false) ) { - const eT tmp_i = A.at( i + row_offset, i + col_offset ); - const eT tmp_j = A.at( j + row_offset, j + col_offset ); + arma_extra_debug_print("trans_A = false; trans_B = false;"); - out_mem[i] = tmp_i; - out_mem[j] = tmp_j; + const uword N = (std::min)(A_n_rows, B_n_cols); + + out.set_size(N,1); + + eT* out_mem = out.memptr(); + + for(uword k=0; k < N; ++k) + { + T acc_real = T(0); + T acc_imag = T(0); + + const eT* B_colptr = B.colptr(k); + + // condition: A_n_cols = B_n_rows + + for(uword i=0; i < A_n_cols; ++i) + { + // acc += A.at(k, i) * B_colptr[i]; + + const std::complex& xx = A.at(k, i); + const std::complex& yy = B_colptr[i]; + + const T a = xx.real(); + const T b = xx.imag(); + + const T c = yy.real(); + const T d = yy.imag(); + + acc_real += (a*c) - (b*d); + acc_imag += (a*d) + (b*c); + } + + const eT acc = std::complex(acc_real, acc_imag); + + out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc); + } + } + else + if( (partial_unwrap::do_trans == true) && (partial_unwrap::do_trans == false) ) + { + arma_extra_debug_print("trans_A = true; trans_B = false;"); + + const uword N = (std::min)(A_n_cols, B_n_cols); + + out.set_size(N,1); + + eT* out_mem = out.memptr(); + + for(uword k=0; k < N; ++k) + { + T acc_real = T(0); + T acc_imag = T(0); + + const eT* A_colptr = A.colptr(k); + const eT* B_colptr = B.colptr(k); + + // condition: A_n_rows = B_n_rows + + for(uword i=0; i < A_n_rows; ++i) + { + // acc += std::conj(A_colptr[i]) * B_colptr[i]; + + const std::complex& xx = A_colptr[i]; + const std::complex& yy = B_colptr[i]; + + const T a = xx.real(); + const T b = xx.imag(); + + const T c = yy.real(); + const T d = yy.imag(); + + // take into account the complex conjugate of xx + + acc_real += (a*c) + (b*d); + acc_imag += (a*d) - (b*c); + } + + const eT acc = std::complex(acc_real, acc_imag); + + out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc); + } + } + else + if( (partial_unwrap::do_trans == false) && (partial_unwrap::do_trans == true) ) + { + arma_extra_debug_print("trans_A = false; trans_B = true;"); + + const uword N = (std::min)(A_n_rows, B_n_rows); + + out.set_size(N,1); + + eT* out_mem = out.memptr(); + + for(uword k=0; k < N; ++k) + { + T acc_real = T(0); + T acc_imag = T(0); + + // condition: A_n_cols = B_n_cols + + for(uword i=0; i < A_n_cols; ++i) + { + // acc += A.at(k,i) * std::conj(B.at(k,i)); + + const std::complex& xx = A.at(k, i); + const std::complex& yy = B.at(k, i); + + const T a = xx.real(); + const T b = xx.imag(); + + const T c = yy.real(); + const T d = -yy.imag(); // take the conjugate + + acc_real += (a*c) - (b*d); + acc_imag += (a*d) + (b*c); + } + + const eT acc = std::complex(acc_real, acc_imag); + + out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc); + } + } + else + if( (partial_unwrap::do_trans == true) && (partial_unwrap::do_trans == true) ) + { + arma_extra_debug_print("trans_A = true; trans_B = true;"); + + const uword N = (std::min)(A_n_cols, B_n_rows); + + out.set_size(N,1); + + eT* out_mem = out.memptr(); + + for(uword k=0; k < N; ++k) + { + T acc_real = T(0); + T acc_imag = T(0); + + const eT* A_colptr = A.colptr(k); + + // condition: A_n_rows = B_n_cols + + for(uword i=0; i < A_n_rows; ++i) + { + // acc += std::conj(A_colptr[i]) * std::conj(B.at(k,i)); + + const std::complex& xx = A_colptr[i]; + const std::complex& yy = B.at(k, i); + + const T a = xx.real(); + const T b = -xx.imag(); // take the conjugate + + const T c = yy.real(); + const T d = -yy.imag(); // take the conjugate + + acc_real += (a*c) - (b*d); + acc_imag += (a*d) + (b*c); + } + + const eT acc = std::complex(acc_real, acc_imag); + + out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc); + } } - if(i < len) + if(is_alias) { actual_out.steal_mem(tmp); } + } + + + +// +// +// + + + +template +inline +void +op_diagvec2::apply(Mat& out, const Op& X) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + 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 P(X.m); + + if(P.is_alias(out) == false) + { + op_diagvec2::apply_proxy(out, P, row_offset, col_offset); + } + else { - out_mem[i] = A.at( i + row_offset, i + col_offset ); + Mat tmp; + + op_diagvec2::apply_proxy(tmp, P, row_offset, col_offset); + + out.steal_mem(tmp); } } template -arma_hot inline void -op_diagvec::apply_proxy(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset, const uword len) +op_diagvec2::apply_proxy(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); + + arma_debug_check_bounds + ( + ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), + "diagvec(): requested diagonal is out of bounds" + ); + + const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset); + out.set_size(len, 1); eT* out_mem = out.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_diff_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_diff_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_diff_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_diff_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_diff_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_diff_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_diff_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_diff_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_dot_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_dot_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_dot_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_dot_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,7 +28,7 @@ public: template - arma_hot arma_inline static + arma_inline static typename arma_not_cx::result direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_dotext_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_dotext_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_dotext_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_dotext_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_dotext_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_dotext_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_dotext_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_dotext_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_dot_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_dot_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_dot_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_dot_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,7 +23,6 @@ //! for two arrays, generic version for non-complex values template -arma_hot arma_inline typename arma_not_cx::result op_dot::direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B) @@ -474,7 +475,7 @@ { arma_extra_debug_sigprint(); - if( (is_Mat::value == true) && (is_Mat::value == true) ) + if(is_Mat::value && is_Mat::value) { return op_cdot::apply_unwrap(X,Y); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_div.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_div.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_div.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_div.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_minus.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_minus.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_minus.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_minus.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_plus.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_plus.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_plus.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_plus.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_relational.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_relational.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_relational.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_relational.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_schur.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_schur.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_schur.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_schur.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_times.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_times.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_cube_times.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_cube_times.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_div.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_div.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_div.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_div.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,7 +25,7 @@ template arma_inline typename -enable_if2< is_arma_type::value, const eOp >::result +enable_if2< is_arma_type::value, const eOp< T1, eop_scalar_div_post> >::result operator/ ( const T1& X, @@ -41,7 +43,7 @@ template arma_inline typename -enable_if2< is_arma_type::value, const eOp >::result +enable_if2< is_arma_type::value, const eOp< T1, eop_scalar_div_pre> >::result operator/ ( const typename T1::elem_type k, @@ -154,7 +156,7 @@ template inline typename -enable_if2::value, SpMat >::result +enable_if2< is_arma_sparse_type::value, SpMat >::result operator/ ( const T1& X, @@ -300,7 +302,7 @@ arma_debug_assert_same_size(n_rows, n_cols, pb.get_n_rows(), pb.get_n_cols(), "element-wise division"); - Mat result(n_rows, n_cols); + Mat result(n_rows, n_cols, arma_nozeros_indicator()); for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_minus.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_minus.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_minus.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_minus.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -264,7 +266,7 @@ Mat result(x); - const SpProxy pb(y.get_ref()); + const SpProxy pb(y); arma_debug_assert_same_size( result.n_rows, result.n_cols, pb.get_n_rows(), pb.get_n_cols(), "subtraction" ); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_ostream.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_ostream.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_ostream.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_ostream.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_plus.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_plus.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_plus.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_plus.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -178,7 +180,7 @@ -//! addition of sparse and non-sparse object +//! addition of one dense and one sparse object template inline typename @@ -215,7 +217,7 @@ -//! addition of sparse and non-sparse object +//! addition of one sparse and one dense object template inline typename @@ -232,9 +234,22 @@ { arma_extra_debug_sigprint(); - // Just call the other order (these operations are commutative) - // TODO: if there is a matrix size mismatch, the debug assert will print the matrix sizes in wrong order - return (y + x); + const SpProxy pa(x); + + Mat result(y); + + arma_debug_assert_same_size( pa.get_n_rows(), pa.get_n_cols(), result.n_rows, result.n_cols, "addition" ); + + typename SpProxy::const_iterator_type it = pa.begin(); + typename SpProxy::const_iterator_type it_end = pa.end(); + + while(it != it_end) + { + result.at(it.row(), it.col()) += (*it); + ++it; + } + + return result; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_relational.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_relational.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_relational.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_relational.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -437,5 +439,45 @@ } + +template +inline +typename +enable_if2 + < + (is_arma_sparse_type::value && is_arma_sparse_type::value && (is_cx::no) && (is_cx::no)), + const mtSpGlue + >::result +operator&& +(const T1& X, const T2& Y) + { + arma_extra_debug_sigprint(); + + // TODO: ensure T1::elem_type and T2::elem_type are the same + + return mtSpGlue( X, Y ); + } + + + +template +inline +typename +enable_if2 + < + (is_arma_sparse_type::value && is_arma_sparse_type::value && (is_cx::no) && (is_cx::no)), + const mtSpGlue + >::result +operator|| +(const T1& X, const T2& Y) + { + arma_extra_debug_sigprint(); + + // TODO: ensure T1::elem_type and T2::elem_type are the same + + return mtSpGlue( X, Y ); + } + + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_schur.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_schur.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_schur.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_schur.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/operator_times.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/operator_times.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/operator_times.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/operator_times.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -178,7 +180,7 @@ arma_debug_assert_mul_size(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); - Mat out(A.n_rows, B.n_cols, fill::zeros); + Mat out(A.n_rows, B.n_cols, arma_zeros_indicator()); const uword A_length = (std::min)(A.n_rows, A.n_cols); const uword B_length = (std::min)(B.n_rows, B.n_cols); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_expmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_expmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_expmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_expmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_expmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_expmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_expmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_expmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -62,10 +64,7 @@ const uword N = (std::min)(out.n_rows, out.n_cols); - for(uword i=0; i eigval; + Mat eigvec; + + const bool eig_status = eig_sym_helper(eigval, eigvec, A, 'd', "expmat()"); + + if(eig_status) + { + eigval = exp(eigval); + + out = eigvec * diagmat(eigval) * eigvec.t(); + + return true; + } + + arma_extra_debug_print("op_expmat: sympd optimisation failed"); + + // fallthrough if eigen decomposition failed + } + const T norm_val = arma::norm(A, "inf"); const double log2_val = (norm_val > T(0)) ? double(eop_aux::log2(norm_val)) : double(0); @@ -109,7 +152,7 @@ if( (D.is_finite() == false) || (E.is_finite() == false) ) { return false; } - const bool status = solve(out, D, E); + const bool status = solve(out, D, E, solve_opts::no_approx); if(status == false) { return false; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_fft_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_fft_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_fft_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_fft_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_fft_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_fft_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_fft_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_fft_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -267,7 +269,7 @@ // correct the scaling for the inverse transform - if(inverse == true) + if(inverse) { typedef typename get_pod_type::result T; @@ -291,7 +293,7 @@ { arma_extra_debug_sigprint(); - if(is_Mat< typename Proxy::stored_type >::value == true) + if(is_Mat< typename Proxy::stored_type >::value) { op_fft_cx::copy_vec_unwrap(dest, P, N); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_find_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_find_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -39,8 +41,8 @@ ( Mat& indices, const mtOp& X, - const typename arma_op_rel_only::result junk1 = 0, - const typename arma_not_cx::result junk2 = 0 + const typename arma_op_rel_only::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr ); template @@ -49,8 +51,8 @@ ( Mat& indices, const mtOp& X, - const typename arma_op_rel_only::result junk1 = 0, - const typename arma_cx_only::result junk2 = 0 + const typename arma_op_rel_only::result* junk1 = nullptr, + const typename arma_cx_only::result* junk2 = nullptr ); template @@ -59,9 +61,9 @@ ( Mat& indices, const mtGlue& X, - const typename arma_glue_rel_only::result junk1 = 0, - const typename arma_not_cx::result junk2 = 0, - const typename arma_not_cx::result junk3 = 0 + const typename arma_glue_rel_only::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr, + const typename arma_not_cx::result* junk3 = nullptr ); template @@ -70,9 +72,9 @@ ( Mat& indices, const mtGlue& X, - const typename arma_glue_rel_only::result junk1 = 0, - const typename arma_cx_only::result junk2 = 0, - const typename arma_cx_only::result junk3 = 0 + const typename arma_glue_rel_only::result* junk1 = nullptr, + const typename arma_cx_only::result* junk2 = nullptr, + const typename arma_cx_only::result* junk3 = nullptr ); template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_find_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_find_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -79,8 +81,8 @@ ( Mat& indices, const mtOp& X, - const typename arma_op_rel_only::result junk1, - const typename arma_not_cx::result junk2 + const typename arma_op_rel_only::result* junk1, + const typename arma_not_cx::result* junk2 ) { arma_extra_debug_sigprint(); @@ -91,6 +93,11 @@ const eT val = X.aux; + if((is_same_type::yes || is_same_type::yes) && arma_config::debug && arma_isnan(val)) + { + arma_debug_warn_level(1, "find(): NaN is not equal to anything; suggest to use find_nonfinite() instead"); + } + const Proxy A(X.m); const uword n_elem = A.get_n_elem(); @@ -137,8 +144,8 @@ else if(is_same_type::yes) { not_zero_j = (tpj != val); } else { not_zero_j = false; } - if(not_zero_i == true) { indices_mem[n_nz] = i; ++n_nz; } - if(not_zero_j == true) { indices_mem[n_nz] = j; ++n_nz; } + if(not_zero_i) { indices_mem[n_nz] = i; ++n_nz; } + if(not_zero_j) { indices_mem[n_nz] = j; ++n_nz; } } if(i < n_elem) @@ -159,7 +166,7 @@ else if(is_same_type::yes) { not_zero = (tmp != val); } else { not_zero = false; } - if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } + if(not_zero) { indices_mem[n_nz] = i; ++n_nz; } } } else @@ -188,7 +195,7 @@ else if(is_same_type::yes) { not_zero = (tmp != val); } else { not_zero = false; } - if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } + if(not_zero) { indices_mem[n_nz] = i; ++n_nz; } ++i; } @@ -206,8 +213,8 @@ ( Mat& indices, const mtOp& X, - const typename arma_op_rel_only::result junk1, - const typename arma_cx_only::result junk2 + const typename arma_op_rel_only::result* junk1, + const typename arma_cx_only::result* junk2 ) { arma_extra_debug_sigprint(); @@ -219,9 +226,13 @@ const eT val = X.aux; + if((is_same_type::yes || is_same_type::yes) && arma_config::debug && arma_isnan(val)) + { + arma_debug_warn_level(1, "find(): NaN is not equal to anything; suggest to use find_nonfinite() instead"); + } + const Proxy A(X.m); - ea_type PA = A.get_ea(); const uword n_elem = A.get_n_elem(); indices.set_size(n_elem, 1); @@ -232,6 +243,8 @@ if(Proxy::use_at == false) { + ea_type PA = A.get_ea(); + for(uword i=0; i::yes) { not_zero = (tmp != val); } else { not_zero = false; } - if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } + if(not_zero) { indices_mem[n_nz] = i; ++n_nz; } } } else @@ -263,7 +276,7 @@ else if(is_same_type::yes) { not_zero = (tmp != val); } else { not_zero = false; } - if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } + if(not_zero) { indices_mem[n_nz] = i; ++n_nz; } i++; } @@ -281,9 +294,9 @@ ( Mat& indices, const mtGlue& X, - const typename arma_glue_rel_only::result junk1, - const typename arma_not_cx::result junk2, - const typename arma_not_cx::result junk3 + const typename arma_glue_rel_only::result* junk1, + const typename arma_not_cx::result* junk2, + const typename arma_not_cx::result* junk3 ) { arma_extra_debug_sigprint(); @@ -302,34 +315,67 @@ arma_debug_assert_same_size(A, B, "relational operator"); - ea_type1 PA = A.get_ea(); - ea_type2 PB = B.get_ea(); - - const uword n_elem = B.get_n_elem(); + const uword n_elem = A.get_n_elem(); indices.set_size(n_elem, 1); uword* indices_mem = indices.memptr(); uword n_nz = 0; - for(uword i=0; i::use_at == false) && (Proxy::use_at == false)) { - const eT1 tmp1 = PA[i]; - const eT2 tmp2 = PB[i]; + ea_type1 PA = A.get_ea(); + ea_type2 PB = B.get_ea(); - bool not_zero; + for(uword i=0; i::yes) { not_zero = (tmp1 < tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 > tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 <= tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 >= tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 == tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 != tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 && tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 || tmp2); } + else { not_zero = false; } + + if(not_zero) { indices_mem[n_nz] = i; ++n_nz; } + } + } + else + { + const uword n_rows = A.get_n_rows(); + const uword n_cols = A.get_n_cols(); - if(is_same_type::yes) { not_zero = (tmp1 < tmp2); } - else if(is_same_type::yes) { not_zero = (tmp1 > tmp2); } - else if(is_same_type::yes) { not_zero = (tmp1 <= tmp2); } - else if(is_same_type::yes) { not_zero = (tmp1 >= tmp2); } - else if(is_same_type::yes) { not_zero = (tmp1 == tmp2); } - else if(is_same_type::yes) { not_zero = (tmp1 != tmp2); } - else if(is_same_type::yes) { not_zero = (tmp1 && tmp2); } - else if(is_same_type::yes) { not_zero = (tmp1 || tmp2); } - else { not_zero = false; } + uword i = 0; - if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } + for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) + { + const eT1 tmp1 = A.at(row,col); + const eT2 tmp2 = B.at(row,col); + + bool not_zero; + + if(is_same_type::yes) { not_zero = (tmp1 < tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 > tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 <= tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 >= tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 == tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 != tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 && tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 || tmp2); } + else { not_zero = false; } + + if(not_zero) { indices_mem[n_nz] = i; ++n_nz; } + + i++; + } } return n_nz; @@ -344,9 +390,9 @@ ( Mat& indices, const mtGlue& X, - const typename arma_glue_rel_only::result junk1, - const typename arma_cx_only::result junk2, - const typename arma_cx_only::result junk3 + const typename arma_glue_rel_only::result* junk1, + const typename arma_cx_only::result* junk2, + const typename arma_cx_only::result* junk3 ) { arma_extra_debug_sigprint(); @@ -362,19 +408,18 @@ arma_debug_assert_same_size(A, B, "relational operator"); - ea_type1 PA = A.get_ea(); - ea_type2 PB = B.get_ea(); - - const uword n_elem = B.get_n_elem(); + const uword n_elem = A.get_n_elem(); indices.set_size(n_elem, 1); uword* indices_mem = indices.memptr(); uword n_nz = 0; - - if(Proxy::use_at == false) + if((Proxy::use_at == false) && (Proxy::use_at == false)) { + ea_type1 PA = A.get_ea(); + ea_type2 PB = B.get_ea(); + for(uword i=0; i::yes) { not_zero = (PA[i] != PB[i]); } else { not_zero = false; } - if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } + if(not_zero) { indices_mem[n_nz] = i; ++n_nz; } } } else @@ -402,11 +447,11 @@ else if(is_same_type::yes) { not_zero = (A.at(row,col) != B.at(row,col)); } else { not_zero = false; } - if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } + if(not_zero) { indices_mem[n_nz] = i; ++n_nz; } i++; } - } + } return n_nz; } @@ -479,7 +524,7 @@ const uword n_elem = P.get_n_elem(); - Mat indices(n_elem,1); + Mat indices(n_elem, 1, arma_nozeros_indicator()); uword* indices_mem = indices.memptr(); uword count = 0; @@ -525,7 +570,7 @@ const uword n_elem = P.get_n_elem(); - Mat indices(n_elem,1); + Mat indices(n_elem, 1, arma_nozeros_indicator()); uword* indices_mem = indices.memptr(); uword count = 0; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_find_unique_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_unique_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_find_unique_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_unique_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_find_unique_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_unique_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_find_unique_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_unique_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -33,7 +35,7 @@ if(n_elem == 0) { out.set_size(0,1); return true; } if(n_elem == 1) { out.set_size(1,1); out[0] = 0; return true; } - uvec indices(n_elem); + uvec indices(n_elem, arma_nozeros_indicator()); std::vector< arma_find_unique_packet > packet_vec(n_elem); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_flip_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_flip_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_flip_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_flip_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_flip_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_flip_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_flip_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_flip_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,17 +28,32 @@ { arma_extra_debug_sigprint(); - const Proxy P(in.m); + typedef typename T1::elem_type eT; - if(is_Mat::stored_type>::value || P.is_alias(out)) + if(is_Mat::value) { - const unwrap::stored_type> U(P.Q); + // allow detection of in-place operation + + const unwrap U(in.m); op_flipud::apply_direct(out, U.M); } else { - op_flipud::apply_proxy_noalias(out, P); + const Proxy P(in.m); + + if(P.is_alias(out)) + { + Mat tmp; + + op_flipud::apply_proxy_noalias(tmp, P); + + out.steal_mem(tmp); + } + else + { + op_flipud::apply_proxy_noalias(out, P); + } } } @@ -121,6 +138,17 @@ typedef typename T1::elem_type eT; + typedef typename Proxy::stored_type P_stored_type; + + if(is_Mat::value) + { + const unwrap U(P.Q); + + op_flipud::apply_direct(out, U.M); + + return; + } + const uword P_n_rows = P.get_n_rows(); const uword P_n_cols = P.get_n_cols(); @@ -166,17 +194,32 @@ { arma_extra_debug_sigprint(); - const Proxy P(in.m); + typedef typename T1::elem_type eT; - if(is_Mat::stored_type>::value || P.is_alias(out)) + if(is_Mat::value) { - const unwrap::stored_type> U(P.Q); + // allow detection of in-place operation + + const unwrap U(in.m); op_fliplr::apply_direct(out, U.M); } else { - op_fliplr::apply_proxy_noalias(out, P); + const Proxy P(in.m); + + if(P.is_alias(out)) + { + Mat tmp; + + op_fliplr::apply_proxy_noalias(tmp, P); + + out.steal_mem(tmp); + } + else + { + op_fliplr::apply_proxy_noalias(out, P); + } } } @@ -250,6 +293,17 @@ typedef typename T1::elem_type eT; + typedef typename Proxy::stored_type P_stored_type; + + if(is_Mat::value) + { + const unwrap U(P.Q); + + op_fliplr::apply_direct(out, U.M); + + return; + } + const uword P_n_rows = P.get_n_rows(); const uword P_n_cols = P.get_n_cols(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_hist_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_hist_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_hist_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_hist_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_hist_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_hist_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_hist_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_hist_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -58,15 +60,21 @@ 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(); } if(arma_isfinite(max_val) == false) { max_val = priv::most_pos(); } - Col c(n_bins); + Col c(n_bins, arma_nozeros_indicator()); eT* c_mem = c.memptr(); 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 +97,26 @@ 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::value) { - Mat tmp; - - op_hist::apply_noalias(tmp, U.M, n_bins, dim); - - out.steal_mem(tmp); + if(U.is_alias(out)) + { + Mat 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 converted = conv_to< Mat >::from(U.M); + + op_hist::apply_noalias(out, converted, n_bins, dim); } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_htrans_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_htrans_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_htrans_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_htrans_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,16 +29,16 @@ template struct traits { - static const bool is_row = T1::is_col; // deliberately swapped - static const bool is_col = T1::is_row; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_col; // deliberately swapped + static constexpr bool is_col = T1::is_row; + static constexpr bool is_xvec = T1::is_xvec; }; template - arma_hot arma_inline static void apply_mat_noalias(Mat& out, const Mat& A, const typename arma_not_cx::result* junk = 0); + arma_hot inline static void apply_mat_noalias(Mat& out, const Mat& A, const typename arma_not_cx::result* junk = nullptr); template - arma_hot inline static void apply_mat_noalias(Mat& out, const Mat& A, const typename arma_cx_only::result* junk = 0); + arma_hot inline static void apply_mat_noalias(Mat& out, const Mat& A, const typename arma_cx_only::result* junk = nullptr); // @@ -49,36 +51,34 @@ // template - arma_hot arma_inline static void apply_mat_inplace(Mat& out, const typename arma_not_cx::result* junk = 0); + arma_hot inline static void apply_mat_inplace(Mat& out, const typename arma_not_cx::result* junk = nullptr); template - arma_hot inline static void apply_mat_inplace(Mat& out, const typename arma_cx_only::result* junk = 0); + arma_hot inline static void apply_mat_inplace(Mat& out, const typename arma_cx_only::result* junk = nullptr); // template - arma_hot arma_inline static void apply_mat(Mat& out, const Mat& A, const typename arma_not_cx::result* junk = 0); + inline static void apply_mat(Mat& out, const Mat& A, const typename arma_not_cx::result* junk = nullptr); template - arma_hot inline static void apply_mat(Mat& out, const Mat& A, const typename arma_cx_only::result* junk = 0); + inline static void apply_mat(Mat& out, const Mat& A, const typename arma_cx_only::result* junk = nullptr); // template - arma_hot inline static void apply_proxy(Mat& out, const T1& X); + inline static void apply_proxy(Mat& out, const Proxy& P); // template - arma_hot inline static void apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk = 0); + inline static void apply_direct(Mat& out, const T1& X); template - arma_hot inline static void apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk = 0); - - // + inline static void apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk = nullptr); template - arma_hot inline static void apply(Mat& out, const Op< Op, op_htrans>& in); + inline static void apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk = nullptr); }; @@ -90,29 +90,16 @@ template struct traits { - static const bool is_row = T1::is_col; // deliberately swapped - static const bool is_col = T1::is_row; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_col; // deliberately swapped + static constexpr bool is_col = T1::is_row; + static constexpr bool is_xvec = T1::is_xvec; }; - template - arma_hot inline static void apply_noalias(Mat& out, const Mat& A, const eT val); - - template - arma_hot inline static void apply(Mat& out, const Mat& A, const eT val); - - // - - template - arma_hot inline static void apply_proxy(Mat& out, const T1& X, const typename T1::elem_type val); - - // - template - arma_hot inline static void apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk = 0); + inline static void apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk = nullptr); template - arma_hot inline static void apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk = 0); + inline static void apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk = nullptr); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_htrans_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_htrans_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_htrans_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_htrans_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,7 +23,7 @@ template arma_hot -arma_inline +inline void op_htrans::apply_mat_noalias(Mat& out, const Mat& A, const typename arma_not_cx::result* junk) { @@ -164,7 +166,7 @@ template arma_hot -arma_inline +inline void op_htrans::apply_mat_inplace(Mat& out, const typename arma_not_cx::result* junk) { @@ -221,8 +223,7 @@ template -arma_hot -arma_inline +inline void op_htrans::apply_mat(Mat& out, const Mat& A, const typename arma_not_cx::result* junk) { @@ -235,7 +236,6 @@ template -arma_hot inline void op_htrans::apply_mat(Mat& out, const Mat& A, const typename arma_cx_only::result* junk) @@ -256,205 +256,44 @@ template -arma_hot inline void -op_htrans::apply_proxy(Mat& out, const T1& X) +op_htrans::apply_proxy(Mat& out, const Proxy& P) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const Proxy P(X); + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); - // allow detection of in-place transpose - if( (is_Mat::stored_type>::value == true) && (Proxy::fake_mat == false) ) + if( (resolves_to_vector::yes) && (Proxy::use_at == false) ) { - const unwrap::stored_type> tmp(P.Q); + out.set_size(n_cols, n_rows); - op_htrans::apply_mat(out, tmp.M); - } - else - { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); + eT* out_mem = out.memptr(); - const bool is_alias = P.is_alias(out); + const uword n_elem = P.get_n_elem(); - if( (resolves_to_vector::yes) && (Proxy::use_at == false) ) - { - if(is_alias == false) - { - out.set_size(n_cols, n_rows); - - eT* out_mem = out.memptr(); - - const uword n_elem = P.get_n_elem(); - - typename Proxy::ea_type Pea = P.get_ea(); - - for(uword i=0; i < n_elem; ++i) - { - out_mem[i] = std::conj(Pea[i]); - } - } - else // aliasing - { - Mat out2(n_cols, n_rows); - - eT* out_mem = out2.memptr(); - - const uword n_elem = P.get_n_elem(); - - typename Proxy::ea_type Pea = P.get_ea(); - - for(uword i=0; i < n_elem; ++i) - { - out_mem[i] = std::conj(Pea[i]); - } - - out.steal_mem(out2); - } - } - else - { - if(is_alias == false) - { - out.set_size(n_cols, n_rows); - - eT* outptr = out.memptr(); - - for(uword k=0; k < n_rows; ++k) - { - for(uword j=0; j < n_cols; ++j) - { - (*outptr) = std::conj(P.at(k,j)); - - outptr++; - } - } - } - else // aliasing - { - Mat out2(n_cols, n_rows); - - eT* out2ptr = out2.memptr(); - - for(uword k=0; k < n_rows; ++k) - { - for(uword j=0; j < n_cols; ++j) - { - (*out2ptr) = std::conj(P.at(k,j)); - - out2ptr++; - } - } - - out.steal_mem(out2); - } - } - } - } - - - -template -arma_hot -inline -void -op_htrans::apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk) - { - arma_extra_debug_sigprint(); - arma_ignore(junk); - - op_strans::apply_proxy(out, in.m); - } - - - -template -arma_hot -inline -void -op_htrans::apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk) - { - arma_extra_debug_sigprint(); - arma_ignore(junk); - - op_htrans::apply_proxy(out, in.m); - } - - - -template -arma_hot -inline -void -op_htrans::apply(Mat& out, const Op< Op, op_htrans>& in) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - const unwrap tmp(in.m.m); - const Mat& A = tmp.M; - - const bool upper = in.m.aux_uword_a; - - op_trimat::apply_htrans(out, A, upper); - } - - - -// -// op_htrans2 - - - -template -arma_hot -arma_inline -void -op_htrans2::apply_noalias(Mat& out, const Mat& A, const eT val) - { - arma_extra_debug_sigprint(); - - const uword A_n_rows = A.n_rows; - const uword A_n_cols = A.n_cols; - - out.set_size(A_n_cols, A_n_rows); - - if( (A_n_cols == 1) || (A_n_rows == 1) ) - { - const uword n_elem = A.n_elem; - - const eT* A_mem = A.memptr(); - eT* out_mem = out.memptr(); + typename Proxy::ea_type Pea = P.get_ea(); for(uword i=0; i < n_elem; ++i) { - out_mem[i] = val * std::conj(A_mem[i]); + out_mem[i] = std::conj(Pea[i]); } } else - if( (A_n_rows >= 512) && (A_n_cols >= 512) ) - { - op_htrans::apply_mat_noalias_large(out, A); - arrayops::inplace_mul( out.memptr(), val, out.n_elem ); - } - else { + out.set_size(n_cols, n_rows); + eT* outptr = out.memptr(); - for(uword k=0; k < A_n_rows; ++k) + for(uword k=0; k < n_rows; ++k) { - const eT* Aptr = &(A.at(k,0)); - - for(uword j=0; j < A_n_cols; ++j) + for(uword j=0; j < n_cols; ++j) { - (*outptr) = val * std::conj(*Aptr); + (*outptr) = std::conj(P.at(k,j)); - Aptr += A_n_rows; outptr++; } } @@ -463,155 +302,58 @@ -template -arma_hot -inline -void -op_htrans2::apply(Mat& out, const Mat& A, const eT val) - { - arma_extra_debug_sigprint(); - - if(&out != &A) - { - op_htrans2::apply_noalias(out, A, val); - } - else - { - const uword n_rows = out.n_rows; - const uword n_cols = out.n_cols; - - if(n_rows == n_cols) - { - arma_extra_debug_print("doing in-place hermitian transpose of a square matrix"); - - // TODO: do multiplication while swapping - - for(uword col=0; col < n_cols; ++col) - { - eT* coldata = out.colptr(col); - - out.at(col,col) = std::conj( out.at(col,col) ); - - for(uword row=(col+1); row < n_rows; ++row) - { - const eT val1 = std::conj(coldata[row]); - const eT val2 = std::conj(out.at(col,row)); - - out.at(col,row) = val1; - coldata[row] = val2; - } - } - - arrayops::inplace_mul( out.memptr(), val, out.n_elem ); - } - else - { - Mat tmp; - op_htrans2::apply_noalias(tmp, A, val); - - out.steal_mem(tmp); - } - } - } - - - template -arma_hot inline void -op_htrans2::apply_proxy(Mat& out, const T1& X, const typename T1::elem_type val) +op_htrans::apply_direct(Mat& out, const T1& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const Proxy P(X); - // allow detection of in-place transpose - if( (is_Mat::stored_type>::value == true) && (Proxy::fake_mat == false) ) + if(is_Mat::value || (arma_config::openmp && Proxy::use_mp)) { - const unwrap::stored_type> tmp(P.Q); + const unwrap U(X); - op_htrans2::apply(out, tmp.M, val); + op_htrans::apply_mat(out, U.M); } else { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); + const Proxy P(X); const bool is_alias = P.is_alias(out); - if( (resolves_to_vector::yes) && (Proxy::use_at == false) ) + if(is_Mat::stored_type>::value) { - if(is_alias == false) + const quasi_unwrap::stored_type> U(P.Q); + + if(is_alias) { - out.set_size(n_cols, n_rows); - - eT* out_mem = out.memptr(); + Mat tmp; - const uword n_elem = P.get_n_elem(); + op_htrans::apply_mat_noalias(tmp, U.M); - typename Proxy::ea_type Pea = P.get_ea(); - - for(uword i=0; i < n_elem; ++i) - { - out_mem[i] = val * std::conj(Pea[i]); - } + out.steal_mem(tmp); } - else // aliasing + else { - Mat out2(n_cols, n_rows); - - eT* out_mem = out2.memptr(); - - const uword n_elem = P.get_n_elem(); - - typename Proxy::ea_type Pea = P.get_ea(); - - for(uword i=0; i < n_elem; ++i) - { - out_mem[i] = val * std::conj(Pea[i]); - } - - out.steal_mem(out2); + op_htrans::apply_mat_noalias(out, U.M); } } else { - if(is_alias == false) + if(is_alias) { - out.set_size(n_cols, n_rows); + Mat tmp; - eT* outptr = out.memptr(); + op_htrans::apply_proxy(tmp, P); - for(uword k=0; k < n_rows; ++k) - { - for(uword j=0; j < n_cols; ++j) - { - (*outptr) = val * std::conj(P.at(k,j)); - - outptr++; - } - } + out.steal_mem(tmp); } - else // aliasing + else { - Mat out2(n_cols, n_rows); - - eT* out2ptr = out2.memptr(); - - for(uword k=0; k < n_rows; ++k) - { - for(uword j=0; j < n_cols; ++j) - { - (*out2ptr) = val * std::conj(P.at(k,j)); - - out2ptr++; - } - } - - out.steal_mem(out2); + op_htrans::apply_proxy(out, P); } } } @@ -620,7 +362,37 @@ template -arma_hot +inline +void +op_htrans::apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + op_strans::apply_direct(out, in.m); + } + + + +template +inline +void +op_htrans::apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + op_htrans::apply_direct(out, in.m); + } + + + +// +// op_htrans2 + + + +template inline void op_htrans2::apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk) @@ -628,13 +400,14 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - op_strans2::apply_proxy(out, in.m, in.aux); + op_strans::apply_direct(out, in.m); + + arrayops::inplace_mul(out.memptr(), in.aux, out.n_elem); } template -arma_hot inline void op_htrans2::apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk) @@ -642,7 +415,9 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - op_htrans2::apply_proxy(out, in.m, in.aux); + op_htrans::apply_direct(out, in.m); + + arrayops::inplace_mul(out.memptr(), in.aux, out.n_elem); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_index_max_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_index_max_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_index_max_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_index_max_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -38,10 +40,10 @@ inline static void apply(Cube& out, const mtOpCube& in); template - inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_not_cx::result* junk = 0); + inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_not_cx::result* junk = nullptr); template - inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_cx_only::result* junk = 0); + inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_cx_only::result* junk = nullptr); // sparse matrices diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_index_max_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_index_max_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_index_max_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_index_max_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,7 +31,7 @@ typedef typename T1::elem_type eT; const uword dim = in.aux_uword_a; - arma_debug_check( (dim > 1), "index_max(): parameter 'dim' must be 0 or 1"); + arma_debug_check( (dim > 1), "index_max(): parameter 'dim' must be 0 or 1" ); const quasi_unwrap U(in.m); const Mat& X = U.M; @@ -88,7 +90,7 @@ uword* out_mem = out.memptr(); - Col tmp(X_n_rows); + Col tmp(X_n_rows, arma_nozeros_indicator()); T* tmp_mem = tmp.memptr(); @@ -98,7 +100,7 @@ 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 +115,7 @@ for(uword row=0; row < X_n_rows; ++row) { T& max_val = tmp_mem[row]; - T col_val = (is_cx::yes) ? T(std::abs(col_mem[row])) : T(access::tmp_real(col_mem[row])); + T col_val = (is_cx::yes) ? T(eop_aux::arma_abs(col_mem[row])) : T(access::tmp_real(col_mem[row])); if(max_val < col_val) { @@ -195,7 +197,7 @@ if(out.is_empty() || X.is_empty()) { return; } - Col tmp(X_n_rows); + Col tmp(X_n_rows, arma_nozeros_indicator()); eT* tmp_mem = tmp.memptr(); @@ -299,7 +301,7 @@ if(out.is_empty() || X.is_empty()) { return; } - Col tmp(X_n_rows); + Col tmp(X_n_rows, arma_nozeros_indicator()); T* tmp_mem = tmp.memptr(); @@ -342,7 +344,7 @@ uword* out_mem = out.memptr(); - Mat tmp(X_n_rows, X_n_cols); + Mat tmp(X_n_rows, X_n_cols, arma_nozeros_indicator()); T* tmp_mem = tmp.memptr(); const eT* X_slice0_mem = X.slice_memptr(0); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_index_min_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_index_min_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_index_min_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_index_min_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -38,10 +40,10 @@ inline static void apply(Cube& out, const mtOpCube& in); template - inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_not_cx::result* junk = 0); + inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_not_cx::result* junk = nullptr); template - inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_cx_only::result* junk = 0); + inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_cx_only::result* junk = nullptr); // sparse matrices diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_index_min_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_index_min_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_index_min_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_index_min_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,7 +31,7 @@ typedef typename T1::elem_type eT; const uword dim = in.aux_uword_a; - arma_debug_check( (dim > 1), "index_min(): parameter 'dim' must be 0 or 1"); + arma_debug_check( (dim > 1), "index_min(): parameter 'dim' must be 0 or 1" ); const quasi_unwrap U(in.m); const Mat& X = U.M; @@ -88,7 +90,7 @@ uword* out_mem = out.memptr(); - Col tmp(X_n_rows); + Col tmp(X_n_rows, arma_nozeros_indicator()); T* tmp_mem = tmp.memptr(); @@ -98,7 +100,7 @@ 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 +115,7 @@ for(uword row=0; row < X_n_rows; ++row) { T& min_val = tmp_mem[row]; - T col_val = (is_cx::yes) ? T(std::abs(col_mem[row])) : T(access::tmp_real(col_mem[row])); + T col_val = (is_cx::yes) ? T(eop_aux::arma_abs(col_mem[row])) : T(access::tmp_real(col_mem[row])); if(min_val > col_val) { @@ -195,7 +197,7 @@ if(out.is_empty() || X.is_empty()) { return; } - Col tmp(X_n_rows); + Col tmp(X_n_rows, arma_nozeros_indicator()); eT* tmp_mem = tmp.memptr(); @@ -299,7 +301,7 @@ if(out.is_empty() || X.is_empty()) { return; } - Col tmp(X_n_rows); + Col tmp(X_n_rows, arma_nozeros_indicator()); T* tmp_mem = tmp.memptr(); @@ -342,7 +344,7 @@ uword* out_mem = out.memptr(); - Mat tmp(X_n_rows, X_n_cols); + Mat tmp(X_n_rows, X_n_cols, arma_nozeros_indicator()); T* tmp_mem = tmp.memptr(); const eT* X_slice0_mem = X.slice_memptr(0); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_inv_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_inv_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,37 +21,34 @@ -//! 'invert matrix' operation (general matrices) class op_inv : public traits_op_default { public: + template + struct pos + { + static constexpr uword n2 = row + col*2; + static constexpr uword n3 = row + col*3; + static constexpr uword n4 = row + col*4; + }; + template inline static void apply(Mat& out, const Op& in); - template - inline static void apply_noalias(Mat& out, const Mat& A); - template - inline static void apply_diagmat(Mat& out, const T1& X); - }; - - - -//! 'invert matrix' operation (triangular matrices) -class op_inv_tr - : public traits_op_default - { - public: + inline static bool apply_direct(Mat& out, const Base& expr, const char* caller_sig); template - inline static void apply(Mat& out, const Op& in); + inline static bool apply_diagmat(Mat& out, const T1& X, const char* caller_sig); + + template + arma_cold inline static bool apply_tiny_noalias(Mat& out, const Mat& X); }; -//! 'invert matrix' operation (symmetric positive definite matrices) class op_inv_sympd : public traits_op_default { @@ -57,6 +56,9 @@ template inline static void apply(Mat& out, const Op& in); + + template + inline static bool apply_direct(Mat& out, const Base& expr); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_inv_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_inv_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,74 +28,100 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - - const strip_diagmat strip(X.m); + const bool status = op_inv::apply_direct(out, X.m, "inv()"); - if(strip.do_diagmat) - { - op_inv::apply_diagmat(out, strip.M); - } - else + if(status == false) { - const quasi_unwrap U(X.m); - - if(U.is_alias(out)) - { - Mat tmp; - - op_inv::apply_noalias(tmp, U.M); - - out.steal_mem(tmp); - } - else - { - op_inv::apply_noalias(out, U.M); - } + out.soft_reset(); + arma_stop_runtime_error("inv(): matrix is singular"); } } -template +template inline -void -op_inv::apply_noalias(Mat& out, const Mat& A) +bool +op_inv::apply_direct(Mat& out, const Base& expr, const char* caller_sig) { arma_extra_debug_sigprint(); - arma_debug_check( (A.n_rows != A.n_cols), "inv(): given matrix must be square sized" ); - - bool status = false; + typedef typename T1::elem_type eT; - if(A.n_rows <= 4) + if(strip_diagmat::do_diagmat) { - status = auxlib::inv_tiny(out, A); + const strip_diagmat strip(expr.get_ref()); + + return op_inv::apply_diagmat(out, strip.M, caller_sig); } - else - if(sympd_helper::guess_sympd(A)) + + if(strip_trimat::do_trimat) { - status = auxlib::inv_sympd(out, A); + const strip_trimat strip(expr.get_ref()); + + out = strip.M; + + arma_debug_check( (out.is_square() == false), caller_sig, ": given matrix must be square sized" ); + + return auxlib::inv_tr(out, (strip.do_triu ? uword(0) : uword(1))); } - if(status == false) + out = expr.get_ref(); + + arma_debug_check( (out.is_square() == false), caller_sig, ": given matrix must be square sized" ); + + if((out.n_rows <= 4) && is_cx::no) { - status = auxlib::inv(out, A); + arma_extra_debug_print("op_inv: attempting tinymatrix optimisation"); + + Mat tmp(out.n_rows, out.n_rows, arma_nozeros_indicator()); + + const bool status = op_inv::apply_tiny_noalias(tmp, out); + + if(status) { arrayops::copy(out.memptr(), tmp.memptr(), tmp.n_elem); return true; } + + arma_extra_debug_print("op_inv: tinymatrix optimisation failed"); + + // fallthrough if optimisation failed } - if(status == false) + if(out.is_diagmat()) { return op_inv::apply_diagmat(out, out, caller_sig); } + + const bool is_triu = trimat_helper::is_triu(out); + const bool is_tril = (is_triu) ? false : trimat_helper::is_tril(out); + + if(is_triu || is_tril) { return auxlib::inv_tr(out, ((is_triu) ? uword(0) : uword(1))); } + + #if defined(ARMA_OPTIMISE_SYMPD) + const bool try_sympd = sympd_helper::guess_sympd(out); + #else + const bool try_sympd = false; + #endif + + if(try_sympd) { - out.soft_reset(); - arma_stop_runtime_error("inv(): matrix seems singular"); + arma_extra_debug_print("op_inv: attempting sympd optimisation"); + + Mat tmp = out; + + const bool status = auxlib::inv_sympd(tmp); + + if(status) { out.steal_mem(tmp); return true; } + + arma_extra_debug_print("op_inv: sympd optimisation failed"); + + // fallthrough if optimisation failed } + + return auxlib::inv(out); } template inline -void -op_inv::apply_diagmat(Mat& out, const T1& X) +bool +op_inv::apply_diagmat(Mat& out, const T1& X, const char* caller_sig) { arma_extra_debug_sigprint(); @@ -101,7 +129,7 @@ const diagmat_proxy A(X); - arma_debug_check( (A.n_rows != A.n_cols), "inv(): given matrix must be square sized" ); + arma_debug_check( (A.n_rows != A.n_cols), caller_sig, ": given matrix must be square sized" ); const uword N = (std::min)(A.n_rows, A.n_cols); @@ -115,32 +143,143 @@ { const eT val = A[i]; - out.at(i,i) = eT(1) / val; + status = (val == eT(0)) ? false : status; - if(val == eT(0)) { status = false; } + out.at(i,i) = eT(1) / val; } } else { - Mat tmp(N, N, fill::zeros); + Mat tmp(N, N, arma_zeros_indicator()); for(uword i=0; i +arma_cold +inline +bool +op_inv::apply_tiny_noalias(Mat& out, const Mat& X) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + // NOTE: assuming matrix X is square sized + + const uword N = X.n_rows; + + out.set_size(N,N); + + constexpr T det_min = std::numeric_limits::epsilon(); + constexpr T det_max = T(1) / std::numeric_limits::epsilon(); + + const eT* Xm = X.memptr(); + eT* outm = out.memptr(); + + if(N == 0) { return true; } + + if(N == 1) { outm[0] = eT(1) / Xm[0]; return true; }; + + if(N == 2) { - out.soft_reset(); - arma_stop_runtime_error("inv(): matrix seems singular"); + const eT a = Xm[pos<0,0>::n2]; + const eT b = Xm[pos<0,1>::n2]; + const eT c = Xm[pos<1,0>::n2]; + const eT d = Xm[pos<1,1>::n2]; + + const eT det_val = (a*d - b*c); + const T abs_det_val = std::abs(det_val); + + if((abs_det_val < det_min) || (abs_det_val > det_max)) { return false; } + + outm[pos<0,0>::n2] = d / det_val; + outm[pos<0,1>::n2] = -b / det_val; + outm[pos<1,0>::n2] = -c / det_val; + outm[pos<1,1>::n2] = a / det_val; + + return true; + } + + if(N == 3) + { + const eT det_val = op_det::apply_tiny(X); + const T abs_det_val = std::abs(det_val); + + if((abs_det_val < det_min) || (abs_det_val > det_max)) { return false; } + + outm[pos<0,0>::n3] = (Xm[pos<2,2>::n3]*Xm[pos<1,1>::n3] - Xm[pos<2,1>::n3]*Xm[pos<1,2>::n3]) / det_val; + outm[pos<1,0>::n3] = -(Xm[pos<2,2>::n3]*Xm[pos<1,0>::n3] - Xm[pos<2,0>::n3]*Xm[pos<1,2>::n3]) / det_val; + outm[pos<2,0>::n3] = (Xm[pos<2,1>::n3]*Xm[pos<1,0>::n3] - Xm[pos<2,0>::n3]*Xm[pos<1,1>::n3]) / det_val; + + outm[pos<0,1>::n3] = -(Xm[pos<2,2>::n3]*Xm[pos<0,1>::n3] - Xm[pos<2,1>::n3]*Xm[pos<0,2>::n3]) / det_val; + outm[pos<1,1>::n3] = (Xm[pos<2,2>::n3]*Xm[pos<0,0>::n3] - Xm[pos<2,0>::n3]*Xm[pos<0,2>::n3]) / det_val; + outm[pos<2,1>::n3] = -(Xm[pos<2,1>::n3]*Xm[pos<0,0>::n3] - Xm[pos<2,0>::n3]*Xm[pos<0,1>::n3]) / det_val; + + outm[pos<0,2>::n3] = (Xm[pos<1,2>::n3]*Xm[pos<0,1>::n3] - Xm[pos<1,1>::n3]*Xm[pos<0,2>::n3]) / det_val; + outm[pos<1,2>::n3] = -(Xm[pos<1,2>::n3]*Xm[pos<0,0>::n3] - Xm[pos<1,0>::n3]*Xm[pos<0,2>::n3]) / det_val; + outm[pos<2,2>::n3] = (Xm[pos<1,1>::n3]*Xm[pos<0,0>::n3] - Xm[pos<1,0>::n3]*Xm[pos<0,1>::n3]) / det_val; + + const eT check_val = Xm[pos<0,0>::n3]*outm[pos<0,0>::n3] + Xm[pos<0,1>::n3]*outm[pos<1,0>::n3] + Xm[pos<0,2>::n3]*outm[pos<2,0>::n3]; + + const T max_diff = (is_float::value) ? T(1e-4) : T(1e-10); // empirically determined; may need tuning + + if(std::abs(T(1) - check_val) >= max_diff) { return false; } + + return true; + } + + if(N == 4) + { + const eT det_val = op_det::apply_tiny(X); + const T abs_det_val = std::abs(det_val); + + if((abs_det_val < det_min) || (abs_det_val > det_max)) { return false; } + + outm[pos<0,0>::n4] = ( Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] + Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<1,0>::n4] = ( Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<2,0>::n4] = ( Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<3,0>::n4] = ( Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] ) / det_val; + + outm[pos<0,1>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<1,1>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<2,1>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<3,1>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] ) / det_val; + + outm[pos<0,2>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<1,2>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<2,2>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,3>::n4] ) / det_val; + outm[pos<3,2>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,2>::n4] ) / det_val; + + outm[pos<0,3>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4] ) / det_val; + outm[pos<1,3>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4] ) / det_val; + outm[pos<2,3>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4] ) / det_val; + outm[pos<3,3>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4] ) / det_val; + + const eT check_val = Xm[pos<0,0>::n4]*outm[pos<0,0>::n4] + Xm[pos<0,1>::n4]*outm[pos<1,0>::n4] + Xm[pos<0,2>::n4]*outm[pos<2,0>::n4] + Xm[pos<0,3>::n4]*outm[pos<3,0>::n4]; + + const T max_diff = (is_float::value) ? T(1e-4) : T(1e-10); // empirically determined; may need tuning + + if(std::abs(T(1) - check_val) >= max_diff) { return false; } + + return true; } + + return false; } @@ -148,16 +287,16 @@ template inline void -op_inv_tr::apply(Mat& out, const Op& X) +op_inv_sympd::apply(Mat& out, const Op& X) { arma_extra_debug_sigprint(); - const bool status = auxlib::inv_tr(out, X.m, X.aux_uword_a); + const bool status = op_inv_sympd::apply_direct(out, X.m); if(status == false) { out.soft_reset(); - arma_stop_runtime_error("inv(): matrix seems singular"); + arma_stop_runtime_error("inv_sympd(): matrix is singular or not positive definite"); } } @@ -165,18 +304,64 @@ template inline -void -op_inv_sympd::apply(Mat& out, const Op& X) +bool +op_inv_sympd::apply_direct(Mat& out, const Base& expr) { arma_extra_debug_sigprint(); - const bool status = auxlib::inv_sympd(out, X.m); + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + out = expr.get_ref(); - if(status == false) + arma_debug_check( (out.is_square() == false), "inv_sympd(): given matrix must be square sized" ); + + if((arma_config::debug) && (auxlib::rudimentary_sym_check(out) == false)) { - out.soft_reset(); - arma_stop_runtime_error("inv_sympd(): matrix is singular or not positive definite"); + if(is_cx::no ) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, "inv_sympd(): given matrix is not hermitian"); } + } + + if((out.n_rows <= 4) && is_cx::no) + { + arma_extra_debug_print("op_inv_sympd: attempting tinymatrix optimisation"); + + Mat tmp(out.n_rows, out.n_rows, arma_nozeros_indicator()); + + const bool status = op_inv::apply_tiny_noalias(tmp, out); + + if(status) { arrayops::copy(out.memptr(), tmp.memptr(), tmp.n_elem); return true; } + + arma_extra_debug_print("op_inv_sympd: tinymatrix optimisation failed"); + + // fallthrough if optimisation failed + } + + if((is_cx::no) && (is_op_diagmat::value || out.is_diagmat())) + { + arma_extra_debug_print("op_inv_sympd: detected diagonal matrix"); + + // specialised handling of real matrices only; + // currently auxlib::inv_sympd() does not enforce that + // imaginary components of diagonal elements must be zero; + // strictly enforcing this constraint may break existing user software. + + const uword N = (std::min)(out.n_rows, out.n_cols); + + for(uword i=0; i + inline static bool apply_direct(typename T1::elem_type& out_val, typename T1::pod_type& out_sign, const Base& expr); + + template + inline static bool apply_diagmat(typename T1::elem_type& out_val, typename T1::pod_type& out_sign, const Base& expr); + + template + inline static bool apply_trimat(typename T1::elem_type& out_val, typename T1::pod_type& out_sign, const Base& expr); + }; + + + +class op_log_det_sympd + : public traits_op_default + { + public: + + template + inline static bool apply_direct(typename T1::pod_type& out_val, const Base& expr); + }; + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_log_det_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_log_det_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_log_det_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_log_det_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup op_log_det +//! @{ + + + +template +inline +bool +op_log_det::apply_direct(typename T1::elem_type& out_val, typename T1::pod_type& out_sign, const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + if(strip_diagmat::do_diagmat) + { + const strip_diagmat strip(expr.get_ref()); + + return op_log_det::apply_diagmat(out_val, out_sign, strip.M); + } + + if(strip_trimat::do_trimat) + { + const strip_trimat strip(expr.get_ref()); + + return op_log_det::apply_trimat(out_val, out_sign, strip.M); + } + + Mat A(expr.get_ref()); + + arma_debug_check( (A.is_square() == false), "log_det(): given matrix must be square sized" ); + + if(A.is_diagmat()) { return op_log_det::apply_diagmat(out_val, out_sign, A); } + + const bool is_triu = trimat_helper::is_triu(A); + const bool is_tril = is_triu ? false : trimat_helper::is_tril(A); + + if(is_triu || is_tril) { return op_log_det::apply_trimat(out_val, out_sign, A); } + + return auxlib::log_det(out_val, out_sign, A); + } + + + +template +inline +bool +op_log_det::apply_diagmat(typename T1::elem_type& out_val, typename T1::pod_type& out_sign, const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + const diagmat_proxy A(expr.get_ref()); + + arma_debug_check( (A.n_rows != A.n_cols), "log_det(): given matrix must be square sized" ); + + const uword N = (std::min)(A.n_rows, A.n_cols); + + if(N == 0) + { + out_val = eT(0); + out_sign = T(1); + + return true; + } + + eT x = A[0]; + + T sign = (is_cx::no) ? ( (access::tmp_real(x) < T(0)) ? T(-1) : T(1) ) : T(1); + eT val = (is_cx::no) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x); + + for(uword i=1; i::no) ? ( (access::tmp_real(x) < T(0)) ? T(-1) : T(1) ) : T(1); + val += (is_cx::no) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x); + } + + out_val = val; + out_sign = sign; + + return (arma_isnan(out_val) == false); + } + + + +template +inline +bool +op_log_det::apply_trimat(typename T1::elem_type& out_val, typename T1::pod_type& out_sign, const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + const Proxy P(expr.get_ref()); + + const uword N = P.get_n_rows(); + + arma_debug_check( (N != P.get_n_cols()), "log_det(): given matrix must be square sized" ); + + if(N == 0) + { + out_val = eT(0); + out_sign = T(1); + + return true; + } + + eT x = P.at(0,0); + + T sign = (is_cx::no) ? ( (access::tmp_real(x) < T(0)) ? T(-1) : T(1) ) : T(1); + eT val = (is_cx::no) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x); + + for(uword i=1; i::no) ? ( (access::tmp_real(x) < T(0)) ? T(-1) : T(1) ) : T(1); + val += (is_cx::no) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x); + } + + out_val = val; + out_sign = sign; + + return (arma_isnan(out_val) == false); + } + + + +// + + + +template +inline +bool +op_log_det_sympd::apply_direct(typename T1::pod_type& out_val, const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + Mat A(expr.get_ref()); + + arma_debug_check( (A.is_square() == false), "log_det_sympd(): given matrix must be square sized" ); + + if((arma_config::debug) && (auxlib::rudimentary_sym_check(A) == false)) + { + if(is_cx::no ) { arma_debug_warn_level(1, "log_det_sympd(): given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, "log_det_sympd(): given matrix is not hermitian"); } + } + + return auxlib::log_det_sympd(out_val, A); + } + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_logmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_logmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_logmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_logmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_logmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_logmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_logmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_logmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -58,7 +60,7 @@ const uword N = P.n_rows; - out.zeros(N,N); + out.zeros(N,N); // aliasing can't happen as op_logmat is defined as cx_mat = op(mat) for(uword i=0; i out_T; - const Proxy P(expr.get_ref()); + const quasi_unwrap expr_unwrap(expr.get_ref()); + const Mat& A = expr_unwrap.M; - arma_debug_check( (P.get_n_rows() != P.get_n_cols()), "logmat(): given matrix must be square sized" ); + arma_debug_check( (A.is_square() == false), "logmat(): given matrix must be square sized" ); - if(P.get_n_elem() == 0) + if(A.n_elem == 0) { out.reset(); return true; } else - if(P.get_n_elem() == 1) + if(A.n_elem == 1) { out.set_size(1,1); - out[0] = std::log( std::complex( P[0] ) ); + out[0] = std::log( std::complex( A[0] ) ); + return true; + } + + if(A.is_diagmat()) + { + arma_extra_debug_print("op_logmat: detected diagonal matrix"); + + const uword N = A.n_rows; + + out.zeros(N,N); // aliasing can't happen as op_logmat is defined as cx_mat = op(mat) + + for(uword i=0; i= in_T(0)) + { + out.at(i,i) = std::log(val); + } + else + { + out.at(i,i) = std::log( out_T(val) ); + } + } + return true; } - typename Proxy::ea_type Pea = P.get_ea(); + #if defined(ARMA_OPTIMISE_SYMPD) + const bool try_sympd = sympd_helper::guess_sympd(A); + #else + const bool try_sympd = false; + #endif + + if(try_sympd) + { + arma_extra_debug_print("op_logmat: attempting sympd optimisation"); + + // if matrix A is sympd, all its eigenvalues are positive + + Col eigval; + Mat eigvec; + + const bool eig_status = eig_sym_helper(eigval, eigvec, A, 'd', "logmat()"); + + if(eig_status) + { + // ensure each eigenvalue is > 0 + + const uword N = eigval.n_elem; + const in_T* eigval_mem = eigval.memptr(); + + bool all_pos = true; + + for(uword i=0; i >::from( eigvec * diagmat(eigval) * eigvec.t() ); + + return true; + } + } + + arma_extra_debug_print("op_logmat: sympd optimisation failed"); + + // fallthrough if eigen decomposition failed or an eigenvalue is zero + } - Mat U; - Mat S(P.get_n_rows(), P.get_n_rows()); - out_T* Smem = S.memptr(); + Mat S(A.n_rows, A.n_cols, arma_nozeros_indicator()); - const uword n_elem = P.get_n_elem(); + const in_T* Amem = A.memptr(); + out_T* Smem = S.memptr(); + + const uword n_elem = A.n_elem; for(uword i=0; i( Pea[i] ); + Smem[i] = std::complex( Amem[i] ); } return op_logmat_cx::apply_common(out, S, n_iters); @@ -204,6 +274,7 @@ { arma_extra_debug_sigprint(); + typedef typename T1::pod_type T; typedef typename T1::elem_type eT; Mat S = expr.get_ref(); @@ -223,6 +294,62 @@ return true; } + if(S.is_diagmat()) + { + arma_extra_debug_print("op_logmat_cx: detected diagonal matrix"); + + const uword N = S.n_rows; + + out.zeros(N,N); // aliasing can't happen as S is generated + + for(uword i=0; i eigval; + Mat eigvec; + + const bool eig_status = eig_sym_helper(eigval, eigvec, S, 'd', "logmat()"); + + if(eig_status) + { + // ensure each eigenvalue is > 0 + + const uword N = eigval.n_elem; + const T* eigval_mem = eigval.memptr(); + + bool all_pos = true; + + for(uword i=0; i= n_iters) { arma_debug_warn("logmat(): reached max iterations without full convergence"); } + if(iter >= n_iters) { arma_debug_warn_level(2, "logmat(): reached max iterations without full convergence"); } S.diag() -= eT(1); @@ -312,7 +439,7 @@ const vec indices = regspace(1,m-1); - mat tmp(m,m,fill::zeros); + mat tmp(m, m, arma_zeros_indicator()); tmp.diag(-1) = indices / sqrt(square(2.0*indices) - 1.0); tmp.diag(+1) = indices / sqrt(square(2.0*indices) - 1.0); @@ -329,7 +456,7 @@ const uword N = A.n_rows; - Mat B(N,N,fill::zeros); + Mat B(N, N, arma_zeros_indicator()); Mat X; @@ -338,7 +465,7 @@ // B += weights(i) * solve( (nodes(i)*A + eye< Mat >(N,N)), A ); //const bool solve_ok = solve( X, (nodes(i)*A + eye< Mat >(N,N)), A, solve_opts::fast ); - const bool solve_ok = solve( X, trimatu(nodes(i)*A + eye< Mat >(N,N)), A ); + const bool solve_ok = solve( X, trimatu(nodes(i)*A + eye< Mat >(N,N)), A, solve_opts::no_approx ); if(solve_ok == false) { arma_extra_debug_print("logmat(): solve() failed"); return false; } @@ -399,7 +526,7 @@ bool all_pos = true; - for(uword i=0; i& out, const Op& in); template - inline static void apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_not_cx::result* junk = 0); + inline static void apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_not_cx::result* junk = nullptr); template - inline static void apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_cx_only::result* junk = 0); + inline static void apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_cx_only::result* junk = nullptr); // @@ -43,10 +45,10 @@ inline static void apply(Cube& out, const OpCube& in); template - inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_not_cx::result* junk = 0); + inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_not_cx::result* junk = nullptr); template - inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_cx_only::result* junk = 0); + inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_cx_only::result* junk = nullptr); // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_max_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_max_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_max_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_max_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,7 +31,7 @@ typedef typename T1::elem_type eT; const uword dim = in.aux_uword_a; - arma_debug_check( (dim > 1), "max(): parameter 'dim' must be 0 or 1"); + arma_debug_check( (dim > 1), "max(): parameter 'dim' must be 0 or 1" ); const quasi_unwrap U(in.m); const Mat& X = U.M; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_mean_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_mean_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_mean_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_mean_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_mean_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_mean_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_mean_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_mean_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Op_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Op_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Op_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Op_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_median_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_median_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_median_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_median_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -43,20 +45,20 @@ { public: - template - inline static void apply(Mat& out, const Op& in); + template + inline static void apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk = nullptr); - template - inline static void apply(Mat< std::complex >& out, const Op& in); + template + inline static void apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk = nullptr); // // template - inline static typename T1::elem_type median_vec(const T1& X, const typename arma_not_cx::result* junk = 0); + inline static typename T1::elem_type median_vec(const T1& X, const typename arma_not_cx::result* junk = nullptr); template - inline static typename T1::elem_type median_vec(const T1& X, const typename arma_cx_only::result* junk = 0); + inline static typename T1::elem_type median_vec(const T1& X, const typename arma_cx_only::result* junk = nullptr); // // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_median_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_median_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_median_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_median_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,14 +25,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 +template inline void -op_median::apply(Mat& out, const Op& in) +op_median::apply(Mat& out, const Op& in, const typename arma_not_cx::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 +44,7 @@ const bool is_alias = P.is_alias(out); - if( (is_Mat::value == true) || is_alias ) + if(is_Mat::value || is_alias) { const unwrap_check tmp(P.Q, is_alias); @@ -134,14 +137,16 @@ //! Implementation for complex numbers -template +template inline void -op_median::apply(Mat< std::complex >& out, const Op& in) +op_median::apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk) { arma_extra_debug_sigprint(); + arma_ignore(junk); - typedef typename std::complex eT; + // typedef typename std::complex eT; + typedef typename get_pod_type::result T; arma_type_check(( is_same_type::no )); @@ -242,7 +247,7 @@ std::vector tmp_vec(n_elem); - if(is_Mat::value == true) + if(is_Mat::value) { const unwrap tmp(P.Q); @@ -385,6 +390,8 @@ { arma_extra_debug_sigprint(); + // TODO: if NaN is detected, return NaN + const uword n_elem = uword(X.size()); const uword half = n_elem/2; @@ -426,6 +433,8 @@ typedef arma_cx_median_packet eT; + // TODO: if NaN is detected, return bool set to false, indicating presence of NaN + const uword n_elem = uword(X.size()); const uword half = n_elem/2; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_min_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_min_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_min_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_min_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -30,10 +32,10 @@ inline static void apply(Mat& out, const Op& in); template - inline static void apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_not_cx::result* junk = 0); + inline static void apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_not_cx::result* junk = nullptr); template - inline static void apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_cx_only::result* junk = 0); + inline static void apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_cx_only::result* junk = nullptr); // @@ -43,10 +45,10 @@ inline static void apply(Cube& out, const OpCube& in); template - inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_not_cx::result* junk = 0); + inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_not_cx::result* junk = nullptr); template - inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_cx_only::result* junk = 0); + inline static void apply_noalias(Cube& out, const Cube& X, const uword dim, const typename arma_cx_only::result* junk = nullptr); // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_min_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_min_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_min_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_min_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,7 +31,7 @@ typedef typename T1::elem_type eT; const uword dim = in.aux_uword_a; - arma_debug_check( (dim > 1), "min(): parameter 'dim' must be 0 or 1"); + arma_debug_check( (dim > 1), "min(): parameter 'dim' must be 0 or 1" ); const quasi_unwrap U(in.m); const Mat& X = U.M; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_misc_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_misc_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_misc_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_misc_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_misc_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_misc_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_misc_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_misc_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_nonzeros_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_nonzeros_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_nonzeros_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_nonzeros_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_nonzeros_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_nonzeros_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_nonzeros_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_nonzeros_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -31,7 +33,7 @@ const uword N_max = P.get_n_elem(); - Mat tmp(N_max, 1); + Mat tmp(N_max, 1, arma_nozeros_indicator()); eT* tmp_mem = tmp.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_normalise_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_normalise_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_normalise_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_normalise_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_normalise_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_normalise_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_normalise_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_normalise_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_norm_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_norm_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_norm_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_norm_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,15 +25,13 @@ { public: - // norms for dense vectors and matrices - - template arma_hot inline static typename T1::pod_type vec_norm_1(const Proxy& P, const typename arma_not_cx::result* junk = 0); - template arma_hot inline static typename T1::pod_type vec_norm_1(const Proxy& P, const typename arma_cx_only::result* junk = 0); + template arma_hot inline static typename T1::pod_type vec_norm_1(const Proxy& P, const typename arma_not_cx::result* junk = nullptr); + template arma_hot inline static typename T1::pod_type vec_norm_1(const Proxy& P, const typename arma_cx_only::result* junk = nullptr); template arma_hot inline static eT vec_norm_1_direct_std(const Mat& X); template arma_hot inline static eT vec_norm_1_direct_mem(const uword N, const eT* A); - template arma_hot inline static typename T1::pod_type vec_norm_2(const Proxy& P, const typename arma_not_cx::result* junk = 0); - template arma_hot inline static typename T1::pod_type vec_norm_2(const Proxy& P, const typename arma_cx_only::result* junk = 0); + template arma_hot inline static typename T1::pod_type vec_norm_2(const Proxy& P, const typename arma_not_cx::result* junk = nullptr); + template arma_hot inline static typename T1::pod_type vec_norm_2(const Proxy& P, const typename arma_cx_only::result* junk = nullptr); template arma_hot inline static eT vec_norm_2_direct_std(const Mat& X); template arma_hot inline static eT vec_norm_2_direct_mem(const uword N, const eT* A); template arma_hot inline static eT vec_norm_2_direct_robust(const Mat& X); @@ -41,20 +41,10 @@ template arma_hot inline static typename T1::pod_type vec_norm_max(const Proxy& P); template arma_hot inline static typename T1::pod_type vec_norm_min(const Proxy& P); - template inline static typename T1::pod_type mat_norm_1(const Proxy& P); - template inline static typename T1::pod_type mat_norm_2(const Proxy& P); - - template inline static typename T1::pod_type mat_norm_inf(const Proxy& P); - + template inline static typename get_pod_type::result mat_norm_1(const Mat& X); + template inline static typename get_pod_type::result mat_norm_2(const Mat& X); - // norms for sparse matrices - - template inline static typename T1::pod_type mat_norm_1(const SpProxy& P); - - template inline static typename T1::pod_type mat_norm_2(const SpProxy& P, const typename arma_real_only::result* junk = 0); - template inline static typename T1::pod_type mat_norm_2(const SpProxy& P, const typename arma_cx_only::result* junk = 0); - - template inline static typename T1::pod_type mat_norm_inf(const SpProxy& P); + template inline static typename get_pod_type::result mat_norm_inf(const Mat& X); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_norm_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_norm_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_norm_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_norm_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,9 +30,9 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - const bool have_direct_mem = (is_Mat::stored_type>::value) || (is_subview_col::stored_type>::value); + const bool use_direct_mem = (is_Mat::stored_type>::value) || (is_subview_col::stored_type>::value) || (arma_config::openmp && Proxy::use_mp); - if(have_direct_mem) + if(use_direct_mem) { const quasi_unwrap::stored_type> tmp(P.Q); @@ -311,9 +313,9 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - const bool have_direct_mem = (is_Mat::stored_type>::value) || (is_subview_col::stored_type>::value); + const bool use_direct_mem = (is_Mat::stored_type>::value) || (is_subview_col::stored_type>::value) || (arma_config::openmp && Proxy::use_mp); - if(have_direct_mem) + if(use_direct_mem) { const quasi_unwrap::stored_type> tmp(P.Q); @@ -703,15 +705,7 @@ const uword N = P.get_n_elem(); - uword i,j; - - for(i=0, j=1; j -inline -typename T1::pod_type -op_norm::mat_norm_1(const Proxy& P) - { - arma_extra_debug_sigprint(); - - // TODO: this can be sped up with a dedicated implementation - return as_scalar( max( sum(abs(P.Q), 0), 1) ); - } - - - -template -inline -typename T1::pod_type -op_norm::mat_norm_2(const Proxy& P) - { - arma_extra_debug_sigprint(); - - typedef typename T1::pod_type T; - - Col S; - svd(S, P.Q); - - return (S.n_elem > 0) ? max(S) : T(0); - } - - - -template -inline -typename T1::pod_type -op_norm::mat_norm_inf(const Proxy& P) - { - arma_extra_debug_sigprint(); - - // TODO: this can be sped up with a dedicated implementation - return as_scalar( max( sum(abs(P.Q), 1), 0) ); - } - - - -// -// norms for sparse matrices - - - -template +template inline -typename T1::pod_type -op_norm::mat_norm_1(const SpProxy& P) +typename get_pod_type::result +op_norm::mat_norm_1(const Mat& X) { arma_extra_debug_sigprint(); // TODO: this can be sped up with a dedicated implementation - return as_scalar( max( sum(abs(P.Q), 0), 1) ); + return as_scalar( max( sum(abs(X), 0), 1) ); } -template -inline -typename T1::pod_type -op_norm::mat_norm_2(const SpProxy& P, const typename arma_real_only::result* junk) - { - arma_extra_debug_sigprint(); - arma_ignore(junk); - - // norm = sqrt( largest eigenvalue of (A^H)*A ), where ^H is the conjugate transpose - // http://math.stackexchange.com/questions/4368/computing-the-largest-eigenvalue-of-a-very-large-sparse-matrix - - typedef typename T1::elem_type eT; - typedef typename T1::pod_type T; - - const unwrap_spmat::stored_type> tmp(P.Q); - - const SpMat& A = tmp.M; - const SpMat B = trans(A); - - const SpMat C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A); - - Col eigval; - eigs_sym(eigval, C, 1); - - return (eigval.n_elem > 0) ? std::sqrt(eigval[0]) : T(0); - } - - - -template +template inline -typename T1::pod_type -op_norm::mat_norm_2(const SpProxy& P, const typename arma_cx_only::result* junk) +typename get_pod_type::result +op_norm::mat_norm_2(const Mat& X) { arma_extra_debug_sigprint(); - arma_ignore(junk); - typedef typename T1::elem_type eT; - typedef typename T1::pod_type T; + typedef typename get_pod_type::result T; - // we're calling eigs_gen(), which currently requires ARPACK - #if !defined(ARMA_USE_ARPACK) - { - arma_stop_logic_error("norm(): use of ARPACK must be enabled for norm of complex matrices"); - return T(0); - } - #endif - - const unwrap_spmat::stored_type> tmp(P.Q); - - const SpMat& A = tmp.M; - const SpMat B = trans(A); + if(X.is_finite() == false) { arma_debug_warn_level(1, "norm(): given matrix has non-finite elements"); } - const SpMat C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A); - - Col eigval; - eigs_gen(eigval, C, 1); + Col S; + svd(S, X); - return (eigval.n_elem > 0) ? std::sqrt(std::real(eigval[0])) : T(0); + return (S.n_elem > 0) ? S[0] : T(0); } -template +template inline -typename T1::pod_type -op_norm::mat_norm_inf(const SpProxy& P) +typename get_pod_type::result +op_norm::mat_norm_inf(const Mat& X) { arma_extra_debug_sigprint(); // TODO: this can be sped up with a dedicated implementation - return as_scalar( max( sum(abs(P.Q), 1), 0) ); + return as_scalar( max( sum(abs(X), 1), 0) ); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_orth_null_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_orth_null_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_orth_null_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_orth_null_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_orth_null_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_orth_null_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_orth_null_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_orth_null_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,6 +37,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("orth(): svd failed"); } } @@ -53,18 +56,17 @@ arma_debug_check((tol < T(0)), "orth(): tolerance must be >= 0"); - const unwrap tmp(expr.get_ref()); - const Mat& X = tmp.M; + Mat A(expr.get_ref()); Mat U; Col< T> s; Mat V; - const bool status = auxlib::svd_dc(U, s, V, X); + const bool status = auxlib::svd_dc(U, s, V, A); V.reset(); - if(status == false) { out.soft_reset(); return false; } + if(status == false) { return false; } if(s.is_empty()) { out.reset(); return true; } @@ -72,7 +74,7 @@ const T* s_mem = s.memptr(); // set tolerance to default if it hasn't been specified - if(tol == T(0)) { tol = (std::max)(X.n_rows, X.n_cols) * s_mem[0] * std::numeric_limits::epsilon(); } + if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits::epsilon(); } uword count = 0; @@ -84,7 +86,7 @@ } else { - out.set_size(X.n_rows, 0); + out.set_size(A.n_rows, 0); } return true; @@ -111,6 +113,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("null(): svd failed"); } } @@ -129,18 +132,17 @@ arma_debug_check((tol < T(0)), "null(): tolerance must be >= 0"); - const unwrap tmp(expr.get_ref()); - const Mat& X = tmp.M; + Mat A(expr.get_ref()); Mat U; Col< T> s; Mat V; - const bool status = auxlib::svd_dc(U, s, V, X); + const bool status = auxlib::svd_dc(U, s, V, A); U.reset(); - if(status == false) { out.soft_reset(); return false; } + if(status == false) { return false; } if(s.is_empty()) { out.reset(); return true; } @@ -148,15 +150,15 @@ const T* s_mem = s.memptr(); // set tolerance to default if it hasn't been specified - if(tol == T(0)) { tol = (std::max)(X.n_rows, X.n_cols) * s_mem[0] * std::numeric_limits::epsilon(); } + if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits::epsilon(); } uword count = 0; for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); } - if(count < X.n_cols) + if(count < A.n_cols) { - out = V.tail_cols(X.n_cols - count); + out = V.tail_cols(A.n_cols - count); const uword out_n_elem = out.n_elem; eT* out_mem = out.memptr(); @@ -168,7 +170,7 @@ } else { - out.set_size(X.n_cols, 0); + out.set_size(A.n_cols, 0); } return true; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_pinv_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_pinv_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_pinv_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_pinv_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,8 +28,12 @@ public: template inline static void apply(Mat& out, const Op& in); - - template inline static bool apply_direct(Mat& out, const Base& expr, typename T1::pod_type tol, const bool use_divide_and_conquer); + + template inline static bool apply_direct(Mat& out, const Base& expr, typename T1::pod_type tol, const uword method_id); + + template inline static bool apply_diag(Mat& out, const Mat& A, typename get_pod_type::result tol); + + template inline static bool apply_sym (Mat& out, const Mat& A, typename get_pod_type::result tol, const uword method_id); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_pinv_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_pinv_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_pinv_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_pinv_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,14 +31,14 @@ typedef typename T1::pod_type T; - const T tol = access::tmp_real(in.aux); - - const bool use_divide_and_conquer = (in.aux_uword_a == 1); + const T tol = access::tmp_real(in.aux); + const uword method_id = in.aux_uword_a; - const bool status = op_pinv::apply_direct(out, in.m, tol, use_divide_and_conquer); + const bool status = op_pinv::apply_direct(out, in.m, tol, method_id); if(status == false) { + out.soft_reset(); arma_stop_runtime_error("pinv(): svd failed"); } } @@ -46,7 +48,7 @@ template inline bool -op_pinv::apply_direct(Mat& out, const Base& expr, typename T1::pod_type tol, const bool use_divide_and_conquer) +op_pinv::apply_direct(Mat& out, const Base& expr, typename T1::pod_type tol, const uword method_id) { arma_extra_debug_sigprint(); @@ -55,128 +57,224 @@ arma_debug_check((tol < T(0)), "pinv(): tolerance must be >= 0"); - const Proxy P(expr.get_ref()); + // method_id = 0 -> default setting + // method_id = 1 -> use standard algorithm + // method_id = 2 -> use divide and conquer algorithm + + Mat A(expr.get_ref()); + + const uword n_rows = A.n_rows; + const uword n_cols = A.n_cols; + + if(A.is_empty()) { out.set_size(n_cols,n_rows); return true; } + + if(is_op_diagmat::value || A.is_diagmat()) + { + arma_extra_debug_print("op_pinv: detected diagonal matrix"); + + return op_pinv::apply_diag(out, A, tol); + } - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); + #if defined(ARMA_OPTIMISE_SYMPD) + bool do_sym = false; + bool do_sympd = false; + + const bool is_sym_size_ok = (n_rows > (is_cx::yes ? uword(20) : uword(40))); + const bool is_arg_default = ((tol == T(0)) && (method_id == uword(0))); + + if( (auxlib::crippled_lapack(A) == false) && (is_arg_default || is_sym_size_ok) ) + { + bool is_approx_sym = false; + bool is_approx_sympd = false; + + sympd_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A); + + do_sym = is_sym_size_ok && ((is_cx::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd)); + do_sympd = is_arg_default && is_approx_sympd; + } + #else + const bool do_sym = false; + const bool do_sympd = false; + #endif - if( (n_rows*n_cols) == 0 ) + if(do_sympd) { - out.set_size(n_cols,n_rows); - return true; + arma_extra_debug_print("op_pinv: attempting sympd optimisation"); + + out = A; + + const T rcond_threshold = T((std::max)(uword(100), uword(A.n_rows))) * std::numeric_limits::epsilon(); + + const bool status = auxlib::inv_sympd_rcond(out, rcond_threshold); + + if(status) { return true; } + + arma_extra_debug_print("op_pinv: sympd optimisation failed"); + // auxlib::inv_sympd_rcond() will fail if A isn't really positive definite or its rcond is below rcond_threshold } + if(do_sym) + { + arma_extra_debug_print("op_pinv: symmetric/hermitian optimisation"); + + return op_pinv::apply_sym(out, A, tol, method_id); + } // economical SVD decomposition Mat U; Col< T> s; Mat V; - bool status = false; + if(n_cols > n_rows) { A = trans(A); } + + const bool status = ((method_id == uword(0)) || (method_id == uword(2))) ? auxlib::svd_dc_econ(U, s, V, A) : auxlib::svd_econ(U, s, V, A, 'b'); + + if(status == false) { return false; } + + // set tolerance to default if it hasn't been specified + if( (tol == T(0)) && (s.n_elem > 0) ) { tol = (std::max)(n_rows, n_cols) * s[0] * std::numeric_limits::epsilon(); } - if(use_divide_and_conquer) + uword count = 0; + + for(uword i=0; i < s.n_elem; ++i) { count += (s[i] >= tol) ? uword(1) : uword(0); } + + if(count == 0) { out.zeros(n_cols, n_rows); return true; } + + Col s2(count, arma_nozeros_indicator()); + + uword count2 = 0; + + for(uword i=0; i < s.n_elem; ++i) { - status = (n_cols > n_rows) ? auxlib::svd_dc_econ(U, s, V, trans(P.Q)) : auxlib::svd_dc_econ(U, s, V, P.Q); + const T val = s[i]; + + if(val >= tol) { s2[count2] = (val > T(0)) ? T(T(1) / val) : T(0); ++count2; } } - else + + const Mat U_use(U.memptr(), U.n_rows, count, false); + const Mat V_use(V.memptr(), V.n_rows, count, false); + + Mat tmp; + + if(n_rows >= n_cols) { - status = (n_cols > n_rows) ? auxlib::svd_econ(U, s, V, trans(P.Q), 'b') : auxlib::svd_econ(U, s, V, P.Q, 'b'); + // out = ( (V.n_cols > count) ? V.cols(0,count-1) : V ) * diagmat(s2) * trans( (U.n_cols > count) ? U.cols(0,count-1) : U ); + + tmp = V_use * diagmat(s2); + + out = tmp * trans(U_use); } - - if(status == false) + else { - out.soft_reset(); - return false; + // out = ( (U.n_cols > count) ? U.cols(0,count-1) : U ) * diagmat(s2) * trans( (V.n_cols > count) ? V.cols(0,count-1) : V ); + + tmp = U_use * diagmat(s2); + + out = tmp * trans(V_use); } - const uword s_n_elem = s.n_elem; - const T* s_mem = s.memptr(); + return true; + } + + + +template +inline +bool +op_pinv::apply_diag(Mat& out, const Mat& A, typename get_pod_type::result tol) + { + arma_extra_debug_sigprint(); - // set tolerance to default if it hasn't been specified - if( (tol == T(0)) && (s_n_elem > 0) ) - { - tol = (std::max)(n_rows, n_cols) * s_mem[0] * std::numeric_limits::epsilon(); - } + typedef typename get_pod_type::result T; + out.zeros(A.n_cols, A.n_rows); - uword count = 0; + const uword N = (std::min)(A.n_rows, A.n_cols); - for(uword i = 0; i < s_n_elem; ++i) - { - count += (s_mem[i] >= tol) ? uword(1) : uword(0); - } + podarray diag_abs_vals(N); + T max_abs_Aii = T(0); - if(count > 0) + for(uword i=0; i s2(count); + const eT Aii = A.at(i,i); + const T abs_Aii = std::abs(Aii); - T* s2_mem = s2.memptr(); + if(arma_isnan(Aii)) { return false; } - uword count2 = 0; + diag_abs_vals[i] = abs_Aii; - for(uword i=0; i < s_n_elem; ++i) - { - const T val = s_mem[i]; - - if(val >= tol) { s2_mem[count2] = T(1) / val; ++count2; } - } - - - if(n_rows >= n_cols) - { - // out = ( (V.n_cols > count) ? V.cols(0,count-1) : V ) * diagmat(s2) * trans( (U.n_cols > count) ? U.cols(0,count-1) : U ); - - Mat tmp; - - if(count < V.n_cols) - { - tmp = V.cols(0,count-1) * diagmat(s2); - } - else - { - tmp = V * diagmat(s2); - } - - if(count < U.n_cols) - { - out = tmp * trans(U.cols(0,count-1)); - } - else - { - out = tmp * trans(U); - } - } - else + max_abs_Aii = (abs_Aii > max_abs_Aii) ? abs_Aii : max_abs_Aii; + } + + if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_Aii * std::numeric_limits::epsilon(); } + + for(uword i=0; i= tol) { - // out = ( (U.n_cols > count) ? U.cols(0,count-1) : U ) * diagmat(s2) * trans( (V.n_cols > count) ? V.cols(0,count-1) : V ); + const eT Aii = A.at(i,i); - Mat tmp; - - if(count < U.n_cols) - { - tmp = U.cols(0,count-1) * diagmat(s2); - } - else - { - tmp = U * diagmat(s2); - } - - if(count < V.n_cols) - { - out = tmp * trans(V.cols(0,count-1)); - } - else - { - out = tmp * trans(V); - } + if(Aii != eT(0)) { out.at(i,i) = eT(eT(1) / Aii); } } } - else + + return true; + } + + + +template +inline +bool +op_pinv::apply_sym(Mat& out, const Mat& A, typename get_pod_type::result tol, const uword method_id) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + Col< T> eigval; + Mat eigvec; + + const bool status = ((method_id == uword(0)) || (method_id == uword(2))) ? auxlib::eig_sym_dc(eigval, eigvec, A) : auxlib::eig_sym(eigval, eigvec, A); + + if(status == false) { return false; } + + if(eigval.n_elem == 0) { out.zeros(A.n_cols, A.n_rows); return true; } + + Col abs_eigval = arma::abs(eigval); + + const uvec indices = sort_index(abs_eigval, "descend"); + + abs_eigval = abs_eigval.elem(indices); + eigval = eigval.elem(indices); + eigvec = eigvec.cols(indices); + + // set tolerance to default if it hasn't been specified + if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * abs_eigval[0] * std::numeric_limits::epsilon(); } + + uword count = 0; + + for(uword i=0; i < abs_eigval.n_elem; ++i) { count += (abs_eigval[i] >= tol) ? uword(1) : uword(0); } + + if(count == 0) { out.zeros(A.n_cols, A.n_rows); return true; } + + Col eigval2(count, arma_nozeros_indicator()); + + uword count2 = 0; + + for(uword i=0; i < eigval.n_elem; ++i) { - out.zeros(n_cols, n_rows); + const T abs_val = abs_eigval[i]; + const T val = eigval[i]; + + if(abs_val >= tol) { eigval2[count2] = (val != T(0)) ? T(T(1) / val) : T(0); ++count2; } } + const Mat eigvec_use(eigvec.memptr(), eigvec.n_rows, count, false); + + out = (eigvec_use * diagmat(eigval2)).eval() * eigvec_use.t(); + return true; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_powmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_powmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_powmat_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_powmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup op_powmat +//! @{ + + + +class op_powmat + : public traits_op_default + { + public: + + template + inline static void apply(Mat& out, const Op& expr); + + template + inline static bool apply_direct(Mat& out, const Base& X, const uword y, const bool y_neg); + + template + inline static void apply_direct_positive(Mat& out, const Mat& X, const uword y); + }; + + + +class op_powmat_cx + : public traits_op_default + { + public: + + template + inline static void apply(Mat< std::complex >& out, const mtOp,T1,op_powmat_cx>& expr); + + template + inline static bool apply_direct(Mat< std::complex >& out, const Base& X, const typename T1::pod_type y); + }; + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_powmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_powmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_powmat_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_powmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup op_powmat +//! @{ + + +template +inline +void +op_powmat::apply(Mat& out, const Op& expr) + { + arma_extra_debug_sigprint(); + + const uword y = expr.aux_uword_a; + const bool y_neg = (expr.aux_uword_b == uword(1)); + + const bool status = op_powmat::apply_direct(out, expr.m, y, y_neg); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("powmat(): transformation failed"); + } + } + + + +template +inline +bool +op_powmat::apply_direct(Mat& out, const Base& X, const uword y, const bool y_neg) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + if(y_neg) + { + if(y == uword(1)) + { + return op_inv::apply_direct(out, X.get_ref(), "powmat()"); + } + else + { + Mat X_inv; + + const bool inv_status = op_inv::apply_direct(X_inv, X.get_ref(), "powmat()"); + + if(inv_status == false) { return false; } + + op_powmat::apply_direct_positive(out, X_inv, y); + } + } + else + { + const quasi_unwrap U(X.get_ref()); + + arma_debug_check( (U.M.is_square() == false), "powmat(): given matrix must be square sized" ); + + op_powmat::apply_direct_positive(out, U.M, y); + } + + return true; + } + + + +template +inline +void +op_powmat::apply_direct_positive(Mat& out, const Mat& X, const uword y) + { + arma_extra_debug_sigprint(); + + const uword N = X.n_rows; + + if(y == uword(0)) { out.eye(N,N); return; } + if(y == uword(1)) { out = X; return; } + + if(X.is_diagmat()) + { + arma_extra_debug_print("op_powmat: detected diagonal matrix"); + + podarray tmp(N); // use temporary array in case we have aliasing + + for(uword i=0; i tmp = X*X; out = X*tmp; } + else if(y == uword(4)) { const Mat tmp = X*X; out = tmp*tmp; } + else if(y == uword(5)) { const Mat tmp = X*X; out = X*tmp*tmp; } + else + { + Mat tmp = X; + + out = X; + + uword z = y-1; + + while(z > 0) + { + if(z & 1) { out = tmp * out; } + + z /= uword(2); + + if(z > 0) { tmp = tmp * tmp; } + } + } + } + } + + + +template +inline +void +op_powmat_cx::apply(Mat< std::complex >& out, const mtOp,T1,op_powmat_cx>& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type in_T; + + const in_T y = std::real(expr.aux_out_eT); + + const bool status = op_powmat_cx::apply_direct(out, expr.m, y); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("powmat(): transformation failed"); + } + } + + + +template +inline +bool +op_powmat_cx::apply_direct(Mat< std::complex >& out, const Base& X, const typename T1::pod_type y) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type in_eT; + typedef typename T1::pod_type in_T; + typedef std::complex out_eT; + + if( y == in_T(int(y)) ) + { + arma_extra_debug_print("op_powmat_cx::apply_direct(): integer exponent detected; redirecting to op_powmat"); + + const uword y_val = (y < int(0)) ? uword(-y) : uword(y); + const bool y_neg = (y < int(0)); + + Mat tmp; + + const bool status = op_powmat::apply_direct(tmp, X.get_ref(), y_val, y_neg); + + if(status == false) { return false; } + + out = conv_to< Mat >::from(tmp); + + return true; + } + + const quasi_unwrap U(X.get_ref()); + const Mat& A = U.M; + + arma_debug_check( (A.is_square() == false), "powmat(): given matrix must be square sized" ); + + const uword N = A.n_rows; + + if(A.is_diagmat()) + { + arma_extra_debug_print("op_powmat_cx: detected diagonal matrix"); + + podarray tmp(N); // use temporary array in case we have aliasing + + for(uword i=0; i(A.at(i,i)), y) ; } + + out.zeros(N,N); + + for(uword i=0; i eigval; + Mat eigvec; + + const bool eig_status = eig_sym(eigval, eigvec, A); + + if(eig_status) + { + eigval = pow(eigval, y); + + const Mat tmp = diagmat(eigval) * eigvec.t(); + + out = conv_to< Mat >::from(eigvec * tmp); + + return true; + } + + arma_extra_debug_print("op_powmat_cx: sympd optimisation failed"); + + // fallthrough if optimisation failed + } + + bool powmat_status = false; + + Col eigval; + Mat eigvec; + + const bool eig_status = eig_gen(eigval, eigvec, A); + + if(eig_status) + { + eigval = pow(eigval, y); + + Mat eigvec_t = trans(eigvec); + Mat tmp = diagmat(conj(eigval)) * eigvec_t; + + const bool solve_status = auxlib::solve_square_fast(out, eigvec_t, tmp); + + if(solve_status) { out = trans(out); powmat_status = true; } + } + + return powmat_status; + } + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_princomp_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_princomp_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_princomp_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_princomp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_princomp_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_princomp_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_princomp_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_princomp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -72,7 +74,7 @@ { score_out.cols(n_rows-1,n_cols-1).zeros(); - Col s_tmp(n_cols, fill::zeros); + Col s_tmp(n_cols, arma_zeros_indicator()); s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2); s = s_tmp; @@ -164,7 +166,7 @@ { score_out.cols(n_rows-1,n_cols-1).zeros(); - Col s_tmp(n_cols, fill::zeros); + Col s_tmp(n_cols, arma_zeros_indicator()); s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2); s = s_tmp; @@ -264,6 +266,7 @@ arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; const unwrap Y( X.get_ref() ); const Mat& in = Y.M; @@ -274,7 +277,7 @@ // singular value decomposition Mat U; - Col 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); @@ -301,12 +304,7 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - - const unwrap_check tmp(in.m, out); - const Mat& A = tmp.M; - - const bool status = op_princomp::direct_princomp(out, A); + const bool status = op_princomp::direct_princomp(out, in.m); if(status == false) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_prod_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_prod_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_prod_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_prod_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_prod_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_prod_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_prod_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_prod_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,7 +30,7 @@ const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; - if(dim == 0) // traverse across rows (i.e. find the product in each column) + if(dim == 0) // traverse across rows (ie. find the product in each column) { out.set_size(1, X_n_cols); @@ -39,7 +41,7 @@ out_mem[col] = arrayops::product(X.colptr(col), X_n_rows); } } - else // traverse across columns (i.e. find the product in each row) + else // traverse across columns (ie. find the product in each row) { out.ones(X_n_rows, 1); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_range_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_range_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_range_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_range_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_range_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_range_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_range_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_range_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,7 +31,7 @@ typedef typename T1::elem_type eT; const uword dim = in.aux_uword_a; - arma_debug_check( (dim > 1), "range(): parameter 'dim' must be 0 or 1"); + arma_debug_check( (dim > 1), "range(): parameter 'dim' must be 0 or 1" ); const quasi_unwrap U(in.m); const Mat& X = U.M; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_rank_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_rank_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_rank_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_rank_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup op_rank +//! @{ + + + +class op_rank + : public traits_op_default + { + public: + + template inline static bool apply(uword& out, const Base& expr, const typename T1::pod_type tol); + + template inline static bool apply_gen(uword& out, Mat& A, typename get_pod_type::result tol); + + template inline static bool apply_sym(uword& out, Mat& A, typename get_pod_type::result tol); + + template inline static bool apply_diag(uword& out, Mat& A, typename get_pod_type::result tol); + }; + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_rank_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_rank_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_rank_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_rank_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup op_rank +//! @{ + + + +template +inline +bool +op_rank::apply(uword& out, const Base& expr, const typename T1::pod_type tol) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + Mat A(expr.get_ref()); + + if(A.is_empty()) { out = uword(0); return true; } + + if(is_op_diagmat::value || A.is_diagmat()) + { + arma_extra_debug_print("op_rank::apply(): detected diagonal matrix"); + + return op_rank::apply_diag(out, A, tol); + } + + #if defined(ARMA_OPTIMISE_SYMPD) + bool do_sym = false; + + if((auxlib::crippled_lapack(A) == false) && (A.n_rows >= (is_cx::yes ? uword(64) : uword(128)))) + { + bool is_approx_sym = false; + bool is_approx_sympd = false; + + sympd_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A); + + do_sym = (is_cx::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd); + } + #else + const bool do_sym = false; + #endif + + if(do_sym) + { + arma_extra_debug_print("op_rank::apply(): symmetric/hermitian optimisation"); + + return op_rank::apply_sym(out, A, tol); + } + + return op_rank::apply_gen(out, A, tol); + } + + + +template +inline +bool +op_rank::apply_diag(uword& out, Mat& A, typename get_pod_type::result tol) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + const uword N = (std::min)(A.n_rows, A.n_cols); + + podarray diag_abs_vals(N); + + T max_abs_Aii = T(0); + + for(uword i=0; i max_abs_Aii) ? abs_Aii : max_abs_Aii; + } + + // set tolerance to default if it hasn't been specified + if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_Aii * std::numeric_limits::epsilon(); } + + uword count = 0; + + for(uword i=0; i tol) ? uword(1) : uword(0); } + + out = count; + + return true; + } + + + +template +inline +bool +op_rank::apply_sym(uword& out, Mat& A, typename get_pod_type::result tol) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + if(A.is_square() == false) { out = uword(0); return false; } + + Col v; + + const bool status = auxlib::eig_sym(v, A); + + if(status == false) { out = uword(0); return false; } + + const uword v_n_elem = v.n_elem; + T* v_mem = v.memptr(); + + if(v_n_elem == 0) { out = uword(0); return true; } + + T max_abs_v = T(0); + + for(uword i=0; i < v_n_elem; ++i) { const T val = std::abs(v_mem[i]); v_mem[i] = val; if(val > max_abs_v) { max_abs_v = val; } } + + // set tolerance to default if it hasn't been specified + if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_v * std::numeric_limits::epsilon(); } + + uword count = 0; + + for(uword i=0; i < v_n_elem; ++i) { count += (v_mem[i] > tol) ? uword(1) : uword(0); } + + out = count; + + return true; + } + + + +template +inline +bool +op_rank::apply_gen(uword& out, Mat& A, typename get_pod_type::result tol) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + Col s; + + const bool status = auxlib::svd_dc(s, A); + + if(status == false) { out = uword(0); return false; } + + const uword s_n_elem = s.n_elem; + const T* s_mem = s.memptr(); + + if(s_n_elem == 0) { out = uword(0); return true; } + + // set tolerance to default if it hasn't been specified + if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits::epsilon(); } + + uword count = 0; + + for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); } + + out = count; + + return true; + } + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_relational_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_relational_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_relational_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_relational_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_relational_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_relational_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_relational_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_relational_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_repelem_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_repelem_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_repelem_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_repelem_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_repelem_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_repelem_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_repelem_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_repelem_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_repmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_repmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_repmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_repmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_repmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_repmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_repmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_repmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_reshape_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_reshape_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_reshape_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_reshape_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,22 +27,36 @@ { public: - template inline static void apply_unwrap(Mat& out, const Mat& A, const uword in_n_rows, const uword in_n_cols, const uword in_dim); + template inline static void apply(Mat& out, const Op& in); + + template inline static void apply_mat_inplace(Mat& A, const uword new_n_rows, const uword new_n_cols); + + template inline static void apply_mat_noalias(Mat& out, const Mat& A, const uword new_n_rows, const uword new_n_cols); + + template inline static void apply_proxy_noalias(Mat& out, const Proxy& P, const uword new_n_rows, const uword new_n_cols); - template inline static void apply_proxy (Mat& out, const Proxy& P, const uword in_n_rows, const uword in_n_cols); + // - template inline static void apply (Mat& out, const Op& in); + template inline static void apply(Cube& out, const OpCube& in); + + template inline static void apply_cube_inplace(Cube& A, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + + template inline static void apply_cube_noalias(Cube& out, const Cube& A, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); }; -class op_reshape_ext +//! NOTE: deprecated +class op_reshape_old : public traits_op_default { public: - template inline static void apply( Mat& out, const Op& in); - template inline static void apply(Cube& out, const OpCube& in); + template arma_cold inline static void apply(Mat& out, const Op& in); + + template arma_cold inline static void apply_mat_inplace(Mat& A, const uword new_n_rows, const uword new_n_cols, const uword dim); + + template arma_cold inline static void apply_mat_noalias(Mat& out, const Mat& A, const uword new_n_rows, const uword new_n_cols, const uword dim); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_reshape_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_reshape_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_reshape_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_reshape_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,104 +22,98 @@ -template +template inline void -op_reshape::apply_unwrap(Mat& out, const Mat& A, const uword in_n_rows, const uword in_n_cols, const uword in_dim) +op_reshape::apply(Mat& actual_out, const Op& in) { arma_extra_debug_sigprint(); - const bool is_alias = (&out == &A); + typedef typename T1::elem_type eT; - const uword in_n_elem = in_n_rows * in_n_cols; + const uword new_n_rows = in.aux_uword_a; + const uword new_n_cols = in.aux_uword_b; - if(A.n_elem == in_n_elem) + if(is_Mat::value || (arma_config::openmp && Proxy::use_mp)) { - if(in_dim == 0) + const unwrap U(in.m); + const Mat& A = U.M; + + if(&actual_out == &A) { - if(is_alias == false) - { - out.set_size(in_n_rows, in_n_cols); - arrayops::copy( out.memptr(), A.memptr(), out.n_elem ); - } - else // &out == &A, i.e. inplace resize - { - out.set_size(in_n_rows, in_n_cols); - // set_size() doesn't destroy data as long as the number of elements in the matrix remains the same - } + op_reshape::apply_mat_inplace(actual_out, new_n_rows, new_n_cols); } else { - unwrap_check< Mat > B_tmp(A, is_alias); - const Mat& B = B_tmp.M; - - out.set_size(in_n_rows, in_n_cols); - - eT* out_mem = out.memptr(); - - const uword B_n_rows = B.n_rows; - const uword B_n_cols = B.n_cols; - - for(uword row=0; row > B_tmp(A, is_alias); - const Mat& B = B_tmp.M; - - const uword n_elem_to_copy = (std::min)(B.n_elem, in_n_elem); + const Proxy P(in.m); - out.set_size(in_n_rows, in_n_cols); + const bool is_alias = P.is_alias(actual_out); - eT* out_mem = out.memptr(); + Mat tmp; + Mat& out = (is_alias) ? tmp : actual_out; - if(in_dim == 0) + if(is_Mat::stored_type>::value) { - arrayops::copy( out_mem, B.memptr(), n_elem_to_copy ); + const quasi_unwrap::stored_type> U(P.Q); + + op_reshape::apply_mat_noalias(out, U.M, new_n_rows, new_n_cols); } else { - uword row = 0; - uword col = 0; - - const uword B_n_cols = B.n_cols; - - for(uword i=0; i= B_n_cols) - { - col = 0; - ++row; - } - } + op_reshape::apply_proxy_noalias(out, P, new_n_rows, new_n_cols); } - for(uword i=n_elem_to_copy; i +inline +void +op_reshape::apply_mat_inplace(Mat& A, const uword new_n_rows, const uword new_n_cols) + { + arma_extra_debug_sigprint(); + + const uword new_n_elem = new_n_rows * new_n_cols; + + if(A.n_elem == new_n_elem) { A.set_size(new_n_rows, new_n_cols); return; } + + Mat B; + + op_reshape::apply_mat_noalias(B, A, new_n_rows, new_n_cols); + + A.steal_mem(B); + } + + + +template +inline +void +op_reshape::apply_mat_noalias(Mat& out, const Mat& A, const uword new_n_rows, const uword new_n_cols) + { + arma_extra_debug_sigprint(); + + out.set_size(new_n_rows, new_n_cols); + + const uword n_elem_to_copy = (std::min)(A.n_elem, out.n_elem); + + eT* out_mem = out.memptr(); + + arrayops::copy( out_mem, A.memptr(), n_elem_to_copy ); + + if(n_elem_to_copy < out.n_elem) + { + const uword n_elem_leftover = out.n_elem - n_elem_to_copy; + arrayops::fill_zeros(&(out_mem[n_elem_to_copy]), n_elem_leftover); } } @@ -126,91 +122,49 @@ template inline void -op_reshape::apply_proxy(Mat& out, const Proxy& P, const uword in_n_rows, const uword in_n_cols) +op_reshape::apply_proxy_noalias(Mat& out, const Proxy& P, const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - out.set_size(in_n_rows, in_n_cols); + out.set_size(new_n_rows, new_n_cols); - eT* out_mem = out.memptr(); + const uword n_elem_to_copy = (std::min)(P.get_n_elem(), out.n_elem); - const uword in_n_elem = in_n_rows * in_n_cols; + eT* out_mem = out.memptr(); - if(P.get_n_elem() == in_n_elem) + if(Proxy::use_at == false) { - if(Proxy::use_at == false) - { - typename Proxy::ea_type Pea = P.get_ea(); - - for(uword i=0; i::ea_type Pea = P.get_ea(); + + for(uword i=0; i < n_elem_to_copy; ++i) { out_mem[i] = Pea[i]; } } else { - const uword n_elem_to_copy = (std::min)(P.get_n_elem(), in_n_elem); + uword i = 0; - if(Proxy::use_at == false) - { - typename Proxy::ea_type Pea = P.get_ea(); - - for(uword i=0; i= n_elem_to_copy) { goto nested_loop_end; } - for(uword col=0; col < P_n_cols; ++col) - for(uword row=0; row < P_n_rows; ++row) - { - if(i >= n_elem_to_copy) { goto nested_loop_end; } - - out_mem[i] = P.at(row,col); - - ++i; - } + out_mem[i] = P.at(row,col); - nested_loop_end: ; + ++i; } - for(uword i=n_elem_to_copy; i inline void -op_reshape::apply(Mat& out, const Op& in) +op_reshape::apply(Cube& out, const OpCube& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const Proxy P(in.m); + const unwrap_cube U(in.m); + const Cube& A = U.M; - const uword in_n_rows = in.aux_uword_a; - const uword in_n_cols = in.aux_uword_b; + const uword new_n_rows = in.aux_uword_a; + const uword new_n_cols = in.aux_uword_b; + const uword new_n_slices = in.aux_uword_c; - if( (is_Mat::stored_type>::value == true) && (Proxy::fake_mat == false) ) + if(&out == &A) { - // not checking for aliasing here, as this might be an inplace reshape - - const unwrap::stored_type> tmp(P.Q); - - op_reshape::apply_unwrap(out, tmp.M, in_n_rows, in_n_cols, uword(0)); + op_reshape::apply_cube_inplace(out, new_n_rows, new_n_cols, new_n_slices); } else { - if(P.is_alias(out)) - { - Mat tmp; - - op_reshape::apply_proxy(tmp, P, in_n_rows, in_n_cols); - - out.steal_mem(tmp); - } - else - { - op_reshape::apply_proxy(out, P, in_n_rows, in_n_cols); - } + op_reshape::apply_cube_noalias(out, A, new_n_rows, new_n_cols, new_n_slices); } } + +template +inline +void +op_reshape::apply_cube_inplace(Cube& A, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) + { + arma_extra_debug_sigprint(); + + const uword new_n_elem = new_n_rows * new_n_cols * new_n_slices; + + if(A.n_elem == new_n_elem) { A.set_size(new_n_rows, new_n_cols, new_n_slices); return; } + + Cube B; + + op_reshape::apply_cube_noalias(B, A, new_n_rows, new_n_cols, new_n_slices); + + A.steal_mem(B); + } -template + + +template inline void -op_reshape_ext::apply(Mat& out, const Op& in) +op_reshape::apply_cube_noalias(Cube& out, const Cube& A, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); - const unwrap tmp(in.m); + out.set_size(new_n_rows, new_n_cols, new_n_slices); + + const uword n_elem_to_copy = (std::min)(A.n_elem, out.n_elem); + + eT* out_mem = out.memptr(); - const uword in_n_rows = in.aux_uword_a; - const uword in_n_cols = in.aux_uword_b; - const uword in_dim = in.aux_uword_c; + arrayops::copy( out_mem, A.memptr(), n_elem_to_copy ); - op_reshape::apply_unwrap(out, tmp.M, in_n_rows, in_n_cols, in_dim); + if(n_elem_to_copy < out.n_elem) + { + const uword n_elem_leftover = out.n_elem - n_elem_to_copy; + + arrayops::fill_zeros(&(out_mem[n_elem_to_copy]), n_elem_leftover); + } } +// + + + template +arma_cold inline void -op_reshape_ext::apply(Cube& out, const OpCube& in) +op_reshape_old::apply(Mat& out, const Op& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const unwrap_cube A_tmp(in.m); - const Cube& A = A_tmp.M; + const uword new_n_rows = in.aux_uword_a; + const uword new_n_cols = in.aux_uword_b; + const uword dim = in.aux_uword_c; - const uword in_n_rows = in.aux_uword_a; - const uword in_n_cols = in.aux_uword_b; - const uword in_n_slices = in.aux_uword_c; - const uword in_dim = in.aux_uword_d; + const unwrap U(in.m); + const Mat& A = U.M; - const uword in_n_elem = in_n_rows * in_n_cols * in_n_slices; + if(&out == &A) + { + op_reshape_old::apply_mat_inplace(out, new_n_rows, new_n_cols, dim); + } + else + { + op_reshape_old::apply_mat_noalias(out, A, new_n_rows, new_n_cols, dim); + } + } + + + +template +arma_cold +inline +void +op_reshape_old::apply_mat_inplace(Mat& A, const uword new_n_rows, const uword new_n_cols, const uword dim) + { + arma_extra_debug_sigprint(); - if(A.n_elem == in_n_elem) + if(dim == 0) { - if(in_dim == 0) - { - if(&out != &A) - { - out.set_size(in_n_rows, in_n_cols, in_n_slices); - arrayops::copy( out.memptr(), A.memptr(), out.n_elem ); - } - else // &out == &A, i.e. inplace resize - { - out.set_size(in_n_rows, in_n_cols, in_n_slices); - // set_size() doesn't destroy data as long as the number of elements in the cube remains the same - } - } - else - { - unwrap_cube_check< Cube > B_tmp(A, out); - const Cube& B = B_tmp.M; - - out.set_size(in_n_rows, in_n_cols, in_n_slices); - - eT* out_mem = out.memptr(); - - const uword B_n_rows = B.n_rows; - const uword B_n_cols = B.n_cols; - const uword B_n_slices = B.n_slices; - - for(uword slice = 0; slice < B_n_slices; ++slice) - for(uword row = 0; row < B_n_rows; ++row ) - for(uword col = 0; col < B_n_cols; ++col ) - { - *out_mem = B.at(row,col,slice); - out_mem++; - } - } + op_reshape::apply_mat_inplace(A, new_n_rows, new_n_cols); } else + if(dim == 1) { - const unwrap_cube_check< Cube > B_tmp(A, out); - const Cube& B = B_tmp.M; - - const uword n_elem_to_copy = (std::min)(B.n_elem, in_n_elem); - - out.set_size(in_n_rows, in_n_cols, in_n_slices); + Mat tmp; - eT* out_mem = out.memptr(); + op_strans::apply_mat_noalias(tmp, A); - if(in_dim == 0) - { - arrayops::copy( out_mem, B.memptr(), n_elem_to_copy ); - } - else - { - uword row = 0; - uword col = 0; - uword slice = 0; - - const uword B_n_rows = B.n_rows; - const uword B_n_cols = B.n_cols; - - for(uword i=0; i= B_n_cols) - { - col = 0; - ++row; - - if(row >= B_n_rows) - { - row = 0; - ++slice; - } - } - } - } + op_reshape::apply_mat_noalias(A, tmp, new_n_rows, new_n_cols); + } + } + + + +template +arma_cold +inline +void +op_reshape_old::apply_mat_noalias(Mat& out, const Mat& A, const uword new_n_rows, const uword new_n_cols, const uword dim) + { + arma_extra_debug_sigprint(); + + if(dim == 0) + { + op_reshape::apply_mat_noalias(out, A, new_n_rows, new_n_cols); + } + else + if(dim == 1) + { + Mat tmp; - for(uword i=n_elem_to_copy; i inline static void apply( Mat& out, const Op& in); + template inline static void apply(Mat& out, const Op& in); + + template inline static void apply_mat_inplace(Mat& A, const uword new_n_rows, const uword new_n_cols); + + template inline static void apply_mat_noalias(Mat& out, const Mat& A, const uword new_n_rows, const uword new_n_cols); + + // + template inline static void apply(Cube& out, const OpCube& in); + + template inline static void apply_cube_inplace(Cube& A, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + + template inline static void apply_cube_noalias(Cube& out, const Cube& A, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_resize_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_resize_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_resize_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_resize_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -23,122 +25,143 @@ template inline void -op_resize::apply(Mat& actual_out, const Op& in) +op_resize::apply(Mat& out, const Op& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const uword out_n_rows = in.aux_uword_a; - const uword out_n_cols = in.aux_uword_b; + const uword new_n_rows = in.aux_uword_a; + const uword new_n_cols = in.aux_uword_b; const unwrap tmp(in.m); const Mat& A = tmp.M; - const uword A_n_rows = A.n_rows; - const uword A_n_cols = A.n_cols; - - const bool alias = (&actual_out == &A); - - if(alias) + if(&out == &A) { - if( (A_n_rows == out_n_rows) && (A_n_cols == out_n_cols) ) - { - return; - } - - if(actual_out.is_empty()) - { - actual_out.zeros(out_n_rows, out_n_cols); - return; - } + op_resize::apply_mat_inplace(out, new_n_rows, new_n_cols); } + else + { + op_resize::apply_mat_noalias(out, A, new_n_rows, new_n_cols); + } + } + + + +template +inline +void +op_resize::apply_mat_inplace(Mat& A, const uword new_n_rows, const uword new_n_cols) + { + arma_extra_debug_sigprint(); - Mat B; - Mat& out = alias ? B : actual_out; + if( (A.n_rows == new_n_rows) && (A.n_cols == new_n_cols) ) { return; } - out.set_size(out_n_rows, out_n_cols); + if(A.is_empty()) { A.zeros(new_n_rows, new_n_cols); return; } - if( (out_n_rows > A_n_rows) || (out_n_cols > A_n_cols) ) - { - out.zeros(); - } + Mat B; + + op_resize::apply_mat_noalias(B, A, new_n_rows, new_n_cols); + + A.steal_mem(B); + } + + + +template +inline +void +op_resize::apply_mat_noalias(Mat& out, const Mat& A, const uword new_n_rows, const uword new_n_cols) + { + arma_extra_debug_sigprint(); + + out.set_size(new_n_rows, new_n_cols); + + if( (new_n_rows > A.n_rows) || (new_n_cols > A.n_cols) ) { out.zeros(); } if( (out.n_elem > 0) && (A.n_elem > 0) ) { - const uword end_row = (std::min)(out_n_rows, A_n_rows) - 1; - const uword end_col = (std::min)(out_n_cols, A_n_cols) - 1; + const uword end_row = (std::min)(new_n_rows, A.n_rows) - 1; + const uword end_col = (std::min)(new_n_cols, A.n_cols) - 1; out.submat(0, 0, end_row, end_col) = A.submat(0, 0, end_row, end_col); } - - if(alias) - { - actual_out.steal_mem(B); - } } +// + + + template inline void -op_resize::apply(Cube& actual_out, const OpCube& in) +op_resize::apply(Cube& out, const OpCube& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const uword out_n_rows = in.aux_uword_a; - const uword out_n_cols = in.aux_uword_b; - const uword out_n_slices = in.aux_uword_c; + const uword new_n_rows = in.aux_uword_a; + const uword new_n_cols = in.aux_uword_b; + const uword new_n_slices = in.aux_uword_c; const unwrap_cube tmp(in.m); const Cube& A = tmp.M; - const uword A_n_rows = A.n_rows; - const uword A_n_cols = A.n_cols; - const uword A_n_slices = A.n_slices; - - const bool alias = (&actual_out == &A); - - if(alias) - { - if( (A_n_rows == out_n_rows) && (A_n_cols == out_n_cols) && (A_n_slices == out_n_slices) ) - { - return; - } - - if(actual_out.is_empty()) - { - actual_out.zeros(out_n_rows, out_n_cols, out_n_slices); - return; - } + if(&out == &A) + { + op_resize::apply_cube_inplace(out, new_n_rows, new_n_cols, new_n_slices); } + else + { + op_resize::apply_cube_noalias(out, A, new_n_rows, new_n_cols, new_n_slices); + } + } + + + +template +inline +void +op_resize::apply_cube_inplace(Cube& A, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) + { + arma_extra_debug_sigprint(); - Cube B; - Cube& out = alias ? B : actual_out; + if( (A.n_rows == new_n_rows) && (A.n_cols == new_n_cols) && (A.n_slices == new_n_slices) ) { return; } - out.set_size(out_n_rows, out_n_cols, out_n_slices); + if(A.is_empty()) { A.zeros(new_n_rows, new_n_cols, new_n_slices); return; } - if( (out_n_rows > A_n_rows) || (out_n_cols > A_n_cols) || (out_n_slices > A_n_slices) ) - { - out.zeros(); - } + Cube B; + + op_resize::apply_cube_noalias(B, A, new_n_rows, new_n_cols, new_n_slices); + + A.steal_mem(B); + } + + + +template +inline +void +op_resize::apply_cube_noalias(Cube& out, const Cube& A, const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) + { + arma_extra_debug_sigprint(); + + out.set_size(new_n_rows, new_n_cols, new_n_slices); + + if( (new_n_rows > A.n_rows) || (new_n_cols > A.n_cols) || (new_n_slices > A.n_slices) ) { out.zeros(); } if( (out.n_elem > 0) && (A.n_elem > 0) ) { - const uword end_row = (std::min)(out_n_rows, A_n_rows) - 1; - const uword end_col = (std::min)(out_n_cols, A_n_cols) - 1; - const uword end_slice = (std::min)(out_n_slices, A_n_slices) - 1; + const uword end_row = (std::min)(new_n_rows, A.n_rows) - 1; + const uword end_col = (std::min)(new_n_cols, A.n_cols) - 1; + const uword end_slice = (std::min)(new_n_slices, A.n_slices) - 1; out.subcube(0, 0, 0, end_row, end_col, end_slice) = A.subcube(0, 0, 0, end_row, end_col, end_slice); } - - if(alias) - { - actual_out.steal_mem(B); - } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_reverse_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_reverse_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_reverse_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_reverse_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_reverse_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_reverse_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_reverse_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_reverse_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,36 +28,38 @@ { arma_extra_debug_sigprint(); + typedef typename T1::elem_type eT; + const uword dim = in.aux_uword_a; arma_debug_check( (dim > 1), "reverse(): parameter 'dim' must be 0 or 1" ); - const Proxy P(in.m); - - if(is_Mat::stored_type>::value || P.is_alias(out)) + if(is_Mat::value) { - const unwrap::stored_type> U(P.Q); + // allow detection of in-place operation - if(dim == 0) - { - op_flipud::apply_direct(out, U.M); - } - else - if(dim == 1) - { - op_fliplr::apply_direct(out, U.M); - } + const unwrap U(in.m); + + if(dim == 0) { op_flipud::apply_direct(out, U.M); } + if(dim == 1) { op_fliplr::apply_direct(out, U.M); } } else { - if(dim == 0) + const Proxy P(in.m); + + if(P.is_alias(out)) { - op_flipud::apply_proxy_noalias(out, P); + Mat tmp; + + if(dim == 0) { op_flipud::apply_proxy_noalias(tmp, P); } + if(dim == 1) { op_fliplr::apply_proxy_noalias(tmp, P); } + + out.steal_mem(tmp); } else - if(dim == 1) { - op_fliplr::apply_proxy_noalias(out, P); + if(dim == 0) { op_flipud::apply_proxy_noalias(out, P); } + if(dim == 1) { op_fliplr::apply_proxy_noalias(out, P); } } } } @@ -69,11 +73,13 @@ { arma_extra_debug_sigprint(); - const Proxy P(in.m); + typedef typename T1::elem_type eT; - if(is_Mat::stored_type>::value || P.is_alias(out)) + if(is_Mat::value) { - const unwrap::stored_type> U(P.Q); + // allow detection of in-place operation + + const unwrap U(in.m); if((T1::is_xvec) ? bool(U.M.is_rowvec()) : bool(T1::is_row)) { @@ -86,13 +92,33 @@ } else { - if((T1::is_xvec) ? bool(P.get_n_rows() == 1) : bool(T1::is_row)) + const Proxy P(in.m); + + if(P.is_alias(out)) { - op_fliplr::apply_proxy_noalias(out, P); + Mat tmp; + + if((T1::is_xvec) ? bool(P.get_n_rows() == 1) : bool(T1::is_row)) + { + op_fliplr::apply_proxy_noalias(tmp, P); + } + else + { + op_flipud::apply_proxy_noalias(tmp, P); + } + + out.steal_mem(tmp); } else { - op_flipud::apply_proxy_noalias(out, P); + if((T1::is_xvec) ? bool(P.get_n_rows() == 1) : bool(T1::is_row)) + { + op_fliplr::apply_proxy_noalias(out, P); + } + else + { + op_flipud::apply_proxy_noalias(out, P); + } } } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_roots_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_roots_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_roots_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_roots_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_roots_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_roots_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_roots_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_roots_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -28,7 +30,11 @@ const bool status = op_roots::apply_direct(out, expr.m); - if(status == false) { arma_stop_runtime_error("roots(): eigen decomposition failed"); } + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("roots(): eigen decomposition failed"); + } } @@ -59,8 +65,6 @@ status = op_roots::apply_noalias(out, U.M); } - if(status == false) { out.soft_reset(); } - return status; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_shift_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_shift_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_shift_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_shift_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_shift_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_shift_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_shift_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_shift_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -66,8 +68,8 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ((dim == 0) && (len >= X.n_rows)), "shift(): shift amount out of bounds" ); - arma_debug_check( ((dim == 1) && (len >= X.n_cols)), "shift(): shift amount out of bounds" ); + arma_debug_check_bounds( ((dim == 0) && (len >= X.n_rows)), "shift(): shift amount out of bounds" ); + arma_debug_check_bounds( ((dim == 1) && (len >= X.n_cols)), "shift(): shift amount out of bounds" ); if(&out == &X) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_shuffle_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_shuffle_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_shuffle_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_shuffle_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_shuffle_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_shuffle_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_shuffle_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_shuffle_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -118,7 +120,7 @@ if(dim == 0) { - if(X.n_rows > 1) // i.e. column vector + if(X.n_rows > 1) // ie. column vector { for(uword i=0; i 1) // i.e. row vector + if(X.n_cols > 1) // ie. row vector { for(uword i=0; i 1) // i.e. column vector + if(X.n_rows > 1) // ie. column vector { for(uword i=0; i 1) // i.e. row vector + if(X.n_cols > 1) // ie. row vector { for(uword i=0; i 1), "sort(): parameter 'sort_type' must be 0 or 1" ); - arma_debug_check( (X.has_nan()), "sort(): detected NaN" ); + if((X.n_rows * X.n_cols) <= 1) { out = X; return; } if(dim == 0) // sort the contents of each column { @@ -177,12 +172,15 @@ typedef typename T1::elem_type eT; const quasi_unwrap U(in.m); - - const Mat& X = U.M; + const Mat& X = U.M; const uword sort_type = in.aux_uword_a; const uword dim = in.aux_uword_b; + arma_debug_check( (sort_type > 1), "sort(): parameter 'sort_type' must be 0 or 1" ); + arma_debug_check( (dim > 1), "sort(): parameter 'dim' must be 0 or 1" ); + arma_debug_check( (X.has_nan()), "sort(): detected NaN" ); + if(U.is_alias(out)) { Mat tmp; @@ -208,24 +206,34 @@ typedef typename T1::elem_type eT; - const quasi_unwrap U(in.m); - + const unwrap U(in.m); // not using quasi_unwrap, to ensure there is no aliasing with subviews const Mat& X = U.M; const uword sort_type = in.aux_uword_a; - const uword dim = (T1::is_xvec) ? uword(U.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0); - if(U.is_alias(out)) + arma_debug_check( (sort_type > 1), "sort(): parameter 'sort_type' must be 0 or 1" ); + arma_debug_check( (X.has_nan()), "sort(): detected NaN" ); + + out = X; // not checking for aliasing, to allow inplace sorting of vectors + + if(out.n_elem <= 1) { return; } + + eT* out_mem = out.memptr(); + + eT* start_ptr = out_mem; + eT* endp1_ptr = &out_mem[out.n_elem]; + + if(sort_type == 0) { - Mat tmp; - - op_sort::apply_noalias(tmp, X, sort_type, dim); + arma_lt_comparator comparator; - out.steal_mem(tmp); + std::sort(start_ptr, endp1_ptr, comparator); } else { - op_sort::apply_noalias(out, X, sort_type, dim); + arma_gt_comparator comparator; + + std::sort(start_ptr, endp1_ptr, comparator); } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_sp_minus_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_sp_minus_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_sp_minus_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_sp_minus_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_sp_minus_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_sp_minus_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_sp_minus_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_sp_minus_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -179,8 +181,8 @@ const eT k = in.aux; - for (uword c = 0; c < n_cols; ++c) - for (uword r = 0; r < n_rows; ++r) + for(uword c = 0; c < n_cols; ++c) + for(uword r = 0; r < n_rows; ++r) { out.at(r, c) = proxy.at(r, c) - k; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_sp_plus_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_sp_plus_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_sp_plus_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_sp_plus_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_sp_plus_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_sp_plus_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_sp_plus_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_sp_plus_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_sqrtmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_sqrtmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_sqrtmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_sqrtmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_sqrtmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_sqrtmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_sqrtmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_sqrtmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -38,7 +40,7 @@ if(status == false) { - arma_debug_warn("sqrtmat(): given matrix seems singular; may not have a square root"); + arma_debug_warn_level(3, "sqrtmat(): given matrix is singular; may not have a square root"); } } @@ -94,28 +96,104 @@ typedef typename T1::elem_type in_T; typedef typename std::complex out_T; - const Proxy P(expr.get_ref()); + const quasi_unwrap expr_unwrap(expr.get_ref()); + const Mat& A = expr_unwrap.M; - arma_debug_check( (P.get_n_rows() != P.get_n_cols()), "sqrtmat(): given matrix must be square sized" ); + arma_debug_check( (A.is_square() == false), "sqrtmat(): given matrix must be square sized" ); - if(P.get_n_elem() == 0) + if(A.n_elem == 0) { out.reset(); return true; } + else + if(A.n_elem == 1) + { + out.set_size(1,1); + out[0] = std::sqrt( std::complex( A[0] ) ); + return true; + } + + if(A.is_diagmat()) + { + arma_extra_debug_print("op_sqrtmat: detected diagonal matrix"); + + const uword N = A.n_rows; + + out.zeros(N,N); // aliasing can't happen as op_sqrtmat is defined as cx_mat = op(mat) + + for(uword i=0; i= in_T(0)) + { + out.at(i,i) = std::sqrt(val); + } + else + { + out.at(i,i) = std::sqrt( out_T(val) ); + } + } + + return true; + } + + #if defined(ARMA_OPTIMISE_SYMPD) + const bool try_sympd = sympd_helper::guess_sympd(A); + #else + const bool try_sympd = false; + #endif + + if(try_sympd) + { + arma_extra_debug_print("op_sqrtmat: attempting sympd optimisation"); + + // if matrix A is sympd, all its eigenvalues are positive + + Col eigval; + Mat eigvec; + + const bool eig_status = eig_sym_helper(eigval, eigvec, A, 'd', "sqrtmat()"); + + if(eig_status) + { + // ensure each eigenvalue is > 0 + + const uword N = eigval.n_elem; + const in_T* eigval_mem = eigval.memptr(); + + bool all_pos = true; + + for(uword i=0; i >::from( eigvec * diagmat(eigval) * eigvec.t() ); + + return true; + } + } + + arma_extra_debug_print("op_sqrtmat: sympd optimisation failed"); + + // fallthrough if eigen decomposition failed or an eigenvalue is zero + } - typename Proxy::ea_type Pea = P.get_ea(); Mat U; - Mat S(P.get_n_rows(), P.get_n_cols()); + Mat S(A.n_rows, A.n_cols, arma_nozeros_indicator()); - out_T* Smem = S.memptr(); + const in_T* Amem = A.memptr(); + out_T* Smem = S.memptr(); - const uword N = P.get_n_elem(); + const uword n_elem = A.n_elem; - for(uword i=0; i( Pea[i] ); + Smem[i] = std::complex( Amem[i] ); } const bool schur_ok = auxlib::schur(U,S); @@ -151,7 +229,7 @@ if(status == false) { - arma_debug_warn("sqrtmat(): given matrix seems singular; may not have a square root"); + arma_debug_warn_level(3, "sqrtmat(): given matrix is singular; may not have a square root"); } } @@ -228,18 +306,82 @@ { arma_extra_debug_sigprint(); + typedef typename T1::pod_type T; typedef typename T1::elem_type eT; Mat U; Mat S = expr.get_ref(); - if(S.is_empty()) + arma_debug_check( (S.n_rows != S.n_cols), "sqrtmat(): given matrix must be square sized" ); + + if(S.n_elem == 0) { out.reset(); return true; } + else + if(S.n_elem == 1) + { + out.set_size(1,1); + out[0] = std::sqrt(S[0]); + return true; + } - arma_debug_check( (S.n_rows != S.n_cols), "sqrtmat(): given matrix must be square sized" ); + if(S.is_diagmat()) + { + arma_extra_debug_print("op_sqrtmat_cx: detected diagonal matrix"); + + const uword N = S.n_rows; + + out.zeros(N,N); // aliasing can't happen as S is generated + + for(uword i=0; i eigval; + Mat eigvec; + + const bool eig_status = eig_sym_helper(eigval, eigvec, S, 'd', "sqrtmat()"); + + if(eig_status) + { + // ensure each eigenvalue is > 0 + + const uword N = eigval.n_elem; + const T* eigval_mem = eigval.memptr(); + + bool all_pos = true; + + for(uword i=0; i struct traits { - static const bool is_row = T1::is_col; // deliberately swapped - static const bool is_col = T1::is_row; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_col; // deliberately swapped + static constexpr bool is_col = T1::is_row; + static constexpr bool is_xvec = T1::is_xvec; }; template struct pos { - static const uword n2 = (do_flip == false) ? (row + col*2) : (col + row*2); - static const uword n3 = (do_flip == false) ? (row + col*3) : (col + row*3); - static const uword n4 = (do_flip == false) ? (row + col*4) : (col + row*4); + static constexpr uword n2 = (do_flip == false) ? (row + col*2) : (col + row*2); + static constexpr uword n3 = (do_flip == false) ? (row + col*3) : (col + row*3); + static constexpr uword n4 = (do_flip == false) ? (row + col*4) : (col + row*4); }; template @@ -56,50 +58,16 @@ arma_hot inline static void apply_mat_inplace(Mat& out); template - arma_hot inline static void apply_mat(Mat& out, const TA& A); - - template - arma_hot inline static void apply_proxy(Mat& out, const T1& X); + inline static void apply_mat(Mat& out, const TA& A); template - arma_hot inline static void apply(Mat& out, const Op& in); - }; - - - -class op_strans2 - { - public: + inline static void apply_proxy(Mat& out, const Proxy& P); template - struct traits - { - static const bool is_row = T1::is_col; // deliberately swapped - static const bool is_col = T1::is_row; - static const bool is_xvec = T1::is_xvec; - }; - - template - struct pos - { - static const uword n2 = (do_flip == false) ? (row + col*2) : (col + row*2); - static const uword n3 = (do_flip == false) ? (row + col*3) : (col + row*3); - static const uword n4 = (do_flip == false) ? (row + col*4) : (col + row*4); - }; - - template - arma_cold inline static void apply_noalias_tinysq(Mat& out, const TA& A, const eT val); - - template - arma_hot inline static void apply_noalias(Mat& out, const TA& A, const eT val); - - template - arma_hot inline static void apply(Mat& out, const TA& A, const eT val); + inline static void apply_direct(Mat& out, const T1& X); template - arma_hot inline static void apply_proxy(Mat& out, const T1& X, const typename T1::elem_type val); - - // NOTE: there is no direct handling of Op, as op_strans2::apply_proxy() is currently only called by op_htrans2 for non-complex numbers + inline static void apply(Mat& out, const Op& in); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_strans_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_strans_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_strans_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_strans_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -282,7 +284,6 @@ template -arma_hot inline void op_strans::apply_mat(Mat& out, const TA& A) @@ -302,373 +303,68 @@ template -arma_hot inline void -op_strans::apply_proxy(Mat& out, const T1& X) +op_strans::apply_proxy(Mat& out, const Proxy& P) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const Proxy P(X); + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); - // allow detection of in-place transpose - if( (is_Mat::stored_type>::value == true) && (Proxy::fake_mat == false) ) - { - const unwrap::stored_type> tmp(P.Q); - - op_strans::apply_mat(out, tmp.M); - } - else + if( (resolves_to_vector::yes) && (Proxy::use_at == false) ) { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); + out.set_size(n_cols, n_rows); - const bool is_alias = P.is_alias(out); - - if( (resolves_to_vector::yes) && (Proxy::use_at == false) ) - { - if(is_alias == false) - { - out.set_size(n_cols, n_rows); - - eT* out_mem = out.memptr(); - - const uword n_elem = P.get_n_elem(); - - typename Proxy::ea_type Pea = P.get_ea(); - - uword i,j; - for(i=0, j=1; j < n_elem; i+=2, j+=2) - { - const eT tmp_i = Pea[i]; - const eT tmp_j = Pea[j]; - - out_mem[i] = tmp_i; - out_mem[j] = tmp_j; - } - - if(i < n_elem) - { - out_mem[i] = Pea[i]; - } - } - else // aliasing - { - Mat out2(n_cols, n_rows); - - eT* out_mem = out2.memptr(); - - const uword n_elem = P.get_n_elem(); - - typename Proxy::ea_type Pea = P.get_ea(); - - uword i,j; - for(i=0, j=1; j < n_elem; i+=2, j+=2) - { - const eT tmp_i = Pea[i]; - const eT tmp_j = Pea[j]; - - out_mem[i] = tmp_i; - out_mem[j] = tmp_j; - } - - if(i < n_elem) - { - out_mem[i] = Pea[i]; - } - - out.steal_mem(out2); - } - } - else // general matrix transpose - { - if(is_alias == false) - { - out.set_size(n_cols, n_rows); - - eT* outptr = out.memptr(); - - for(uword k=0; k < n_rows; ++k) - { - uword j; - for(j=1; j < n_cols; j+=2) - { - const uword i = j-1; - - const eT tmp_i = P.at(k,i); - const eT tmp_j = P.at(k,j); - - (*outptr) = tmp_i; outptr++; - (*outptr) = tmp_j; outptr++; - } - - const uword i = j-1; - - if(i < n_cols) - { - (*outptr) = P.at(k,i); outptr++; - } - } - } - else // aliasing - { - Mat out2(n_cols, n_rows); - - eT* out2ptr = out2.memptr(); - - for(uword k=0; k < n_rows; ++k) - { - uword j; - for(j=1; j < n_cols; j+=2) - { - const uword i = j-1; - - const eT tmp_i = P.at(k,i); - const eT tmp_j = P.at(k,j); - - (*out2ptr) = tmp_i; out2ptr++; - (*out2ptr) = tmp_j; out2ptr++; - } - - const uword i = j-1; - - if(i < n_cols) - { - (*out2ptr) = P.at(k,i); out2ptr++; - } - } - - out.steal_mem(out2); - } - } - } - } - - - -template -arma_hot -inline -void -op_strans::apply(Mat& out, const Op& in) - { - arma_extra_debug_sigprint(); - - op_strans::apply_proxy(out, in.m); - } - - - -// -// op_strans2 - - - -//! for tiny square matrices (size <= 4x4) -template -arma_cold -inline -void -op_strans2::apply_noalias_tinysq(Mat& out, const TA& A, const eT val) - { - const eT* Am = A.memptr(); - eT* outm = out.memptr(); - - switch(A.n_rows) - { - case 1: - { - outm[0] = val * Am[0]; - } - break; - - case 2: - { - outm[pos::n2] = val * Am[pos::n2]; - outm[pos::n2] = val * Am[pos::n2]; - - outm[pos::n2] = val * Am[pos::n2]; - outm[pos::n2] = val * Am[pos::n2]; - } - break; + eT* out_mem = out.memptr(); - case 3: - { - outm[pos::n3] = val * Am[pos::n3]; - outm[pos::n3] = val * Am[pos::n3]; - outm[pos::n3] = val * Am[pos::n3]; - - outm[pos::n3] = val * Am[pos::n3]; - outm[pos::n3] = val * Am[pos::n3]; - outm[pos::n3] = val * Am[pos::n3]; - - outm[pos::n3] = val * Am[pos::n3]; - outm[pos::n3] = val * Am[pos::n3]; - outm[pos::n3] = val * Am[pos::n3]; - } - break; + const uword n_elem = P.get_n_elem(); - case 4: - { - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - outm[pos::n4] = val * Am[pos::n4]; - } - break; - - default: - ; - } - - } - - - -template -arma_hot -inline -void -op_strans2::apply_noalias(Mat& out, const TA& A, const eT val) - { - arma_extra_debug_sigprint(); - - const uword A_n_cols = A.n_cols; - const uword A_n_rows = A.n_rows; - - out.set_size(A_n_cols, A_n_rows); - - if( (TA::is_col) || (TA::is_row) || (A_n_cols == 1) || (A_n_rows == 1) ) - { - const uword N = A.n_elem; - - const eT* A_mem = A.memptr(); - eT* out_mem = out.memptr(); + typename Proxy::ea_type Pea = P.get_ea(); uword i,j; - for(i=0, j=1; j < N; i+=2, j+=2) + for(i=0, j=1; j < n_elem; i+=2, j+=2) { - const eT tmp_i = A_mem[i]; - const eT tmp_j = A_mem[j]; + const eT tmp_i = Pea[i]; + const eT tmp_j = Pea[j]; - out_mem[i] = val * tmp_i; - out_mem[j] = val * tmp_j; + out_mem[i] = tmp_i; + out_mem[j] = tmp_j; } - if(i < N) + if(i < n_elem) { - out_mem[i] = val * A_mem[i]; + out_mem[i] = Pea[i]; } } - else + else // general matrix transpose { - if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) ) - { - op_strans2::apply_noalias_tinysq(out, A, val); - } - else - if( (A_n_rows >= 512) && (A_n_cols >= 512) ) - { - op_strans::apply_mat_noalias_large(out, A); - arrayops::inplace_mul( out.memptr(), val, out.n_elem ); - } - else + out.set_size(n_cols, n_rows); + + eT* outptr = out.memptr(); + + for(uword k=0; k < n_rows; ++k) { - eT* outptr = out.memptr(); - - for(uword k=0; k < A_n_rows; ++k) + uword j; + for(j=1; j < n_cols; j+=2) { - const eT* Aptr = &(A.at(k,0)); + const uword i = j-1; - uword j; - for(j=1; j < A_n_cols; j+=2) - { - const eT tmp_i = (*Aptr); Aptr += A_n_rows; - const eT tmp_j = (*Aptr); Aptr += A_n_rows; - - (*outptr) = val * tmp_i; outptr++; - (*outptr) = val * tmp_j; outptr++; - } + const eT tmp_i = P.at(k,i); + const eT tmp_j = P.at(k,j); - if((j-1) < A_n_cols) - { - (*outptr) = val * (*Aptr); outptr++;; - } + (*outptr) = tmp_i; outptr++; + (*outptr) = tmp_j; outptr++; } - } - } - } - - - -template -arma_hot -inline -void -op_strans2::apply(Mat& out, const TA& A, const eT val) - { - arma_extra_debug_sigprint(); - - if(&out != &A) - { - op_strans2::apply_noalias(out, A, val); - } - else - { - const uword n_rows = out.n_rows; - const uword n_cols = out.n_cols; - - if(n_rows == n_cols) - { - arma_extra_debug_print("op_strans2::apply(): doing in-place transpose of a square matrix"); - const uword N = n_rows; + const uword i = j-1; - // TODO: do multiplication while swapping - - for(uword k=0; k < N; ++k) + if(i < n_cols) { - eT* colptr = out.colptr(k); - - uword i,j; - - for(i=(k+1), j=(k+2); j < N; i+=2, j+=2) - { - std::swap(out.at(k,i), colptr[i]); - std::swap(out.at(k,j), colptr[j]); - } - - if(i < N) - { - std::swap(out.at(k,i), colptr[i]); - } + (*outptr) = P.at(k,i); outptr++; } - - arrayops::inplace_mul( out.memptr(), val, out.n_elem ); - } - else - { - Mat tmp; - op_strans2::apply_noalias(tmp, A, val); - - out.steal_mem(tmp); } } } @@ -676,145 +372,57 @@ template -arma_hot inline void -op_strans2::apply_proxy(Mat& out, const T1& X, const typename T1::elem_type val) +op_strans::apply_direct(Mat& out, const T1& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; - const Proxy P(X); - // allow detection of in-place transpose - if( (is_Mat::stored_type>::value == true) && (Proxy::fake_mat == false) ) + if(is_Mat::value || (arma_config::openmp && Proxy::use_mp)) { - const unwrap::stored_type> tmp(P.Q); + const unwrap U(X); - op_strans2::apply(out, tmp.M, val); + op_strans::apply_mat(out, U.M); } else { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); + const Proxy P(X); const bool is_alias = P.is_alias(out); - if( (resolves_to_vector::yes) && (Proxy::use_at == false) ) + if(is_Mat::stored_type>::value) { - if(is_alias == false) + const quasi_unwrap::stored_type> U(P.Q); + + if(is_alias) { - out.set_size(n_cols, n_rows); - - eT* out_mem = out.memptr(); + Mat tmp; - const uword n_elem = P.get_n_elem(); - - typename Proxy::ea_type Pea = P.get_ea(); - - uword i,j; - for(i=0, j=1; j < n_elem; i+=2, j+=2) - { - const eT tmp_i = Pea[i]; - const eT tmp_j = Pea[j]; - - out_mem[i] = val * tmp_i; - out_mem[j] = val * tmp_j; - } + op_strans::apply_mat_noalias(tmp, U.M); - if(i < n_elem) - { - out_mem[i] = val * Pea[i]; - } + out.steal_mem(tmp); } - else // aliasing + else { - Mat out2(n_cols, n_rows); - - eT* out_mem = out2.memptr(); - - const uword n_elem = P.get_n_elem(); - - typename Proxy::ea_type Pea = P.get_ea(); - - uword i,j; - for(i=0, j=1; j < n_elem; i+=2, j+=2) - { - const eT tmp_i = Pea[i]; - const eT tmp_j = Pea[j]; - - out_mem[i] = val * tmp_i; - out_mem[j] = val * tmp_j; - } - - if(i < n_elem) - { - out_mem[i] = val * Pea[i]; - } - - out.steal_mem(out2); + op_strans::apply_mat_noalias(out, U.M); } } - else // general matrix transpose + else { - if(is_alias == false) + if(is_alias) { - out.set_size(n_cols, n_rows); + Mat tmp; - eT* outptr = out.memptr(); + op_strans::apply_proxy(tmp, P); - for(uword k=0; k < n_rows; ++k) - { - uword j; - for(j=1; j < n_cols; j+=2) - { - const uword i = j-1; - - const eT tmp_i = P.at(k,i); - const eT tmp_j = P.at(k,j); - - (*outptr) = val * tmp_i; outptr++; - (*outptr) = val * tmp_j; outptr++; - } - - const uword i = j-1; - - if(i < n_cols) - { - (*outptr) = val * P.at(k,i); outptr++; - } - } + out.steal_mem(tmp); } - else // aliasing + else { - Mat out2(n_cols, n_rows); - - eT* out2ptr = out2.memptr(); - - for(uword k=0; k < n_rows; ++k) - { - uword j; - for(j=1; j < n_cols; j+=2) - { - const uword i = j-1; - - const eT tmp_i = P.at(k,i); - const eT tmp_j = P.at(k,j); - - (*out2ptr) = val * tmp_i; out2ptr++; - (*out2ptr) = val * tmp_j; out2ptr++; - } - - const uword i = j-1; - - if(i < n_cols) - { - (*out2ptr) = val * P.at(k,i); out2ptr++; - } - } - - out.steal_mem(out2); + op_strans::apply_proxy(out, P); } } } @@ -822,6 +430,24 @@ +template +inline +void +op_strans::apply(Mat& out, const Op& in) + { + arma_extra_debug_sigprint(); + + op_strans::apply_direct(out, in.m); + } + + + +// +// +// + + + template inline void diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_sum_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_sum_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_sum_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_sum_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -37,9 +39,6 @@ template arma_hot inline static void apply_noalias_proxy(Mat& out, const Proxy& P, const uword dim); - template - arma_hot inline static void apply_noalias_proxy_mp(Mat& out, const Proxy& P, const uword dim); - // cubes @@ -54,9 +53,6 @@ template arma_hot inline static void apply_noalias_proxy(Cube& out, const ProxyCube& P, const uword dim); - - template - arma_hot inline static void apply_noalias_proxy_mp(Cube& out, const ProxyCube& P, const uword dim); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_sum_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_sum_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_sum_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_sum_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -58,7 +60,7 @@ { arma_extra_debug_sigprint(); - if(is_Mat::stored_type>::value) + if(is_Mat::stored_type>::value || (arma_config::openmp && Proxy::use_mp)) { op_sum::apply_noalias_unwrap(out, P, dim); } @@ -125,13 +127,6 @@ typedef typename T1::elem_type eT; - if( arma_config::openmp && Proxy::use_mp && mp_gate::eval(P.get_n_elem()) ) - { - op_sum::apply_noalias_proxy_mp(out, P, dim); - - return; - } - const uword P_n_rows = P.get_n_rows(); const uword P_n_cols = P.get_n_cols(); @@ -177,80 +172,6 @@ -template -arma_hot -inline -void -op_sum::apply_noalias_proxy_mp(Mat& out, const Proxy& P, const uword dim) - { - arma_extra_debug_sigprint(); - - #if defined(ARMA_USE_OPENMP) - { - typedef typename T1::elem_type eT; - - const uword P_n_rows = P.get_n_rows(); - const uword P_n_cols = P.get_n_cols(); - - const int n_threads = mp_thread_limit::get(); - - if(dim == 0) - { - out.set_size(1, P_n_cols); - - eT* out_mem = out.memptr(); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword col=0; col < P_n_cols; ++col) - { - eT val1 = eT(0); - eT val2 = eT(0); - - uword i,j; - for(i=0, j=1; j < P_n_rows; i+=2, j+=2) - { - val1 += P.at(i,col); - val2 += P.at(j,col); - } - - if(i < P_n_rows) - { - val1 += P.at(i,col); - } - - out_mem[col] = (val1 + val2); - } - } - else - { - out.set_size(P_n_rows, 1); - - eT* out_mem = out.memptr(); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword row=0; row < P_n_rows; ++row) - { - eT acc = eT(0); - for(uword col=0; col < P_n_cols; ++col) - { - acc += P.at(row,col); - } - - out_mem[row] = acc; - } - } - } - #else - { - arma_ignore(out); - arma_ignore(P); - arma_ignore(dim); - } - #endif - } - - - // // cubes @@ -295,7 +216,7 @@ { arma_extra_debug_sigprint(); - if(is_Cube::stored_type>::value) + if(is_Cube::stored_type>::value || (arma_config::openmp && ProxyCube::use_mp)) { op_sum::apply_noalias_unwrap(out, P, dim); } @@ -382,13 +303,6 @@ typedef typename T1::elem_type eT; - if( arma_config::openmp && ProxyCube::use_mp && mp_gate::eval(P.get_n_elem()) ) - { - op_sum::apply_noalias_proxy_mp(out, P, dim); - - return; - } - const uword P_n_rows = P.get_n_rows(); const uword P_n_cols = P.get_n_cols(); const uword P_n_slices = P.get_n_slices(); @@ -459,122 +373,5 @@ } - -template -arma_hot -inline -void -op_sum::apply_noalias_proxy_mp(Cube& out, const ProxyCube& P, const uword dim) - { - arma_extra_debug_sigprint(); - - #if defined(ARMA_USE_OPENMP) - { - typedef typename T1::elem_type eT; - - const uword P_n_rows = P.get_n_rows(); - const uword P_n_cols = P.get_n_cols(); - const uword P_n_slices = P.get_n_slices(); - - const int n_threads = mp_thread_limit::get(); - - if(dim == 0) - { - out.set_size(1, P_n_cols, P_n_slices); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword slice=0; slice < P_n_slices; ++slice) - { - eT* out_mem = out.slice_memptr(slice); - - for(uword col=0; col < P_n_cols; ++col) - { - eT val1 = eT(0); - eT val2 = eT(0); - - uword i,j; - for(i=0, j=1; j < P_n_rows; i+=2, j+=2) - { - val1 += P.at(i,col,slice); - val2 += P.at(j,col,slice); - } - - if(i < P_n_rows) - { - val1 += P.at(i,col,slice); - } - - out_mem[col] = (val1 + val2); - } - } - } - else - if(dim == 1) - { - out.zeros(P_n_rows, 1, P_n_slices); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword slice=0; slice < P_n_slices; ++slice) - { - eT* out_mem = out.slice_memptr(slice); - - for(uword col=0; col < P_n_cols; ++col) - for(uword row=0; row < P_n_rows; ++row) - { - out_mem[row] += P.at(row,col,slice); - } - } - } - else - if(dim == 2) - { - out.zeros(P_n_rows, P_n_cols, 1); - - if(P_n_cols >= P_n_rows) - { - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword col=0; col < P_n_cols; ++col) - { - for(uword row=0; row < P_n_rows; ++row) - { - eT acc = eT(0); - for(uword slice=0; slice < P_n_slices; ++slice) - { - acc += P.at(row,col,slice); - } - - out.at(row,col,0) = acc; - } - } - } - else - { - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword row=0; row < P_n_rows; ++row) - { - for(uword col=0; col < P_n_cols; ++col) - { - eT acc = eT(0); - for(uword slice=0; slice < P_n_slices; ++slice) - { - acc += P.at(row,col,slice); - } - - out.at(row,col,0) = acc; - } - } - } - } - } - #else - { - arma_ignore(out); - arma_ignore(P); - arma_ignore(dim); - } - #endif - } - - //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_symmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_symmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_symmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_symmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,24 +21,46 @@ -class op_symmat +class op_symmatu + : public traits_op_default + { + public: + + template + inline static void apply(Mat& out, const Op& in); + }; + + + +class op_symmatl + : public traits_op_default + { + public: + + template + inline static void apply(Mat& out, const Op& in); + }; + + + +class op_symmatu_cx : public traits_op_default { public: template - inline static void apply(Mat& out, const Op& in); + inline static void apply(Mat& out, const Op& in); }; -class op_symmat_cx +class op_symmatl_cx : public traits_op_default { public: template - inline static void apply(Mat& out, const Op& in); + inline static void apply(Mat& out, const Op& in); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_symmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_symmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_symmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_symmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,7 +24,7 @@ template inline void -op_symmat::apply(Mat& out, const Op& in) +op_symmatu::apply(Mat& out, const Op& in) { arma_extra_debug_sigprint(); @@ -31,78 +33,104 @@ const unwrap tmp(in.m); const Mat& A = tmp.M; - arma_debug_check( (A.is_square() == false), "symmatu()/symmatl(): given matrix must be square sized" ); + arma_debug_check( (A.is_square() == false), "symmatu(): given matrix must be square sized" ); - const uword N = A.n_rows; - const bool upper = (in.aux_uword_a == 0); + const uword N = A.n_rows; if(&out != &A) { out.copy_size(A); - if(upper) + // upper triangular: copy the diagonal and the elements above the diagonal + + for(uword i=0; i +inline +void +op_symmatl::apply(Mat& out, const Op& in) + { + arma_extra_debug_sigprint(); + typedef typename T1::elem_type eT; + + const unwrap tmp(in.m); + const Mat& A = tmp.M; - if(upper) + arma_debug_check( (A.is_square() == false), "symmatl(): given matrix must be square sized" ); + + const uword N = A.n_rows; + + if(&out != &A) { - // reflect elements across the diagonal from upper triangle to lower triangle + out.copy_size(A); - for(uword col=1; col < N; ++col) + // lower triangular: copy the diagonal and the elements below the diagonal + + for(uword i=0; i inline void -op_symmat_cx::apply(Mat& out, const Op& in) +op_symmatu_cx::apply(Mat& out, const Op& in) { arma_extra_debug_sigprint(); @@ -111,103 +139,135 @@ const unwrap tmp(in.m); const Mat& A = tmp.M; - arma_debug_check( (A.is_square() == false), "symmatu()/symmatl(): given matrix must be square sized" ); + arma_debug_check( (A.is_square() == false), "symmatu(): given matrix must be square sized" ); const uword N = A.n_rows; - const bool upper = (in.aux_uword_a == 0); const bool do_conj = (in.aux_uword_b == 1); if(&out != &A) { out.copy_size(A); - if(upper) - { - // upper triangular: copy the diagonal and the elements above the diagonal - - for(uword i=0; i +inline +void +op_symmatl_cx::apply(Mat& out, const Op& in) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap tmp(in.m); + const Mat& A = tmp.M; + + arma_debug_check( (A.is_square() == false), "symmatl(): given matrix must be square sized" ); + + const uword N = A.n_rows; + + const bool do_conj = (in.aux_uword_b == 1); + + if(&out != &A) { - if(upper) + out.copy_size(A); + + // lower triangular: copy the diagonal and the elements below the diagonal + + for(uword i=0; i tmp(in.m, out); const Mat& X = tmp.M; - arma_debug_check( ((X.is_vec() == false) && (X.is_empty() == false)), "toeplitz(): given object is not a vector" ); + arma_debug_check( ((X.is_vec() == false) && (X.is_empty() == false)), "toeplitz(): given object must be a vector" ); const uword N = X.n_elem; const eT* X_mem = X.memptr(); @@ -66,14 +68,14 @@ const unwrap_check tmp(in.m, out); const Mat& X = tmp.M; - arma_debug_check( ((X.is_vec() == false) && (X.is_empty() == false)), "circ_toeplitz(): given object is not a vector" ); + arma_debug_check( ((X.is_vec() == false) && (X.is_empty() == false)), "circ_toeplitz(): given object must be a vector" ); const uword N = X.n_elem; const eT* X_mem = X.memptr(); out.set_size(N,N); - if(X.is_rowvec() == true) + if(X.is_rowvec()) { for(uword row=0; row < N; ++row) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_trimat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_trimat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_trimat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_trimat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,6 +21,8 @@ +// NOTE: don't split op_trimat into seperate op_trimatu and op_trimatl classes, +// NOTE: as several instances elsewhere rely on trimatu() and trimatl() producing the same type class op_trimat : public traits_op_default { @@ -32,16 +36,11 @@ template inline static void apply(Mat& out, const Op& in); - template - inline static void apply(Mat& out, const Op, op_trimat>& in); - - // - template - inline static void apply_htrans(Mat& out, const Mat& A, const bool upper, const typename arma_not_cx::result* junk = 0); + inline static void apply_unwrap(Mat& out, const Mat& A, const bool upper); - template - inline static void apply_htrans(Mat& out, const Mat& A, const bool upper, const typename arma_cx_only::result* junk = 0); + template + inline static void apply_proxy(Mat& out, const Proxy& P, const bool upper); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_trimat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_trimat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_trimat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_trimat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -36,7 +38,7 @@ { eT* data = out.colptr(i); - arrayops::inplace_set( &data[i+1], eT(0), (N-(i+1)) ); + arrayops::fill_zeros( &data[i+1], (N-(i+1)) ); } } else @@ -47,7 +49,7 @@ { eT* data = out.colptr(i); - arrayops::inplace_set( data, eT(0), i ); + arrayops::fill_zeros( data, i ); } } } @@ -63,62 +65,54 @@ typedef typename T1::elem_type eT; - const unwrap tmp(in.m); - const Mat& A = tmp.M; - - arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square sized" ); - - const uword N = A.n_rows; - const bool upper = (in.aux_uword_a == 0); + const bool upper = (in.aux_uword_a == 0); - if(&out != &A) + // allow detection of in-place operation + if(is_Mat::value || (arma_config::openmp && Proxy::use_mp)) { - out.copy_size(A); + const unwrap U(in.m); - if(upper) + op_trimat::apply_unwrap(out, U.M, upper); + } + else + { + const Proxy P(in.m); + + const bool is_alias = P.is_alias(out); + + if(is_Mat::stored_type>::value) { - // upper triangular: copy the diagonal and the elements above the diagonal - for(uword i=0; i::stored_type> U(P.Q); + + if(is_alias) { - const eT* A_data = A.colptr(i); - eT* out_data = out.colptr(i); + Mat tmp; - arrayops::copy( out_data, A_data, i+1 ); + op_trimat::apply_unwrap(tmp, U.M, upper); + + out.steal_mem(tmp); + } + else + { + op_trimat::apply_unwrap(out, U.M, upper); } } else { - // lower triangular: copy the diagonal and the elements below the diagonal - for(uword i=0; i tmp; - arrayops::copy( &out_data[i], &A_data[i], N-i ); + op_trimat::apply_proxy(tmp, P, upper); + + out.steal_mem(tmp); + } + else + { + op_trimat::apply_proxy(out, P, upper); } } } - - op_trimat::fill_zeros(out, upper); - } - - - -template -inline -void -op_trimat::apply(Mat& out, const Op, op_trimat>& in) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - const unwrap tmp(in.m.m); - const Mat& A = tmp.M; - - const bool upper = (in.aux_uword_a == 0); - - op_trimat::apply_htrans(out, A, upper); } @@ -126,62 +120,38 @@ template inline void -op_trimat::apply_htrans - ( - Mat& out, - const Mat& A, - const bool upper, - const typename arma_not_cx::result* junk - ) +op_trimat::apply_unwrap(Mat& out, const Mat& A, const bool upper) { arma_extra_debug_sigprint(); - arma_ignore(junk); - - // This specialisation is for trimatl(trans(X)) = trans(trimatu(X)) and also - // trimatu(trans(X)) = trans(trimatl(X)). We want to avoid the creation of an - // extra temporary. - - // It doesn't matter if the input and output matrices are the same; we will - // pull data from the upper or lower triangular to the lower or upper - // triangular (respectively) and then set the rest to 0, so overwriting issues - // aren't present. arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square sized" ); - const uword N = A.n_rows; - if(&out != &A) { out.copy_size(A); - } - - // We can't really get away with any array copy operations here, - // unfortunately... - - if(upper) - { - // Upper triangular: but since we're transposing, we're taking the lower - // triangular and putting it in the upper half. - for(uword row = 0; row < N; ++row) + + const uword N = A.n_rows; + + if(upper) { - eT* out_colptr = out.colptr(row); - - for(uword col = 0; col <= row; ++col) + // upper triangular: copy the diagonal and the elements above the diagonal + for(uword i=0; i +template inline void -op_trimat::apply_htrans - ( - Mat& out, - const Mat& A, - const bool upper, - const typename arma_cx_only::result* junk - ) +op_trimat::apply_proxy(Mat& out, const Proxy& P, const bool upper) { arma_extra_debug_sigprint(); - arma_ignore(junk); - arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square sized" ); + arma_debug_check( (P.get_n_rows() != P.get_n_cols()), "trimatu()/trimatl(): given matrix must be square sized" ); - const uword N = A.n_rows; + const uword N = P.get_n_rows(); - if(&out != &A) - { - out.copy_size(A); - } + out.set_size(N,N); if(upper) { - // Upper triangular: but since we're transposing, we're taking the lower - // triangular and putting it in the upper half. - for(uword row = 0; row < N; ++row) + for(uword j=0; j < N; ++j) + for(uword i=0; i < (j+1); ++i) { - eT* out_colptr = out.colptr(row); - - for(uword col = 0; col <= row; ++col) - { - //out.at(col, row) = std::conj( A.at(row, col) ); - out_colptr[col] = std::conj( A.at(row, col) ); - } + out.at(i,j) = P.at(i,j); } } else { - // Lower triangular: but since we're transposing, we're taking the upper - // triangular and putting it in the lower half. - for(uword row = 0; row < N; ++row) + for(uword j=0; j 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatu(): requested diagonal is out of bounds" ); + arma_debug_check_bounds( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatu(): requested diagonal is out of bounds" ); if(&out != &A) { @@ -362,7 +311,7 @@ const uword n_rows = A.n_rows; const uword n_cols = A.n_cols; - arma_debug_check( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatl(): requested diagonal is out of bounds" ); + arma_debug_check_bounds( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatl(): requested diagonal is out of bounds" ); if(&out != &A) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_unique_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_unique_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_unique_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_unique_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_unique_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_unique_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_unique_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_unique_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -56,7 +58,7 @@ return true; } - Mat X(n_elem,1); + Mat X(n_elem, 1, arma_nozeros_indicator()); eT* X_mem = X.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_var_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_var_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_var_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_var_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_var_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_var_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_var_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_var_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_vectorise_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_vectorise_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_vectorise_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_vectorise_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -69,7 +71,9 @@ template inline static void apply_subview(Mat& out, const subview_cube& sv); - template inline static void apply_proxy(Mat& out, const ProxyCube& P); + template inline static void apply_unwrap(Mat& out, const T1& expr); + + template inline static void apply_proxy(Mat& out, const T1& expr); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_vectorise_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_vectorise_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_vectorise_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_vectorise_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -41,15 +43,80 @@ typedef typename T1::elem_type eT; - if(is_same_type< T1, subview >::yes) + // allow detection of in-place operation + if(is_Mat::value || (arma_config::openmp && Proxy::use_mp)) { - op_vectorise_col::apply_subview(out, reinterpret_cast< const subview& >(expr)); + const unwrap U(expr); + + if(&out == &(U.M)) + { + // output matrix is the same as the input matrix + + out.set_size(out.n_elem, 1); // set_size() doesn't destroy data as long as the number of elements in the matrix remains the same + } + else + { + out.set_size(U.M.n_elem, 1); + + arrayops::copy(out.memptr(), U.M.memptr(), U.M.n_elem); + } + } + else + if(is_subview::value) + { + const subview& sv = reinterpret_cast< const subview& >(expr); + + if(&out == &(sv.m)) + { + Mat tmp; + + op_vectorise_col::apply_subview(tmp, sv); + + out.steal_mem(tmp); + } + else + { + op_vectorise_col::apply_subview(out, sv); + } } else { const Proxy P(expr); - op_vectorise_col::apply_proxy(out, P); + const bool is_alias = P.is_alias(out); + + if(is_Mat::stored_type>::value) + { + const quasi_unwrap::stored_type> U(P.Q); + + if(is_alias) + { + Mat tmp(U.M.memptr(), U.M.n_elem, 1); + + out.steal_mem(tmp); + } + else + { + out.set_size(U.M.n_elem, 1); + + arrayops::copy(out.memptr(), U.M.memptr(), U.M.n_elem); + } + } + else + { + if(is_alias) + { + Mat tmp; + + op_vectorise_col::apply_proxy(tmp, P); + + out.steal_mem(tmp); + } + else + { + op_vectorise_col::apply_proxy(out, P); + } + } } } @@ -62,31 +129,18 @@ { arma_extra_debug_sigprint(); - const bool is_alias = (&out == &(sv.m)); + const uword sv_n_rows = sv.n_rows; + const uword sv_n_cols = sv.n_cols; - if(is_alias == false) - { - const uword sv_n_rows = sv.n_rows; - const uword sv_n_cols = sv.n_cols; - - out.set_size(sv.n_elem, 1); - - eT* out_mem = out.memptr(); - - for(uword col=0; col < sv_n_cols; ++col) - { - arrayops::copy(out_mem, sv.colptr(col), sv_n_rows); - - out_mem += sv_n_rows; - } - } - else + out.set_size(sv.n_elem, 1); + + eT* out_mem = out.memptr(); + + for(uword col=0; col < sv_n_cols; ++col) { - Mat tmp; + arrayops::copy(out_mem, sv.colptr(col), sv_n_rows); - op_vectorise_col::apply_subview(tmp, sv); - - out.steal_mem(tmp); + out_mem += sv_n_rows; } } @@ -101,83 +155,54 @@ typedef typename T1::elem_type eT; - if(P.is_alias(out) == false) + const uword N = P.get_n_elem(); + + out.set_size(N, 1); + + eT* outmem = out.memptr(); + + if(Proxy::use_at == false) { - const uword N = P.get_n_elem(); + // TODO: add handling of aligned access ? - out.set_size(N, 1); - - if(is_Mat::stored_type>::value == true) + typename Proxy::ea_type A = P.get_ea(); + + uword i,j; + + for(i=0, j=1; j < N; i+=2, j+=2) { - const unwrap::stored_type> tmp(P.Q); + const eT tmp_i = A[i]; + const eT tmp_j = A[j]; - arrayops::copy(out.memptr(), tmp.M.memptr(), N); + outmem[i] = tmp_i; + outmem[j] = tmp_j; } - else + + if(i < N) { - eT* outmem = out.memptr(); - - if(Proxy::use_at == false) - { - // TODO: add handling of aligned access ? - - typename Proxy::ea_type A = P.get_ea(); - - uword i,j; - - for(i=0, j=1; j < N; i+=2, j+=2) - { - const eT tmp_i = A[i]; - const eT tmp_j = A[j]; - - outmem[i] = tmp_i; - outmem[j] = tmp_j; - } - - if(i < N) - { - outmem[i] = A[i]; - } - } - else - { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); - - if(n_rows == 1) - { - for(uword i=0; i < n_cols; ++i) - { - outmem[i] = P.at(0,i); - } - } - else - { - for(uword col=0; col < n_cols; ++col) - for(uword row=0; row < n_rows; ++row) - { - *outmem = P.at(row,col); - outmem++; - } - } - } + outmem[i] = A[i]; } } - else // we have aliasing + else { - arma_extra_debug_print("op_vectorise_col::apply(): aliasing detected"); + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); - if( (is_Mat::stored_type>::value == true) && (Proxy::fake_mat == false) ) + if(n_rows == 1) { - out.set_size(out.n_elem, 1); // set_size() doesn't destroy data as long as the number of elements in the matrix remains the same + for(uword i=0; i < n_cols; ++i) + { + outmem[i] = P.at(0,i); + } } else { - Mat tmp; - - op_vectorise_col::apply_proxy(tmp, P); - - out.steal_mem(tmp); + for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) + { + *outmem = P.at(row,col); + outmem++; + } } } } @@ -203,9 +228,22 @@ { arma_extra_debug_sigprint(); + typedef typename T1::elem_type eT; + const Proxy P(expr); - op_vectorise_row::apply_proxy(out, P); + if(P.is_alias(out)) + { + Mat tmp; + + op_vectorise_row::apply_proxy(tmp, P); + + out.steal_mem(tmp); + } + else + { + op_vectorise_row::apply_proxy(out, P); + } } @@ -219,61 +257,48 @@ typedef typename T1::elem_type eT; - if(P.is_alias(out) == false) + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); + const uword n_elem = P.get_n_elem(); + + out.set_size(1, n_elem); + + eT* outmem = out.memptr(); + + if(n_cols == 1) { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); - const uword n_elem = P.get_n_elem(); - - out.set_size(1, n_elem); - - eT* outmem = out.memptr(); - - if(n_cols == 1) + if(is_Mat::stored_type>::value) { - if(is_Mat::stored_type>::value == true) - { - const unwrap::stored_type> tmp(P.Q); - - arrayops::copy(out.memptr(), tmp.M.memptr(), n_elem); - } - else - { - for(uword i=0; i < n_elem; ++i) { outmem[i] = P.at(i,0); } - } + const unwrap::stored_type> tmp(P.Q); + + arrayops::copy(out.memptr(), tmp.M.memptr(), n_elem); } else { - for(uword row=0; row < n_rows; ++row) + for(uword i=0; i < n_elem; ++i) { outmem[i] = P.at(i,0); } + } + } + else + { + for(uword row=0; row < n_rows; ++row) + { + uword i,j; + + for(i=0, j=1; j < n_cols; i+=2, j+=2) { - uword i,j; + const eT tmp_i = P.at(row,i); + const eT tmp_j = P.at(row,j); - for(i=0, j=1; j < n_cols; i+=2, j+=2) - { - const eT tmp_i = P.at(row,i); - const eT tmp_j = P.at(row,j); - - *outmem = tmp_i; outmem++; - *outmem = tmp_j; outmem++; - } - - if(i < n_cols) - { - *outmem = P.at(row,i); outmem++; - } + *outmem = tmp_i; outmem++; + *outmem = tmp_j; outmem++; + } + + if(i < n_cols) + { + *outmem = P.at(row,i); outmem++; } } } - else // we have aliasing - { - arma_extra_debug_print("op_vectorise_row::apply(): aliasing detected"); - - Mat tmp; - - op_vectorise_row::apply_proxy(tmp, P); - - out.steal_mem(tmp); - } } @@ -318,9 +343,14 @@ } else { - const ProxyCube P(in.m); - - op_vectorise_cube_col::apply_proxy(out, P); + if(is_Cube::value || (arma_config::openmp && ProxyCube::use_mp)) + { + op_vectorise_cube_col::apply_unwrap(out, in.m); + } + else + { + op_vectorise_cube_col::apply_proxy(out, in.m); + } } } @@ -333,86 +363,101 @@ { arma_extra_debug_sigprint(); - const uword sv_n_rows = sv.n_rows; - const uword sv_n_cols = sv.n_cols; - const uword sv_n_slices = sv.n_slices; + const uword sv_nr = sv.n_rows; + const uword sv_nc = sv.n_cols; + const uword sv_ns = sv.n_slices; out.set_size(sv.n_elem, 1); eT* out_mem = out.memptr(); - for(uword slice=0; slice < sv_n_slices; ++slice) - for(uword col=0; col < sv_n_cols; ++col ) + for(uword s=0; s < sv_ns; ++s) + for(uword c=0; c < sv_nc; ++c) { - arrayops::copy(out_mem, sv.slice_colptr(slice,col), sv_n_rows); + arrayops::copy(out_mem, sv.slice_colptr(s,c), sv_nr); - out_mem += sv_n_rows; + out_mem += sv_nr; } } + + + +template +inline +void +op_vectorise_cube_col::apply_unwrap(Mat& out, const T1& expr) + { + arma_extra_debug_sigprint(); + const unwrap_cube U(expr); + out.set_size(U.M.n_elem, 1); + arrayops::copy(out.memptr(), U.M.memptr(), U.M.n_elem); + } + + + template inline void -op_vectorise_cube_col::apply_proxy(Mat& out, const ProxyCube& P) +op_vectorise_cube_col::apply_proxy(Mat& out, const T1& expr) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; + const ProxyCube P(expr); + + if(is_Cube::stored_type>::value) + { + op_vectorise_cube_col::apply_unwrap(out, P.Q); + + return; + } + const uword N = P.get_n_elem(); out.set_size(N, 1); - if(is_Cube::stored_type>::value == true) + eT* outmem = out.memptr(); + + if(ProxyCube::use_at == false) { - const unwrap_cube::stored_type> tmp(P.Q); + typename ProxyCube::ea_type A = P.get_ea(); - arrayops::copy(out.memptr(), tmp.M.memptr(), N); - } - else - { - eT* outmem = out.memptr(); + uword i,j; - if(ProxyCube::use_at == false) + for(i=0, j=1; j < N; i+=2, j+=2) { - typename ProxyCube::ea_type A = P.get_ea(); - - uword i,j; + const eT tmp_i = A[i]; + const eT tmp_j = A[j]; - for(i=0, j=1; j < N; i+=2, j+=2) - { - const eT tmp_i = A[i]; - const eT tmp_j = A[j]; - - outmem[i] = tmp_i; - outmem[j] = tmp_j; - } - - if(i < N) - { - outmem[i] = A[i]; - } + outmem[i] = tmp_i; + outmem[j] = tmp_j; } - else + + if(i < N) { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); - const uword n_slices = P.get_n_slices(); - - for(uword slice=0; slice < n_slices; ++slice) - for(uword col=0; col < n_cols; ++col ) - for(uword row=0; row < n_rows; ++row ) - { - *outmem = P.at(row,col,slice); - outmem++; - } + outmem[i] = A[i]; + } + } + else + { + const uword nr = P.get_n_rows(); + const uword nc = P.get_n_cols(); + const uword ns = P.get_n_slices(); + + for(uword s=0; s < ns; ++s) + for(uword c=0; c < nc; ++c) + for(uword r=0; r < nr; ++r) + { + *outmem = P.at(r,c,s); + outmem++; } } } - //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_wishrnd_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_wishrnd_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_wishrnd_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_wishrnd_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/op_wishrnd_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/op_wishrnd_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/op_wishrnd_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/op_wishrnd_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -40,6 +42,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("wishrnd(): given matrix is not symmetric positive definite"); } } @@ -74,8 +77,6 @@ if(mode == 2) { status = op_wishrnd::apply_noalias_mode2(out, U.M, df); } } - if(status == false) { out.soft_reset(); } - return status; } @@ -92,6 +93,8 @@ if(S.is_empty()) { out.reset(); return true; } + if(auxlib::rudimentary_sym_check(S) == false) { return false; } + Mat D; const bool status = op_chol::apply_direct(D, S, 0); @@ -110,62 +113,49 @@ { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_CXX11) + arma_debug_check( (df <= eT(0)), "df must be greater than zero" ); + arma_debug_check( (D.is_square() == false), "wishrnd(): given matrix must be square sized" ); + + if(D.is_empty()) { out.reset(); return true; } + + const uword N = D.n_rows; + + if(df < eT(N)) { - arma_debug_check( (df <= eT(0)), "df must be greater than zero" ); - arma_debug_check( (D.is_square() == false), "wishrnd(): given matrix must be square sized" ); + arma_extra_debug_print("simple generator"); - if(D.is_empty()) { out.reset(); return true; } + const uword df_floor = uword(std::floor(df)); + + const Mat tmp = (randn< Mat >(df_floor, N)) * D; + + out = tmp.t() * tmp; + } + else + { + arma_extra_debug_print("standard generator"); - const uword N = D.n_rows; + op_chi2rnd_varying_df chi2rnd_generator; - if(df < eT(N)) + Mat A(N, N, arma_zeros_indicator()); + + for(uword i=0; i tmp = (randn< Mat >(df_floor, N)) * D; - - out = tmp.t() * tmp; + A.at(i,i) = std::sqrt( chi2rnd_generator(df - eT(i)) ); } - else + + for(uword i=1; i < N; ++i) { - arma_extra_debug_print("standard generator"); - - op_chi2rnd_varying_df chi2rnd_generator; - - Mat A(N, N, fill::zeros); - - for(uword i=0; i::fill( A.colptr(i), i ); - } - - const Mat tmp = A * D; - - A.reset(); - - out = tmp.t() * tmp; + arma_rng::randn::fill( A.colptr(i), i ); } - return true; - } - #else - { - arma_ignore(out); - arma_ignore(D); - arma_ignore(df); - arma_stop_logic_error("wishrnd(): C++11 compiler required"); + const Mat tmp = A * D; + + A.reset(); - return false; + out = tmp.t() * tmp; } - #endif + + return true; } @@ -190,6 +180,7 @@ if(status == false) { + out.soft_reset(); arma_stop_runtime_error("iwishrnd(): given matrix is not symmetric positive definite and/or df is too low"); } } @@ -224,8 +215,6 @@ if(mode == 2) { status = op_iwishrnd::apply_noalias_mode2(out, U.M, df); } } - if(status == false) { out.soft_reset(); } - return status; } @@ -242,6 +231,8 @@ if(T.is_empty()) { out.reset(); return true; } + if(auxlib::rudimentary_sym_check(T) == false) { return false; } + Mat Tinv; Mat Dinv; @@ -265,37 +256,24 @@ { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_CXX11) - { - arma_debug_check( (df <= eT(0)), "df must be greater than zero" ); - arma_debug_check( (Dinv.is_square() == false), "iwishrnd(): given matrix must be square sized" ); - - if(Dinv.is_empty()) { out.reset(); return true; } - - Mat tmp; - - const bool wishrnd_status = op_wishrnd::apply_noalias_mode2(tmp, Dinv, df); - - if(wishrnd_status == false) { return false; } - - const bool inv_status1 = auxlib::inv_sympd(out, tmp); - - const bool inv_status2 = (inv_status1) ? bool(true) : bool(auxlib::inv(out, tmp)); - - if(inv_status2 == false) { return false; } - - return true; - } - #else - { - arma_ignore(out); - arma_ignore(Dinv); - arma_ignore(df); - arma_stop_logic_error("iwishrnd(): C++11 compiler required"); - - return false; - } - #endif + arma_debug_check( (df <= eT(0)), "df must be greater than zero" ); + arma_debug_check( (Dinv.is_square() == false), "iwishrnd(): given matrix must be square sized" ); + + if(Dinv.is_empty()) { out.reset(); return true; } + + Mat tmp; + + const bool wishrnd_status = op_wishrnd::apply_noalias_mode2(tmp, Dinv, df); + + if(wishrnd_status == false) { return false; } + + const bool inv_status1 = auxlib::inv_sympd(out, tmp); + + const bool inv_status2 = (inv_status1) ? bool(true) : bool(auxlib::inv(out, tmp)); + + if(inv_status2 == false) { return false; } + + return true; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/podarray_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/podarray_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/podarray_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/podarray_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,7 +23,7 @@ struct podarray_prealloc_n_elem { - static const uword val = 16; + static constexpr uword val = 16; }; @@ -76,7 +78,7 @@ arma_inline eT* memptr(); arma_inline const eT* memptr() const; - arma_hot inline void copy_row(const Mat& A, const uword row); + inline void copy_row(const Mat& A, const uword row); protected: diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/podarray_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/podarray_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/podarray_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/podarray_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -193,7 +195,7 @@ eT podarray::operator() (const uword i) const { - arma_debug_check( (i >= n_elem), "podarray::operator(): index out of bounds"); + arma_debug_check_bounds( (i >= n_elem), "podarray::operator(): index out of bounds" ); return mem[i]; } @@ -205,7 +207,7 @@ eT& podarray::operator() (const uword i) { - arma_debug_check( (i >= n_elem), "podarray::operator(): index out of bounds"); + arma_debug_check_bounds( (i >= n_elem), "podarray::operator(): index out of bounds" ); return access::rw(mem[i]); } @@ -219,10 +221,7 @@ { arma_extra_debug_sigprint(); - if(min_n_elem > n_elem) - { - init_warm(min_n_elem); - } + if(min_n_elem > n_elem) { init_warm(min_n_elem); } } @@ -310,7 +309,6 @@ template -arma_hot inline void podarray::copy_row(const Mat& A, const uword row) @@ -364,21 +362,13 @@ template -arma_hot inline void podarray::init_cold(const uword new_n_elem) { arma_extra_debug_sigprint(); - if(new_n_elem <= podarray_prealloc_n_elem::val ) - { - mem = mem_local; - } - else - { - mem = memory::acquire(new_n_elem); - } + mem = (new_n_elem <= podarray_prealloc_n_elem::val) ? mem_local : memory::acquire(new_n_elem); } @@ -390,24 +380,11 @@ { arma_extra_debug_sigprint(); - if(n_elem == new_n_elem) - { - return; - } + if(n_elem == new_n_elem) { return; } - if(n_elem > podarray_prealloc_n_elem::val ) - { - memory::release( mem ); - } + if(n_elem > podarray_prealloc_n_elem::val) { memory::release( mem ); } - if(new_n_elem <= podarray_prealloc_n_elem::val ) - { - mem = mem_local; - } - else - { - mem = memory::acquire(new_n_elem); - } + mem = (new_n_elem <= podarray_prealloc_n_elem::val) ? mem_local : memory::acquire(new_n_elem); access::rw(n_elem) = new_n_elem; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/promote_type.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/promote_type.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/promote_type.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/promote_type.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,33 +23,29 @@ template struct is_promotable { - static const bool value = false; + static constexpr bool value = false; typedef T1 result; }; struct is_promotable_ok { - static const bool value = true; + static constexpr bool value = true; }; template struct is_promotable : public is_promotable_ok { typedef T result; }; template struct is_promotable, T> : public is_promotable_ok { typedef std::complex result; }; -template<> struct is_promotable, std::complex > : public is_promotable_ok { typedef std::complex result; }; -template<> struct is_promotable, float> : public is_promotable_ok { typedef std::complex result; }; -template<> struct is_promotable, double> : public is_promotable_ok { typedef std::complex result; }; +template<> struct is_promotable, std::complex> : public is_promotable_ok { typedef std::complex result; }; +template<> struct is_promotable, float> : public is_promotable_ok { typedef std::complex result; }; +template<> struct is_promotable, double> : public is_promotable_ok { typedef std::complex result; }; -#if defined(ARMA_USE_U64S64) template struct is_promotable, u64> : public is_promotable_ok { typedef std::complex result; }; template struct is_promotable, s64> : public is_promotable_ok { typedef std::complex result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template struct is_promotable, ulng_t> : public is_promotable_ok { typedef std::complex result; }; template struct is_promotable, slng_t> : public is_promotable_ok { typedef std::complex result; }; -#endif template struct is_promotable, s32> : public is_promotable_ok { typedef std::complex result; }; template struct is_promotable, u32> : public is_promotable_ok { typedef std::complex result; }; template struct is_promotable, s16> : public is_promotable_ok { typedef std::complex result; }; @@ -57,14 +55,10 @@ template<> struct is_promotable : public is_promotable_ok { typedef double result; }; -#if defined(ARMA_USE_U64S64) template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; -#endif template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; @@ -72,14 +66,10 @@ template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; -#if defined(ARMA_USE_U64S64) template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; -#endif template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; @@ -87,13 +77,10 @@ template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; -#if defined(ARMA_USE_U64S64) template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; -#endif -#if defined(ARMA_USE_U64S64) template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; @@ -101,7 +88,6 @@ template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; -#endif template<> struct is_promotable : public is_promotable_ok { typedef s32 result; }; // float ? template<> struct is_promotable : public is_promotable_ok { typedef s32 result; }; @@ -129,37 +115,29 @@ // // mirrored versions -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; -template<> struct is_promotable, std::complex > : public is_promotable_ok { typedef std::complex result; }; -template<> struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -template<> struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; - -#if defined(ARMA_USE_U64S64) -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -#endif -#if defined(ARMA_ALLOW_LONG) -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -#endif -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; -template struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; +template<> struct is_promotable, std::complex> : public is_promotable_ok { typedef std::complex result; }; +template<> struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template<> struct is_promotable > : public is_promotable_ok { typedef std::complex result; }; + +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; +template struct is_promotable> : public is_promotable_ok { typedef std::complex result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; -#if defined(ARMA_USE_U64S64) template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; -#endif template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; @@ -167,14 +145,10 @@ template<> struct is_promotable : public is_promotable_ok { typedef double result; }; template<> struct is_promotable : public is_promotable_ok { typedef double result; }; -#if defined(ARMA_USE_U64S64) template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; -#endif template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; @@ -182,13 +156,10 @@ template<> struct is_promotable : public is_promotable_ok { typedef float result; }; template<> struct is_promotable : public is_promotable_ok { typedef float result; }; -#if defined(ARMA_USE_U64S64) template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef u64 result; }; -#endif -#if defined(ARMA_USE_U64S64) template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; // float ? template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; @@ -196,7 +167,6 @@ template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; template<> struct is_promotable : public is_promotable_ok { typedef s64 result; }; -#endif template<> struct is_promotable : public is_promotable_ok { typedef s32 result; }; // float ? template<> struct is_promotable : public is_promotable_ok { typedef s32 result; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/ProxyCube.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/ProxyCube.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/ProxyCube.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/ProxyCube.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,9 +22,8 @@ template -class ProxyCube +struct ProxyCube { - public: inline ProxyCube(const T1&) { arma_type_check(( is_arma_cube_type::value == false )); @@ -35,19 +36,17 @@ // which can provide access to elements via operator[] template -class ProxyCube< Cube > +struct ProxyCube< Cube > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Cube stored_type; typedef const eT* ea_type; typedef const Cube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const Cube& Q; @@ -63,9 +62,9 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -73,25 +72,26 @@ template arma_inline bool is_alias(const Cube& X) const { return (void_ptr(&Q) == void_ptr(&X)); } + template + arma_inline bool has_overlap(const subview_cube& X) const { return is_alias(X.m); } + arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; template -class ProxyCube< GenCube > +struct ProxyCube< GenCube > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef GenCube stored_type; typedef const GenCube& ea_type; typedef const GenCube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const GenCube& Q; @@ -107,15 +107,18 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_rows*Q.n_cols*Q.n_slices; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } + + template + constexpr bool has_overlap(const subview_cube&) const { return false; } arma_inline bool is_aligned() const { return GenCube::is_simple; } }; @@ -123,19 +126,17 @@ template -class ProxyCube< GenCube > +struct ProxyCube< GenCube > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Cube stored_type; typedef const eT* ea_type; typedef const Cube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const Cube Q; @@ -151,15 +152,18 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } + + template + constexpr bool has_overlap(const subview_cube&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -167,19 +171,17 @@ template -class ProxyCube< GenCube > +struct ProxyCube< GenCube > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Cube stored_type; typedef const eT* ea_type; typedef const Cube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const Cube Q; @@ -195,15 +197,18 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } + + template + constexpr bool has_overlap(const subview_cube&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -211,19 +216,17 @@ template -class ProxyCube< OpCube > +struct ProxyCube< OpCube > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Cube stored_type; typedef const elem_type* ea_type; typedef const Cube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const Cube Q; @@ -239,15 +242,18 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } + + template + constexpr bool has_overlap(const subview_cube&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -255,19 +261,17 @@ template -class ProxyCube< GlueCube > +struct ProxyCube< GlueCube > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Cube stored_type; typedef const elem_type* ea_type; typedef const Cube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const Cube Q; @@ -283,15 +287,18 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } + + template + constexpr bool has_overlap(const subview_cube&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -299,19 +306,17 @@ template -class ProxyCube< subview_cube > +struct ProxyCube< subview_cube > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef subview_cube stored_type; typedef const subview_cube& ea_type; typedef const subview_cube& aligned_ea_type; - static const bool use_at = true; - static const bool use_mp = false; - static const bool has_subview = true; + static constexpr bool use_at = true; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; arma_aligned const subview_cube& Q; @@ -327,9 +332,9 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -337,25 +342,26 @@ template arma_inline bool is_alias(const Cube& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); } - arma_inline bool is_aligned() const { return false; } + template + arma_inline bool has_overlap(const subview_cube& X) const { return Q.check_overlap(X); } + + constexpr bool is_aligned() const { return false; } }; template -class ProxyCube< subview_cube_slices > +struct ProxyCube< subview_cube_slices > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Cube stored_type; typedef const eT* ea_type; typedef const Cube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const Cube Q; @@ -371,15 +377,18 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } + + template + constexpr bool has_overlap(const subview_cube&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -387,19 +396,17 @@ template -class ProxyCube< eOpCube > +struct ProxyCube< eOpCube > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef eOpCube stored_type; typedef const eOpCube& ea_type; typedef const eOpCube& aligned_ea_type; - static const bool use_at = eOpCube::use_at; - static const bool use_mp = eOpCube::use_mp; - static const bool has_subview = eOpCube::has_subview; + static constexpr bool use_at = eOpCube::use_at; + static constexpr bool use_mp = eOpCube::use_mp; + static constexpr bool has_subview = eOpCube::has_subview; arma_aligned const eOpCube& Q; @@ -415,9 +422,9 @@ arma_inline uword get_n_slices() const { return Q.get_n_slices(); } arma_inline uword get_n_elem() const { return Q.get_n_elem(); } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -425,25 +432,26 @@ template arma_inline bool is_alias(const Cube& X) const { return Q.P.is_alias(X); } + template + arma_inline bool has_overlap(const subview_cube& X) const { return Q.P.has_overlap(X); } + arma_inline bool is_aligned() const { return Q.P.is_aligned(); } }; template -class ProxyCube< eGlueCube > +struct ProxyCube< eGlueCube > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef eGlueCube stored_type; typedef const eGlueCube& ea_type; typedef const eGlueCube& aligned_ea_type; - static const bool use_at = eGlueCube::use_at; - static const bool use_mp = eGlueCube::use_mp; - static const bool has_subview = eGlueCube::has_subview; + static constexpr bool use_at = eGlueCube::use_at; + static constexpr bool use_mp = eGlueCube::use_mp; + static constexpr bool has_subview = eGlueCube::has_subview; arma_aligned const eGlueCube& Q; @@ -459,9 +467,9 @@ arma_inline uword get_n_slices() const { return Q.get_n_slices(); } arma_inline uword get_n_elem() const { return Q.get_n_elem(); } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -469,25 +477,26 @@ template arma_inline bool is_alias(const Cube& X) const { return (Q.P1.is_alias(X) || Q.P2.is_alias(X)); } + template + arma_inline bool has_overlap(const subview_cube& X) const { return (Q.P1.has_overlap(X) || Q.P2.has_overlap(X)); } + arma_inline bool is_aligned() const { return Q.P1.is_aligned() && Q.P2.is_aligned(); } }; template -class ProxyCube< mtOpCube > +struct ProxyCube< mtOpCube > { - public: - typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; typedef Cube stored_type; typedef const elem_type* ea_type; typedef const Cube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const Cube Q; @@ -503,15 +512,18 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } + + template + constexpr bool has_overlap(const subview_cube&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -519,19 +531,17 @@ template -class ProxyCube< mtGlueCube > +struct ProxyCube< mtGlueCube > { - public: - typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; typedef Cube stored_type; typedef const elem_type* ea_type; typedef const Cube& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; arma_aligned const Cube Q; @@ -547,15 +557,18 @@ arma_inline uword get_n_slices() const { return Q.n_slices; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } + + template + constexpr bool has_overlap(const subview_cube&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Proxy.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Proxy.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Proxy.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Proxy.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,7 +31,6 @@ // use_at = boolean indicating whether at(row,col) must be used to get elements // use_mp = boolean indicating whether OpenMP can be used while processing elements // has_subview = boolean indicating whether the Q object has a subview -// fake_mat = boolean indicating whether the Q object is a matrix using memory from another object // // is_row = boolean indicating whether the Q object can be treated a row vector // is_col = boolean indicating whether the Q object can be treated a column vector @@ -74,14 +75,13 @@ typedef const elem_type* ea_type; typedef const T1& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = T1::is_row; - static const bool is_col = T1::is_col; - static const bool is_xvec = T1::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T1::is_col; + static constexpr bool is_xvec = T1::is_xvec; arma_aligned const T1& Q; @@ -91,13 +91,22 @@ arma_extra_debug_sigprint(); } - arma_inline static uword get_n_rows() { return T1::n_rows; } - arma_inline static uword get_n_cols() { return T1::n_cols; } - arma_inline static uword get_n_elem() { return T1::n_elem; } - - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + //// this may require T1::n_elem etc to be declared as static constexpr inline variables (C++17) + //// see also the notes in Mat::fixed + //// https://en.cppreference.com/w/cpp/language/static + //// https://en.cppreference.com/w/cpp/language/inline + // + // static constexpr uword get_n_rows() { return T1::n_rows; } + // static constexpr uword get_n_cols() { return T1::n_cols; } + // static constexpr uword get_n_elem() { return T1::n_elem; } + + arma_inline uword get_n_rows() const { return is_row ? 1 : T1::n_rows; } + arma_inline uword get_n_cols() const { return is_col ? 1 : T1::n_cols; } + arma_inline uword get_n_elem() const { return T1::n_elem; } + + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -132,11 +141,10 @@ template -class Proxy : public Proxy_redirect::value >::result +struct Proxy : public Proxy_redirect::value>::result { - public: inline Proxy(const T1& A) - : Proxy_redirect< T1, is_Mat_fixed::value >::result(A) + : Proxy_redirect::value>::result(A) { } }; @@ -144,24 +152,21 @@ template -class Proxy< Mat > +struct Proxy< Mat > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const eT* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const Mat& Q; @@ -175,9 +180,9 @@ arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -194,24 +199,21 @@ template -class Proxy< Col > +struct Proxy< Col > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Col stored_type; typedef const eT* ea_type; typedef const Col& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const Col& Q; @@ -222,12 +224,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -244,24 +246,21 @@ template -class Proxy< Row > +struct Proxy< Row > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Row stored_type; typedef const eT* ea_type; typedef const Row& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = true; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const Row& Q; @@ -271,13 +270,13 @@ arma_extra_debug_sigprint(); } - arma_inline uword get_n_rows() const { return 1; } + constexpr uword get_n_rows() const { return 1; } arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword, const uword col) const { return Q[col]; } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword, const uword c) const { return Q[c]; } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -294,24 +293,21 @@ template -class Proxy< Gen > +struct Proxy< Gen > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Gen stored_type; typedef const Gen& ea_type; typedef const Gen& aligned_ea_type; - static const bool use_at = Gen::use_at; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = Gen::is_row; - static const bool is_col = Gen::is_col; - static const bool is_xvec = Gen::is_xvec; + static constexpr bool use_at = Gen::use_at; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = Gen::is_row; + static constexpr bool is_col = Gen::is_col; + static constexpr bool is_xvec = Gen::is_xvec; arma_aligned const Gen& Q; @@ -325,18 +321,18 @@ arma_inline uword get_n_cols() const { return (is_col ? 1 : Q.n_cols); } arma_inline uword get_n_elem() const { return (is_row ? 1 : Q.n_rows) * (is_col ? 1 : Q.n_cols); } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return Gen::is_simple; } }; @@ -344,24 +340,21 @@ template -class Proxy< Gen > +struct Proxy< Gen > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = Gen::is_row; - static const bool is_col = Gen::is_col; - static const bool is_xvec = Gen::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = Gen::is_row; + static constexpr bool is_col = Gen::is_col; + static constexpr bool is_xvec = Gen::is_xvec; arma_aligned const Mat Q; @@ -375,18 +368,18 @@ arma_inline uword get_n_cols() const { return (is_col ? 1 : Q.n_cols); } arma_inline uword get_n_elem() const { return (is_row ? 1 : Q.n_rows) * (is_col ? 1 : Q.n_cols); } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -394,24 +387,21 @@ template -class Proxy< Gen > +struct Proxy< Gen > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = Gen::is_row; - static const bool is_col = Gen::is_col; - static const bool is_xvec = Gen::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = Gen::is_row; + static constexpr bool is_col = Gen::is_col; + static constexpr bool is_xvec = Gen::is_xvec; arma_aligned const Mat Q; @@ -425,18 +415,18 @@ arma_inline uword get_n_cols() const { return (is_col ? 1 : Q.n_cols); } arma_inline uword get_n_elem() const { return (is_row ? 1 : Q.n_rows) * (is_col ? 1 : Q.n_cols); } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -444,24 +434,21 @@ template -class Proxy< eOp > +struct Proxy< eOp > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef eOp stored_type; typedef const eOp& ea_type; typedef const eOp& aligned_ea_type; - static const bool use_at = eOp::use_at; - static const bool use_mp = eOp::use_mp; - static const bool has_subview = eOp::has_subview; - static const bool fake_mat = eOp::fake_mat; - - static const bool is_row = eOp::is_row; - static const bool is_col = eOp::is_col; - static const bool is_xvec = eOp::is_xvec; + static constexpr bool use_at = eOp::use_at; + static constexpr bool use_mp = eOp::use_mp; + static constexpr bool has_subview = eOp::has_subview; + + static constexpr bool is_row = eOp::is_row; + static constexpr bool is_col = eOp::is_col; + static constexpr bool is_xvec = eOp::is_xvec; arma_aligned const eOp& Q; @@ -475,9 +462,9 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.get_n_cols(); } arma_inline uword get_n_elem() const { return Q.get_n_elem(); } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -494,24 +481,21 @@ template -class Proxy< eGlue > +struct Proxy< eGlue > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef eGlue stored_type; typedef const eGlue& ea_type; typedef const eGlue& aligned_ea_type; - static const bool use_at = eGlue::use_at; - static const bool use_mp = eGlue::use_mp; - static const bool has_subview = eGlue::has_subview; - static const bool fake_mat = eGlue::fake_mat; - - static const bool is_row = eGlue::is_row; - static const bool is_col = eGlue::is_col; - static const bool is_xvec = eGlue::is_xvec; + static constexpr bool use_at = eGlue::use_at; + static constexpr bool use_mp = eGlue::use_mp; + static constexpr bool has_subview = eGlue::has_subview; + + static constexpr bool is_row = eGlue::is_row; + static constexpr bool is_col = eGlue::is_col; + static constexpr bool is_xvec = eGlue::is_xvec; arma_aligned const eGlue& Q; @@ -525,9 +509,9 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.get_n_cols(); } arma_inline uword get_n_elem() const { return Q.get_n_elem(); } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -544,24 +528,21 @@ template -class Proxy< Op > +struct Proxy< Op > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = Op::is_row; - static const bool is_col = Op::is_col; - static const bool is_xvec = Op::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = Op::is_row; + static constexpr bool is_col = Op::is_col; + static constexpr bool is_xvec = Op::is_xvec; arma_aligned const Mat Q; @@ -575,18 +556,18 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -594,24 +575,21 @@ template -class Proxy< Glue > +struct Proxy< Glue > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool has_subview = false; - static const bool use_mp = false; - static const bool fake_mat = false; - - static const bool is_row = Glue::is_row; - static const bool is_col = Glue::is_col; - static const bool is_xvec = Glue::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = Glue::is_row; + static constexpr bool is_col = Glue::is_col; + static constexpr bool is_xvec = Glue::is_xvec; arma_aligned const Mat Q; @@ -625,43 +603,156 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; -template -class Proxy< mtOp > +template +struct Proxy< Glue > + { + typedef Glue this_Glue_type; + typedef Proxy< Glue > this_Proxy_type; + + typedef typename T1::elem_type elem_type; + typedef typename get_pod_type::result pod_type; + typedef this_Glue_type stored_type; + typedef const this_Proxy_type& ea_type; + typedef const this_Proxy_type& aligned_ea_type; + + static constexpr bool use_at = (Proxy::use_at || Proxy::use_at ); + static constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp ); + static constexpr bool has_subview = (Proxy::has_subview || Proxy::has_subview); + + static constexpr bool is_row = this_Glue_type::is_row; + static constexpr bool is_col = this_Glue_type::is_col; + static constexpr bool is_xvec = this_Glue_type::is_xvec; + + arma_aligned const this_Glue_type& Q; + arma_aligned const Proxy P1; + arma_aligned const Proxy P2; + + arma_lt_comparator comparator; + + inline explicit Proxy(const this_Glue_type& X) + : Q (X ) + , P1(X.A) + , P2(X.B) + { + arma_extra_debug_sigprint(); + + arma_debug_assert_same_size(P1, P2, "element-wise min()"); + } + + arma_inline uword get_n_rows() const { return is_row ? 1 : P1.get_n_rows(); } + arma_inline uword get_n_cols() const { return is_col ? 1 : P1.get_n_cols(); } + arma_inline uword get_n_elem() const { return P1.get_n_elem(); } + + arma_inline elem_type operator[] (const uword i) const { const elem_type A = P1[i]; const elem_type B = P2[i]; return comparator(A,B) ? A : B; } + arma_inline elem_type at (const uword r, const uword c) const { const elem_type A = P1.at(r,c); const elem_type B = P2.at(r,c); return comparator(A,B) ? A : B; } + arma_inline elem_type at_alt (const uword i) const { const elem_type A = P1.at_alt(i); const elem_type B = P2.at_alt(i); return comparator(A,B) ? A : B; } + + arma_inline ea_type get_ea() const { return *this; } + arma_inline aligned_ea_type get_aligned_ea() const { return *this; } + + template + arma_inline bool is_alias(const Mat& X) const { return (P1.is_alias(X) || P2.is_alias(X)); } + + template + arma_inline bool has_overlap(const subview& X) const { return (P1.has_overlap(X) || P2.has_overlap(X)); } + + arma_inline bool is_aligned() const { return (P1.is_aligned() && P2.is_aligned()); } + }; + + + +template +struct Proxy< Glue > { - public: + typedef Glue this_Glue_type; + typedef Proxy< Glue > this_Proxy_type; + + typedef typename T1::elem_type elem_type; + typedef typename get_pod_type::result pod_type; + typedef this_Glue_type stored_type; + typedef const this_Proxy_type& ea_type; + typedef const this_Proxy_type& aligned_ea_type; + + static constexpr bool use_at = (Proxy::use_at || Proxy::use_at ); + static constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp ); + static constexpr bool has_subview = (Proxy::has_subview || Proxy::has_subview); + + static constexpr bool is_row = this_Glue_type::is_row; + static constexpr bool is_col = this_Glue_type::is_col; + static constexpr bool is_xvec = this_Glue_type::is_xvec; + + arma_aligned const this_Glue_type& Q; + arma_aligned const Proxy P1; + arma_aligned const Proxy P2; + + arma_gt_comparator comparator; + + inline explicit Proxy(const this_Glue_type& X) + : Q (X ) + , P1(X.A) + , P2(X.B) + { + arma_extra_debug_sigprint(); + + arma_debug_assert_same_size(P1, P2, "element-wise max()"); + } + arma_inline uword get_n_rows() const { return is_row ? 1 : P1.get_n_rows(); } + arma_inline uword get_n_cols() const { return is_col ? 1 : P1.get_n_cols(); } + arma_inline uword get_n_elem() const { return P1.get_n_elem(); } + + arma_inline elem_type operator[] (const uword i) const { const elem_type A = P1[i]; const elem_type B = P2[i]; return comparator(A,B) ? A : B; } + arma_inline elem_type at (const uword r, const uword c) const { const elem_type A = P1.at(r,c); const elem_type B = P2.at(r,c); return comparator(A,B) ? A : B; } + arma_inline elem_type at_alt (const uword i) const { const elem_type A = P1.at_alt(i); const elem_type B = P2.at_alt(i); return comparator(A,B) ? A : B; } + + arma_inline ea_type get_ea() const { return *this; } + arma_inline aligned_ea_type get_aligned_ea() const { return *this; } + + template + arma_inline bool is_alias(const Mat& X) const { return (P1.is_alias(X) || P2.is_alias(X)); } + + template + arma_inline bool has_overlap(const subview& X) const { return (P1.has_overlap(X) || P2.has_overlap(X)); } + + arma_inline bool is_aligned() const { return (P1.is_aligned() && P2.is_aligned()); } + }; + + + +template +struct Proxy< mtOp > + { typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = mtOp::is_row; - static const bool is_col = mtOp::is_col; - static const bool is_xvec = mtOp::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = mtOp::is_row; + static constexpr bool is_col = mtOp::is_col; + static constexpr bool is_xvec = mtOp::is_xvec; arma_aligned const Mat Q; @@ -675,18 +766,18 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row,col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r,c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -694,24 +785,21 @@ template -class Proxy< mtGlue > +struct Proxy< mtGlue > { - public: - typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = mtGlue::is_row; - static const bool is_col = mtGlue::is_col; - static const bool is_xvec = mtGlue::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = mtGlue::is_row; + static constexpr bool is_col = mtGlue::is_col; + static constexpr bool is_xvec = mtGlue::is_xvec; arma_aligned const Mat Q; @@ -725,18 +813,18 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row,col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r,c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -744,24 +832,21 @@ template -class Proxy< CubeToMatOp > +struct Proxy< CubeToMatOp > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = CubeToMatOp::is_row; - static const bool is_col = CubeToMatOp::is_col; - static const bool is_xvec = CubeToMatOp::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = CubeToMatOp::is_row; + static constexpr bool is_col = CubeToMatOp::is_col; + static constexpr bool is_xvec = CubeToMatOp::is_xvec; arma_aligned const Mat Q; @@ -775,18 +860,18 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -794,24 +879,21 @@ template -class Proxy< CubeToMatOp > +struct Proxy< CubeToMatOp > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = true; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const unwrap_cube U; arma_aligned const Mat Q; @@ -824,21 +906,21 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -846,24 +928,21 @@ template -class Proxy< SpToDOp > +struct Proxy< SpToDOp > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = SpToDOp::is_row; - static const bool is_col = SpToDOp::is_col; - static const bool is_xvec = SpToDOp::is_xvec; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = SpToDOp::is_row; + static constexpr bool is_col = SpToDOp::is_col; + static constexpr bool is_xvec = SpToDOp::is_xvec; arma_aligned const Mat Q; @@ -877,18 +956,18 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -896,24 +975,21 @@ template -class Proxy< SpToDOp > +struct Proxy< SpToDOp > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = true; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const unwrap_spmat U; arma_aligned const Mat Q; @@ -926,21 +1002,21 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -948,24 +1024,21 @@ template -class Proxy< subview > +struct Proxy< subview > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef subview stored_type; typedef const subview& ea_type; typedef const subview& aligned_ea_type; - static const bool use_at = true; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = true; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const subview& Q; @@ -979,9 +1052,9 @@ arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -992,30 +1065,27 @@ template arma_inline bool has_overlap(const subview& X) const { return Q.check_overlap(X); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< subview_col > +struct Proxy< subview_col > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef subview_col stored_type; typedef const eT* ea_type; typedef const subview_col& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_col& Q; @@ -1026,12 +1096,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.colmem; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -1048,24 +1118,70 @@ template -class Proxy< subview_row > +struct Proxy< subview_cols > { - public: + typedef eT elem_type; + typedef typename get_pod_type::result pod_type; + typedef Mat stored_type; + typedef const eT* ea_type; + typedef const Mat& aligned_ea_type; + + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; + + arma_aligned const subview_cols& sv; + arma_aligned const Mat Q; + + inline explicit Proxy(const subview_cols& A) + : sv(A) + , Q ( const_cast( A.colptr(0) ), A.n_rows, A.n_cols, false, false ) + { + arma_extra_debug_sigprint(); + } + + arma_inline uword get_n_rows() const { return Q.n_rows; } + arma_inline uword get_n_cols() const { return Q.n_cols; } + arma_inline uword get_n_elem() const { return Q.n_elem; } + + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r,c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + + arma_inline ea_type get_ea() const { return Q.memptr(); } + arma_inline aligned_ea_type get_aligned_ea() const { return Q; } + + template + arma_inline bool is_alias(const Mat& X) const { return (is_same_type::value) ? (void_ptr(&(sv.m)) == void_ptr(&X)) : false; } + + template + arma_inline bool has_overlap(const subview& X) const { return sv.check_overlap(X); } + arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } + }; + + + +template +struct Proxy< subview_row > + { typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef subview_row stored_type; typedef const subview_row& ea_type; typedef const subview_row& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = true; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const subview_row& Q; @@ -1075,13 +1191,13 @@ arma_extra_debug_sigprint(); } - arma_inline uword get_n_rows() const { return 1; } + constexpr uword get_n_rows() const { return 1; } arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword, const uword col) const { return Q[col]; } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword, const uword c) const { return Q[c]; } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -1092,30 +1208,27 @@ template arma_inline bool has_overlap(const subview& X) const { return Q.check_overlap(X); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< subview_elem1 > +struct Proxy< subview_elem1 > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef subview_elem1 stored_type; typedef const Proxy< subview_elem1 >& ea_type; typedef const Proxy< subview_elem1 >& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_elem1& Q; arma_aligned const Proxy R; @@ -1129,16 +1242,16 @@ const bool R_is_vec = ((R.get_n_rows() == 1) || (R.get_n_cols() == 1)); const bool R_is_empty = (R.get_n_elem() == 0); - arma_debug_check( ((R_is_vec == false) && (R_is_empty == false)), "Mat::elem(): given object is not a vector" ); + arma_debug_check( ((R_is_vec == false) && (R_is_empty == false)), "Mat::elem(): given object must be a vector" ); } arma_inline uword get_n_rows() const { return R.get_n_elem(); } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return R.get_n_elem(); } - arma_inline elem_type operator[] (const uword i) const { const uword ii = (Proxy::use_at) ? R.at(i, 0) : R[i ]; arma_debug_check( (ii >= Q.m.n_elem), "Mat::elem(): index out of bounds" ); return Q.m[ii]; } - arma_inline elem_type at (const uword row, const uword) const { const uword ii = (Proxy::use_at) ? R.at(row,0) : R[row]; arma_debug_check( (ii >= Q.m.n_elem), "Mat::elem(): index out of bounds" ); return Q.m[ii]; } - arma_inline elem_type at_alt (const uword i) const { const uword ii = (Proxy::use_at) ? R.at(i, 0) : R[i ]; arma_debug_check( (ii >= Q.m.n_elem), "Mat::elem(): index out of bounds" ); return Q.m[ii]; } + arma_inline elem_type operator[] (const uword i) const { const uword ii = (Proxy::use_at) ? R.at(i,0) : R[i]; arma_debug_check_bounds( (ii >= Q.m.n_elem), "Mat::elem(): index out of bounds" ); return Q.m[ii]; } + arma_inline elem_type at (const uword r, const uword) const { const uword ii = (Proxy::use_at) ? R.at(r,0) : R[r]; arma_debug_check_bounds( (ii >= Q.m.n_elem), "Mat::elem(): index out of bounds" ); return Q.m[ii]; } + arma_inline elem_type at_alt (const uword i) const { const uword ii = (Proxy::use_at) ? R.at(i,0) : R[i]; arma_debug_check_bounds( (ii >= Q.m.n_elem), "Mat::elem(): index out of bounds" ); return Q.m[ii]; } arma_inline ea_type get_ea() const { return (*this); } arma_inline aligned_ea_type get_aligned_ea() const { return (*this); } @@ -1149,30 +1262,27 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< subview_elem2 > +struct Proxy< subview_elem2 > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const eT* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const Mat Q; @@ -1186,18 +1296,18 @@ arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -1205,24 +1315,21 @@ template -class Proxy< diagview > +struct Proxy< diagview > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef diagview stored_type; typedef const diagview& ea_type; typedef const diagview& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const diagview& Q; @@ -1233,12 +1340,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q.at(row, 0); } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q.at(r, 0); } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -1249,13 +1356,13 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy_diagvec_mat +struct Proxy_diagvec_mat { inline Proxy_diagvec_mat(const T1&) {} }; @@ -1263,41 +1370,38 @@ template -class Proxy_diagvec_mat< Op > +struct Proxy_diagvec_mat< Op > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef diagview stored_type; typedef const diagview& ea_type; typedef const diagview& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const Mat& R; arma_aligned const diagview Q; inline explicit Proxy_diagvec_mat(const Op& A) - : R(A.m), Q( R.diag( (A.aux_uword_b > 0) ? -sword(A.aux_uword_a) : sword(A.aux_uword_a) ) ) + : R(A.m), Q( R.diag() ) { arma_extra_debug_sigprint(); } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q.at(row, 0); } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q.at(r, 0); } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -1308,13 +1412,13 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy_diagvec_expr +struct Proxy_diagvec_expr { inline Proxy_diagvec_expr(const T1&) {} }; @@ -1322,24 +1426,21 @@ template -class Proxy_diagvec_expr< Op > +struct Proxy_diagvec_expr< Op > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const Mat Q; @@ -1350,21 +1451,21 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q.at(row, 0); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q.at(r, 0); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -1383,11 +1484,9 @@ template -class Proxy< Op > +struct Proxy< Op > : public Proxy_diagvec_redirect< Op, is_Mat::value >::result { - public: - typedef typename Proxy_diagvec_redirect< Op, is_Mat::value >::result Proxy_diagvec; inline explicit Proxy(const Op& A) @@ -1400,6 +1499,53 @@ template +struct Proxy< Op > + { + typedef typename T1::elem_type elem_type; + typedef typename get_pod_type::result pod_type; + typedef Mat stored_type; + typedef const elem_type* ea_type; + typedef const Mat& aligned_ea_type; + + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; + + arma_aligned const Mat Q; + + inline explicit Proxy(const Op& A) + : Q(A) + { + arma_extra_debug_sigprint(); + } + + arma_inline uword get_n_rows() const { return Q.n_rows; } + constexpr uword get_n_cols() const { return 1; } + arma_inline uword get_n_elem() const { return Q.n_elem; } + + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q.at(r, 0); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + + arma_inline ea_type get_ea() const { return Q.memptr(); } + arma_inline aligned_ea_type get_aligned_ea() const { return Q; } + + template + constexpr bool is_alias(const Mat&) const { return false; } + + template + constexpr bool has_overlap(const subview&) const { return false; } + + arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } + }; + + + +template struct Proxy_xtrans_default { inline Proxy_xtrans_default(const T1&) {} @@ -1410,22 +1556,19 @@ template struct Proxy_xtrans_default< Op > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef xtrans_mat stored_type; typedef const xtrans_mat& ea_type; typedef const xtrans_mat& aligned_ea_type; - static const bool use_at = true; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = true; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; const unwrap U; const xtrans_mat Q; @@ -1446,7 +1589,7 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; @@ -1454,22 +1597,19 @@ template struct Proxy_xtrans_default< Op > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef xtrans_mat stored_type; typedef const xtrans_mat& ea_type; typedef const xtrans_mat& aligned_ea_type; - static const bool use_at = true; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = true; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; const unwrap U; const xtrans_mat Q; @@ -1490,7 +1630,7 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; @@ -1512,15 +1652,14 @@ typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = quasi_unwrap::has_subview; - static const bool fake_mat = true; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = quasi_unwrap::has_subview; // NOTE: the Op class takes care of swapping row and col for op_htrans - static const bool is_row = Op::is_row; - static const bool is_col = Op::is_col; - static const bool is_xvec = Op::is_xvec; + static constexpr bool is_row = Op::is_row; + static constexpr bool is_col = Op::is_col; + static constexpr bool is_xvec = Op::is_xvec; arma_aligned const quasi_unwrap U; // avoid copy if T1 is a Row, Col or subview_col arma_aligned const Mat Q; @@ -1555,15 +1694,14 @@ typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = quasi_unwrap::has_subview; - static const bool fake_mat = true; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = quasi_unwrap::has_subview; // NOTE: the Op class takes care of swapping row and col for op_strans - static const bool is_row = Op::is_row; - static const bool is_col = Op::is_col; - static const bool is_xvec = Op::is_xvec; + static constexpr bool is_row = Op::is_row; + static constexpr bool is_col = Op::is_col; + static constexpr bool is_xvec = Op::is_xvec; arma_aligned const quasi_unwrap U; // avoid copy if T1 is a Row, Col or subview_col arma_aligned const Mat Q; @@ -1601,7 +1739,7 @@ template -class Proxy< Op > +struct Proxy< Op > : public Proxy_xtrans_redirect < @@ -1609,8 +1747,6 @@ ((is_cx::no) && ((Op::is_row) || (Op::is_col)) ) >::result { - public: - typedef typename Proxy_xtrans_redirect @@ -1626,14 +1762,13 @@ typedef typename Proxy_xtrans::ea_type ea_type; typedef typename Proxy_xtrans::aligned_ea_type aligned_ea_type; - static const bool use_at = Proxy_xtrans::use_at; - static const bool use_mp = Proxy_xtrans::use_mp; - static const bool has_subview = Proxy_xtrans::has_subview; - static const bool fake_mat = Proxy_xtrans::fake_mat; - - static const bool is_row = Proxy_xtrans::is_row; - static const bool is_col = Proxy_xtrans::is_col; - static const bool is_xvec = Proxy_xtrans::is_xvec; + static constexpr bool use_at = Proxy_xtrans::use_at; + static constexpr bool use_mp = Proxy_xtrans::use_mp; + static constexpr bool has_subview = Proxy_xtrans::has_subview; + + static constexpr bool is_row = Proxy_xtrans::is_row; + static constexpr bool is_col = Proxy_xtrans::is_col; + static constexpr bool is_xvec = Proxy_xtrans::is_xvec; using Proxy_xtrans::Q; @@ -1647,9 +1782,9 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Proxy_xtrans::get_ea(); } arma_inline aligned_ea_type get_aligned_ea() const { return Proxy_xtrans::get_aligned_ea(); } @@ -1666,7 +1801,7 @@ template -class Proxy< Op > +struct Proxy< Op > : public Proxy_xtrans_redirect < @@ -1674,8 +1809,6 @@ ( (Op::is_row) || (Op::is_col) ) >::result { - public: - typedef typename Proxy_xtrans_redirect @@ -1691,14 +1824,13 @@ typedef typename Proxy_xtrans::ea_type ea_type; typedef typename Proxy_xtrans::aligned_ea_type aligned_ea_type; - static const bool use_at = Proxy_xtrans::use_at; - static const bool use_mp = Proxy_xtrans::use_mp; - static const bool has_subview = Proxy_xtrans::has_subview; - static const bool fake_mat = Proxy_xtrans::fake_mat; - - static const bool is_row = Proxy_xtrans::is_row; - static const bool is_col = Proxy_xtrans::is_col; - static const bool is_xvec = Proxy_xtrans::is_xvec; + static constexpr bool use_at = Proxy_xtrans::use_at; + static constexpr bool use_mp = Proxy_xtrans::use_mp; + static constexpr bool has_subview = Proxy_xtrans::has_subview; + + static constexpr bool is_row = Proxy_xtrans::is_row; + static constexpr bool is_col = Proxy_xtrans::is_col; + static constexpr bool is_xvec = Proxy_xtrans::is_xvec; using Proxy_xtrans::Q; @@ -1712,9 +1844,9 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Proxy_xtrans::get_ea(); } arma_inline aligned_ea_type get_aligned_ea() const { return Proxy_xtrans::get_aligned_ea(); } @@ -1739,14 +1871,13 @@ typedef const subview_row_htrans& ea_type; typedef const subview_row_htrans& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_row_htrans Q; @@ -1774,14 +1905,13 @@ typedef const subview_row_strans& ea_type; typedef const subview_row_strans& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_row_strans Q; @@ -1812,7 +1942,7 @@ template -class Proxy< Op, op_htrans> > +struct Proxy< Op, op_htrans> > : public Proxy_subview_row_htrans_redirect < @@ -1820,8 +1950,6 @@ is_cx::yes >::result { - public: - typedef typename Proxy_subview_row_htrans_redirect @@ -1837,14 +1965,13 @@ typedef typename Proxy_sv_row_ht::ea_type ea_type; typedef typename Proxy_sv_row_ht::ea_type aligned_ea_type; - static const bool use_at = Proxy_sv_row_ht::use_at; - static const bool use_mp = Proxy_sv_row_ht::use_mp; - static const bool has_subview = Proxy_sv_row_ht::has_subview; - static const bool fake_mat = Proxy_sv_row_ht::fake_mat; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = Proxy_sv_row_ht::use_at; + static constexpr bool use_mp = Proxy_sv_row_ht::use_mp; + static constexpr bool has_subview = Proxy_sv_row_ht::has_subview; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; using Proxy_sv_row_ht::Q; @@ -1855,12 +1982,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -1871,30 +1998,27 @@ template arma_inline bool has_overlap(const subview& X) const { return Proxy_sv_row_ht::has_overlap(X); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< Op, op_strans> > +struct Proxy< Op, op_strans> > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef subview_row_strans stored_type; typedef const subview_row_strans& ea_type; typedef const subview_row_strans& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_row_strans Q; @@ -1905,12 +2029,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -1921,16 +2045,14 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< Op< Row< std::complex >, op_htrans> > +struct Proxy< Op< Row< std::complex >, op_htrans> > { - public: - typedef typename std::complex eT; typedef typename std::complex elem_type; @@ -1939,14 +2061,13 @@ typedef const xvec_htrans& ea_type; typedef const xvec_htrans& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; const xvec_htrans Q; const Row& src; @@ -1959,12 +2080,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -1975,16 +2096,14 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< Op< Col< std::complex >, op_htrans> > +struct Proxy< Op< Col< std::complex >, op_htrans> > { - public: - typedef typename std::complex eT; typedef typename std::complex elem_type; @@ -1993,14 +2112,13 @@ typedef const xvec_htrans& ea_type; typedef const xvec_htrans& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = true; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; const xvec_htrans Q; const Col& src; @@ -2012,13 +2130,13 @@ arma_extra_debug_sigprint(); } - arma_inline uword get_n_rows() const { return 1; } + constexpr uword get_n_rows() const { return 1; } arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword, const uword col) const { return Q[col]; } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword, const uword c) const { return Q[c]; } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -2029,16 +2147,14 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< Op< subview_col< std::complex >, op_htrans> > +struct Proxy< Op< subview_col< std::complex >, op_htrans> > { - public: - typedef typename std::complex eT; typedef typename std::complex elem_type; @@ -2047,14 +2163,13 @@ typedef const xvec_htrans& ea_type; typedef const xvec_htrans& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = true; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; const xvec_htrans Q; const subview_col& src; @@ -2066,13 +2181,13 @@ arma_extra_debug_sigprint(); } - arma_inline uword get_n_rows() const { return 1; } + constexpr uword get_n_rows() const { return 1; } arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword, const uword col) const { return Q[col]; } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword, const uword c) const { return Q[c]; } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -2083,31 +2198,28 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< Op > +struct Proxy< Op > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef eOp< Op, eop_scalar_times> stored_type; typedef const eOp< Op, eop_scalar_times>& ea_type; typedef const eOp< Op, eop_scalar_times>& aligned_ea_type; - static const bool use_at = eOp< Op, eop_scalar_times>::use_at; - static const bool use_mp = eOp< Op, eop_scalar_times>::use_mp; - static const bool has_subview = eOp< Op, eop_scalar_times>::has_subview; - static const bool fake_mat = eOp< Op, eop_scalar_times>::fake_mat; + static constexpr bool use_at = eOp< Op, eop_scalar_times>::use_at; + static constexpr bool use_mp = eOp< Op, eop_scalar_times>::use_mp; + static constexpr bool has_subview = eOp< Op, eop_scalar_times>::has_subview; // NOTE: the Op class takes care of swapping row and col for op_htrans - static const bool is_row = eOp< Op, eop_scalar_times>::is_row; - static const bool is_col = eOp< Op, eop_scalar_times>::is_col; - static const bool is_xvec = eOp< Op, eop_scalar_times>::is_xvec; + static constexpr bool is_row = eOp< Op, eop_scalar_times>::is_row; + static constexpr bool is_col = eOp< Op, eop_scalar_times>::is_col; + static constexpr bool is_xvec = eOp< Op, eop_scalar_times>::is_xvec; arma_aligned const Op R; arma_aligned const eOp< Op, eop_scalar_times > Q; @@ -2123,9 +2235,9 @@ arma_inline uword get_n_cols() const { return is_col ? 1 : Q.get_n_cols(); } arma_inline uword get_n_elem() const { return Q.get_n_elem(); } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r, c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -2142,24 +2254,21 @@ template -class Proxy< subview_row_strans > +struct Proxy< subview_row_strans > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef subview_row_strans stored_type; typedef const subview_row_strans& ea_type; typedef const subview_row_strans& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_row_strans& Q; @@ -2170,12 +2279,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -2186,30 +2295,27 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< subview_row_htrans > +struct Proxy< subview_row_htrans > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef subview_row_htrans stored_type; typedef const subview_row_htrans& ea_type; typedef const subview_row_htrans& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_row_htrans& Q; @@ -2220,12 +2326,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q[i]; } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q[i]; } arma_inline ea_type get_ea() const { return Q; } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -2236,30 +2342,27 @@ template arma_inline bool has_overlap(const subview& X) const { return is_alias(X.m); } - arma_inline bool is_aligned() const { return false; } + constexpr bool is_aligned() const { return false; } }; template -class Proxy< xtrans_mat > +struct Proxy< xtrans_mat > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const eT* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const Mat Q; @@ -2273,18 +2376,18 @@ arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row,col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r,c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -2292,24 +2395,21 @@ template -class Proxy< xvec_htrans > +struct Proxy< xvec_htrans > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const eT* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = false; - static const bool fake_mat = false; - - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = true; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = true; arma_aligned const Mat Q; @@ -2323,18 +2423,18 @@ arma_inline uword get_n_cols() const { return Q.n_cols; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row,col); } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword c) const { return Q.at(r,c); } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } template - arma_inline bool has_overlap(const subview&) const { return false; } + constexpr bool has_overlap(const subview&) const { return false; } arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); } }; @@ -2342,7 +2442,7 @@ template -class Proxy_vectorise_col_mat +struct Proxy_vectorise_col_mat { inline Proxy_vectorise_col_mat(const T1&) {} }; @@ -2350,24 +2450,21 @@ template -class Proxy_vectorise_col_mat< Op > +struct Proxy_vectorise_col_mat< Op > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Mat stored_type; typedef const elem_type* ea_type; typedef const Mat& aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = false; - static const bool has_subview = true; - static const bool fake_mat = true; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = false; + static constexpr bool has_subview = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const unwrap U; arma_aligned const Mat Q; @@ -2380,12 +2477,12 @@ } arma_inline uword get_n_rows() const { return Q.n_rows; } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return Q.n_elem; } - arma_inline elem_type operator[] (const uword i) const { return Q[i]; } - arma_inline elem_type at (const uword row, const uword) const { return Q[row]; } - arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword r, const uword) const { return Q[r]; } + arma_inline elem_type at_alt (const uword i) const { return Q.at_alt(i); } arma_inline ea_type get_ea() const { return Q.memptr(); } arma_inline aligned_ea_type get_aligned_ea() const { return Q; } @@ -2402,7 +2499,7 @@ template -class Proxy_vectorise_col_expr +struct Proxy_vectorise_col_expr { inline Proxy_vectorise_col_expr(const T1&) {} }; @@ -2410,24 +2507,21 @@ template -class Proxy_vectorise_col_expr< Op > +struct Proxy_vectorise_col_expr< Op > { - public: - typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; typedef Op stored_type; typedef typename Proxy::ea_type ea_type; typedef typename Proxy::aligned_ea_type aligned_ea_type; - static const bool use_at = false; - static const bool use_mp = Proxy::use_mp; - static const bool has_subview = Proxy::has_subview; - static const bool fake_mat = Proxy::fake_mat; - - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool use_at = false; + static constexpr bool use_mp = Proxy::use_mp; + static constexpr bool has_subview = Proxy::has_subview; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const Op& Q; arma_aligned const Proxy R; @@ -2440,12 +2534,12 @@ } arma_inline uword get_n_rows() const { return R.get_n_elem(); } - arma_inline uword get_n_cols() const { return 1; } + constexpr uword get_n_cols() const { return 1; } arma_inline uword get_n_elem() const { return R.get_n_elem(); } - arma_inline elem_type operator[] (const uword i) const { return R[i]; } - arma_inline elem_type at (const uword row, const uword) const { return R.at(row, 0); } - arma_inline elem_type at_alt (const uword i) const { return R.at_alt(i); } + arma_inline elem_type operator[] (const uword i) const { return R[i]; } + arma_inline elem_type at (const uword r, const uword) const { return R.at(r, 0); } + arma_inline elem_type at_alt (const uword i) const { return R.at_alt(i); } arma_inline ea_type get_ea() const { return R.get_ea(); } arma_inline aligned_ea_type get_aligned_ea() const { return R.get_aligned_ea(); } @@ -2473,11 +2567,9 @@ template -class Proxy< Op > +struct Proxy< Op > : public Proxy_vectorise_col_redirect< Op, (Proxy::use_at) >::result { - public: - typedef typename Proxy_vectorise_col_redirect< Op, (Proxy::use_at) >::result Proxy_vectorise_col; inline explicit Proxy(const Op& A) diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/restrictors.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/restrictors.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/restrictors.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/restrictors.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -32,14 +34,10 @@ template<> struct arma_scalar_only< s16 > { typedef s16 result; }; template<> struct arma_scalar_only< u32 > { typedef u32 result; }; template<> struct arma_scalar_only< s32 > { typedef s32 result; }; -#if defined(ARMA_USE_U64S64) template<> struct arma_scalar_only< u64 > { typedef u64 result; }; template<> struct arma_scalar_only< s64 > { typedef s64 result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct arma_scalar_only< ulng_t > { typedef ulng_t result; }; template<> struct arma_scalar_only< slng_t > { typedef slng_t result; }; -#endif template<> struct arma_scalar_only< float > { typedef float result; }; template<> struct arma_scalar_only< double > { typedef double result; }; template<> struct arma_scalar_only< cx_float > { typedef cx_float result; }; @@ -55,14 +53,10 @@ template<> struct arma_integral_only< s16 > { typedef s16 result; }; template<> struct arma_integral_only< u32 > { typedef u32 result; }; template<> struct arma_integral_only< s32 > { typedef s32 result; }; -#if defined(ARMA_USE_U64S64) template<> struct arma_integral_only< u64 > { typedef u64 result; }; template<> struct arma_integral_only< s64 > { typedef s64 result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct arma_integral_only< ulng_t > { typedef ulng_t result; }; template<> struct arma_integral_only< slng_t > { typedef slng_t result; }; -#endif @@ -71,12 +65,8 @@ template<> struct arma_unsigned_integral_only< u8 > { typedef u8 result; }; template<> struct arma_unsigned_integral_only< u16 > { typedef u16 result; }; template<> struct arma_unsigned_integral_only< u32 > { typedef u32 result; }; -#if defined(ARMA_USE_U64S64) template<> struct arma_unsigned_integral_only< u64 > { typedef u64 result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct arma_unsigned_integral_only< ulng_t > { typedef ulng_t result; }; -#endif @@ -85,12 +75,8 @@ template<> struct arma_signed_integral_only< s8 > { typedef s8 result; }; template<> struct arma_signed_integral_only< s16 > { typedef s16 result; }; template<> struct arma_signed_integral_only< s32 > { typedef s32 result; }; -#if defined(ARMA_USE_U64S64) template<> struct arma_signed_integral_only< s64 > { typedef s64 result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct arma_signed_integral_only< slng_t > { typedef slng_t result; }; -#endif @@ -99,12 +85,8 @@ template<> struct arma_signed_only< s8 > { typedef s8 result; }; template<> struct arma_signed_only< s16 > { typedef s16 result; }; template<> struct arma_signed_only< s32 > { typedef s32 result; }; -#if defined(ARMA_USE_U64S64) template<> struct arma_signed_only< s64 > { typedef s64 result; }; -#endif -#if defined(ARMA_ALLOW_LONG) template<> struct arma_signed_only< slng_t > { typedef slng_t result; }; -#endif template<> struct arma_signed_only< float > { typedef float result; }; template<> struct arma_signed_only< double > { typedef double result; }; template<> struct arma_signed_only< cx_float > { typedef cx_float result; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Row_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Row_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Row_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Row_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,20 +29,29 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_col = false; - static const bool is_row = true; - static const bool is_xvec = false; + static constexpr bool is_col = false; + static constexpr bool is_row = true; + static constexpr bool is_xvec = false; + + inline Row(); + inline Row(const Row& X); - inline Row(); - inline Row(const Row& X); inline explicit Row(const uword N); inline explicit Row(const uword in_rows, const uword in_cols); inline explicit Row(const SizeMat& s); + template inline explicit Row(const uword N, const arma_initmode_indicator&); + template inline explicit Row(const uword in_rows, const uword in_cols, const arma_initmode_indicator&); + template inline explicit Row(const SizeMat& s, const arma_initmode_indicator&); + template inline Row(const uword n_elem, const fill::fill_class& f); template inline Row(const uword in_rows, const uword in_cols, const fill::fill_class& f); template inline Row(const SizeMat& s, const fill::fill_class& f); + inline Row(const uword N, const fill::scalar_holder f); + inline Row(const uword in_rows, const uword in_cols, const fill::scalar_holder f); + inline Row(const SizeMat& s, const fill::scalar_holder f); + inline Row(const char* text); inline Row& operator=(const char* text); @@ -50,13 +61,11 @@ inline Row(const std::vector& x); inline Row& operator=(const std::vector& x); - #if defined(ARMA_USE_CXX11) inline Row(const std::initializer_list& list); inline Row& operator=(const std::initializer_list& list); inline Row(Row&& m); inline Row& operator=(Row&& m); - #endif inline Row& operator=(const eT val); inline Row& operator=(const Row& X); @@ -79,13 +88,13 @@ inline Row(const subview_cube& X); inline Row& operator=(const subview_cube& X); - inline mat_injector operator<<(const eT val); + arma_cold inline mat_injector operator<<(const eT val); - arma_inline const Op,op_htrans> t() const; - arma_inline const Op,op_htrans> ht() const; - arma_inline const Op,op_strans> st() const; + arma_inline arma_warn_unused const Op,op_htrans> t() const; + arma_inline arma_warn_unused const Op,op_htrans> ht() const; + arma_inline arma_warn_unused const Op,op_strans> st() const; - arma_inline const Op,op_strans> as_col() const; + arma_inline arma_warn_unused const Op,op_strans> as_col() const; arma_inline subview_row col(const uword col_num); arma_inline const subview_row col(const uword col_num) const; @@ -173,7 +182,7 @@ { private: - static const bool use_extra = (fixed_n_elem > arma_config::mat_prealloc); + static constexpr bool use_extra = (fixed_n_elem > arma_config::mat_prealloc); arma_align_mem eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ]; @@ -185,9 +194,9 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_col = false; - static const bool is_row = true; - static const bool is_xvec = false; + static constexpr bool is_col = false; + static constexpr bool is_row = true; + static constexpr bool is_xvec = false; static const uword n_rows; // value provided below the class definition static const uword n_cols; // value provided below the class definition @@ -197,6 +206,7 @@ arma_inline fixed(const fixed& X); inline fixed(const subview_cube& X); + inline fixed(const fill::scalar_holder f); template inline fixed(const fill::fill_class& f); template inline fixed(const Base& A); template inline fixed(const Base& A, const Base& B); @@ -215,10 +225,8 @@ using Row::operator(); - #if defined(ARMA_USE_CXX11) - inline fixed(const std::initializer_list& list); - inline Row& operator=(const std::initializer_list& list); - #endif + inline fixed(const std::initializer_list& list); + inline Row& operator=(const std::initializer_list& list); arma_inline Row& operator=(const fixed& X); @@ -227,9 +235,9 @@ template inline Row& operator=(const eGlue& X); #endif - arma_inline const Op< Row_fixed_type, op_htrans > t() const; - arma_inline const Op< Row_fixed_type, op_htrans > ht() const; - arma_inline const Op< Row_fixed_type, op_strans > st() const; + arma_inline arma_warn_unused const Op< Row_fixed_type, op_htrans > t() const; + arma_inline arma_warn_unused const Op< Row_fixed_type, op_htrans > ht() const; + arma_inline arma_warn_unused const Op< Row_fixed_type, op_strans > st() const; arma_inline arma_warn_unused const eT& at_alt (const uword i) const; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/Row_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/Row_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/Row_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/Row_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -48,6 +50,13 @@ : Mat(arma_vec_indicator(), 1, in_n_elem, 2) { arma_extra_debug_sigprint(); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Row::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + #endif } @@ -60,6 +69,13 @@ arma_extra_debug_sigprint(); Mat::init_warm(in_n_rows, in_n_cols); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Row::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + #endif } @@ -72,6 +88,71 @@ arma_extra_debug_sigprint(); Mat::init_warm(s.n_rows, s.n_cols); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Row::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + #endif + } + + + +//! internal use only +template +template +inline +Row::Row(const uword in_n_elem, const arma_initmode_indicator&) + : Mat(arma_vec_indicator(), 1, in_n_elem, 2) + { + arma_extra_debug_sigprint(); + + if(do_zeros) + { + arma_extra_debug_print("Row::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + } + + + +//! internal use only +template +template +inline +Row::Row(const uword in_n_rows, const uword in_n_cols, const arma_initmode_indicator&) + : Mat(arma_vec_indicator(), 0, 0, 2) + { + arma_extra_debug_sigprint(); + + Mat::init_warm(in_n_rows, in_n_cols); + + if(do_zeros) + { + arma_extra_debug_print("Row::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } + } + + + +//! internal use only +template +template +inline +Row::Row(const SizeMat& s, const arma_initmode_indicator&) + : Mat(arma_vec_indicator(), 0, 0, 2) + { + arma_extra_debug_sigprint(); + + Mat::init_warm(s.n_rows, s.n_cols); + + if(do_zeros) + { + arma_extra_debug_print("Row::constructor: zeroing memory"); + arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); + } } @@ -121,6 +202,46 @@ template inline +Row::Row(const uword in_n_elem, const fill::scalar_holder f) + : Mat(arma_vec_indicator(), 1, in_n_elem, 2) + { + arma_extra_debug_sigprint(); + + (*this).fill(f.scalar); + } + + + +template +inline +Row::Row(const uword in_n_rows, const uword in_n_cols, const fill::scalar_holder f) + : Mat(arma_vec_indicator(), 0, 0, 2) + { + arma_extra_debug_sigprint(); + + Mat::init_warm(in_n_rows, in_n_cols); + + (*this).fill(f.scalar); + } + + + +template +inline +Row::Row(const SizeMat& s, const fill::scalar_holder f) + : Mat(arma_vec_indicator(), 0, 0, 2) + { + arma_extra_debug_sigprint(); + + Mat::init_warm(s.n_rows, s.n_cols); + + (*this).fill(f.scalar); + } + + + +template +inline Row::Row(const char* text) : Mat(arma_vec_indicator(), 2) { @@ -221,102 +342,100 @@ -#if defined(ARMA_USE_CXX11) +template +inline +Row::Row(const std::initializer_list& list) + : Mat(arma_vec_indicator(), 2) + { + arma_extra_debug_sigprint(); - template - inline - Row::Row(const std::initializer_list& list) - : Mat(arma_vec_indicator(), 2) - { - arma_extra_debug_sigprint(); - - (*this).operator=(list); - } + (*this).operator=(list); + } + + + +template +inline +Row& +Row::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + Mat tmp(list); + arma_debug_check( ((tmp.n_elem > 0) && (tmp.is_vec() == false)), "Mat::init(): requested size is not compatible with row vector layout" ); - template - inline - Row& - Row::operator=(const std::initializer_list& list) - { - arma_extra_debug_sigprint(); - - Mat tmp(list); - - arma_debug_check( ((tmp.n_elem > 0) && (tmp.is_vec() == false)), "Mat::init(): requested size is not compatible with row vector layout" ); - - access::rw(tmp.n_rows) = 1; - access::rw(tmp.n_cols) = tmp.n_elem; - - (*this).steal_mem(tmp); - - return *this; - } + access::rw(tmp.n_rows) = 1; + access::rw(tmp.n_cols) = tmp.n_elem; + (*this).steal_mem(tmp); + return *this; + } + + + +template +inline +Row::Row(Row&& X) + : Mat(arma_vec_indicator(), 2) + { + arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - template - inline - Row::Row(Row&& X) - : Mat(arma_vec_indicator(), 2) + access::rw(Mat::n_rows) = 1; + access::rw(Mat::n_cols) = X.n_cols; + access::rw(Mat::n_elem) = X.n_elem; + access::rw(Mat::n_alloc) = X.n_alloc; + + if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) ) + { + access::rw(Mat::mem_state) = X.mem_state; + access::rw(Mat::mem) = X.mem; + + access::rw(X.n_rows) = 1; + 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) { - arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); + (*this).init_cold(); - access::rw(Mat::n_rows) = 1; - access::rw(Mat::n_cols) = X.n_cols; - access::rw(Mat::n_elem) = X.n_elem; + arrayops::copy( (*this).memptr(), X.mem, X.n_elem ); - if( ((X.mem_state == 0) && (X.n_elem > arma_config::mat_prealloc)) || (X.mem_state == 1) || (X.mem_state == 2) ) + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) { - access::rw(Mat::mem_state) = X.mem_state; - access::rw(Mat::mem) = X.mem; - - access::rw(X.n_rows) = 1; - access::rw(X.n_cols) = 0; - access::rw(X.n_elem) = 0; - access::rw(X.mem_state) = 0; - access::rw(X.mem) = 0; - } - else - { - (*this).init_cold(); - - arrayops::copy( (*this).memptr(), X.mem, X.n_elem ); - - if( (X.mem_state == 0) && (X.n_elem <= arma_config::mat_prealloc) ) - { - access::rw(X.n_rows) = 1; - access::rw(X.n_cols) = 0; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = 0; - } + access::rw(X.n_rows) = 1; + access::rw(X.n_cols) = 0; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; } } + } + + + +template +inline +Row& +Row::operator=(Row&& X) + { + arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); + (*this).steal_mem(X); - - template - inline - Row& - Row::operator=(Row&& X) + if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) && (this != &X) ) { - arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - - (*this).steal_mem(X); - - if( (X.mem_state == 0) && (X.n_elem <= arma_config::mat_prealloc) && (this != &X) ) - { - access::rw(X.n_rows) = 1; - access::rw(X.n_cols) = 0; - access::rw(X.n_elem) = 0; - access::rw(X.mem) = 0; - } - - return *this; + access::rw(X.n_rows) = 1; + access::rw(X.n_cols) = 0; + access::rw(X.n_elem) = 0; + access::rw(X.mem) = nullptr; } -#endif + return *this; + } @@ -506,6 +625,7 @@ template inline +arma_cold mat_injector< Row > Row::operator<<(const eT val) { @@ -516,6 +636,7 @@ template arma_inline +arma_warn_unused const Op,op_htrans> Row::t() const { @@ -526,6 +647,7 @@ template arma_inline +arma_warn_unused const Op,op_htrans> Row::ht() const { @@ -536,6 +658,7 @@ template arma_inline +arma_warn_unused const Op,op_strans> Row::st() const { @@ -546,6 +669,7 @@ template arma_inline +arma_warn_unused const Op,op_strans> Row::as_col() const { @@ -561,7 +685,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_col1 >= Mat::n_cols), "Row::col(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( (in_col1 >= Mat::n_cols), "Row::col(): indices out of bounds or incorrectly used" ); return subview_row(*this, 0, in_col1, 1); } @@ -575,7 +699,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (in_col1 >= Mat::n_cols), "Row::col(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( (in_col1 >= Mat::n_cols), "Row::col(): indices out of bounds or incorrectly used" ); return subview_row(*this, 0, in_col1, 1); } @@ -589,7 +713,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "Row::cols(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "Row::cols(): indices out of bounds or incorrectly used" ); const uword subview_n_cols = in_col2 - in_col1 + 1; @@ -605,7 +729,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "Row::cols(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "Row::cols(): indices out of bounds or incorrectly used" ); const uword subview_n_cols = in_col2 - in_col1 + 1; @@ -621,7 +745,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "Row::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "Row::subvec(): indices out of bounds or incorrectly used" ); const uword subview_n_cols = in_col2 - in_col1 + 1; @@ -637,7 +761,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "Row::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "Row::subvec(): indices out of bounds or incorrectly used" ); const uword subview_n_cols = in_col2 - in_col1 + 1; @@ -685,7 +809,7 @@ const uword in_col2 = col_span.b; const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used" ); return subview_row(*this, 0, in_col1, subvec_n_cols); } @@ -707,7 +831,7 @@ const uword in_col2 = col_span.b; const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used" ); return subview_row(*this, 0, in_col1, subvec_n_cols); } @@ -747,7 +871,7 @@ arma_debug_check( (s.n_rows != 1), "Row::subvec(): given size does not specify a row vector" ); - arma_debug_check( ( (start_col >= Mat::n_cols) || ((start_col + s.n_cols) > Mat::n_cols) ), "Row::subvec(): size out of bounds" ); + arma_debug_check_bounds( ( (start_col >= Mat::n_cols) || ((start_col + s.n_cols) > Mat::n_cols) ), "Row::subvec(): size out of bounds" ); return subview_row(*this, 0, start_col, s.n_cols); } @@ -763,7 +887,7 @@ arma_debug_check( (s.n_rows != 1), "Row::subvec(): given size does not specify a row vector" ); - arma_debug_check( ( (start_col >= Mat::n_cols) || ((start_col + s.n_cols) > Mat::n_cols) ), "Row::subvec(): size out of bounds" ); + arma_debug_check_bounds( ( (start_col >= Mat::n_cols) || ((start_col + s.n_cols) > Mat::n_cols) ), "Row::subvec(): size out of bounds" ); return subview_row(*this, 0, start_col, s.n_cols); } @@ -777,7 +901,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > Mat::n_cols), "Row::head(): size out of bounds"); + arma_debug_check_bounds( (N > Mat::n_cols), "Row::head(): size out of bounds" ); return subview_row(*this, 0, 0, N); } @@ -791,7 +915,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > Mat::n_cols), "Row::head(): size out of bounds"); + arma_debug_check_bounds( (N > Mat::n_cols), "Row::head(): size out of bounds" ); return subview_row(*this, 0, 0, N); } @@ -805,7 +929,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > Mat::n_cols), "Row::tail(): size out of bounds"); + arma_debug_check_bounds( (N > Mat::n_cols), "Row::tail(): size out of bounds" ); const uword start_col = Mat::n_cols - N; @@ -821,7 +945,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > Mat::n_cols), "Row::tail(): size out of bounds"); + arma_debug_check_bounds( (N > Mat::n_cols), "Row::tail(): size out of bounds" ); const uword start_col = Mat::n_cols - N; @@ -886,7 +1010,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= Mat::n_cols, "Row::shed_col(): index out of bounds"); + arma_debug_check_bounds( col_num >= Mat::n_cols, "Row::shed_col(): index out of bounds" ); shed_cols(col_num, col_num); } @@ -901,7 +1025,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols), "Row::shed_cols(): indices out of bounds or incorrectly used" @@ -910,7 +1034,7 @@ const uword n_keep_front = in_col1; const uword n_keep_back = Mat::n_cols - (in_col2 + 1); - Row X(n_keep_front + n_keep_back); + Row X(n_keep_front + n_keep_back, arma_nozeros_indicator()); eT* X_mem = X.memptr(); const eT* t_mem = (*this).memptr(); @@ -959,11 +1083,11 @@ const uword B_n_cols = t_n_cols - col_num; // insertion at col_num == n_cols is in effect an append operation - arma_debug_check( (col_num > t_n_cols), "Row::insert_cols(): index out of bounds"); + arma_debug_check_bounds( (col_num > t_n_cols), "Row::insert_cols(): index out of bounds" ); if(N > 0) { - Row out(t_n_cols + N); + Row out(t_n_cols + N, arma_nozeros_indicator()); eT* out_mem = out.memptr(); const eT* t_mem = (*this).memptr(); @@ -1055,7 +1179,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= Mat::n_rows), "Row::begin_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= Mat::n_rows), "Row::begin_row(): index out of bounds" ); return Mat::memptr(); } @@ -1069,7 +1193,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= Mat::n_rows), "Row::begin_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= Mat::n_rows), "Row::begin_row(): index out of bounds" ); return Mat::memptr(); } @@ -1083,7 +1207,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= Mat::n_rows), "Row::end_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= Mat::n_rows), "Row::end_row(): index out of bounds" ); return Mat::memptr() + Mat::n_cols; } @@ -1097,7 +1221,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= Mat::n_rows), "Row::end_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= Mat::n_rows), "Row::end_row(): index out of bounds" ); return Mat::memptr() + Mat::n_cols; } @@ -1111,6 +1235,16 @@ : Row( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat::mem_local) ) { arma_extra_debug_sigprint_this(this); + + #if (!defined(ARMA_DONT_ZERO_INIT)) + { + arma_extra_debug_print("Row::fixed::constructor: zeroing memory"); + + eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(Mat::mem_local[0]); + + arrayops::inplace_set_fixed( mem_use, eT(0) ); + } + #endif } @@ -1146,6 +1280,19 @@ template template +inline +Row::fixed::fixed(const fill::scalar_holder f) + : Row( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat::mem_local) ) + { + arma_extra_debug_sigprint_this(this); + + (*this).fill(f.scalar); + } + + + +template +template template inline Row::fixed::fixed(const fill::fill_class&) @@ -1153,11 +1300,11 @@ { arma_extra_debug_sigprint_this(this); - if(is_same_type::yes) (*this).zeros(); - if(is_same_type::yes) (*this).ones(); - if(is_same_type::yes) (*this).eye(); - if(is_same_type::yes) (*this).randu(); - if(is_same_type::yes) (*this).randn(); + if(is_same_type::yes) { (*this).zeros(); } + if(is_same_type::yes) { (*this).ones(); } + if(is_same_type::yes) { (*this).eye(); } + if(is_same_type::yes) { (*this).randu(); } + if(is_same_type::yes) { (*this).randn(); } } @@ -1302,43 +1449,39 @@ -#if defined(ARMA_USE_CXX11) +template +template +inline +Row::fixed::fixed(const std::initializer_list& list) + : Row( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat::mem_local) ) + { + arma_extra_debug_sigprint_this(this); - template - template - inline - Row::fixed::fixed(const std::initializer_list& list) - : Row( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat::mem_local) ) - { - arma_extra_debug_sigprint_this(this); - - (*this).operator=(list); - } + (*this).operator=(list); + } + + + +template +template +inline +Row& +Row::fixed::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + const uword N = uword(list.size()); + arma_debug_check( (N > fixed_n_elem), "Row::fixed: initialiser list is too long" ); - template - template - inline - Row& - Row::fixed::operator=(const std::initializer_list& list) - { - arma_extra_debug_sigprint(); - - const uword N = uword(list.size()); - - arma_debug_check( (N > fixed_n_elem), "Row::fixed: initialiser list is too long" ); - - eT* this_mem = (*this).memptr(); - - arrayops::copy( this_mem, list.begin(), N ); - - for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); } - - return *this; - } + eT* this_mem = (*this).memptr(); -#endif + arrayops::copy( this_mem, list.begin(), N ); + + for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); } + + return *this; + } @@ -1442,6 +1585,7 @@ template template arma_inline +arma_warn_unused const Op< typename Row::template fixed::Row_fixed_type, op_htrans > Row::fixed::t() const { @@ -1453,6 +1597,7 @@ template template arma_inline +arma_warn_unused const Op< typename Row::template fixed::Row_fixed_type, op_htrans > Row::fixed::ht() const { @@ -1464,6 +1609,7 @@ template template arma_inline +arma_warn_unused const Op< typename Row::template fixed::Row_fixed_type, op_strans > Row::fixed::st() const { @@ -1549,7 +1695,7 @@ eT& Row::fixed::operator() (const uword ii) { - arma_debug_check( (ii >= fixed_n_elem), "Row::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= fixed_n_elem), "Row::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[ii] : Mat::mem_local[ii]; } @@ -1563,7 +1709,7 @@ const eT& Row::fixed::operator() (const uword ii) const { - arma_debug_check( (ii >= fixed_n_elem), "Row::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= fixed_n_elem), "Row::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[ii] : Mat::mem_local[ii]; } @@ -1601,7 +1747,7 @@ eT& Row::fixed::operator() (const uword in_row, const uword in_col) { - arma_debug_check( ((in_row > 0) || (in_col >= fixed_n_elem)), "Row::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row > 0) || (in_col >= fixed_n_elem)), "Row::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[in_col] : Mat::mem_local[in_col]; } @@ -1615,7 +1761,7 @@ const eT& Row::fixed::operator() (const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row > 0) || (in_col >= fixed_n_elem)), "Row::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row > 0) || (in_col >= fixed_n_elem)), "Row::operator(): index out of bounds" ); return (use_extra) ? mem_local_extra[in_col] : Mat::mem_local[in_col]; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/running_stat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/running_stat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -102,16 +104,16 @@ public: template - inline static void update_stats(running_stat& x, const eT sample, const typename arma_not_cx::result* junk = 0); + inline static void update_stats(running_stat& x, const eT sample, const typename arma_not_cx::result* junk = nullptr); template - inline static void update_stats(running_stat& x, const std::complex& sample, const typename arma_not_cx::result* junk = 0); + inline static void update_stats(running_stat& x, const std::complex& sample, const typename arma_not_cx::result* junk = nullptr); template - inline static void update_stats(running_stat& x, const typename eT::value_type sample, const typename arma_cx_only::result* junk = 0); + inline static void update_stats(running_stat& x, const typename eT::value_type sample, const typename arma_cx_only::result* junk = nullptr); template - inline static void update_stats(running_stat& x, const eT& sample, const typename arma_cx_only::result* junk = 0); + inline static void update_stats(running_stat& x, const eT& sample, const typename arma_cx_only::result* junk = nullptr); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/running_stat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/running_stat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -162,7 +164,7 @@ if( arma_isfinite(sample) == false ) { - arma_debug_warn("running_stat: sample ignored as it is non-finite" ); + arma_debug_warn_level(3, "running_stat: sample ignored as it is non-finite" ); return; } @@ -181,7 +183,7 @@ if( arma_isfinite(sample) == false ) { - arma_debug_warn("running_stat: sample ignored as it is non-finite" ); + arma_debug_warn_level(3, "running_stat: sample ignored as it is non-finite" ); return; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/running_stat_vec_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_vec_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/running_stat_vec_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_vec_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -119,7 +121,7 @@ ( running_stat_vec& x, const Mat::eT>& sample, - const typename arma_not_cx::eT>::result* junk = 0 + const typename arma_not_cx::eT>::result* junk = nullptr ); template @@ -128,7 +130,7 @@ ( running_stat_vec& x, const Mat::T > >& sample, - const typename arma_not_cx::eT>::result* junk = 0 + const typename arma_not_cx::eT>::result* junk = nullptr ); template @@ -137,7 +139,7 @@ ( running_stat_vec& x, const Mat< typename running_stat_vec::T >& sample, - const typename arma_cx_only::eT>::result* junk = 0 + const typename arma_cx_only::eT>::result* junk = nullptr ); template @@ -146,7 +148,7 @@ ( running_stat_vec& x, const Mat::eT>& sample, - const typename arma_cx_only::eT>::result* junk = 0 + const typename arma_cx_only::eT>::result* junk = nullptr ); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/running_stat_vec_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_vec_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/running_stat_vec_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_vec_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -99,7 +101,7 @@ if( sample.is_finite() == false ) { - arma_debug_warn("running_stat_vec: sample ignored as it has non-finite elements"); + arma_debug_warn_level(3, "running_stat_vec: sample ignored as it has non-finite elements"); return; } @@ -128,7 +130,7 @@ if( sample.is_finite() == false ) { - arma_debug_warn("running_stat_vec: sample ignored as it has non-finite elements"); + arma_debug_warn_level(3, "running_stat_vec: sample ignored as it has non-finite elements"); return; } @@ -427,7 +429,7 @@ } else { - arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector"); + arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample must be a vector" ); x.r_mean.set_size(sample.n_rows, sample.n_cols); @@ -588,7 +590,7 @@ } else { - arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector"); + arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample must be a vector" ); x.r_mean.set_size(sample.n_rows, sample.n_cols); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SizeCube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SizeCube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SizeCube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SizeCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SizeCube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SizeCube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SizeCube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SizeCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -51,7 +53,7 @@ if(dim == 1) { return n_cols; } if(dim == 2) { return n_slices; } - arma_debug_check(true, "size(): index out of bounds"); + arma_debug_check_bounds(true, "size(): index out of bounds"); return uword(1); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SizeMat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SizeMat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SizeMat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SizeMat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SizeMat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SizeMat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SizeMat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SizeMat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -48,7 +50,7 @@ if(dim == 0) { return n_rows; } if(dim == 1) { return n_cols; } - arma_debug_check(true, "size(): index out of bounds"); + arma_debug_check_bounds(true, "size(): index out of bounds"); return uword(1); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/span.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/span.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/span.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/span.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -70,8 +72,8 @@ } - // the "explicit" keyword is required here to prevent a C++11 compiler - // automatically converting {a,b} into an instance of span() when submatrices are specified + // the "explicit" keyword is required here to prevent automatic conversion of {a,b} + // into an instance of span() when submatrices are specified inline explicit span(const uword in_a, const uword in_b) diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/sp_auxlib_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/sp_auxlib_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/sp_auxlib_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/sp_auxlib_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,38 +27,55 @@ enum form_type { - form_none, form_lm, form_sm, form_lr, form_la, form_sr, form_li, form_si, form_sa + form_none, form_lm, form_sm, form_lr, form_la, form_sr, form_li, form_si, form_sa, form_sigma }; inline static form_type interpret_form_str(const char* form_str); // - // eigs_sym() + // eigs_sym() for real matrices template - inline static bool eigs_sym(Col& eigval, Mat& eigvec, const SpBase& X, const uword n_eigvals, const char* form_str, const eT default_tol); + inline static bool eigs_sym(Col& eigval, Mat& eigvec, const SpBase& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts); - template - inline static bool eigs_sym_newarp(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const char* form_str, const eT default_tol); + template + inline static bool eigs_sym(Col& eigval, Mat& eigvec, const SpBase& X, const uword n_eigvals, const eT sigma, const eigs_opts& opts); template - inline static bool eigs_sym_arpack(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const char* form_str, const eT default_tol); + inline static bool eigs_sym_newarp(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts); + + template + inline static bool eigs_sym_newarp(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const eT sigma, const eigs_opts& opts); + + template + inline static bool eigs_sym_arpack(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const form_type form_val, const eT sigma, const eigs_opts& opts); // - // eigs_gen() + // eigs_gen() for real matrices template - inline static bool eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase& X, const uword n_eigvals, const char* form_str, const T default_tol); + inline static bool eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts); - template - inline static bool eigs_gen_newarp(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat& X, const uword n_eigvals, const char* form_str, const T default_tol); + template + inline static bool eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase& X, const uword n_eigvals, const std::complex sigma, const eigs_opts& opts); template - inline static bool eigs_gen_arpack(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat& X, const uword n_eigvals, const char* form_str, const T default_tol); + inline static bool eigs_gen_newarp(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts); + + template + inline static bool eigs_gen_arpack(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat& X, const uword n_eigvals, const form_type form_val, const std::complex sigma, const eigs_opts& opts); + + // + // eigs_gen() for complex matrices + + template + inline static bool eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase< std::complex, T1>& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts); template - inline static bool eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase< std::complex, T1>& X, const uword n_eigvals, const char* form_str, const T default_tol); + inline static bool eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase< std::complex, T1>& X, const uword n_eigvals, const std::complex sigma, const eigs_opts& opts); + template + inline static bool eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat< std::complex >& X, const uword n_eigvals, const form_type form_val, const std::complex sigma, const eigs_opts& opts); // // spsolve() via SuperLU @@ -67,16 +86,40 @@ template inline static bool spsolve_refine(Mat& out, typename T1::pod_type& out_rcond, const SpBase& A, const Base& B, const superlu_opts& user_opts); + // // + // // rcond() via SuperLU + // + // template + // sinline static typename T1::pod_type rcond(const SpBase& A); + + // + // support functions + #if defined(ARMA_USE_SUPERLU) + + template + inline static typename get_pod_type::result norm1(superlu::SuperMatrix* A); + + template + inline static typename get_pod_type::result lu_rcond(superlu::SuperMatrix* L, superlu::SuperMatrix* U, typename get_pod_type::result norm_val); + inline static void set_superlu_opts(superlu::superlu_options_t& options, const superlu_opts& user_opts); template inline static bool copy_to_supermatrix(superlu::SuperMatrix& out, const SpMat& A); template + inline static bool copy_to_supermatrix_with_shift(superlu::SuperMatrix& out, const SpMat& A, const eT shift); + + // // for debugging only + // template + // inline static void copy_to_spmat(SpMat& out, const superlu::SuperMatrix& A); + + template inline static bool wrap_to_supermatrix(superlu::SuperMatrix& out, const Mat& A); inline static void destroy_supermatrix(superlu::SuperMatrix& out); + #endif @@ -88,10 +131,23 @@ // functions are very different and we can't combine their code template - inline static void run_aupd + inline static void run_aupd_plain + ( + const uword n_eigvals, char* which, + const SpMat& X, const bool sym, + blas_int& n, eT& tol, blas_int& maxiter, + podarray& resid, blas_int& ncv, podarray& v, blas_int& ldv, + podarray& iparam, podarray& ipntr, + podarray& workd, podarray& workl, blas_int& lworkl, podarray& rwork, + blas_int& info + ); + + template + inline static void run_aupd_shiftinvert ( - const uword n_eigvals, char* which, const SpMat& X, const bool sym, - blas_int& n, eT& tol, + const uword n_eigvals, const T sigma, + const SpMat& X, const bool sym, + blas_int& n, eT& tol, blas_int& maxiter, podarray& resid, blas_int& ncv, podarray& v, blas_int& ldv, podarray& iparam, podarray& ipntr, podarray& workd, podarray& workl, blas_int& lworkl, podarray& rwork, @@ -105,3 +161,72 @@ template inline static bool rudimentary_sym_check(const SpMat< std::complex >& X); }; + + + +#if defined(ARMA_USE_SUPERLU) + +class superlu_supermatrix_wrangler + { + private: + + bool used = false; + + arma_aligned superlu::SuperMatrix m; + + public: + + inline ~superlu_supermatrix_wrangler(); + inline superlu_supermatrix_wrangler(); + + inline superlu_supermatrix_wrangler(const superlu_supermatrix_wrangler&) = delete; + inline void operator= (const superlu_supermatrix_wrangler&) = delete; + + inline superlu::SuperMatrix& get_ref(); + inline superlu::SuperMatrix* get_ptr(); + }; + + +class superlu_stat_wrangler + { + private: + + arma_aligned superlu::SuperLUStat_t stat; + + public: + + inline ~superlu_stat_wrangler(); + inline superlu_stat_wrangler(); + + inline superlu_stat_wrangler(const superlu_stat_wrangler&) = delete; + inline void operator= (const superlu_stat_wrangler&) = delete; + + inline superlu::SuperLUStat_t* get_ptr(); + }; + + +template +class superlu_array_wrangler + { + private: + + arma_aligned eT* mem = nullptr; + + public: + + inline ~superlu_array_wrangler(); + inline superlu_array_wrangler(const uword n_elem); + + inline superlu_array_wrangler() = delete; + inline superlu_array_wrangler(const superlu_array_wrangler&) = delete; + inline void operator= (const superlu_array_wrangler&) = delete; + + inline eT* get_ptr(); + }; + +#endif + + + +//! @} + diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/sp_auxlib_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/sp_auxlib_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/sp_auxlib_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/sp_auxlib_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -25,7 +27,7 @@ arma_extra_debug_sigprint(); // the order of the 3 if statements below is important - if( form_str == NULL ) { return form_none; } + if( form_str == nullptr ) { return form_none; } if( form_str[0] == char(0) ) { return form_none; } if( form_str[1] == char(0) ) { return form_none; } @@ -57,33 +59,40 @@ template inline bool -sp_auxlib::eigs_sym(Col& eigval, Mat& eigvec, const SpBase& X, const uword n_eigvals, const char* form_str, const eT default_tol) +sp_auxlib::eigs_sym(Col& eigval, Mat& eigvec, const SpBase& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts) { arma_extra_debug_sigprint(); const unwrap_spmat U(X.get_ref()); + arma_debug_check( (U.M.is_square() == false), "eigs_sym(): given matrix must be square sized" ); + if((arma_config::debug) && (sp_auxlib::rudimentary_sym_check(U.M) == false)) { - if(is_cx::no ) { arma_debug_warn("eigs_sym(): given matrix is not symmetric"); } - if(is_cx::yes) { arma_debug_warn("eigs_sym(): given matrix is not hermitian"); } + if(is_cx::no ) { arma_debug_warn_level(1, "eigs_sym(): given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, "eigs_sym(): given matrix is not hermitian"); } } + // TODO: investigate optional redirection of "sm" to ARPACK as it's capable of shift-invert; + // TODO: in shift-invert mode, "sm" maps to "lm" of the shift-inverted matrix (with sigma = 0) + #if defined(ARMA_USE_NEWARP) { - return sp_auxlib::eigs_sym_newarp(eigval, eigvec, U.M, n_eigvals, form_str, default_tol); + return sp_auxlib::eigs_sym_newarp(eigval, eigvec, U.M, n_eigvals, form_val, opts); } #elif defined(ARMA_USE_ARPACK) { - return sp_auxlib::eigs_sym_arpack(eigval, eigvec, U.M, n_eigvals, form_str, default_tol); + constexpr eT sigma = eT(0); + + return sp_auxlib::eigs_sym_arpack(eigval, eigvec, U.M, n_eigvals, form_val, sigma, opts); } #else { arma_ignore(eigval); arma_ignore(eigvec); arma_ignore(n_eigvals); - arma_ignore(form_str); - arma_ignore(default_tol); + arma_ignore(form_val); + arma_ignore(opts); arma_stop_logic_error("eigs_sym(): use of NEWARP or ARPACK must be enabled"); return false; @@ -93,22 +102,64 @@ +//! immediate eigendecomposition of symmetric real sparse object +template +inline +bool +sp_auxlib::eigs_sym(Col& eigval, Mat& eigvec, const SpBase& X, const uword n_eigvals, const eT sigma, const eigs_opts& opts) + { + arma_extra_debug_sigprint(); + + const unwrap_spmat U(X.get_ref()); + + arma_debug_check( (U.M.is_square() == false), "eigs_sym(): given matrix must be square sized" ); + + if((arma_config::debug) && (sp_auxlib::rudimentary_sym_check(U.M) == false)) + { + if(is_cx::no ) { arma_debug_warn_level(1, "eigs_sym(): given matrix is not symmetric"); } + if(is_cx::yes) { arma_debug_warn_level(1, "eigs_sym(): given matrix is not hermitian"); } + } + + #if (defined(ARMA_USE_NEWARP) && defined(ARMA_USE_SUPERLU)) + { + return sp_auxlib::eigs_sym_newarp(eigval, eigvec, U.M, n_eigvals, sigma, opts); + } + #elif (defined(ARMA_USE_ARPACK) && defined(ARMA_USE_SUPERLU)) + { + constexpr form_type form_val = form_sigma; + + return sp_auxlib::eigs_sym_arpack(eigval, eigvec, U.M, n_eigvals, form_val, sigma, opts); + } + #else + { + arma_ignore(eigval); + arma_ignore(eigvec); + arma_ignore(n_eigvals); + arma_ignore(sigma); + arma_ignore(opts); + + arma_stop_logic_error("eigs_sym(): use of NEWARP or ARPACK as well as SuperLU must be enabled to use 'sigma'"); + return false; + } + #endif + } + + + template inline bool -sp_auxlib::eigs_sym_newarp(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const char* form_str, const eT default_tol) +sp_auxlib::eigs_sym_newarp(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_NEWARP) { - const form_type form_val = sp_auxlib::interpret_form_str(form_str); - arma_debug_check( (form_val != form_lm) && (form_val != form_sm) && (form_val != form_la) && (form_val != form_sa), "eigs_sym(): unknown form specified" ); - const newarp::SparseGenMatProd op(X); + if(X.is_square() == false) { return false; } - arma_debug_check( (op.n_rows != op.n_cols), "eigs_sym(): given matrix must be square sized" ); + const newarp::SparseGenMatProd op(X); arma_debug_check( (n_eigvals >= op.n_rows), "eigs_sym(): n_eigvals must be less than the number of rows in the matrix" ); @@ -121,12 +172,39 @@ } uword n = op.n_rows; - uword ncv = n_eigvals + 2 + 1; - if(ncv < (2 * n_eigvals + 1)) { ncv = 2 * n_eigvals + 1; } - if(ncv > n) { ncv = n; } + // Use max(2*k+1, 20) as default subspace dimension for the sym case; MATLAB uses max(2*k, 20), but we need to be backward-compatible. + uword ncv_default = uword( ((2*n_eigvals+1)>(20)) ? (2*n_eigvals+1) : (20) ); + + // Use opts.subdim only if it's within the limits, otherwise cap it. + uword ncv = ncv_default; + + if(opts.subdim != 0) + { + if(opts.subdim < (n_eigvals + 1)) + { + arma_debug_warn_level(1, "eigs_sym(): opts.subdim must be greater than k; using k+1 instead of ", opts.subdim); + ncv = uword(n_eigvals + 1); + } + else + if(opts.subdim > n) + { + arma_debug_warn_level(1, "eigs_sym(): opts.subdim cannot be greater than n_rows; using n_rows instead of ", opts.subdim); + ncv = n; + } + else + { + ncv = uword(opts.subdim); + } + } + + // Re-check that we are within the limits + if(ncv < (n_eigvals + 1)) { ncv = (n_eigvals + 1); } + if(ncv > n ) { ncv = n; } - eT tol = (std::max)(default_tol, std::numeric_limits::epsilon()); + eT tol = (std::max)(eT(opts.tol), std::numeric_limits::epsilon()); + + uword maxiter = uword(opts.maxiter); // eigval.set_size(n_eigvals); // eigvec.set_size(n, n_eigvals); @@ -141,7 +219,7 @@ { newarp::SymEigsSolver< eT, newarp::EigsSelect::LARGEST_MAGN, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -150,7 +228,7 @@ { newarp::SymEigsSolver< eT, newarp::EigsSelect::SMALLEST_MAGN, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -159,7 +237,7 @@ { newarp::SymEigsSolver< eT, newarp::EigsSelect::LARGEST_ALGE, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -168,7 +246,7 @@ { newarp::SymEigsSolver< eT, newarp::EigsSelect::SMALLEST_ALGE, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -191,8 +269,8 @@ arma_ignore(eigvec); arma_ignore(X); arma_ignore(n_eigvals); - arma_ignore(form_str); - arma_ignore(default_tol); + arma_ignore(form_val); + arma_ignore(opts); return false; } @@ -204,34 +282,135 @@ template inline bool -sp_auxlib::eigs_sym_arpack(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const char* form_str, const eT default_tol) +sp_auxlib::eigs_sym_newarp(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const eT sigma, const eigs_opts& opts) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_NEWARP) + { + if(X.is_square() == false) { return false; } + + const newarp::SparseGenRealShiftSolve op(X, sigma); + + if(op.valid == false) { return false; } + + arma_debug_check( (n_eigvals >= op.n_rows), "eigs_sym(): n_eigvals must be less than the number of rows in the matrix" ); + + // If the matrix is empty, the case is trivial. + if( (op.n_cols == 0) || (n_eigvals == 0) ) // We already know n_cols == n_rows. + { + eigval.reset(); + eigvec.reset(); + return true; + } + + uword n = op.n_rows; + + // Use max(2*k+1, 20) as default subspace dimension for the sym case; MATLAB uses max(2*k, 20), but we need to be backward-compatible. + uword ncv_default = uword( ((2*n_eigvals+1)>(20)) ? (2*n_eigvals+1) : (20) ); + + // Use opts.subdim only if it's within the limits, otherwise cap it. + uword ncv = ncv_default; + + if(opts.subdim != 0) + { + if(opts.subdim < (n_eigvals + 1)) + { + arma_debug_warn_level(1, "eigs_sym(): opts.subdim must be greater than k; using k+1 instead of ", opts.subdim); + ncv = uword(n_eigvals + 1); + } + else + if(opts.subdim > n) + { + arma_debug_warn_level(1, "eigs_sym(): opts.subdim cannot be greater than n_rows; using n_rows instead of ", opts.subdim); + ncv = n; + } + else + { + ncv = uword(opts.subdim); + } + } + + // Re-check that we are within the limits + if(ncv < (n_eigvals + 1)) { ncv = (n_eigvals + 1); } + if(ncv > n ) { ncv = n; } + + eT tol = (std::max)(eT(opts.tol), std::numeric_limits::epsilon()); + + uword maxiter = uword(opts.maxiter); + + // eigval.set_size(n_eigvals); + // eigvec.set_size(n, n_eigvals); + + bool status = true; + + uword nconv = 0; + + try + { + newarp::SymEigsShiftSolver< eT, newarp::EigsSelect::LARGEST_MAGN, newarp::SparseGenRealShiftSolve > eigs(op, n_eigvals, ncv, sigma); + eigs.init(); + nconv = eigs.compute(maxiter, tol); + eigval = eigs.eigenvalues(); + eigvec = eigs.eigenvectors(); + } + catch(const std::runtime_error&) + { + status = false; + } + + if(status == true) + { + if(nconv == 0) { status = false; } + } + + return status; + } + #else + { + arma_ignore(eigval); + arma_ignore(eigvec); + arma_ignore(X); + arma_ignore(n_eigvals); + arma_ignore(sigma); + arma_ignore(opts); + + return false; + } + #endif + } + + + +template +inline +bool +sp_auxlib::eigs_sym_arpack(Col& eigval, Mat& eigvec, const SpMat& X, const uword n_eigvals, const form_type form_val, const eT sigma, const eigs_opts& opts) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_ARPACK) { - const form_type form_val = sp_auxlib::interpret_form_str(form_str); + arma_debug_check( (form_val != form_lm) && (form_val != form_sm) && (form_val != form_la) && (form_val != form_sa) && (form_val != form_sigma), "eigs_sym(): unknown form specified" ); - arma_debug_check( (form_val != form_lm) && (form_val != form_sm) && (form_val != form_la) && (form_val != form_sa), "eigs_sym(): unknown form specified" ); + if(X.is_square() == false) { return false; } char which_sm[3] = "SM"; char which_lm[3] = "LM"; char which_sa[3] = "SA"; char which_la[3] = "LA"; char* which; - switch (form_val) + + switch(form_val) { case form_sm: which = which_sm; break; case form_lm: which = which_lm; break; case form_sa: which = which_sa; break; case form_la: which = which_la; break; - + default: which = which_lm; break; } - // Make sure it's square. - arma_debug_check( (X.n_rows != X.n_cols), "eigs_sym(): given matrix must be square sized" ); - // Make sure we aren't asking for every eigenvalue. // The _saupd() functions allow asking for one more eigenvalue than the _naupd() functions. arma_debug_check( (n_eigvals >= X.n_rows), "eigs_sym(): n_eigvals must be less than the number of rows in the matrix" ); @@ -245,22 +424,57 @@ } // Set up variables that get used for neupd(). - blas_int n, ncv, ldv, lworkl, info; - eT tol = default_tol; + blas_int n, ncv, ncv_default, ldv, lworkl, info, maxiter; + + eT tol = eT(opts.tol); + maxiter = blas_int(opts.maxiter); + podarray resid, v, workd, workl; podarray iparam, ipntr; podarray rwork; // Not used in this case. - run_aupd(n_eigvals, which, X, true /* sym, not gen */, n, tol, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); + n = blas_int(X.n_rows); // The size of the matrix. + + // Use max(2*k+1, 20) as default subspace dimension for the sym case; MATLAB uses max(2*k, 20), but we need to be backward-compatible. + ncv_default = blas_int( ((2*n_eigvals+1)>(20)) ? (2*n_eigvals+1) : (20) ); - if(info != 0) + // Use opts.subdim only if it's within the limits + ncv = ncv_default; + + if(opts.subdim != 0) { - return false; + if(opts.subdim < (n_eigvals + 1)) + { + arma_debug_warn_level(1, "eigs_sym(): opts.subdim must be greater than k; using k+1 instead of ", opts.subdim); + ncv = blas_int(n_eigvals + 1); + } + else + if(blas_int(opts.subdim) > n) + { + arma_debug_warn_level(1, "eigs_sym(): opts.subdim cannot be greater than n_rows; using n_rows instead of ", opts.subdim); + ncv = n; + } + else + { + ncv = blas_int(opts.subdim); + } + } + + if(use_sigma) + //if(form_val == form_sigma) + { + run_aupd_shiftinvert(n_eigvals, sigma, X, true /* sym, not gen */, n, tol, maxiter, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); + } + else + { + run_aupd_plain(n_eigvals, which, X, true /* sym, not gen */, n, tol, maxiter, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); } + if(info != 0) { return false; } + // The process has converged, and now we need to recover the actual eigenvectors using seupd() blas_int rvec = 1; // .TRUE - blas_int nev = n_eigvals; + blas_int nev = blas_int(n_eigvals); char howmny = 'A'; char bmat = 'I'; // We are considering the standard eigenvalue problem. @@ -272,14 +486,10 @@ eigval.zeros(n_eigvals); eigvec.zeros(n, n_eigvals); - arpack::seupd(&rvec, &howmny, select.memptr(), eigval.memptr(), eigvec.memptr(), &ldz, (eT*) NULL, &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, &info); + arpack::seupd(&rvec, &howmny, select.memptr(), eigval.memptr(), eigvec.memptr(), &ldz, (eT*) &sigma, &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, &info); // Check for errors. - if(info != 0) - { - arma_debug_warn("eigs_sym(): ARPACK error ", info, " in seupd()"); - return false; - } + if(info != 0) { arma_debug_warn_level(1, "eigs_sym(): ARPACK error ", info, " in seupd()"); return false; } return (info == 0); } @@ -289,8 +499,9 @@ arma_ignore(eigvec); arma_ignore(X); arma_ignore(n_eigvals); - arma_ignore(form_str); - arma_ignore(default_tol); + arma_ignore(form_val); + arma_ignore(sigma); + arma_ignore(opts); return false; } @@ -303,30 +514,34 @@ template inline bool -sp_auxlib::eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase& X, const uword n_eigvals, const char* form_str, const T default_tol) +sp_auxlib::eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts) { arma_extra_debug_sigprint(); + const unwrap_spmat U(X.get_ref()); + + arma_debug_check( (U.M.is_square() == false), "eigs_gen(): given matrix must be square sized" ); + + // TODO: investigate optional redirection of "sm" to ARPACK as it's capable of shift-invert; + // TODO: in shift-invert mode, "sm" maps to "lm" of the shift-inverted matrix (with sigma = 0) + #if defined(ARMA_USE_NEWARP) { - const unwrap_spmat U(X.get_ref()); - - return sp_auxlib::eigs_gen_newarp(eigval, eigvec, U.M, n_eigvals, form_str, default_tol); + return sp_auxlib::eigs_gen_newarp(eigval, eigvec, U.M, n_eigvals, form_val, opts); } #elif defined(ARMA_USE_ARPACK) { - const unwrap_spmat U(X.get_ref()); - - return sp_auxlib::eigs_gen_arpack(eigval, eigvec, U.M, n_eigvals, form_str, default_tol); + constexpr std::complex sigma = T(0); + + return sp_auxlib::eigs_gen_arpack(eigval, eigvec, U.M, n_eigvals, form_val, sigma, opts); } #else { arma_ignore(eigval); arma_ignore(eigvec); - arma_ignore(X); arma_ignore(n_eigvals); - arma_ignore(form_str); - arma_ignore(default_tol); + arma_ignore(form_val); + arma_ignore(opts); arma_stop_logic_error("eigs_gen(): use of NEWARP or ARPACK must be enabled"); return false; @@ -336,23 +551,55 @@ +//! immediate eigendecomposition of non-symmetric real sparse object +template +inline +bool +sp_auxlib::eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase& X, const uword n_eigvals, const std::complex sigma, const eigs_opts& opts) + { + arma_extra_debug_sigprint(); + + const unwrap_spmat U(X.get_ref()); + + arma_debug_check( (U.M.is_square() == false), "eigs_gen(): given matrix must be square sized" ); + + #if (defined(ARMA_USE_ARPACK) && defined(ARMA_USE_SUPERLU)) + { + constexpr form_type form_val = form_sigma; + + return sp_auxlib::eigs_gen_arpack(eigval, eigvec, U.M, n_eigvals, form_val, sigma, opts); + } + #else + { + arma_ignore(eigval); + arma_ignore(eigvec); + arma_ignore(n_eigvals); + arma_ignore(sigma); + arma_ignore(opts); + + arma_stop_logic_error("eigs_gen(): use of ARPACK and SuperLU must be enabled to use 'sigma'"); + return false; + } + #endif + } + + + template inline bool -sp_auxlib::eigs_gen_newarp(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat& X, const uword n_eigvals, const char* form_str, const T default_tol) +sp_auxlib::eigs_gen_newarp(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat& X, const uword n_eigvals, const form_type form_val, const eigs_opts& opts) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_NEWARP) { - const form_type form_val = sp_auxlib::interpret_form_str(form_str); + arma_debug_check( (form_val != form_lm) && (form_val != form_sm) && (form_val != form_lr) && (form_val != form_sr) && (form_val != form_li) && (form_val != form_si), "eigs_gen(): unknown form specified" ); - arma_debug_check( (form_val == form_none), "eigs_gen(): unknown form specified" ); + if(X.is_square() == false) { return false; } const newarp::SparseGenMatProd op(X); - arma_debug_check( (op.n_rows != op.n_cols), "eigs_sym(): 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" ); // If the matrix is empty, the case is trivial. @@ -364,12 +611,39 @@ } uword n = op.n_rows; - uword ncv = n_eigvals + 2 + 1; - if(ncv < (2 * n_eigvals + 1)) { ncv = 2 * n_eigvals + 1; } - if(ncv > n) { ncv = n; } + // Use max(2*k+1, 20) as default subspace dimension for the gen case; same as MATLAB. + uword ncv_default = uword( ((2*n_eigvals+1)>(20)) ? (2*n_eigvals+1) : (20) ); + + // Use opts.subdim only if it's within the limits + uword ncv = ncv_default; - T tol = (std::max)(default_tol, std::numeric_limits::epsilon()); + if(opts.subdim != 0) + { + if(opts.subdim < (n_eigvals + 3)) + { + arma_debug_warn_level(1, "eigs_gen(): opts.subdim must be greater than k+2; using k+3 instead of ", opts.subdim); + ncv = uword(n_eigvals + 3); + } + else + if(opts.subdim > n) + { + arma_debug_warn_level(1, "eigs_gen(): opts.subdim cannot be greater than n_rows; using n_rows instead of ", opts.subdim); + ncv = n; + } + else + { + ncv = uword(opts.subdim); + } + } + + // Re-check that we are within the limits + if(ncv < (n_eigvals + 3)) { ncv = (n_eigvals + 3); } + if(ncv > n ) { ncv = n; } + + T tol = (std::max)(T(opts.tol), std::numeric_limits::epsilon()); + + uword maxiter = uword(opts.maxiter); // eigval.set_size(n_eigvals); // eigvec.set_size(n, n_eigvals); @@ -384,7 +658,7 @@ { newarp::GenEigsSolver< T, newarp::EigsSelect::LARGEST_MAGN, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -393,7 +667,7 @@ { newarp::GenEigsSolver< T, newarp::EigsSelect::SMALLEST_MAGN, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -402,7 +676,7 @@ { newarp::GenEigsSolver< T, newarp::EigsSelect::LARGEST_REAL, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -411,7 +685,7 @@ { newarp::GenEigsSolver< T, newarp::EigsSelect::SMALLEST_REAL, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -420,7 +694,7 @@ { newarp::GenEigsSolver< T, newarp::EigsSelect::LARGEST_IMAG, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -429,7 +703,7 @@ { newarp::GenEigsSolver< T, newarp::EigsSelect::SMALLEST_IMAG, newarp::SparseGenMatProd > eigs(op, n_eigvals, ncv); eigs.init(); - nconv = eigs.compute(1000, tol); + nconv = eigs.compute(maxiter, tol); eigval = eigs.eigenvalues(); eigvec = eigs.eigenvectors(); } @@ -452,8 +726,8 @@ arma_ignore(eigvec); arma_ignore(X); arma_ignore(n_eigvals); - arma_ignore(form_str); - arma_ignore(default_tol); + arma_ignore(form_val); + arma_ignore(opts); return false; } @@ -463,18 +737,18 @@ -template +template inline bool -sp_auxlib::eigs_gen_arpack(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat& X, const uword n_eigvals, const char* form_str, const T default_tol) +sp_auxlib::eigs_gen_arpack(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat& X, const uword n_eigvals, const form_type form_val, const std::complex sigma, const eigs_opts& opts) { arma_extra_debug_sigprint(); #if defined(ARMA_USE_ARPACK) { - const form_type form_val = sp_auxlib::interpret_form_str(form_str); + arma_debug_check( (form_val != form_lm) && (form_val != form_sm) && (form_val != form_lr) && (form_val != form_sr) && (form_val != form_li) && (form_val != form_si) && (form_val != form_sigma), "eigs_gen(): unknown form specified" ); - arma_debug_check( (form_val == form_none), "eigs_gen(): unknown form specified" ); + if(X.is_square() == false) { return false; } char which_lm[3] = "LM"; char which_sm[3] = "SM"; @@ -497,10 +771,6 @@ default: which = which_lm; } - - // Make sure it's square. - arma_debug_check( (X.n_rows != X.n_cols), "eigs_gen(): given matrix must be square sized" ); - // Make sure we aren't asking for every eigenvalue. arma_debug_check( (n_eigvals + 1 >= X.n_rows), "eigs_gen(): n_eigvals + 1 must be less than the number of rows in the matrix" ); @@ -513,63 +783,107 @@ } // Set up variables that get used for neupd(). - blas_int n, ncv, ldv, lworkl, info; - T tol = default_tol; + blas_int n, ncv, ncv_default, ldv, lworkl, info, maxiter; + + T tol = T(opts.tol); + maxiter = blas_int(opts.maxiter); + podarray resid, v, workd, workl; podarray iparam, ipntr; podarray rwork; // Not used in the real case. - run_aupd(n_eigvals, which, X, false /* gen, not sym */, n, tol, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); + n = blas_int(X.n_rows); // The size of the matrix. + + // Use max(2*k+1, 20) as default subspace dimension for the gen case; same as MATLAB. + ncv_default = blas_int( ((2*n_eigvals+1)>(20)) ? (2*n_eigvals+1) : (20) ); + + // Use opts.subdim only if it's within the limits + ncv = ncv_default; - if(info != 0) + if(opts.subdim != 0) { - return false; + if(opts.subdim < (n_eigvals + 3)) + { + arma_debug_warn_level(1, "eigs_gen(): opts.subdim must be greater than k+2; using k+3 instead of ", opts.subdim); + ncv = blas_int(n_eigvals + 3); + } + else + if(blas_int(opts.subdim) > n) + { + arma_debug_warn_level(1, "eigs_gen(): opts.subdim cannot be greater than n_rows; using n_rows instead of ", opts.subdim); + ncv = n; + } + else + { + ncv = blas_int(opts.subdim); + } + } + + // WARNING!!! + // We are still not able to apply truly complex shifts to real matrices, + // in which case the OP that ARPACK wants is different (see [s/d]naupd). + // Also, if sigma contains a non-zero imaginary part, retrieving the eigenvalues + // becomes utterly messy (see [s/d]eupd, remark #3). + // We should never get to the point in which the imaginary part of sigma is non-zero; + // the user-facing functions currently convert X from real to complex if a complex sigma is detected. + // The check here is just for extra safety, and as a reminder of what's missing. + T sigmar = real(sigma); + T sigmai = imag(sigma); + + if(use_sigma) + //if(form_val == form_sigma) + { + if(sigmai != T(0)) { arma_stop_logic_error("eigs_gen(): complex 'sigma' not applicable to real matrix"); return false; } + + run_aupd_shiftinvert(n_eigvals, sigmar, X, false /* gen, not sym */, n, tol, maxiter, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); + } + else + { + run_aupd_plain(n_eigvals, which, X, false /* gen, not sym */, n, tol, maxiter, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); } + + if(info != 0) { return false; } // The process has converged, and now we need to recover the actual eigenvectors using neupd(). blas_int rvec = 1; // .TRUE - blas_int nev = n_eigvals; + blas_int nev = blas_int(n_eigvals); char howmny = 'A'; char bmat = 'I'; // We are considering the standard eigenvalue problem. - podarray select(ncv); // Logical array of dimension NCV. - podarray dr(nev + 1); // Real array of dimension NEV + 1. - podarray di(nev + 1); // Real array of dimension NEV + 1. - podarray z(n * (nev + 1)); // Real N by NEV array if HOWMNY = 'A'. + podarray select(ncv); // logical array of dimension NCV + podarray dr(nev + 1); // real array of dimension NEV + 1 + podarray di(nev + 1); // real array of dimension NEV + 1 + podarray z(n * (nev + 1)); // real N by NEV array if HOWMNY = 'A' blas_int ldz = n; - podarray workev(3 * ncv); + podarray workev(3 * ncv); dr.zeros(); di.zeros(); z.zeros(); - arpack::neupd(&rvec, &howmny, select.memptr(), dr.memptr(), di.memptr(), z.memptr(), &ldz, (T*) NULL, (T*) NULL, workev.memptr(), &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info); + arpack::neupd(&rvec, &howmny, select.memptr(), dr.memptr(), di.memptr(), z.memptr(), &ldz, (T*) &sigmar, (T*) &sigmai, workev.memptr(), &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info); // Check for errors. - if(info != 0) - { - arma_debug_warn("eigs_gen(): ARPACK error ", info, " in neupd()"); - return false; - } + if(info != 0) { arma_debug_warn_level(1, "eigs_gen(): ARPACK error ", info, " in neupd()"); return false; } // Put it into the outputs. eigval.set_size(n_eigvals); eigvec.zeros(n, n_eigvals); - for (uword i = 0; i < n_eigvals; ++i) + for(uword i = 0; i < n_eigvals; ++i) { eigval[i] = std::complex(dr[i], di[i]); } // Now recover the eigenvectors. - for (uword i = 0; i < n_eigvals; ++i) + for(uword i = 0; i < n_eigvals; ++i) { // ARPACK ?neupd lays things out kinda odd in memory; // so does LAPACK ?geev -- see auxlib::eig_gen() if((i < n_eigvals - 1) && (eigval[i] == std::conj(eigval[i + 1]))) { - for (uword j = 0; j < uword(n); ++j) + for(uword j = 0; j < uword(n); ++j) { eigvec.at(j, i) = std::complex(z[n * i + j], z[n * (i + 1) + j]); eigvec.at(j, i + 1) = std::complex(z[n * i + j], -z[n * (i + 1) + j]); @@ -580,7 +894,7 @@ if((i == n_eigvals - 1) && (std::complex(eigval[i]).imag() != 0.0)) { // We don't have the matched conjugate eigenvalue. - for (uword j = 0; j < uword(n); ++j) + for(uword j = 0; j < uword(n); ++j) { eigvec.at(j, i) = std::complex(z[n * i + j], z[n * (i + 1) + j]); } @@ -588,7 +902,7 @@ else { // The eigenvector is entirely real. - for (uword j = 0; j < uword(n); ++j) + for(uword j = 0; j < uword(n); ++j) { eigvec.at(j, i) = std::complex(z[n * i + j], T(0)); } @@ -603,8 +917,9 @@ arma_ignore(eigvec); arma_ignore(X); arma_ignore(n_eigvals); - arma_ignore(form_str); - arma_ignore(default_tol); + arma_ignore(form_val); + arma_ignore(sigma); + arma_ignore(opts); return false; } @@ -617,19 +932,71 @@ template inline bool -sp_auxlib::eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase< std::complex, T1>& X_expr, const uword n_eigvals, const char* form_str, const T default_tol) +sp_auxlib::eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase< std::complex, T1>& X_expr, const uword n_eigvals, const form_type form_val, const eigs_opts& opts) { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_ARPACK) + const unwrap_spmat U(X_expr.get_ref()); + + arma_debug_check( (U.M.is_square() == false), "eigs_gen(): given matrix must be square sized" ); + + constexpr std::complex sigma = T(0); + + return sp_auxlib::eigs_gen(eigval, eigvec, U.M, n_eigvals, form_val, sigma, opts); + } + + + +//! immediate eigendecomposition of non-symmetric complex sparse object +template +inline +bool +sp_auxlib::eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpBase< std::complex, T1>& X, const uword n_eigvals, const std::complex sigma, const eigs_opts& opts) + { + arma_extra_debug_sigprint(); + + const unwrap_spmat U(X.get_ref()); + + arma_debug_check( (U.M.is_square() == false), "eigs_gen(): given matrix must be square sized" ); + + #if (defined(ARMA_USE_ARPACK) && defined(ARMA_USE_SUPERLU)) { - typedef typename std::complex eT; - - const form_type form_val = sp_auxlib::interpret_form_str(form_str); + constexpr form_type form_val = form_sigma; - arma_debug_check( (form_val == form_none), "eigs_gen(): unknown form specified" ); - - char which_lm[3] = "LM"; + return sp_auxlib::eigs_gen(eigval, eigvec, U.M, n_eigvals, form_val, sigma, opts); + } + #else + { + arma_ignore(eigval); + arma_ignore(eigvec); + arma_ignore(n_eigvals); + arma_ignore(sigma); + arma_ignore(opts); + + arma_stop_logic_error("eigs_gen(): use of ARPACK and SuperLU must be enabled to use 'sigma'"); + return false; + } + #endif + } + + + +template +inline +bool +sp_auxlib::eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigvec, const SpMat< std::complex >& X, const uword n_eigvals, const form_type form_val, const std::complex sigma, const eigs_opts& opts) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_ARPACK) + { + // typedef typename std::complex eT; + + arma_debug_check( (form_val != form_lm) && (form_val != form_sm) && (form_val != form_lr) && (form_val != form_sr) && (form_val != form_li) && (form_val != form_si) && (form_val != form_sigma), "eigs_gen(): unknown form specified" ); + + if(X.is_square() == false) { return false; } + + char which_lm[3] = "LM"; char which_sm[3] = "SM"; char which_lr[3] = "LR"; char which_sr[3] = "SR"; @@ -650,13 +1017,6 @@ default: which = which_lm; } - const unwrap_spmat U(X_expr.get_ref()); - - const SpMat& X = U.M; - - // Make sure it's square. - arma_debug_check( (X.n_rows != X.n_cols), "eigs_gen(): given matrix must be square sized" ); - // Make sure we aren't asking for every eigenvalue. arma_debug_check( (n_eigvals + 1 >= X.n_rows), "eigs_gen(): n_eigvals + 1 must be less than the number of rows in the matrix" ); @@ -669,46 +1029,76 @@ } // Set up variables that get used for neupd(). - blas_int n, ncv, ldv, lworkl, info; - T tol = default_tol; + blas_int n, ncv, ncv_default, ldv, lworkl, info, maxiter; + + T tol = T(opts.tol); + maxiter = blas_int(opts.maxiter); + podarray< std::complex > resid, v, workd, workl; podarray iparam, ipntr; podarray rwork; - run_aupd(n_eigvals, which, X, false /* gen, not sym */, n, tol, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); + n = blas_int(X.n_rows); // The size of the matrix. + + // Use max(2*k+1, 20) as default subspace dimension for the gen case; same as MATLAB. + ncv_default = blas_int( ((2*n_eigvals+1)>(20)) ? (2*n_eigvals+1) : (20) ); - if(info != 0) + // Use opts.subdim only if it's within the limits + ncv = ncv_default; + + if(opts.subdim != 0) { - return false; + if(opts.subdim < (n_eigvals + 3)) + { + arma_debug_warn_level(1, "eigs_gen(): opts.subdim must be greater than k+2; using k+3 instead of ", opts.subdim); + ncv = blas_int(n_eigvals + 3); + } + else + if(blas_int(opts.subdim) > n) + { + arma_debug_warn_level(1, "eigs_gen(): opts.subdim cannot be greater than n_rows; using n_rows instead of ", opts.subdim); + ncv = n; + } + else + { + ncv = blas_int(opts.subdim); + } } + if(use_sigma) + //if(form_val == form_sigma) + { + run_aupd_shiftinvert(n_eigvals, sigma, X, false /* gen, not sym */, n, tol, maxiter, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); + } + else + { + run_aupd_plain(n_eigvals, which, X, false /* gen, not sym */, n, tol, maxiter, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); + } + + if(info != 0) { return false; } + // The process has converged, and now we need to recover the actual eigenvectors using neupd(). blas_int rvec = 1; // .TRUE - blas_int nev = n_eigvals; + blas_int nev = blas_int(n_eigvals); char howmny = 'A'; char bmat = 'I'; // We are considering the standard eigenvalue problem. - podarray select(ncv); // Logical array of dimension NCV. - podarray > d(nev + 1); // Real array of dimension NEV + 1. - podarray > z(n * nev); // Real N by NEV array if HOWMNY = 'A'. + podarray select(ncv); // logical array of dimension NCV + podarray> d(nev + 1); // complex array of dimension NEV + 1 + podarray> z(n * nev); // complex N by NEV array if HOWMNY = 'A' blas_int ldz = n; - podarray > workev(2 * ncv); + podarray> workev(2 * ncv); // Prepare the outputs; neupd() will write directly to them. eigval.zeros(n_eigvals); eigvec.zeros(n, n_eigvals); - std::complex sigma; arpack::neupd(&rvec, &howmny, select.memptr(), eigval.memptr(), (std::complex*) NULL, eigvec.memptr(), &ldz, (std::complex*) &sigma, (std::complex*) NULL, workev.memptr(), &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info); // Check for errors. - if(info != 0) - { - arma_debug_warn("eigs_gen(): ARPACK error ", info, " in neupd()"); - return false; - } + if(info != 0) { arma_debug_warn_level(1, "eigs_gen(): ARPACK error ", info, " in neupd()"); return false; } return (info == 0); } @@ -716,11 +1106,12 @@ { arma_ignore(eigval); arma_ignore(eigvec); - arma_ignore(X_expr); + arma_ignore(X); arma_ignore(n_eigvals); - arma_ignore(form_str); - arma_ignore(default_tol); - + arma_ignore(form_val); + arma_ignore(sigma); + arma_ignore(opts); + arma_stop_logic_error("eigs_gen(): use of ARPACK must be enabled for decomposition of complex matrices"); return false; } @@ -754,7 +1145,8 @@ X.soft_reset(); return false; } - else if(A.n_rows < A.n_cols) + else + if(A.n_rows < A.n_cols) { arma_stop_logic_error("spsolve(): solving under-determined systems currently not supported"); X.soft_reset(); @@ -773,7 +1165,7 @@ if(arma_config::debug) { - bool overflow; + bool overflow = false; overflow = (A.n_nonzero > INT_MAX); overflow = (A.n_rows > INT_MAX) || overflow; @@ -788,41 +1180,28 @@ } } - superlu::SuperMatrix x; arrayops::inplace_set(reinterpret_cast(&x), char(0), sizeof(superlu::SuperMatrix)); - superlu::SuperMatrix a; arrayops::inplace_set(reinterpret_cast(&a), char(0), sizeof(superlu::SuperMatrix)); + superlu_supermatrix_wrangler x; + superlu_supermatrix_wrangler a; - const bool status_x = wrap_to_supermatrix(x, X); - const bool status_a = copy_to_supermatrix(a, A); + const bool status_x = wrap_to_supermatrix(x.get_ref(), X); + const bool status_a = copy_to_supermatrix(a.get_ref(), A); - if( (status_x == false) || (status_a == false) ) - { - destroy_supermatrix(a); - destroy_supermatrix(x); - X.soft_reset(); - return false; - } + if( (status_x == false) || (status_a == false) ) { X.soft_reset(); return false; } - superlu::SuperMatrix l; arrayops::inplace_set(reinterpret_cast(&l), char(0), sizeof(superlu::SuperMatrix)); - superlu::SuperMatrix u; arrayops::inplace_set(reinterpret_cast(&u), char(0), sizeof(superlu::SuperMatrix)); + superlu_supermatrix_wrangler l; + superlu_supermatrix_wrangler u; // paranoia: use SuperLU's memory allocation, in case it reallocs - int* perm_c = (int*) superlu::malloc( (A.n_cols+1) * sizeof(int)); // extra paranoia: increase array length by 1 - int* perm_r = (int*) superlu::malloc( (A.n_rows+1) * sizeof(int)); + superlu_array_wrangler perm_c(A.n_cols+1); // extra paranoia: increase array length by 1 + superlu_array_wrangler perm_r(A.n_rows+1); - arma_check_bad_alloc( (perm_c == 0), "spsolve(): out of memory" ); - arma_check_bad_alloc( (perm_r == 0), "spsolve(): out of memory" ); - - arrayops::inplace_set(perm_c, 0, A.n_cols+1); - arrayops::inplace_set(perm_r, 0, A.n_rows+1); - - superlu::SuperLUStat_t stat; - superlu::init_stat(&stat); + superlu_stat_wrangler stat; int info = 0; // Return code. arma_extra_debug_print("superlu::gssv()"); - superlu::gssv(&options, &a, perm_c, perm_r, &l, &u, &x, &stat, &info); + superlu::gssv(&options, a.get_ptr(), perm_c.get_ptr(), perm_r.get_ptr(), l.get_ptr(), u.get_ptr(), x.get_ptr(), stat.get_ptr(), &info); // Process the return code. @@ -830,29 +1209,20 @@ { // std::ostringstream tmp; // tmp << "spsolve(): could not solve system; LU factorisation completed, but detected zero in U(" << (info-1) << ',' << (info-1) << ')'; - // arma_debug_warn(tmp.str()); + // arma_debug_warn_level(1, tmp.str()); } else if(info > int(A.n_cols)) { - arma_debug_warn("spsolve(): memory allocation failure: could not allocate ", (info - int(A.n_cols)), " bytes"); + arma_debug_warn_level(1, "spsolve(): memory allocation failure: could not allocate ", (info - int(A.n_cols)), " bytes"); } else if(info < 0) { - arma_debug_warn("spsolve(): unknown SuperLU error code from gssv(): ", info); + arma_debug_warn_level(1, "spsolve(): unknown SuperLU error code from gssv(): ", info); } - - superlu::free_stat(&stat); - - superlu::free(perm_c); - superlu::free(perm_r); - - destroy_supermatrix(u); - destroy_supermatrix(l); - destroy_supermatrix(a); - destroy_supermatrix(x); // No need to extract the data from x, since it's using the same memory as X + // No need to extract the data from x, since it's using the same memory as X return (info == 0); } @@ -903,7 +1273,8 @@ X.soft_reset(); return false; } - else if(A.n_rows < A.n_cols) + else + if(A.n_rows < A.n_cols) { arma_stop_logic_error("spsolve(): solving under-determined systems currently not supported"); X.soft_reset(); @@ -940,54 +1311,29 @@ } } - superlu::SuperMatrix x; arrayops::inplace_set(reinterpret_cast(&x), char(0), sizeof(superlu::SuperMatrix)); - superlu::SuperMatrix a; arrayops::inplace_set(reinterpret_cast(&a), char(0), sizeof(superlu::SuperMatrix)); - superlu::SuperMatrix b; arrayops::inplace_set(reinterpret_cast(&b), char(0), sizeof(superlu::SuperMatrix)); - - const bool status_x = wrap_to_supermatrix(x, X); - const bool status_a = copy_to_supermatrix(a, A); // NOTE: superlu::gssvx() modifies 'a' if equilibration is enabled - const bool status_b = wrap_to_supermatrix(b, B); // NOTE: superlu::gssvx() modifies 'b' if equilibration is enabled - - if( (status_x == false) || (status_a == false) || (status_b == false) ) - { - destroy_supermatrix(x); - destroy_supermatrix(a); - destroy_supermatrix(b); - X.soft_reset(); - return false; - } + superlu_supermatrix_wrangler x; + superlu_supermatrix_wrangler a; + superlu_supermatrix_wrangler b; + + const bool status_x = wrap_to_supermatrix(x.get_ref(), X); + const bool status_a = copy_to_supermatrix(a.get_ref(), A); // NOTE: superlu::gssvx() modifies 'a' if equilibration is enabled + const bool status_b = wrap_to_supermatrix(b.get_ref(), B); // NOTE: superlu::gssvx() modifies 'b' if equilibration is enabled - superlu::SuperMatrix l; arrayops::inplace_set(reinterpret_cast(&l), char(0), sizeof(superlu::SuperMatrix)); - superlu::SuperMatrix u; arrayops::inplace_set(reinterpret_cast(&u), char(0), sizeof(superlu::SuperMatrix)); + if( (status_x == false) || (status_a == false) || (status_b == false) ) { X.soft_reset(); return false; } + + superlu_supermatrix_wrangler l; + superlu_supermatrix_wrangler u; // paranoia: use SuperLU's memory allocation, in case it reallocs - int* perm_c = (int*) superlu::malloc( (A.n_cols+1) * sizeof(int) ); // extra paranoia: increase array length by 1 - int* perm_r = (int*) superlu::malloc( (A.n_rows+1) * sizeof(int) ); - int* etree = (int*) superlu::malloc( (A.n_cols+1) * sizeof(int) ); - - T* R = (T*) superlu::malloc( (A.n_rows+1) * sizeof(T) ); - T* C = (T*) superlu::malloc( (A.n_cols+1) * sizeof(T) ); - T* ferr = (T*) superlu::malloc( (B.n_cols+1) * sizeof(T) ); - T* berr = (T*) superlu::malloc( (B.n_cols+1) * sizeof(T) ); - - arma_check_bad_alloc( (perm_c == 0), "spsolve(): out of memory" ); - arma_check_bad_alloc( (perm_r == 0), "spsolve(): out of memory" ); - arma_check_bad_alloc( (etree == 0), "spsolve(): out of memory" ); - - arma_check_bad_alloc( (R == 0), "spsolve(): out of memory" ); - arma_check_bad_alloc( (C == 0), "spsolve(): out of memory" ); - arma_check_bad_alloc( (ferr == 0), "spsolve(): out of memory" ); - arma_check_bad_alloc( (berr == 0), "spsolve(): out of memory" ); - - arrayops::inplace_set(perm_c, int(0), A.n_cols+1); - arrayops::inplace_set(perm_r, int(0), A.n_rows+1); - arrayops::inplace_set(etree, int(0), A.n_cols+1); - - arrayops::inplace_set(R, T(0), A.n_rows+1); - arrayops::inplace_set(C, T(0), A.n_cols+1); - arrayops::inplace_set(ferr, T(0), B.n_cols+1); - arrayops::inplace_set(berr, T(0), B.n_cols+1); + superlu_array_wrangler perm_c(A.n_cols+1); // extra paranoia: increase array length by 1 + superlu_array_wrangler perm_r(A.n_rows+1); + superlu_array_wrangler etree(A.n_cols+1); + + superlu_array_wrangler R(A.n_rows+1); + superlu_array_wrangler C(A.n_cols+1); + superlu_array_wrangler ferr(B.n_cols+1); + superlu_array_wrangler berr(B.n_cols+1); superlu::GlobalLU_t glu; arrayops::inplace_set(reinterpret_cast(&glu), char(0), sizeof(superlu::GlobalLU_t)); @@ -995,8 +1341,7 @@ superlu::mem_usage_t mu; arrayops::inplace_set(reinterpret_cast(&mu), char(0), sizeof(superlu::mem_usage_t)); - superlu::SuperLUStat_t stat; - superlu::init_stat(&stat); + superlu_stat_wrangler stat; char equed[8]; // extra characters for paranoia T rpg = T(0); @@ -1007,7 +1352,7 @@ int lwork = int(0); // 0 means superlu will allocate memory arma_extra_debug_print("superlu::gssvx()"); - superlu::gssvx(&options, &a, perm_c, perm_r, etree, equed, R, C, &l, &u, &work[0], lwork, &b, &x, &rpg, &rcond, ferr, berr, &glu, &mu, &stat, &info); + superlu::gssvx(&options, a.get_ptr(), perm_c.get_ptr(), perm_r.get_ptr(), etree.get_ptr(), equed, R.get_ptr(), C.get_ptr(), l.get_ptr(), u.get_ptr(), &work[0], lwork, b.get_ptr(), x.get_ptr(), &rpg, &rcond, ferr.get_ptr(), berr.get_ptr(), &glu, &mu, stat.get_ptr(), &info); bool status = false; @@ -1020,40 +1365,26 @@ { // std::ostringstream tmp; // tmp << "spsolve(): could not solve system; LU factorisation completed, but detected zero in U(" << (info-1) << ',' << (info-1) << ')'; - // arma_debug_warn(tmp.str()); + // arma_debug_warn_level(1, tmp.str()); } else if( (info == int(A.n_cols+1)) && (user_opts.allow_ugly) ) { - arma_debug_warn("spsolve(): system is singular to working precision (rcond: ", rcond, ")"); + arma_debug_warn_level(2, "spsolve(): system is singular to working precision (rcond: ", rcond, ")"); status = true; } else if(info > int(A.n_cols+1)) { - arma_debug_warn("spsolve(): memory allocation failure: could not allocate ", (info - int(A.n_cols)), " bytes"); + arma_debug_warn_level(1, "spsolve(): memory allocation failure: could not allocate ", (info - int(A.n_cols)), " bytes"); } else if(info < 0) { - arma_debug_warn("spsolve(): unknown SuperLU error code from gssvx(): ", info); + arma_debug_warn_level(1, "spsolve(): unknown SuperLU error code from gssvx(): ", info); } - superlu::free_stat(&stat); - - superlu::free(berr); - superlu::free(ferr); - superlu::free(C); - superlu::free(R); - superlu::free(etree); - superlu::free(perm_r); - superlu::free(perm_c); - - destroy_supermatrix(u); - destroy_supermatrix(l); - destroy_supermatrix(b); - destroy_supermatrix(a); - destroy_supermatrix(x); // No need to extract the data from x, since it's using the same memory as X + // No need to extract the data from x, since it's using the same memory as X out_rcond = rcond; @@ -1074,8 +1405,117 @@ +// template +// inline +// typename T1::pod_type +// sp_auxlib::rcond(const SpBase& A_expr) +// { +// arma_extra_debug_sigprint(); +// +// #if defined(ARMA_USE_SUPERLU) +// { +// typedef typename T1::pod_type T; +// typedef typename T1::elem_type eT; +// +// const unwrap_spmat tmp1(A_expr.get_ref()); +// const SpMat& A = tmp1.M; +// +// arma_debug_check( (A.is_square() == false), "rcond(): matrix must be square sized" ); +// +// superlu_opts superlu_opts_default; +// superlu::superlu_options_t options; +// sp_auxlib::set_superlu_opts(options, superlu_opts_default); +// int lwork = 0; +// +// superlu::GlobalLU_t Glu; +// arrayops::fill_zeros(reinterpret_cast(&Glu), sizeof(superlu::GlobalLU_t)); +// +// superlu_supermatrix_wrangler a; +// superlu_supermatrix_wrangler aC; +// +// const bool status_a = sp_auxlib::copy_to_supermatrix(a.get_ref(), A); +// +// if(status_a == false) { arma_stop_runtime_error("rcond(): could not construct SuperLU matrix"); return T(0); } +// +// superlu_supermatrix_wrangler l; +// superlu_supermatrix_wrangler u; +// +// superlu_array_wrangler perm_c(A.n_cols+1); // paranoia: increase array length by 1 +// superlu_array_wrangler perm_r(A.n_rows+1); +// superlu_array_wrangler etree(A.n_cols+1); +// +// superlu_stat_wrangler stat; +// +// int panel_size = superlu::sp_ispec_environ(1); +// int relax = superlu::sp_ispec_environ(2); +// int slu_info = 0; // Return code. +// +// arma_extra_debug_print("superlu::gstrf()"); +// superlu::get_permutation_c(options.ColPerm, a.get_ptr(), perm_c.get_ptr()); +// superlu::sp_preorder_mat(&options, a.get_ptr(), perm_c.get_ptr(), etree.get_ptr(), aC.get_ptr()); +// superlu::gstrf(&options, aC.get_ptr(), relax, panel_size, etree.get_ptr(), NULL, lwork, perm_c.get_ptr(), perm_r.get_ptr(), l.get_ptr(), u.get_ptr(), &Glu, stat.get_ptr(), &slu_info); +// +// if(slu_info != 0) { return T(0); } +// +// T a_norm_val = sp_auxlib::norm1(a.get_ptr()); +// T a_rcond = sp_auxlib::lu_rcond(l.get_ptr(), u.get_ptr(), a_norm_val); +// +// if(arma_isnan(a_rcond)) { return T(0); } +// +// return a_rcond; +// } +// #else +// { +// typename T1::pod_type T; +// +// arma_ignore(A_expr); +// arma_stop_logic_error("rcond(): use of SuperLU must be enabled"); +// +// return T(0); +// } +// #endif +// } + + + #if defined(ARMA_USE_SUPERLU) + template + inline + typename get_pod_type::result + sp_auxlib::norm1(superlu::SuperMatrix* A) + { + arma_extra_debug_sigprint(); + + char norm_id = '1'; + + return superlu::langs(&norm_id, A); + } + + + + template + inline + typename get_pod_type::result + sp_auxlib::lu_rcond(superlu::SuperMatrix* L, superlu::SuperMatrix* U, typename get_pod_type::result norm_val) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + char norm_id = '1'; + T rcond_out = T(0); + int info = int(0); + + superlu_stat_wrangler stat; + + superlu::gscon(&norm_id, L, U, norm_val, &rcond_out, stat.get_ptr(), &info); + + return (info == 0) ? T(rcond_out) : T(0); + } + + + inline void sp_auxlib::set_superlu_opts(superlu::superlu_options_t& options, const superlu_opts& user_opts) @@ -1122,55 +1562,42 @@ // We store in column-major CSC. out.Stype = superlu::SLU_NC; - if(is_float::value) - { - out.Dtype = superlu::SLU_S; - } - else - if(is_double::value) - { - out.Dtype = superlu::SLU_D; - } - else - if(is_cx_float::value) - { - out.Dtype = superlu::SLU_C; - } - else - if(is_cx_double::value) - { - out.Dtype = superlu::SLU_Z; - } + if( is_float::value) { out.Dtype = superlu::SLU_S; } + else if( is_double::value) { out.Dtype = superlu::SLU_D; } + else if( is_cx_float::value) { out.Dtype = superlu::SLU_C; } + else if(is_cx_double::value) { out.Dtype = superlu::SLU_Z; } out.Mtype = superlu::SLU_GE; // Just a general matrix. We don't know more now. // 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)); - if(nc == NULL) { return false; } + if(nc == nullptr) { return false; } + + A.sync(); nc->nnz = A.n_nonzero; nc->nzval = (void*) superlu::malloc(sizeof(eT) * A.n_nonzero ); nc->colptr = (superlu::int_t*)superlu::malloc(sizeof(superlu::int_t) * (A.n_cols + 1)); nc->rowind = (superlu::int_t*)superlu::malloc(sizeof(superlu::int_t) * A.n_nonzero ); - if( (nc->nzval == NULL) || (nc->colptr == NULL) || (nc->rowind == NULL) ) { return false; } + if( (nc->nzval == nullptr) || (nc->colptr == nullptr) || (nc->rowind == nullptr) ) { return false; } // Fill the matrix. arrayops::copy((eT*) nc->nzval, A.values, A.n_nonzero); // // These have to be copied by hand, because the types may differ. - // for (uword i = 0; i <= A.n_cols; ++i) { nc->colptr[i] = (int_t) A.col_ptrs[i]; } - // for (uword i = 0; i < A.n_nonzero; ++i) { nc->rowind[i] = (int_t) A.row_indices[i]; } + // for(uword i = 0; i <= A.n_cols; ++i) { nc->colptr[i] = (int_t) A.col_ptrs[i]; } + // for(uword i = 0; i < A.n_nonzero; ++i) { nc->rowind[i] = (int_t) A.row_indices[i]; } arrayops::convert(nc->colptr, A.col_ptrs, A.n_cols+1 ); arrayops::convert(nc->rowind, A.row_indices, A.n_nonzero); - out.nrow = A.n_rows; - out.ncol = A.n_cols; + out.nrow = superlu::int_t(A.n_rows); + out.ncol = superlu::int_t(A.n_cols); out.Store = (void*) nc; return true; @@ -1178,44 +1605,250 @@ + // memory efficient implementation of out = A - shift*I, where A is a square matrix template inline bool - sp_auxlib::wrap_to_supermatrix(superlu::SuperMatrix& out, const Mat& A) + sp_auxlib::copy_to_supermatrix_with_shift(superlu::SuperMatrix& out, const SpMat& A, const eT shift) { arma_extra_debug_sigprint(); - // NOTE: this function re-uses memory from matrix A - - // This is being stored as a dense matrix. - out.Stype = superlu::SLU_DN; + arma_debug_check( (A.is_square() == false), "sp_auxlib::copy_to_supermatrix_with_shift(): given matrix must be square sized" ); - if(is_float::value) + if(shift == eT(0)) { - out.Dtype = superlu::SLU_S; + arma_extra_debug_print("sp_auxlib::copy_to_supermatrix_with_shift(): shift is zero; redirecting to sp_auxlib::copy_to_supermatrix()"); + return sp_auxlib::copy_to_supermatrix(out, A); } - else - if(is_double::value) - { - out.Dtype = superlu::SLU_D; - } - else - if(is_cx_float::value) + + // We store in column-major CSC. + out.Stype = superlu::SLU_NC; + + if( is_float::value) { out.Dtype = superlu::SLU_S; } + else if( is_double::value) { out.Dtype = superlu::SLU_D; } + else if( is_cx_float::value) { out.Dtype = superlu::SLU_C; } + else if(is_cx_double::value) { out.Dtype = superlu::SLU_Z; } + + out.Mtype = superlu::SLU_GE; // Just a general matrix. We don't know more now. + + // We have to actually create the object which stores the data. + // This gets cleaned by destroy_supermatrix(). + superlu::NCformat* nc = (superlu::NCformat*)superlu::malloc(sizeof(superlu::NCformat)); + + if(nc == nullptr) { return false; } + + A.sync(); + + uword n_nonzero_diag_old = 0; + uword n_nonzero_diag_new = 0; + + const uword n_search_cols = (std::min)(A.n_rows, A.n_cols); + + for(uword j=0; j < n_search_cols; ++j) { - out.Dtype = superlu::SLU_C; + const uword col_offset = A.col_ptrs[j ]; + const uword next_col_offset = A.col_ptrs[j + 1]; + + const uword* start_ptr = &(A.row_indices[ col_offset]); + const uword* end_ptr = &(A.row_indices[next_col_offset]); + + const uword wanted_row = j; + + const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, wanted_row); // binary search + + if( (pos_ptr != end_ptr) && ((*pos_ptr) == wanted_row) ) + { + // element on the main diagonal is non-zero + ++n_nonzero_diag_old; + + const uword offset = uword(pos_ptr - start_ptr); + const uword index = offset + col_offset; + + const eT new_val = A.values[index] - shift; + + if(new_val != eT(0)) { ++n_nonzero_diag_new; } + } + else + { + // element on the main diagonal is zero, but sigma is non-zero, + // so the number of new non-zero elments on the diagonal is increased + ++n_nonzero_diag_new; + } } - else - if(is_cx_double::value) + + const uword out_n_nonzero = A.n_nonzero - n_nonzero_diag_old + n_nonzero_diag_new; + + arma_extra_debug_print( arma_str::format("A.n_nonzero: %d") % A.n_nonzero ); + arma_extra_debug_print( arma_str::format("n_nonzero_diag_old: %d") % n_nonzero_diag_old ); + arma_extra_debug_print( arma_str::format("n_nonzero_diag_new: %d") % n_nonzero_diag_new ); + arma_extra_debug_print( arma_str::format("out_n_nonzero: %d") % out_n_nonzero ); + + nc->nnz = out_n_nonzero; + nc->nzval = (void*) superlu::malloc(sizeof(eT) * out_n_nonzero ); + nc->colptr = (superlu::int_t*)superlu::malloc(sizeof(superlu::int_t) * (A.n_cols + 1)); + nc->rowind = (superlu::int_t*)superlu::malloc(sizeof(superlu::int_t) * out_n_nonzero ); + + if( (nc->nzval == nullptr) || (nc->colptr == nullptr) || (nc->rowind == nullptr) ) { return false; } + + // fill the matrix column by column, and insert diagonal elements when necessary + + nc->colptr[0] = 0; + + eT* values_current = (eT*) nc->nzval; + superlu::int_t* rowind_current = nc->rowind; + + uword count = 0; + + for(uword j=0; j < A.n_cols; ++j) { - out.Dtype = superlu::SLU_Z; + const uword idx_start = A.col_ptrs[j ]; + const uword idx_end = A.col_ptrs[j + 1]; + + const eT* values_start = values_current; + + uword i = idx_start; + + // elements in the upper triangular part, excluding the main diagonal + for(; (i < idx_end) && (A.row_indices[i] < j); ++i) + { + (*values_current) = A.values[i]; + (*rowind_current) = superlu::int_t(A.row_indices[i]); + + ++values_current; + ++rowind_current; + + ++count; + } + + // elements on the main diagonal + if( (i < idx_end) && (A.row_indices[i] == j) ) + { + // A(j,j) is non-zero + + const eT new_diag_val = A.values[i] - shift; + + if(new_diag_val != eT(0)) + { + (*values_current) = new_diag_val; + (*rowind_current) = superlu::int_t(j); + + ++values_current; + ++rowind_current; + + ++count; + } + + ++i; + } + else + { + // A(j,j) is zero, so insert a new element + + if(j < n_search_cols) + { + (*values_current) = -shift; + (*rowind_current) = superlu::int_t(j); + + ++values_current; + ++rowind_current; + + ++count; + } + } + + // elements in the lower triangular part, excluding the main diagonal + for(; i < idx_end; ++i) + { + (*values_current) = A.values[i]; + (*rowind_current) = superlu::int_t(A.row_indices[i]); + + ++values_current; + ++rowind_current; + + ++count; + } + + // number of non-zero elements in the j-th column of out + const uword nnz_col = values_current - values_start; + nc->colptr[j + 1] = superlu::int_t(nc->colptr[j] + nnz_col); } + arma_extra_debug_print( arma_str::format("count: %d") % count ); + + arma_check( (count != out_n_nonzero), "internal error: sp_auxlib::copy_to_supermatrix_with_shift(): count != out_n_nonzero" ); + + out.nrow = superlu::int_t(A.n_rows); + out.ncol = superlu::int_t(A.n_cols); + out.Store = (void*) nc; + + return true; + } + + + +// // for debugging only +// template +// inline +// void +// sp_auxlib::copy_to_spmat(SpMat& out, const superlu::SuperMatrix& A) +// { +// arma_extra_debug_sigprint(); +// +// bool type_matched = false; +// +// if( is_float::value) { type_matched = (A.Dtype == superlu::SLU_S); } +// else if( is_double::value) { type_matched = (A.Dtype == superlu::SLU_D); } +// else if( is_cx_float::value) { type_matched = (A.Dtype == superlu::SLU_C); } +// else if(is_cx_double::value) { type_matched = (A.Dtype == superlu::SLU_Z); } +// +// arma_debug_check( (type_matched == false), "copy_to_spmat(): type mismatch" ); +// arma_debug_check( (A.Mtype != superlu::SLU_GE), "copy_to_spmat(): unknown layout" ); +// +// const superlu::NCformat* nc = (const superlu::NCformat*)(A.Store); +// +// if(nc == nullptr) { out.reset(); return; } +// +// if( (nc->nzval == nullptr) || (nc->colptr == nullptr) || (nc->rowind == nullptr) ) { out.reset(); return; } +// +// const uword A_n_rows = uword(A.nrow ); +// const uword A_n_cols = uword(A.ncol ); +// const uword A_n_nonzero = uword(nc->nnz); +// +// if(A_n_nonzero == 0) { out.zeros(A_n_rows, A_n_cols); return; } +// +// out.reserve(A_n_rows, A_n_cols, A_n_nonzero); +// +// arrayops::copy(access::rwp(out.values), (const eT*)(nc->nzval), A_n_nonzero); +// +// arrayops::convert(access::rwp(out.col_ptrs), nc->colptr, A_n_cols+1 ); +// arrayops::convert(access::rwp(out.row_indices), nc->rowind, A_n_nonzero); +// } + + + + template + inline + bool + sp_auxlib::wrap_to_supermatrix(superlu::SuperMatrix& out, const Mat& A) + { + arma_extra_debug_sigprint(); + + // NOTE: this function re-uses memory from matrix A + + // This is being stored as a dense matrix. + out.Stype = superlu::SLU_DN; + + if( is_float::value) { out.Dtype = superlu::SLU_S; } + else if( is_double::value) { out.Dtype = superlu::SLU_D; } + else if( is_cx_float::value) { out.Dtype = superlu::SLU_C; } + else if(is_cx_double::value) { out.Dtype = superlu::SLU_Z; } + out.Mtype = superlu::SLU_GE; // We have to create the object that stores the data. superlu::DNformat* dn = (superlu::DNformat*)superlu::malloc(sizeof(superlu::DNformat)); - if(dn == NULL) { return false; } + if(dn == nullptr) { return false; } dn->lda = A.n_rows; dn->nzval = (void*) A.memptr(); // re-use memory instead of copying @@ -1241,6 +1874,11 @@ superlu::destroy_compcol_mat(&out); } else + if(out.Stype == superlu::SLU_NCP) + { + superlu::destroy_compcolperm_mat(&out); + } + else if(out.Stype == superlu::SLU_DN) { // superlu::destroy_dense_mat(&out); @@ -1251,7 +1889,7 @@ superlu::DNformat* dn = (superlu::DNformat*) out.Store; - if(dn != NULL) { superlu::free(dn); } + if(dn != nullptr) { superlu::free(dn); } } else if(out.Stype == superlu::SLU_SC) @@ -1277,8 +1915,8 @@ if(out.Stype == superlu::SLU_DN) { tmp << "SLU_DN"; } if(out.Stype == superlu::SLU_NR_loc) { tmp << "SLU_NR_loc"; } - arma_debug_warn(tmp.str()); - arma_stop_runtime_error("sp_auxlib::destroy_supermatrix(): internal error"); + arma_debug_warn_level(1, tmp.str()); + arma_stop_runtime_error("internal error: sp_auxlib::destroy_supermatrix()"); } } @@ -1289,10 +1927,11 @@ template inline void -sp_auxlib::run_aupd +sp_auxlib::run_aupd_plain ( - const uword n_eigvals, char* which, const SpMat& X, const bool sym, - blas_int& n, eT& tol, + const uword n_eigvals, char* which, + const SpMat& X, const bool sym, + blas_int& n, eT& tol, blas_int& maxiter, podarray& resid, blas_int& ncv, podarray& v, blas_int& ldv, podarray& iparam, podarray& ipntr, podarray& workd, podarray& workl, blas_int& lworkl, podarray& rwork, @@ -1307,24 +1946,24 @@ // return code what we need to do next (usually a matrix-vector product) and // then call it again. So this results in some type of iterative process // where we call saupd()/naupd() many times. + blas_int ido = 0; // This must be 0 for the first call. char bmat = 'I'; // We are considering the standard eigenvalue problem. - n = X.n_rows; // The size of the matrix. + n = X.n_rows; // The size of the matrix (should already be set outside). blas_int nev = n_eigvals; resid.set_size(n); - // Two contraints on NCV: (NCV > NEV + 2) and (NCV <= N) + // Two contraints on NCV: (NCV > NEV) for sym problems or + // (NCV > NEV + 2) for gen problems and (NCV <= N) // // We're calling either arpack::saupd() or arpack::naupd(), // which have slighly different minimum constraint and recommended value for NCV: // http://www.caam.rice.edu/software/ARPACK/UG/node136.html // http://www.caam.rice.edu/software/ARPACK/UG/node138.html - ncv = nev + 2 + 1; - - if (ncv < (2 * nev + 1)) { ncv = 2 * nev + 1; } - if (ncv > n ) { ncv = n; } + if(ncv < (nev + (sym ? 1 : 3))) { ncv = (nev + (sym ? 1 : 3)); } + if(ncv > n ) { ncv = n; } v.set_size(n * ncv); // Array N by NCV (output). rwork.set_size(ncv); // Work array of size NCV for complex calls. @@ -1333,7 +1972,7 @@ // IPARAM: integer array of length 11. iparam.zeros(11); iparam(0) = 1; // Exact shifts (not provided by us). - iparam(2) = 1000; // Maximum iterations; all the examples use 300, but they were written in the ancient times. + iparam(2) = maxiter; // Maximum iterations; all the examples use 300, but they were written in the ancient times. iparam(6) = 1; // Mode 1: A * x = lambda * x. // IPNTR: integer array of length 14 (output). @@ -1351,13 +1990,19 @@ info = 0; // Set to 0 initially to use random initial vector. // All the parameters have been set or created. Time to loop a lot. - while (ido != 99) + while(ido != 99) { // Call saupd() or naupd() with the current parameters. if(sym) + { + arma_extra_debug_print("arpack::saupd()"); arpack::saupd(&ido, &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, &info); + } else + { + arma_extra_debug_print("arpack::naupd()"); arpack::naupd(&ido, &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info); + } // What do we do now? switch (ido) @@ -1380,13 +2025,17 @@ Col in(workd.memptr() + ipntr(0) - 1, n, false /* don't copy */); out.zeros(); - typename SpMat::const_iterator x_it = X.begin(); - typename SpMat::const_iterator x_it_end = X.end(); - while(x_it != x_it_end) + typename SpMat::const_iterator X_it = X.begin(); + typename SpMat::const_iterator X_it_end = X.end(); + + while(X_it != X_it_end) { - out[x_it.row()] += (*x_it) * in[x_it.col()]; - ++x_it; + const uword X_it_row = X_it.row(); + const uword X_it_col = X_it.col(); + + out[X_it_row] += (*X_it) * in[X_it_col]; + ++X_it; } // No need to modify memory further since it was all done in-place. @@ -1410,23 +2059,25 @@ if(sym) { - arma_debug_warn("eigs_sym(): ARPACK error ", info, " in saupd()"); + arma_debug_warn_level(1, "eigs_sym(): ARPACK error ", info, " in saupd()"); } else { - arma_debug_warn("eigs_gen(): ARPACK error ", info, " in naupd()"); + arma_debug_warn_level(1, "eigs_gen(): ARPACK error ", info, " in naupd()"); } return; // Parent frame can look at the value of info. } } #else + { arma_ignore(n_eigvals); arma_ignore(which); arma_ignore(X); arma_ignore(sym); arma_ignore(n); arma_ignore(tol); + arma_ignore(maxiter); arma_ignore(resid); arma_ignore(ncv); arma_ignore(v); @@ -1438,6 +2089,262 @@ arma_ignore(lworkl); arma_ignore(rwork); arma_ignore(info); + } + #endif + } + + + +// Here 'sigma' is 'T', but should be 'eT'. +// Applying complex shifts to real matrices is currently not directly implemented +template +inline +void +sp_auxlib::run_aupd_shiftinvert + ( + const uword n_eigvals, const T sigma, + const SpMat& X, const bool sym, + blas_int& n, eT& tol, blas_int& maxiter, + podarray& resid, blas_int& ncv, podarray& v, blas_int& ldv, + podarray& iparam, podarray& ipntr, + podarray& workd, podarray& workl, blas_int& lworkl, podarray& rwork, + blas_int& info + ) + { + // TODO: inconsistent use of type names: T can be complex while eT can be real + + #if (defined(ARMA_USE_ARPACK) && defined(ARMA_USE_SUPERLU)) + { + char which_lm[3] = "LM"; + + char* which = which_lm; // NOTE: which_lm is the assumed operation when using shift-invert + + blas_int ido = 0; // This must be 0 for the first call. + char bmat = 'I'; // We are considering the standard eigenvalue problem. + n = X.n_rows; // The size of the matrix (should already be set outside). + blas_int nev = n_eigvals; + + resid.set_size(n); + + // Two contraints on NCV: (NCV > NEV) for sym problems or + // (NCV > NEV + 2) for gen problems and (NCV <= N) + // + // We're calling either arpack::saupd() or arpack::naupd(), + // which have slighly different minimum constraint and recommended value for NCV: + // http://www.caam.rice.edu/software/ARPACK/UG/node136.html + // http://www.caam.rice.edu/software/ARPACK/UG/node138.html + + if(ncv < (nev + (sym ? 1 : 3))) { ncv = (nev + (sym ? 1 : 3)); } + if(ncv > n ) { ncv = n; } + + v.set_size(n * ncv); // Array N by NCV (output). + rwork.set_size(ncv); // Work array of size NCV for complex calls. + ldv = n; // "Leading dimension of V exactly as declared in the calling program." + + // IPARAM: integer array of length 11. + iparam.zeros(11); + iparam(0) = 1; // Exact shifts (not provided by us). + iparam(2) = maxiter; // Maximum iterations; all the examples use 300, but they were written in the ancient times. + // iparam(6) = 1; // Mode 1: A * x = lambda * x. + + // Change IPARAM for shift-invert + iparam(6) = 3; // Mode 3: A * x = lambda * M * x, M symmetric semi-definite. OP = inv[A - sigma*M]*M (A complex) or Real_Part{ inv[A - sigma*M]*M } (A real) and B = M. + + // IPNTR: integer array of length 14 (output). + ipntr.set_size(14); + + // Real work array used in the basic Arnoldi iteration for reverse communication. + workd.set_size(3 * n); + + // lworkl must be at least 3 * NCV^2 + 6 * NCV. + lworkl = 3 * (ncv * ncv) + 6 * ncv; + + // Real work array of length lworkl. + workl.set_size(lworkl); + + info = 0; // Set to 0 initially to use random initial vector. + + superlu_opts superlu_opts_default; + superlu::superlu_options_t options; + sp_auxlib::set_superlu_opts(options, superlu_opts_default); + int lwork = 0; + superlu::trans_t trans = superlu::NOTRANS; + + superlu::GlobalLU_t Glu; /* Not needed on return. */ + arrayops::fill_zeros(reinterpret_cast(&Glu), sizeof(superlu::GlobalLU_t)); + + superlu_supermatrix_wrangler x; + superlu_supermatrix_wrangler xC; + + const bool status_x = sp_auxlib::copy_to_supermatrix_with_shift(x.get_ref(), X, sigma); + + if(status_x == false) + { + arma_stop_runtime_error("run_aupd_shiftinvert(): could not construct SuperLU matrix"); + info = blas_int(-1); + return; + } + + // // for debugging only + // if(true) + // { + // cout << "*** testing output of copy_to_supermatrix_with_shift()" << endl; + // cout << "*** sigma: " << sigma << endl; + // + // SpMat Y(X); + // Y.diag() -= sigma; + // + // SpMat Z; + // + // sp_auxlib::copy_to_spmat(Z, x.get_ref()); + // + // cout << "*** size(Y): " << arma::size(Y) << endl; + // cout << "*** size(Z): " << arma::size(Z) << endl; + // cout << "*** accu(abs(Y)): " << accu(abs(Y)) << endl; + // cout << "*** accu(abs(Z)): " << accu(abs(Z)) << endl; + // + // if(arma::size(Y) == arma::size(Z)) + // { + // cout << "*** error: " << accu(abs(Y-Z)) << endl; + // } + // } + + superlu_supermatrix_wrangler l; + superlu_supermatrix_wrangler u; + + superlu_array_wrangler perm_c(X.n_cols+1); // paranoia: increase array length by 1 + superlu_array_wrangler perm_r(X.n_rows+1); + superlu_array_wrangler etree(X.n_cols+1); + + superlu_stat_wrangler stat; + + int panel_size = superlu::sp_ispec_environ(1); + int relax = superlu::sp_ispec_environ(2); + int slu_info = 0; // Return code. + + arma_extra_debug_print("superlu::gstrf()"); + superlu::get_permutation_c(options.ColPerm, x.get_ptr(), perm_c.get_ptr()); + superlu::sp_preorder_mat(&options, x.get_ptr(), perm_c.get_ptr(), etree.get_ptr(), xC.get_ptr()); + superlu::gstrf(&options, xC.get_ptr(), relax, panel_size, etree.get_ptr(), NULL, lwork, perm_c.get_ptr(), perm_r.get_ptr(), l.get_ptr(), u.get_ptr(), &Glu, stat.get_ptr(), &slu_info); + + if(slu_info != 0) + { + arma_debug_warn_level(2, "matrix is singular to working precision"); + info = blas_int(-1); + return; + } + + eT x_norm_val = sp_auxlib::norm1(x.get_ptr()); + eT x_rcond = sp_auxlib::lu_rcond(l.get_ptr(), u.get_ptr(), x_norm_val); + + if( (x_rcond < std::numeric_limits::epsilon()) || arma_isnan(x_rcond) ) + { + arma_debug_warn_level(2, "matrix is singular to working precision (rcond: ", x_rcond, ")"); + info = blas_int(-1); + return; + } + + // All the parameters have been set or created. Time to loop a lot. + while(ido != 99) + { + // Call saupd() or naupd() with the current parameters. + if(sym) + { + arma_extra_debug_print("arpack::saupd()"); + arpack::saupd(&ido, &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, &info); + } + else + { + arma_extra_debug_print("arpack::naupd()"); + arpack::naupd(&ido, &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info); + } + + // What do we do now? + switch (ido) + { + case -1: + // fallthrough + case 1: + { + // We need to calculate the matrix-vector multiplication y = OP * x + // where x is of length n and starts at workd(ipntr(0)), and y is of + // length n and starts at workd(ipntr(1)). + + // operator*(sp_mat, vec) doesn't properly put the result into the + // right place so we'll just reimplement it here for now... + + // Set the output to point at the right memory. We have to subtract + // one from FORTRAN pointers... + Col out(workd.memptr() + ipntr(1) - 1, n, false /* don't copy */); + // Set the input to point at the right memory. + Col in(workd.memptr() + ipntr(0) - 1, n, false /* don't copy */); + + // Consider getting the LU factorization from ZGSTRF, and then + // solve the system L*U*out = in (possibly with permutation matrix?) + // Instead of "spsolve(out,X,in)" we call gstrf above and gstrs below + + out = in; + superlu_supermatrix_wrangler out_slu; + + const bool status_out_slu = sp_auxlib::wrap_to_supermatrix(out_slu.get_ref(), out); + + if(status_out_slu == false) { arma_stop_runtime_error("run_aupd_shiftinvert(): could not construct SuperLU matrix"); return; } + + arma_extra_debug_print("superlu::gstrs()"); + superlu::gstrs(trans, l.get_ptr(), u.get_ptr(), perm_c.get_ptr(), perm_r.get_ptr(), out_slu.get_ptr(), stat.get_ptr(), &info); + + // No need to modify memory further since it was all done in-place. + + break; + } + case 99: + // Nothing to do here, things have converged. + break; + default: + { + return; // Parent frame can look at the value of info. + } + } + } + + // The process has ended; check the return code. + if( (info != 0) && (info != 1) ) + { + // Print warnings if there was a failure. + + if(sym) + { + arma_debug_warn_level(2, "eigs_sym(): ARPACK error ", info, " in saupd()"); + } + else + { + arma_debug_warn_level(2, "eigs_gen(): ARPACK error ", info, " in naupd()"); + } + + return; // Parent frame can look at the value of info. + } + } + #else + { + arma_ignore(n_eigvals); + arma_ignore(sigma); + arma_ignore(X); + arma_ignore(sym); + arma_ignore(n); + arma_ignore(tol); + arma_ignore(maxiter); + arma_ignore(resid); + arma_ignore(ncv); + arma_ignore(v); + arma_ignore(ldv); + arma_ignore(iparam); + arma_ignore(ipntr); + arma_ignore(workd); + arma_ignore(workl); + arma_ignore(lworkl); + arma_ignore(rwork); + arma_ignore(info); + } #endif } @@ -1549,4 +2456,120 @@ +#if defined(ARMA_USE_SUPERLU) + +inline +superlu_supermatrix_wrangler::~superlu_supermatrix_wrangler() + { + arma_extra_debug_sigprint_this(this); + + if(used == false) { return; } + + char* m_char = reinterpret_cast(&m); + bool all_zero = true; + + for(size_t i=0; i < sizeof(superlu::SuperMatrix); ++i) + { + if(m_char[i] != char(0)) { all_zero = false; break; } + } + + if(all_zero == false) { sp_auxlib::destroy_supermatrix(m); } + } + +inline +superlu_supermatrix_wrangler::superlu_supermatrix_wrangler() + { + arma_extra_debug_sigprint_this(this); + + arrayops::fill_zeros(reinterpret_cast(&m), sizeof(superlu::SuperMatrix)); + } + +inline +superlu::SuperMatrix& +superlu_supermatrix_wrangler::get_ref() + { + used = true; + + return m; + } + +inline +superlu::SuperMatrix* +superlu_supermatrix_wrangler::get_ptr() + { + used = true; + + return &m; + } + + +// + + +inline +superlu_stat_wrangler::~superlu_stat_wrangler() + { + arma_extra_debug_sigprint_this(this); + + superlu::free_stat(&stat); + } + +inline +superlu_stat_wrangler::superlu_stat_wrangler() + { + arma_extra_debug_sigprint_this(this); + + arrayops::fill_zeros(reinterpret_cast(&stat), sizeof(superlu::SuperLUStat_t)); + + superlu::init_stat(&stat); + } + +inline +superlu::SuperLUStat_t* +superlu_stat_wrangler::get_ptr() + { + return &stat; + } + + +// + + +template +inline +superlu_array_wrangler::~superlu_array_wrangler() + { + arma_extra_debug_sigprint_this(this); + + if(mem != nullptr) + { + superlu::free(mem); + mem = nullptr; + } + } + +template +inline +superlu_array_wrangler::superlu_array_wrangler(const uword n_elem) + { + arma_extra_debug_sigprint_this(this); + + mem = (eT*)(superlu::malloc(n_elem * sizeof(eT))); + + arma_check_bad_alloc( (mem == nullptr), "superlu::malloc(): out of memory" ); + + arrayops::fill_zeros(mem, n_elem); + } + +template +inline +eT* +superlu_array_wrangler::get_ptr() + { + return mem; + } + +#endif + + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpBase_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpBase_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpBase_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpBase_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,14 +24,14 @@ template struct SpBase_eval_SpMat { - inline const derived& eval() const; + inline arma_warn_unused const derived& eval() const; }; template struct SpBase_eval_expr { - inline SpMat eval() const; //!< force the immediate evaluation of a delayed expression + inline arma_warn_unused SpMat eval() const; //!< force the immediate evaluation of a delayed expression }; @@ -52,9 +54,9 @@ arma_inline bool is_alias(const SpMat& X) const; - inline const SpOp t() const; //!< Hermitian transpose - inline const SpOp ht() const; //!< Hermitian transpose - inline const SpOp st() const; //!< simple transpose + inline arma_warn_unused const SpOp t() const; //!< Hermitian transpose + inline arma_warn_unused const SpOp ht() const; //!< Hermitian transpose + inline arma_warn_unused const SpOp st() const; //!< simple transpose arma_cold inline void print( const std::string extra_text = "") const; arma_cold inline void print(std::ostream& user_stream, const std::string extra_text = "") const; @@ -68,6 +70,9 @@ arma_cold inline void raw_print_dense( const std::string extra_text = "") const; arma_cold inline void raw_print_dense(std::ostream& user_stream, const std::string extra_text = "") const; + arma_cold inline void brief_print( const std::string extra_text = "") const; + arma_cold inline void brief_print(std::ostream& user_stream, const std::string extra_text = "") const; + inline arma_warn_unused elem_type min() const; inline arma_warn_unused elem_type max() const; @@ -86,6 +91,8 @@ inline arma_warn_unused bool is_hermitian() const; inline arma_warn_unused bool is_hermitian(const typename get_pod_type::result tol) const; + inline arma_warn_unused bool is_zero(const typename get_pod_type::result tol = 0) const; + inline arma_warn_unused bool is_trimatu() const; inline arma_warn_unused bool is_trimatl() const; inline arma_warn_unused bool is_diagmat() const; @@ -98,9 +105,8 @@ inline arma_warn_unused bool has_inf() const; inline arma_warn_unused bool has_nan() const; - inline const SpOp as_col() const; - inline const SpOp as_row() const; - + inline arma_warn_unused const SpOp as_col() const; + inline arma_warn_unused const SpOp as_row() const; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpBase_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpBase_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpBase_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpBase_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -41,6 +43,7 @@ template inline +arma_warn_unused const SpOp SpBase::t() const { @@ -50,6 +53,7 @@ template inline +arma_warn_unused const SpOp SpBase::ht() const { @@ -60,6 +64,7 @@ template inline +arma_warn_unused const SpOp SpBase::st() const { @@ -74,9 +79,20 @@ void SpBase::print(const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_spmat tmp( (*this).get_ref() ); - tmp.M.impl_print(extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::print(get_cout_stream(), tmp.M, true); } @@ -87,9 +103,20 @@ void SpBase::print(std::ostream& user_stream, const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_spmat tmp( (*this).get_ref() ); - tmp.M.impl_print(user_stream, extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::print(user_stream, tmp.M, true); } @@ -100,9 +127,20 @@ void SpBase::raw_print(const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_spmat tmp( (*this).get_ref() ); - tmp.M.impl_raw_print(extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::print(get_cout_stream(), tmp.M, false); } @@ -113,9 +151,20 @@ void SpBase::raw_print(std::ostream& user_stream, const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_spmat tmp( (*this).get_ref() ); - tmp.M.impl_raw_print(user_stream, extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::print(user_stream, tmp.M, false); } @@ -126,9 +175,20 @@ void SpBase::print_dense(const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_spmat tmp( (*this).get_ref() ); - tmp.M.impl_print_dense(extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::print_dense(get_cout_stream(), tmp.M, true); } @@ -139,9 +199,20 @@ void SpBase::print_dense(std::ostream& user_stream, const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_spmat tmp( (*this).get_ref() ); - tmp.M.impl_print_dense(user_stream, extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::print_dense(user_stream, tmp.M, true); } @@ -152,9 +223,20 @@ void SpBase::raw_print_dense(const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_spmat tmp( (*this).get_ref() ); - tmp.M.impl_raw_print_dense(extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::print_dense(get_cout_stream(), tmp.M, false); } @@ -165,18 +247,78 @@ void SpBase::raw_print_dense(std::ostream& user_stream, const std::string extra_text) const { + arma_extra_debug_sigprint(); + const unwrap_spmat tmp( (*this).get_ref() ); - tmp.M.impl_raw_print_dense(user_stream, extra_text); + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::print_dense(user_stream, tmp.M, false); + } + + + +template +arma_cold +inline +void +SpBase::brief_print(const std::string extra_text) const + { + arma_extra_debug_sigprint(); + + const unwrap_spmat tmp( (*this).get_ref() ); + + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + arma_ostream::brief_print(get_cout_stream(), tmp.M); } +template +arma_cold +inline +void +SpBase::brief_print(std::ostream& user_stream, const std::string extra_text) const + { + arma_extra_debug_sigprint(); + + const unwrap_spmat tmp( (*this).get_ref() ); + + if(extra_text.length() != 0) + { + const std::streamsize orig_width = user_stream.width(); + + user_stream << extra_text << '\n'; + + user_stream.width(orig_width); + } + + arma_ostream::brief_print(user_stream, tmp.M); + } + + + // // extra functions defined in SpBase_eval_SpMat template inline +arma_warn_unused const derived& SpBase_eval_SpMat::eval() const { @@ -192,6 +334,7 @@ template inline +arma_warn_unused SpMat SpBase_eval_expr::eval() const { @@ -402,6 +545,64 @@ inline arma_warn_unused bool +SpBase::is_zero(const typename get_pod_type::result tol) const + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + arma_debug_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" ); + + const SpProxy P( (*this).get_ref() ); + + if(P.get_n_elem() == 0) { return false; } + + if(P.get_n_nonzero() == 0) { return true; } + + if(is_SpMat::stored_type>::value) + { + const unwrap_spmat::stored_type> U(P.Q); + + return arrayops::is_zero(U.M.values, U.M.n_nonzero, tol); + } + + typename SpProxy::const_iterator_type it = P.begin(); + typename SpProxy::const_iterator_type it_end = P.end(); + + if(is_cx::yes) + { + while(it != it_end) + { + const elem_type val = (*it); + + 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; } + + ++it; + } + } + else // not complex + { + while(it != it_end) + { + if(eop_aux::arma_abs(*it) > tol) { return false; } + + ++it; + } + } + + return true; + } + + + +template +inline +arma_warn_unused +bool SpBase::is_trimatu() const { arma_extra_debug_sigprint(); @@ -656,6 +857,7 @@ template inline +arma_warn_unused const SpOp SpBase::as_col() const { @@ -666,6 +868,7 @@ template inline +arma_warn_unused const SpOp SpBase::as_row() const { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpCol_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpCol_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpCol_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpCol_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; inline SpCol(); @@ -54,6 +56,10 @@ template inline explicit SpCol(const SpBase& A, const SpBase& B); + inline arma_warn_unused const SpOp,spop_htrans> t() const; + inline arma_warn_unused const SpOp,spop_htrans> ht() const; + inline arma_warn_unused const SpOp,spop_strans> st() const; + inline void shed_row (const uword row_num); inline void shed_rows(const uword in_row1, const uword in_row2); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpCol_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpCol_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpCol_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpCol_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -200,6 +202,39 @@ +template +inline +arma_warn_unused +const SpOp,spop_htrans> +SpCol::t() const + { + return SpOp,spop_htrans>(*this); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_htrans> +SpCol::ht() const + { + return SpOp,spop_htrans>(*this); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_strans> +SpCol::st() const + { + return SpOp,spop_strans>(*this); + } + + + //! remove specified row template inline @@ -208,7 +243,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( row_num >= SpMat::n_rows, "SpCol::shed_row(): out of bounds"); + arma_debug_check_bounds( row_num >= SpMat::n_rows, "SpCol::shed_row(): out of bounds" ); shed_rows(row_num, row_num); } @@ -223,7 +258,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= SpMat::n_rows), "SpCol::shed_rows(): indices out of bounds or incorrectly used" @@ -239,14 +274,14 @@ for(uword i = 0; i < SpMat::n_nonzero; ++i) { // Start position found? - if (SpMat::row_indices[i] >= in_row1 && !start_found) + if(SpMat::row_indices[i] >= in_row1 && !start_found) { start = i; start_found = true; } // End position found? - if (SpMat::row_indices[i] > in_row2) + if(SpMat::row_indices[i] > in_row2) { end = i; end_found = true; @@ -254,13 +289,13 @@ } } - if (!end_found) + if(!end_found) { end = SpMat::n_nonzero; } // Now we can make the copy. - if (start != end) + if(start != end) { const uword elem_diff = end - start; @@ -268,14 +303,14 @@ uword* new_row_indices = memory::acquire(SpMat::n_nonzero - elem_diff); // Copy before the section we are dropping (if it exists). - if (start > 0) + if(start > 0) { arrayops::copy(new_values, SpMat::values, start); arrayops::copy(new_row_indices, SpMat::row_indices, start); } // Copy after the section we are dropping (if it exists). - if (end != SpMat::n_nonzero) + if(end != SpMat::n_nonzero) { arrayops::copy(new_values + start, SpMat::values + end, (SpMat::n_nonzero - end)); arrayops::copy(new_row_indices + start, SpMat::row_indices + end, (SpMat::n_nonzero - end)); @@ -311,11 +346,11 @@ // // arma_debug_check(set_to_zero == false, "SpCol::insert_rows(): cannot set nonzero values"); // -// arma_debug_check((row_num > SpMat::n_rows), "SpCol::insert_rows(): out of bounds"); +// arma_debug_check_bounds((row_num > SpMat::n_rows), "SpCol::insert_rows(): out of bounds"); // // for(uword row = 0; row < SpMat::n_rows; ++row) // { -// if (SpMat::row_indices[row] >= row_num) +// if(SpMat::row_indices[row] >= row_num) // { // access::rw(SpMat::row_indices[row]) += N; // } @@ -334,7 +369,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= SpMat::n_rows), "SpCol::begin_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= SpMat::n_rows), "SpCol::begin_row(): index out of bounds" ); SpMat::sync_csc(); @@ -350,7 +385,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= SpMat::n_rows), "SpCol::begin_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= SpMat::n_rows), "SpCol::begin_row(): index out of bounds" ); SpMat::sync_csc(); @@ -366,7 +401,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= SpMat::n_rows), "SpCol::end_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= SpMat::n_rows), "SpCol::end_row(): index out of bounds" ); SpMat::sync_csc(); @@ -382,7 +417,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (row_num >= SpMat::n_rows), "SpCol::end_row(): index out of bounds"); + arma_debug_check_bounds( (row_num >= SpMat::n_rows), "SpCol::end_row(): index out of bounds" ); SpMat::sync_csc(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spdiagview_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spdiagview_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spdiagview_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spdiagview_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,7 +22,7 @@ //! Class for storing data required to extract and set the diagonals of a sparse matrix template -class spdiagview : public SpBase > +class spdiagview : public SpBase< eT, spdiagview > { public: @@ -29,9 +31,9 @@ arma_aligned const SpMat& m; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; const uword row_offset; const uword col_offset; @@ -39,7 +41,7 @@ const uword n_rows; // equal to n_elem const uword n_elem; - static const uword n_cols = 1; + static constexpr uword n_cols = 1; protected: @@ -50,6 +52,7 @@ public: inline ~spdiagview(); + inline spdiagview() = delete; inline void operator=(const spdiagview& x); @@ -86,6 +89,12 @@ inline eT operator()(const uword in_n_row, const uword in_n_col) const; + inline void replace(const eT old_val, const eT new_val); + + inline void clean(const pod_type threshold); + + inline void clamp(const eT min_val, const eT max_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); @@ -97,10 +106,7 @@ inline static void extract( Mat& out, const spdiagview& in); - private: - friend class SpMat; - spdiagview(); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spdiagview_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spdiagview_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spdiagview_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spdiagview_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -186,6 +188,28 @@ const uword d_row_offset = d.row_offset; const uword d_col_offset = d.col_offset; + if(is_same_type< T1, Gen, gen_zeros> >::yes) + { + const Proxy P(o.get_ref()); + + arma_debug_check( (d_n_elem != P.get_n_elem()), "spdiagview: given object has incompatible size" ); + + (*this).zeros(); + + return; + } + + if(is_same_type< T1, Gen, gen_ones> >::yes) + { + const Proxy P(o.get_ref()); + + arma_debug_check( (d_n_elem != P.get_n_elem()), "spdiagview: given object has incompatible size" ); + + (*this).ones(); + + return; + } + const quasi_unwrap U(o.get_ref()); const Mat& x = U.M; @@ -216,6 +240,8 @@ if(has_zero) { tmp1.remove_zeros(); } + if(tmp1.n_nonzero == 0) { (*this).zeros(); return; } + SpMat tmp2; spglue_merge::diagview_merge(tmp2, d_m, tmp1); @@ -683,7 +709,7 @@ const uword d_row_offset = d.row_offset; const uword d_col_offset = d.col_offset; - Col cache(d_n_elem); + Col cache(d_n_elem, arma_nozeros_indicator()); eT* cache_mem = cache.memptr(); uword d_n_nonzero = 0; @@ -790,7 +816,7 @@ SpMat_MapMat_val spdiagview::operator()(const uword i) { - arma_debug_check( (i >= n_elem), "spdiagview::operator(): out of bounds" ); + arma_debug_check_bounds( (i >= n_elem), "spdiagview::operator(): out of bounds" ); return (const_cast< SpMat& >(m)).at(i+row_offset, i+col_offset); } @@ -802,7 +828,7 @@ eT spdiagview::operator()(const uword i) const { - arma_debug_check( (i >= n_elem), "spdiagview::operator(): out of bounds" ); + arma_debug_check_bounds( (i >= n_elem), "spdiagview::operator(): out of bounds" ); return m.at(i+row_offset, i+col_offset); } @@ -834,7 +860,7 @@ SpMat_MapMat_val spdiagview::operator()(const uword row, const uword col) { - arma_debug_check( ((row >= n_elem) || (col > 0)), "spdiagview::operator(): out of bounds" ); + arma_debug_check_bounds( ((row >= n_elem) || (col > 0)), "spdiagview::operator(): out of bounds" ); return (const_cast< SpMat& >(m)).at(row+row_offset, row+col_offset); } @@ -846,7 +872,7 @@ eT spdiagview::operator()(const uword row, const uword col) const { - arma_debug_check( ((row >= n_elem) || (col > 0)), "spdiagview::operator(): out of bounds" ); + arma_debug_check_bounds( ((row >= n_elem) || (col > 0)), "spdiagview::operator(): out of bounds" ); return m.at(row+row_offset, row+col_offset); } @@ -856,11 +882,66 @@ template inline void +spdiagview::replace(const eT old_val, const eT new_val) + { + arma_extra_debug_sigprint(); + + if(old_val == eT(0)) + { + arma_debug_warn_level(1, "spdiagview::replace(): replacement not done, as old_val = 0"); + } + else + { + Mat tmp(*this); + + tmp.replace(old_val, new_val); + + (*this).operator=(tmp); + } + } + + + +template +inline +void +spdiagview::clean(const typename get_pod_type::result threshold) + { + arma_extra_debug_sigprint(); + + Mat tmp(*this); + + tmp.clean(threshold); + + (*this).operator=(tmp); + } + + + +template +inline +void +spdiagview::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + SpMat tmp(*this); + + tmp.clamp(min_val, max_val); + + (*this).operator=(tmp); + } + + + +template +inline +void spdiagview::fill(const eT val) { arma_extra_debug_sigprint(); - if( (row_offset == 0) && (col_offset == 0) ) + if( (row_offset == 0) && (col_offset == 0) && (m.sync_state != 1) ) { if(val == eT(0)) { diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpGlue_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpGlue_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpGlue_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpGlue_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,16 +22,16 @@ template -class SpGlue : public SpBase > +class SpGlue : public SpBase< typename T1::elem_type, SpGlue > { public: typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = spglue_type::template traits::is_row; - static const bool is_col = spglue_type::template traits::is_col; - static const bool is_xvec = spglue_type::template traits::is_xvec; + static constexpr bool is_row = spglue_type::template traits::is_row; + static constexpr bool is_col = spglue_type::template traits::is_col; + static constexpr bool is_xvec = spglue_type::template traits::is_xvec; 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); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_elem_helper_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_elem_helper_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_elem_helper_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_elem_helper_bones.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2008-2016 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -//! \addtogroup spglue_elem_helper -//! @{ - - - -class spglue_elem_helper - : public traits_glue_default - { - public: - - template - arma_hot inline static uword max_n_nonzero_plus(const SpProxy& pa, const SpProxy& pb); - - template - arma_hot inline static uword max_n_nonzero_schur(const SpProxy& pa, const SpProxy& pb); - }; - - - -//! @} - diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_elem_helper_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_elem_helper_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_elem_helper_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_elem_helper_meat.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2008-2016 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -//! \addtogroup spglue_elem_helper -//! @{ - - - -template -arma_hot -inline -uword -spglue_elem_helper::max_n_nonzero_plus(const SpProxy& pa, const SpProxy& pb) - { - arma_extra_debug_sigprint(); - - // assuming that pa and pb have the same size, ie. - // pa.get_n_rows() == pb.get_n_rows() - // pa.get_n_cols() == pb.get_n_cols() - - typename SpProxy::const_iterator_type x_it = pa.begin(); - typename SpProxy::const_iterator_type x_end = pa.end(); - - typename SpProxy::const_iterator_type y_it = pb.begin(); - typename SpProxy::const_iterator_type y_end = pb.end(); - - uword count = 0; - - while( (x_it != x_end) || (y_it != y_end) ) - { - if(x_it == y_it) - { - ++x_it; - ++y_it; - } - else - { - const uword x_it_col = x_it.col(); - const uword x_it_row = x_it.row(); - - const uword y_it_col = y_it.col(); - const uword y_it_row = y_it.row(); - - 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 - { - ++x_it; - } - else - { - ++y_it; - } - } - - ++count; - } - - return count; - } - - - -template -arma_hot -inline -uword -spglue_elem_helper::max_n_nonzero_schur(const SpProxy& pa, const SpProxy& pb) - { - arma_extra_debug_sigprint(); - - // assuming that pa and pb have the same size, ie. - // pa.get_n_rows() == pb.get_n_rows() - // pa.get_n_cols() == pb.get_n_cols() - - typename SpProxy::const_iterator_type x_it = pa.begin(); - typename SpProxy::const_iterator_type x_end = pa.end(); - - typename SpProxy::const_iterator_type y_it = pb.begin(); - typename SpProxy::const_iterator_type y_end = pb.end(); - - uword count = 0; - - while( (x_it != x_end) || (y_it != y_end) ) - { - if(x_it == y_it) - { - ++x_it; - ++y_it; - - ++count; - } - else - { - const uword x_it_col = x_it.col(); - const uword x_it_row = x_it.row(); - - const uword y_it_col = y_it.col(); - const uword y_it_row = y_it.row(); - - 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 - { - ++x_it; - } - else - { - ++y_it; - } - } - } - - return count; - } - - - -//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_join_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_join_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_join_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_join_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,9 +28,9 @@ template struct traits { - static const bool is_row = false; - static const bool is_col = (T1::is_col && T2::is_col); - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = (T1::is_col && T2::is_col); + static constexpr bool is_xvec = false; }; template @@ -53,9 +55,9 @@ template struct traits { - static const bool is_row = (T1::is_row && T2::is_row); - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = (T1::is_row && T2::is_row); + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_join_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_join_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_join_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_join_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -250,8 +252,8 @@ // // OLD METHOD // - // umat locs(2, C_n_nz); - // Col vals( C_n_nz); + // umat locs(2, C_n_nz, arma_nozeros_indicator()); + // Col vals( C_n_nz, arma_nozeros_indicator()); // // uword* locs_mem = locs.memptr(); // eT* vals_mem = vals.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_kron_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_kron_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_kron_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_kron_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,9 +28,9 @@ template struct traits { - static const bool is_row = (T1::is_row && T2::is_row); - static const bool is_col = (T1::is_col && T2::is_col); - static const bool is_xvec = false; + static constexpr bool is_row = (T1::is_row && T2::is_row); + static constexpr bool is_col = (T1::is_col && T2::is_col); + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_kron_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_kron_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_kron_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_kron_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -109,8 +111,8 @@ // const SpMat& A = UA.M; // const SpMat& B = UB.M; // -// umat locs(2, A.n_nonzero * B.n_nonzero); -// Col vals( A.n_nonzero * B.n_nonzero); +// umat locs(2, A.n_nonzero * B.n_nonzero, arma_nozeros_indicator()); +// Col vals( A.n_nonzero * B.n_nonzero, arma_nozeros_indicator()); // // uword* locs_mem = locs.memptr(); // eT* vals_mem = vals.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_max_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_max_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_max_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_max_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_max_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_max_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_max_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_max_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -56,13 +58,9 @@ { arma_extra_debug_sigprint(); - arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise max"); - - if(pa.get_n_nonzero() == 0) { out = pb.Q; return; } - if(pb.get_n_nonzero() == 0) { out = pa.Q; return; } + arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise max()"); - // The plus helper works here also to get an upper bound on n_nonzero. - const uword max_n_nonzero = spglue_elem_helper::max_n_nonzero_plus(pa, pb); + const uword max_n_nonzero = pa.get_n_nonzero() + pb.get_n_nonzero(); // Resize memory to upper bound out.reserve(pa.get_n_rows(), pa.get_n_cols(), max_n_nonzero); @@ -124,6 +122,8 @@ access::rw(out.col_ptrs[out_col + 1])++; ++count; } + + arma_check( (count > max_n_nonzero), "internal error: spglue_max::apply_noalias(): count > max_n_nonzero" ); } const uword out_n_cols = out.n_cols; @@ -184,7 +184,7 @@ 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); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpGlue_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpGlue_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpGlue_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpGlue_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_merge_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_merge_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_merge_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_merge_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_merge_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_merge_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_merge_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_merge_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -174,7 +176,7 @@ y_it_valid = (y_it != y_end); } - arma_check( (count != merge_n_nonzero), "spglue_merge::subview_merge(): internal error: count != merge_n_nonzero" ); + arma_check( (count != merge_n_nonzero), "internal error: spglue_merge::subview_merge(): count != merge_n_nonzero" ); const uword out_n_cols = out.n_cols; @@ -362,7 +364,7 @@ y_it_valid = (y_it != y_end); } - arma_check( (count != merge_n_nonzero), "spglue_merge::subview_merge(): internal error: count != merge_n_nonzero" ); + arma_check( (count != merge_n_nonzero), "internal error: spglue_merge::subview_merge(): count != merge_n_nonzero" ); const uword out_n_cols = out.n_cols; @@ -473,6 +475,8 @@ { 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::const_iterator x_it = A.begin(); @@ -485,7 +489,7 @@ 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 +512,29 @@ { 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; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_min_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_min_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_min_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_min_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_min_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_min_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_min_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_min_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -56,13 +58,9 @@ { arma_extra_debug_sigprint(); - arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise minimum"); - - if(pa.get_n_nonzero() == 0) { out = pb.Q; return; } - if(pb.get_n_nonzero() == 0) { out = pa.Q; return; } + arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise min()"); - // The plus helper works here also to get an upper bound on n_nonzero. - const uword max_n_nonzero = spglue_elem_helper::max_n_nonzero_plus(pa, pb); + const uword max_n_nonzero = pa.get_n_nonzero() + pb.get_n_nonzero(); // Resize memory to upper bound out.reserve(pa.get_n_rows(), pa.get_n_cols(), max_n_nonzero); @@ -124,6 +122,8 @@ access::rw(out.col_ptrs[out_col + 1])++; ++count; } + + arma_check( (count > max_n_nonzero), "internal error: spglue_min::apply_noalias(): count > max_n_nonzero" ); } const uword out_n_cols = out.n_cols; @@ -184,7 +184,7 @@ 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); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_minus_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_minus_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_minus_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_minus_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_minus_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_minus_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_minus_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_minus_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -63,7 +65,7 @@ if(pa.get_n_nonzero() == 0) { out = pb.Q; out *= eT(-1); return; } if(pb.get_n_nonzero() == 0) { out = pa.Q; return; } - const uword max_n_nonzero = spglue_elem_helper::max_n_nonzero_plus(pa, pb); + const uword max_n_nonzero = pa.get_n_nonzero() + pb.get_n_nonzero(); // Resize memory to upper bound out.reserve(pa.get_n_rows(), pa.get_n_cols(), max_n_nonzero); @@ -125,6 +127,8 @@ access::rw(out.col_ptrs[out_col + 1])++; ++count; } + + arma_check( (count > max_n_nonzero), "internal error: spglue_minus::apply_noalias(): count > max_n_nonzero" ); } const uword out_n_cols = out.n_cols; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_plus_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_plus_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_plus_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_plus_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_plus_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_plus_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_plus_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_plus_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -63,7 +65,7 @@ if(pa.get_n_nonzero() == 0) { out = pb.Q; return; } if(pb.get_n_nonzero() == 0) { out = pa.Q; return; } - const uword max_n_nonzero = spglue_elem_helper::max_n_nonzero_plus(pa, pb); + const uword max_n_nonzero = pa.get_n_nonzero() + pb.get_n_nonzero(); // Resize memory to upper bound out.reserve(pa.get_n_rows(), pa.get_n_cols(), max_n_nonzero); @@ -125,6 +127,8 @@ access::rw(out.col_ptrs[out_col + 1])++; ++count; } + + arma_check( (count > max_n_nonzero), "internal error: spglue_plus::apply_noalias(): count > max_n_nonzero" ); } const uword out_n_cols = out.n_cols; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_relational_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_relational_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_relational_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_relational_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -43,6 +45,34 @@ template inline static void apply_noalias(SpMat& out, const SpProxy& PA, const SpProxy& PB); + }; + + + +class spglue_rel_and + : public traits_glue_or + { + public: + + template + inline static void apply(SpMat& out, const mtSpGlue& X); + + template + inline static void apply_noalias(SpMat& out, const SpProxy& PA, const SpProxy& PB); + }; + + + +class spglue_rel_or + : public traits_glue_or + { + public: + + template + inline static void apply(SpMat& out, const mtSpGlue& X); + + template + inline static void apply_noalias(SpMat& out, const SpProxy& PA, const SpProxy& PB); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_relational_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_relational_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_relational_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_relational_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -58,7 +60,7 @@ arma_debug_assert_same_size(PA.get_n_rows(), PA.get_n_cols(), PB.get_n_rows(), PB.get_n_cols(), "operator<"); - const uword max_n_nonzero = spglue_elem_helper::max_n_nonzero_plus(PA, PB); + const uword max_n_nonzero = PA.get_n_nonzero() + PB.get_n_nonzero(); // Resize memory to upper bound out.reserve(PA.get_n_rows(), PA.get_n_cols(), max_n_nonzero); @@ -120,6 +122,8 @@ access::rw(out.col_ptrs[out_col + 1])++; ++count; } + + arma_check( (count > max_n_nonzero), "internal error: spglue_rel_lt::apply_noalias(): count > max_n_nonzero" ); } const uword out_n_cols = out.n_cols; @@ -150,6 +154,10 @@ +// + + + template inline void @@ -189,7 +197,7 @@ arma_debug_assert_same_size(PA.get_n_rows(), PA.get_n_cols(), PB.get_n_rows(), PB.get_n_cols(), "operator>"); - const uword max_n_nonzero = spglue_elem_helper::max_n_nonzero_plus(PA, PB); + const uword max_n_nonzero = PA.get_n_nonzero() + PB.get_n_nonzero(); // Resize memory to upper bound out.reserve(PA.get_n_rows(), PA.get_n_cols(), max_n_nonzero); @@ -251,6 +259,259 @@ access::rw(out.col_ptrs[out_col + 1])++; ++count; } + + arma_check( (count > max_n_nonzero), "internal error: spglue_rel_gt::apply_noalias(): count > max_n_nonzero" ); + } + + const uword out_n_cols = out.n_cols; + + uword* col_ptrs = access::rwp(out.col_ptrs); + + // Fix column pointers to be cumulative. + for(uword c = 1; c <= out_n_cols; ++c) + { + col_ptrs[c] += col_ptrs[c - 1]; + } + + if(count < max_n_nonzero) + { + if(count <= (max_n_nonzero/2)) + { + out.mem_resize(count); + } + else + { + // quick resize without reallocating memory and copying data + access::rw( out.n_nonzero) = count; + access::rw( out.values[count]) = eT(0); + access::rw(out.row_indices[count]) = uword(0); + } + } + } + + + +// + + + +template +inline +void +spglue_rel_and::apply(SpMat& out, const mtSpGlue& X) + { + arma_extra_debug_sigprint(); + + const SpProxy PA(X.A); + const SpProxy PB(X.B); + + const bool is_alias = PA.is_alias(out) || PB.is_alias(out); + + if(is_alias == false) + { + spglue_rel_and::apply_noalias(out, PA, PB); + } + else + { + SpMat tmp; + + spglue_rel_and::apply_noalias(tmp, PA, PB); + + out.steal_mem(tmp); + } + } + + + +template +inline +void +spglue_rel_and::apply_noalias(SpMat& out, const SpProxy& PA, const SpProxy& PB) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + arma_debug_assert_same_size(PA.get_n_rows(), PA.get_n_cols(), PB.get_n_rows(), PB.get_n_cols(), "operator&&"); + + if( (PA.get_n_nonzero() == 0) || (PB.get_n_nonzero() == 0) ) + { + out.zeros(PA.get_n_rows(), PA.get_n_cols()); + return; + } + + const uword max_n_nonzero = (std::min)(PA.get_n_nonzero(), PB.get_n_nonzero()); + + // Resize memory to upper bound + out.reserve(PA.get_n_rows(), PA.get_n_cols(), max_n_nonzero); + + // Now iterate across both matrices. + typename SpProxy::const_iterator_type x_it = PA.begin(); + typename SpProxy::const_iterator_type x_end = PA.end(); + + typename SpProxy::const_iterator_type y_it = PB.begin(); + typename SpProxy::const_iterator_type y_end = PB.end(); + + uword count = 0; + + while( (x_it != x_end) || (y_it != y_end) ) + { + const uword x_it_row = x_it.row(); + const uword x_it_col = x_it.col(); + + const uword y_it_row = y_it.row(); + const uword y_it_col = y_it.col(); + + if(x_it == y_it) + { + access::rw(out.values[count]) = uword(1); + + access::rw(out.row_indices[count]) = x_it_row; + access::rw(out.col_ptrs[x_it_col + 1])++; + ++count; + + ++x_it; + ++y_it; + } + else + { + 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 + { + ++x_it; + } + else + { + ++y_it; + } + } + + arma_check( (count > max_n_nonzero), "internal error: spglue_rel_and::apply_noalias(): count > max_n_nonzero" ); + } + + const uword out_n_cols = out.n_cols; + + uword* col_ptrs = access::rwp(out.col_ptrs); + + // Fix column pointers to be cumulative. + for(uword c = 1; c <= out_n_cols; ++c) + { + col_ptrs[c] += col_ptrs[c - 1]; + } + + if(count < max_n_nonzero) + { + if(count <= (max_n_nonzero/2)) + { + out.mem_resize(count); + } + else + { + // quick resize without reallocating memory and copying data + access::rw( out.n_nonzero) = count; + access::rw( out.values[count]) = eT(0); + access::rw(out.row_indices[count]) = uword(0); + } + } + } + + + +// + + + +template +inline +void +spglue_rel_or::apply(SpMat& out, const mtSpGlue& X) + { + arma_extra_debug_sigprint(); + + const SpProxy PA(X.A); + const SpProxy PB(X.B); + + const bool is_alias = PA.is_alias(out) || PB.is_alias(out); + + if(is_alias == false) + { + spglue_rel_or::apply_noalias(out, PA, PB); + } + else + { + SpMat tmp; + + spglue_rel_or::apply_noalias(tmp, PA, PB); + + out.steal_mem(tmp); + } + } + + + +template +inline +void +spglue_rel_or::apply_noalias(SpMat& out, const SpProxy& PA, const SpProxy& PB) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + arma_debug_assert_same_size(PA.get_n_rows(), PA.get_n_cols(), PB.get_n_rows(), PB.get_n_cols(), "operator||"); + + const uword max_n_nonzero = PA.get_n_nonzero() + PB.get_n_nonzero(); + + // Resize memory to upper bound + out.reserve(PA.get_n_rows(), PA.get_n_cols(), max_n_nonzero); + + // Now iterate across both matrices. + typename SpProxy::const_iterator_type x_it = PA.begin(); + typename SpProxy::const_iterator_type x_end = PA.end(); + + typename SpProxy::const_iterator_type y_it = PB.begin(); + typename SpProxy::const_iterator_type y_end = PB.end(); + + uword count = 0; + + while( (x_it != x_end) || (y_it != y_end) ) + { + const uword x_it_col = x_it.col(); + const uword x_it_row = x_it.row(); + + const uword y_it_col = y_it.col(); + const uword y_it_row = y_it.row(); + + bool use_y_loc = false; + + if(x_it == y_it) + { + ++x_it; + ++y_it; + } + else + { + 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 + { + ++x_it; + } + else + { + ++y_it; + + use_y_loc = true; + } + } + + access::rw(out.values[count]) = uword(1); + + 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; + + arma_check( (count > max_n_nonzero), "internal error: spglue_rel_or::apply_noalias(): count > max_n_nonzero" ); } const uword out_n_cols = out.n_cols; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_schur_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_schur_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_schur_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_schur_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_schur_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_schur_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_schur_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_schur_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -66,7 +68,7 @@ return; } - const uword max_n_nonzero = spglue_elem_helper::max_n_nonzero_schur(pa, pb); + const uword max_n_nonzero = (std::min)(pa.get_n_nonzero(), pb.get_n_nonzero()); // Resize memory to upper bound out.reserve(pa.get_n_rows(), pa.get_n_cols(), max_n_nonzero); @@ -115,6 +117,8 @@ ++y_it; } } + + arma_check( (count > max_n_nonzero), "internal error: spglue_schur::apply_noalias(): count > max_n_nonzero" ); } const uword out_n_cols = out.n_cols; @@ -181,42 +185,34 @@ arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise multiplication"); - // count new size - uword new_n_nonzero = 0; - - typename SpProxy::const_iterator_type it = pb.begin(); - typename SpProxy::const_iterator_type it_end = pb.end(); - - while(it != it_end) - { - if( ((*it) * pa.at(it.row(), it.col())) != eT(0) ) { ++new_n_nonzero; } - - ++it; - } + const uword max_n_nonzero = pb.get_n_nonzero(); - // Resize memory accordingly. - out.reserve(pa.get_n_rows(), pa.get_n_cols(), new_n_nonzero); + // Resize memory to upper bound. + out.reserve(pa.get_n_rows(), pa.get_n_cols(), max_n_nonzero); uword count = 0; - typename SpProxy::const_iterator_type it2 = pb.begin(); + typename SpProxy::const_iterator_type it = pb.begin(); + typename SpProxy::const_iterator_type it_end = pb.end(); - while(it2 != it_end) + while(it != it_end) { - const uword it2_row = it2.row(); - const uword it2_col = it2.col(); + const uword it_row = it.row(); + const uword it_col = it.col(); - const eT val = (*it2) * pa.at(it2_row, it2_col); + const eT val = (*it) * pa.at(it_row, it_col); if(val != eT(0)) { access::rw( out.values[count]) = val; - access::rw( out.row_indices[count]) = it2_row; - access::rw(out.col_ptrs[it2_col + 1])++; + access::rw( out.row_indices[count]) = it_row; + access::rw(out.col_ptrs[it_col + 1])++; ++count; } - ++it2; + ++it; + + arma_check( (count > max_n_nonzero), "internal error: spglue_schur_misc::dense_schur_sparse(): count > max_n_nonzero" ); } // Fix column pointers. @@ -224,6 +220,21 @@ { access::rw(out.col_ptrs[c]) += out.col_ptrs[c - 1]; } + + if(count < max_n_nonzero) + { + if(count <= (max_n_nonzero/2)) + { + out.mem_resize(count); + } + else + { + // quick resize without reallocating memory and copying data + access::rw( out.n_nonzero) = count; + access::rw( out.values[count]) = eT(0); + access::rw(out.row_indices[count]) = uword(0); + } + } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_times_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_times_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_times_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_times_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,9 +28,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template @@ -50,9 +52,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template @@ -71,9 +73,9 @@ template struct traits { - static const bool is_row = T1::is_row; - static const bool is_col = T2::is_col; - static const bool is_xvec = false; + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_times_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_times_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spglue_times_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_times_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -108,11 +110,8 @@ //SpMat c(x_n_rows, y_n_cols); // Initializes col_ptrs to 0. c.zeros(x_n_rows, y_n_cols); - //if( (x.n_elem == 0) || (y.n_elem == 0) ) - if( (x.n_nonzero == 0) || (y.n_nonzero == 0) ) - { - return; - } + //if( (x.n_elem == 0) || (y.n_elem == 0) ) { return; } + if( (x.n_nonzero == 0) || (y.n_nonzero == 0) ) { return; } // Auxiliary storage which denotes when items have been found. podarray index(x_n_rows); @@ -261,7 +260,7 @@ } // Now sort the indices. - if (cur_index != 0) + if(cur_index != 0) { op_sort::direct_sort_ascending(sorted_indices.memptr(), cur_index); @@ -315,6 +314,15 @@ const SpMat& A = UA.M; const Mat& B = UB.M; + if( (resolves_to_vector::no) && (B.is_vec() == false) && B.is_diagmat() ) + { + const SpMat tmp(diagmat(B)); + + out = A * tmp; + + return; + } + const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; @@ -390,42 +398,48 @@ } else { - const Proxy pa(x); - const SpProxy pb(y); + const quasi_unwrap UA(x); + const unwrap_spmat UB(y); - arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "matrix multiplication"); + const Mat& A = UA.M; + const SpMat& B = UB.M; - out.zeros(pa.get_n_rows(), pb.get_n_cols()); + if( (resolves_to_vector::no) && (A.is_vec() == false) && A.is_diagmat() ) + { + const SpMat tmp(diagmat(A)); + + out = tmp * B; + + return; + } - if( (pa.get_n_elem() > 0) && (pb.get_n_nonzero() > 0) ) + arma_debug_assert_mul_size(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); + + out.zeros(A.n_rows, B.n_cols); + + if( (A.n_elem > 0) && (B.n_nonzero > 0) ) { - if( (arma_config::openmp) && (mp_thread_limit::in_parallel() == false) && (pa.get_n_rows() <= (pa.get_n_cols() / uword(100))) ) + if( (arma_config::openmp) && (mp_thread_limit::in_parallel() == false) && (A.n_rows <= (A.n_cols / uword(100))) ) { #if defined(ARMA_USE_OPENMP) { arma_extra_debug_print("using parallelised multiplication"); - const quasi_unwrap::stored_type> UX(pa.Q); - const unwrap_spmat::stored_type> UY(pb.Q); - - const Mat& X = UX.M; - const SpMat& Y = UY.M; - - const uword Y_n_cols = Y.n_cols; + const uword B_n_cols = B.n_cols; const int n_threads = mp_thread_limit::get(); #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword i=0; i < Y_n_cols; ++i) + for(uword i=0; i < B_n_cols; ++i) { - const uword col_offset_1 = Y.col_ptrs[i ]; - const uword col_offset_2 = Y.col_ptrs[i+1]; + const uword col_offset_1 = B.col_ptrs[i ]; + const uword col_offset_2 = B.col_ptrs[i+1]; const uword col_offset_delta = col_offset_2 - col_offset_1; - const uvec indices(const_cast(&(Y.row_indices[col_offset_1])), col_offset_delta, false, false); - const Col Y_col(const_cast< eT*>(&( Y.values[col_offset_1])), col_offset_delta, false, false); + const uvec indices(const_cast(&(B.row_indices[col_offset_1])), col_offset_delta, false, false); + const Col B_col(const_cast< eT*>(&( B.values[col_offset_1])), col_offset_delta, false, false); - out.col(i) = X.cols(indices) * Y_col; + out.col(i) = A.cols(indices) * B_col; } } #endif @@ -434,25 +448,25 @@ { arma_extra_debug_print("using standard multiplication"); - typename SpProxy::const_iterator_type y_it = pb.begin(); - typename SpProxy::const_iterator_type y_it_end = pb.end(); + typename SpMat::const_iterator B_it = B.begin(); + typename SpMat::const_iterator B_it_end = B.end(); const uword out_n_rows = out.n_rows; - while(y_it != y_it_end) + while(B_it != B_it_end) { - const eT y_it_val = (*y_it); - const uword y_it_col = y_it.col(); - const uword y_it_row = y_it.row(); + const eT B_it_val = (*B_it); + const uword B_it_col = B_it.col(); + const uword B_it_row = B_it.row(); - eT* out_col = out.colptr(y_it_col); + eT* out_col = out.colptr(B_it_col); for(uword row = 0; row < out_n_rows; ++row) { - out_col[row] += pa.at(row, y_it_row) * y_it_val; + out_col[row] += A.at(row, B_it_row) * B_it_val; } - ++y_it; + ++B_it; } } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpMat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpMat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ typedef eT elem_type; //!< the type of elements stored in the matrix typedef typename get_pod_type::result pod_type; //!< if eT is std::complex, pod_type is T; otherwise pod_type is eT - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; const uword n_rows; //!< number of rows (read-only) const uword n_cols; //!< number of columns (read-only) @@ -92,13 +94,11 @@ inline SpMat& operator=(const std::string& text); inline SpMat(const SpMat& x); - #if defined(ARMA_USE_CXX11) inline SpMat(SpMat&& m); inline SpMat& operator=(SpMat&& m); - #endif inline explicit SpMat(const MapMat& x); - inline SpMat& operator=(const MapMat& x); + inline SpMat& operator= (const MapMat& x); template inline SpMat(const Base& rowind, const Base& colptr, const Base& values, const uword n_rows, const uword n_cols); @@ -112,12 +112,12 @@ template inline SpMat(const bool add_values, const Base& locations, const Base& values, const uword n_rows, const uword n_cols, const bool sort_locations = true, const bool check_for_zeros = true); - inline SpMat& operator=(const eT val); //! sets size to 1x1 + inline SpMat& operator= (const eT val); //! sets size to 1x1 inline SpMat& operator*=(const eT val); inline SpMat& operator/=(const eT val); // operator+=(val) and operator-=(val) are not defined as they don't make sense for sparse matrices - inline SpMat& operator=(const SpMat& m); + inline SpMat& operator= (const SpMat& m); inline SpMat& operator+=(const SpMat& m); inline SpMat& operator-=(const SpMat& m); inline SpMat& operator*=(const SpMat& m); @@ -125,7 +125,7 @@ inline SpMat& operator/=(const SpMat& m); template inline explicit SpMat(const Base& m); - template inline SpMat& operator=(const Base& m); + template inline SpMat& operator= (const Base& m); template inline SpMat& operator+=(const Base& m); template inline SpMat& operator-=(const Base& m); template inline SpMat& operator*=(const Base& m); @@ -133,7 +133,7 @@ template inline SpMat& operator%=(const Base& m); template inline explicit SpMat(const Op& expr); - template inline SpMat& operator=(const Op& expr); + template inline SpMat& operator= (const Op& expr); template inline SpMat& operator+=(const Op& expr); template inline SpMat& operator-=(const Op& expr); template inline SpMat& operator*=(const Op& expr); @@ -148,15 +148,23 @@ inline explicit SpMat(const SpBase& A, const SpBase& B); inline SpMat(const SpSubview& X); - inline SpMat& operator=(const SpSubview& X); + inline SpMat& operator= (const SpSubview& X); inline SpMat& operator+=(const SpSubview& X); inline SpMat& operator-=(const SpSubview& X); inline SpMat& operator*=(const SpSubview& X); inline SpMat& operator%=(const SpSubview& X); inline SpMat& operator/=(const SpSubview& X); + template inline SpMat(const SpSubview_col_list& X); + template inline SpMat& operator= (const SpSubview_col_list& X); + template inline SpMat& operator+=(const SpSubview_col_list& X); + template inline SpMat& operator-=(const SpSubview_col_list& X); + template inline SpMat& operator*=(const SpSubview_col_list& X); + template inline SpMat& operator%=(const SpSubview_col_list& X); + template inline SpMat& operator/=(const SpSubview_col_list& X); + inline SpMat(const spdiagview& X); - inline SpMat& operator=(const spdiagview& X); + inline SpMat& operator= (const spdiagview& X); inline SpMat& operator+=(const spdiagview& X); inline SpMat& operator-=(const spdiagview& X); inline SpMat& operator*=(const spdiagview& X); @@ -165,7 +173,7 @@ // delayed unary ops template inline SpMat(const SpOp& X); - template inline SpMat& operator=(const SpOp& X); + template inline SpMat& operator= (const SpOp& X); template inline SpMat& operator+=(const SpOp& X); template inline SpMat& operator-=(const SpOp& X); template inline SpMat& operator*=(const SpOp& X); @@ -174,7 +182,7 @@ // delayed binary ops template inline SpMat(const SpGlue& X); - template inline SpMat& operator=(const SpGlue& X); + template inline SpMat& operator= (const SpGlue& X); template inline SpMat& operator+=(const SpGlue& X); template inline SpMat& operator-=(const SpGlue& X); template inline SpMat& operator*=(const SpGlue& X); @@ -183,7 +191,7 @@ // delayed mixed-type unary ops template inline SpMat(const mtSpOp& X); - template inline SpMat& operator=(const mtSpOp& X); + template inline SpMat& operator= (const mtSpOp& X); template inline SpMat& operator+=(const mtSpOp& X); template inline SpMat& operator-=(const mtSpOp& X); template inline SpMat& operator*=(const mtSpOp& X); @@ -192,7 +200,7 @@ // delayed mixed-type binary ops template inline SpMat(const mtSpGlue& X); - template inline SpMat& operator=(const mtSpGlue& X); + template inline SpMat& operator= (const mtSpGlue& X); template inline SpMat& operator+=(const mtSpGlue& X); template inline SpMat& operator-=(const mtSpGlue& X); template inline SpMat& operator*=(const mtSpGlue& X); @@ -200,17 +208,17 @@ template inline SpMat& operator/=(const mtSpGlue& X); - arma_inline SpSubview row(const uword row_num); - arma_inline const SpSubview row(const uword row_num) const; + arma_inline SpSubview_row row(const uword row_num); + arma_inline const SpSubview_row row(const uword row_num) const; - inline SpSubview operator()(const uword row_num, const span& col_span); - inline const SpSubview operator()(const uword row_num, const span& col_span) const; + inline SpSubview_row operator()(const uword row_num, const span& col_span); + inline const SpSubview_row operator()(const uword row_num, const span& col_span) const; - arma_inline SpSubview col(const uword col_num); - arma_inline const SpSubview col(const uword col_num) const; + arma_inline SpSubview_col col(const uword col_num); + arma_inline const SpSubview_col col(const uword col_num) const; - inline SpSubview operator()(const span& row_span, const uword col_num); - inline const SpSubview operator()(const span& row_span, const uword col_num) const; + inline SpSubview_col operator()(const span& row_span, const uword col_num); + inline const SpSubview_col operator()(const span& row_span, const uword col_num) const; arma_inline SpSubview rows(const uword in_row1, const uword in_row2); arma_inline const SpSubview rows(const uword in_row1, const uword in_row2) const; @@ -247,6 +255,10 @@ inline const SpSubview tail_cols(const uword N) const; + template arma_inline SpSubview_col_list cols(const Base& ci); + template arma_inline const SpSubview_col_list cols(const Base& ci) const; + + inline spdiagview diag(const sword in_id = 0); inline const spdiagview diag(const sword in_id = 0) const; @@ -303,19 +315,6 @@ arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; - arma_cold inline void impl_print( const std::string& extra_text) const; - arma_cold inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const; - - arma_cold inline void impl_raw_print( const std::string& extra_text) const; - arma_cold inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const; - - arma_cold inline void impl_print_dense( const std::string& extra_text) const; - arma_cold inline void impl_print_dense(std::ostream& user_stream, const std::string& extra_text) const; - - arma_cold inline void impl_raw_print_dense( const std::string& extra_text) const; - arma_cold inline void impl_raw_print_dense(std::ostream& user_stream, const std::string& extra_text) const; - - template inline void copy_size(const SpMat& m); template inline void copy_size(const Mat& m); @@ -332,8 +331,6 @@ inline void reshape_helper_generic(const uword in_rows, const uword in_cols); //! internal use only inline void reshape_helper_intovec(); //! internal use only - arma_deprecated inline void reshape(const uword in_rows, const uword in_cols, const uword dim); //!< NOTE: don't use this form: it will be removed - template inline const SpMat& for_each(functor F); template inline const SpMat& for_each(functor F) const; @@ -343,6 +340,8 @@ inline const SpMat& clean(const pod_type threshold); + inline const SpMat& clamp(const eT min_val, const eT max_val); + inline const SpMat& zeros(); inline const SpMat& zeros(const uword in_elem); inline const SpMat& zeros(const uword in_rows, const uword in_cols); @@ -363,6 +362,7 @@ inline const SpMat& sprandn(const SizeMat& s, const double density); inline void reset(); + inline void reset_cache(); //! don't use this unless you're writing internal Armadillo code inline void reserve(const uword in_rows, const uword in_cols, const uword new_n_nonzero); @@ -381,16 +381,20 @@ // saving and loading // TODO: implement auto_detect for sparse matrices - inline arma_cold bool save(const std::string name, const file_type type = arma_binary, const bool print_status = true) const; - inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary, const bool print_status = true) const; - - inline arma_cold bool load(const std::string name, const file_type type = arma_binary, const bool print_status = true); - inline arma_cold bool load( std::istream& is, const file_type type = arma_binary, const bool print_status = true); + inline arma_cold bool save(const std::string name, const file_type type = arma_binary) const; + inline arma_cold bool save(const csv_name& spec, const file_type type = csv_ascii) const; + inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary) const; + + inline arma_cold bool load(const std::string name, const file_type type = arma_binary); + inline arma_cold bool load(const csv_name& spec, const file_type type = csv_ascii); + inline arma_cold bool load( std::istream& is, const file_type type = arma_binary); inline arma_cold bool quiet_save(const std::string name, const file_type type = arma_binary) const; + inline arma_cold bool quiet_save(const csv_name& spec, const file_type type = csv_ascii) const; inline arma_cold bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; inline arma_cold bool quiet_load(const std::string name, const file_type type = arma_binary); + inline arma_cold bool quiet_load(const csv_name& spec, const file_type type = csv_ascii); inline arma_cold bool quiet_load( std::istream& is, const file_type type = arma_binary); @@ -475,7 +479,7 @@ inline iterator(SpMat& in_M, uword in_row, uword in_col, uword in_pos) : const_iterator(in_M, in_row, in_col, in_pos) { } inline iterator(const iterator& other) : const_iterator(other) { } - inline arma_hot SpValProxy > operator*(); + inline arma_hot SpValProxy< SpMat > operator*(); // overloads needed for return type correctness inline arma_hot iterator& operator++(); @@ -485,9 +489,9 @@ inline arma_warn_unused iterator operator--(int); // this has a different value_type than iterator_base - typedef SpValProxy > value_type; - typedef const SpValProxy >* pointer; - typedef const SpValProxy >& reference; + typedef SpValProxy< SpMat > value_type; + typedef const SpValProxy< SpMat >* pointer; + typedef const SpValProxy< SpMat >& reference; }; class const_row_iterator : public iterator_base @@ -536,7 +540,7 @@ inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { } inline row_iterator(const row_iterator& other) : const_row_iterator(other) { } - inline arma_hot SpValProxy > operator*(); + inline arma_hot SpValProxy< SpMat > operator*(); // overloads required for return type correctness inline arma_hot row_iterator& operator++(); @@ -546,9 +550,9 @@ inline arma_warn_unused row_iterator operator--(int); // this has a different value_type than iterator_base - typedef SpValProxy > value_type; - typedef const SpValProxy >* pointer; - typedef const SpValProxy >& reference; + typedef SpValProxy< SpMat > value_type; + typedef const SpValProxy< SpMat >* pointer; + typedef const SpValProxy< SpMat >& reference; }; @@ -599,6 +603,12 @@ inline bool empty() const; inline uword size() const; + arma_inline arma_warn_unused SpMat_MapMat_val front(); + arma_inline arma_warn_unused eT front() const; + + arma_inline arma_warn_unused SpMat_MapMat_val back(); + arma_inline arma_warn_unused eT back() const; + // Resize memory. // If the new size is larger, the column pointers and new memory still need to be correctly set. // If the new size is smaller, the first new_n_nonzero elements will be copied. @@ -618,8 +628,8 @@ inline void steal_mem_simple(SpMat& X); //! don't use this unless you're writing internal Armadillo code - template< typename T1, typename Functor> arma_hot inline void init_xform (const SpBase& x, const Functor& func); - template arma_hot inline void init_xform_mt(const SpBase& x, const Functor& func); + template< typename T1, typename Functor> inline void init_xform (const SpBase& x, const Functor& func); + template inline void init_xform_mt(const SpBase& x, const Functor& func); //! don't use this unless you're writing internal Armadillo code arma_inline bool is_alias(const SpMat& X) const; @@ -671,7 +681,7 @@ // 1: CSC needs to be updated from cache (ie. cache has more recent data) // 2: no update required (ie. CSC and cache contain the same data) - #if defined(ARMA_USE_CXX11) + #if (!defined(ARMA_DONT_USE_STD_MUTEX)) arma_aligned mutable std::mutex cache_mutex; #endif @@ -692,6 +702,7 @@ friend class SpSubview_MapMat_val; friend class spdiagview; + template friend class SpSubview_col_list; public: diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpMat_iterators_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_iterators_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpMat_iterators_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_iterators_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,7 +28,7 @@ template inline SpMat::iterator_base::iterator_base() - : M(NULL) + : M(nullptr) , internal_col(0) , internal_pos(0) { @@ -80,6 +82,8 @@ { } + + template inline SpMat::const_iterator::const_iterator(const SpMat& in_M, uword initial_pos) @@ -91,7 +95,7 @@ iterator_base::internal_col = in_M.n_cols; return; } - + // Determine which column we should be in. while(iterator_base::M->col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos) { @@ -108,13 +112,13 @@ { // So we have a position we want to be right after. Skip to the column. iterator_base::internal_pos = iterator_base::M->col_ptrs[iterator_base::internal_col]; - + // Now we have to make sure that is the right column. while(iterator_base::M->col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos) { iterator_base::internal_col++; } - + // Now we have to get to the right row. while((iterator_base::M->row_indices[iterator_base::internal_pos] < in_row) && (iterator_base::internal_col == in_col)) { @@ -151,19 +155,19 @@ SpMat::const_iterator::operator++() { ++iterator_base::internal_pos; - - if (iterator_base::internal_pos == iterator_base::M->n_nonzero) + + if(iterator_base::internal_pos == iterator_base::M->n_nonzero) { iterator_base::internal_col = iterator_base::M->n_cols; return *this; } - + // Check to see if we moved a column. - while (iterator_base::M->col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos) + while(iterator_base::M->col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos) { ++iterator_base::internal_col; } - + return *this; } @@ -176,9 +180,9 @@ SpMat::const_iterator::operator++(int) { typename SpMat::const_iterator tmp(*this); - + ++(*this); - + return tmp; } @@ -193,12 +197,11 @@ --iterator_base::internal_pos; // First, see if we moved back a column. - while (iterator_base::internal_pos < iterator_base::M->col_ptrs[iterator_base::internal_col]) + while(iterator_base::internal_pos < iterator_base::M->col_ptrs[iterator_base::internal_col]) { --iterator_base::internal_col; } - - + return *this; } @@ -211,9 +214,9 @@ SpMat::const_iterator::operator--(int) { typename SpMat::const_iterator tmp(*this); - + --(*this); - + return tmp; } @@ -314,10 +317,10 @@ template inline arma_hot -SpValProxy > +SpValProxy< SpMat > SpMat::iterator::operator*() { - return SpValProxy >( + return SpValProxy< SpMat >( iterator_base::M->row_indices[iterator_base::internal_pos], iterator_base::internal_col, access::rw(*iterator_base::M), @@ -333,6 +336,7 @@ SpMat::iterator::operator++() { const_iterator::operator++(); + return *this; } @@ -345,9 +349,9 @@ SpMat::iterator::operator++(int) { typename SpMat::iterator tmp(*this); - + const_iterator::operator++(); - + return tmp; } @@ -360,6 +364,7 @@ SpMat::iterator::operator--() { const_iterator::operator--(); + return *this; } @@ -372,9 +377,9 @@ SpMat::iterator::operator--(int) { typename SpMat::iterator tmp(*this); - + const_iterator::operator--(); - + return tmp; } @@ -407,73 +412,71 @@ , actual_pos(0) { // Corner case for the end of a matrix. - if (initial_pos == in_M.n_nonzero) + if(initial_pos == in_M.n_nonzero) { iterator_base::internal_col = 0; internal_row = in_M.n_rows; actual_pos = in_M.n_nonzero; iterator_base::internal_pos = in_M.n_nonzero; - + return; } - + // We don't count zeros in our position count, so we have to find the nonzero // value corresponding to the given initial position. We assume initial_pos // is valid. - - // This is irritating because we don't know where the elements are in each - // row. What we will do is loop across all columns looking for elements in - // row 0 (and add to our sum), then in row 1, and so forth, until we get to - // the desired position. + + // This is irritating because we don't know where the elements are in each row. + // What we will do is loop across all columns looking for elements in row 0 + // (and add to our sum), then in row 1, and so forth, until we get to the desired position. uword cur_pos = std::numeric_limits::max(); // Invalid value. uword cur_actual_pos = 0; - - for (uword row = 0; row < iterator_base::M->n_rows; ++row) + + for(uword row = 0; row < iterator_base::M->n_rows; ++row) { - for (uword col = 0; col < iterator_base::M->n_cols; ++col) + for(uword col = 0; col < iterator_base::M->n_cols; ++col) { // Find the first element with row greater than or equal to in_row. const uword col_offset = iterator_base::M->col_ptrs[col ]; const uword next_col_offset = iterator_base::M->col_ptrs[col + 1]; - + const uword* start_ptr = &iterator_base::M->row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->row_indices[next_col_offset]; - - if (start_ptr != end_ptr) + + if(start_ptr != end_ptr) { const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, row); - - // This is the number of elements in the column with row index less than - // in_row. + + // This is the number of elements in the column with row index less than in_row. const uword offset = uword(pos_ptr - start_ptr); - - if (iterator_base::M->row_indices[col_offset + offset] == row) + + if(iterator_base::M->row_indices[col_offset + offset] == row) { cur_actual_pos = col_offset + offset; - + // Increment position portably. - if (cur_pos == std::numeric_limits::max()) - cur_pos = 0; + if(cur_pos == std::numeric_limits::max()) + { cur_pos = 0; } else - ++cur_pos; - + { ++cur_pos; } + // Do we terminate? - if (cur_pos == initial_pos) + if(cur_pos == initial_pos) { internal_row = row; iterator_base::internal_col = col; iterator_base::internal_pos = cur_pos; actual_pos = cur_actual_pos; - + return; } } } } } - - // If we got to here, then we have gone past the end of the matrix. This - // shouldn't happen... + + // If we got to here, then we have gone past the end of the matrix. + // This shouldn't happen... iterator_base::internal_pos = iterator_base::M->n_nonzero; iterator_base::internal_col = 0; internal_row = iterator_base::M->n_rows; @@ -497,41 +500,40 @@ // // We'll find these simultaneously, though we will have to loop over all // columns. - + // This will hold the total number of points with rows less than in_row. uword cur_pos = 0; uword cur_min_row = iterator_base::M->n_rows; uword cur_min_col = 0; uword cur_actual_pos = 0; - - for (uword col = 0; col < iterator_base::M->n_cols; ++col) + + for(uword col = 0; col < iterator_base::M->n_cols; ++col) { // Find the first element with row greater than or equal to in_row. const uword col_offset = iterator_base::M->col_ptrs[col ]; const uword next_col_offset = iterator_base::M->col_ptrs[col + 1]; - + const uword* start_ptr = &iterator_base::M->row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->row_indices[next_col_offset]; - if (start_ptr != end_ptr) + if(start_ptr != end_ptr) { const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, in_row); - - // This is the number of elements in the column with row index less than - // in_row. + + // This is the number of elements in the column with row index less than in_row. const uword offset = uword(pos_ptr - start_ptr); - + cur_pos += offset; - - if (pos_ptr != end_ptr) + + if(pos_ptr != end_ptr) { // This is the row index of the first element in the column with row index // greater than or equal to in_row. - if ((*pos_ptr) < cur_min_row) + if((*pos_ptr) < cur_min_row) { - // If we are in the desired row but before the desired column, we - // can't take this. - if (col >= in_col) + // If we are in the desired row but before the desired column, + // we can't take this. + if(col >= in_col) { cur_min_row = (*pos_ptr); cur_min_col = col; @@ -541,7 +543,7 @@ } } } - + // Now we know what the minimum row is. internal_row = cur_min_row; iterator_base::internal_col = cur_min_col; @@ -577,48 +579,48 @@ { // We just need to find the next nonzero element. iterator_base::internal_pos++; - + if(iterator_base::internal_pos == iterator_base::M->n_nonzero) { internal_row = iterator_base::M->n_rows; iterator_base::internal_col = 0; - + return *this; } - + // Otherwise, we need to search. We can start in the next column and use // lower_bound() to find the next element. uword next_min_row = iterator_base::M->n_rows; uword next_min_col = iterator_base::M->n_cols; uword next_actual_pos = 0; - + // Search from the current column to the end of the matrix. - for (uword col = iterator_base::internal_col + 1; col < iterator_base::M->n_cols; ++col) + for(uword col = iterator_base::internal_col + 1; col < iterator_base::M->n_cols; ++col) { // Find the first element with row greater than or equal to in_row. const uword col_offset = iterator_base::M->col_ptrs[col ]; const uword next_col_offset = iterator_base::M->col_ptrs[col + 1]; - + const uword* start_ptr = &iterator_base::M->row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->row_indices[next_col_offset]; - - if (start_ptr != end_ptr) + + if(start_ptr != end_ptr) { // Find the first element in the column with row greater than or equal to // the current row. const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, internal_row); - - if (pos_ptr != end_ptr) + + if(pos_ptr != end_ptr) { // We found something in the column, but is the row index correct? - if ((*pos_ptr) == internal_row) + if((*pos_ptr) == internal_row) { // Exact match---so we are done. iterator_base::internal_col = col; actual_pos = col_offset + (pos_ptr - start_ptr); return *this; } - else if ((*pos_ptr) < next_min_row) + else if((*pos_ptr) < next_min_row) { // The first element in this column is in a subsequent row, but it's // the minimum row we've seen so far. @@ -626,7 +628,7 @@ next_min_col = col; next_actual_pos = col_offset + (pos_ptr - start_ptr); } - else if ((*pos_ptr) == next_min_row && col < next_min_col) + else if((*pos_ptr) == next_min_row && col < next_min_col) { // The first element in this column is in a subsequent row that we // already have another element for, but the column index is less so @@ -637,25 +639,25 @@ } } } - + // Restart the search in the next row. - for (uword col = 0; col <= iterator_base::internal_col; ++col) + for(uword col = 0; col <= iterator_base::internal_col; ++col) { // Find the first element with row greater than or equal to in_row + 1. const uword col_offset = iterator_base::M->col_ptrs[col ]; const uword next_col_offset = iterator_base::M->col_ptrs[col + 1]; - + const uword* start_ptr = &iterator_base::M->row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->row_indices[next_col_offset]; - - if (start_ptr != end_ptr) + + if(start_ptr != end_ptr) { const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, internal_row + 1); - - if (pos_ptr != end_ptr) + + if(pos_ptr != end_ptr) { // We found something in the column, but is the row index correct? - if ((*pos_ptr) == internal_row + 1) + if((*pos_ptr) == internal_row + 1) { // Exact match---so we are done. iterator_base::internal_col = col; @@ -663,15 +665,15 @@ actual_pos = col_offset + (pos_ptr - start_ptr); return *this; } - else if ((*pos_ptr) < next_min_row) + else if((*pos_ptr) < next_min_row) { - // The first element in this column is in a subsequent row, but it's - // the minimum row we've seen so far. + // The first element in this column is in a subsequent row, + // but it's the minimum row we've seen so far. next_min_row = (*pos_ptr); next_min_col = col; next_actual_pos = col_offset + (pos_ptr - start_ptr); } - else if ((*pos_ptr) == next_min_row && col < next_min_col) + else if((*pos_ptr) == next_min_row && col < next_min_col) { // The first element in this column is in a subsequent row that we // already have another element for, but the column index is less so @@ -682,11 +684,11 @@ } } } - + iterator_base::internal_col = next_min_col; internal_row = next_min_row; actual_pos = next_actual_pos; - + return *this; // Now we are done. } @@ -702,9 +704,9 @@ SpMat::const_row_iterator::operator++(int) { typename SpMat::const_row_iterator tmp(*this); - + ++(*this); - + return tmp; } @@ -719,45 +721,45 @@ typename SpMat::const_row_iterator& SpMat::const_row_iterator::operator--() { - if (iterator_base::internal_pos == 0) + if(iterator_base::internal_pos == 0) { // Do nothing; we are already at the beginning. return *this; } - + iterator_base::internal_pos--; - + // We have to search backwards. We'll do this by going backwards over columns // and seeing if we find an element in the same row. uword max_row = 0; uword max_col = 0; uword next_actual_pos = 0; - - //for (uword col = iterator_base::internal_col; col > 1; --col) - for (uword col = iterator_base::internal_col; col >= 1; --col) + + //for(uword col = iterator_base::internal_col; col > 1; --col) + for(uword col = iterator_base::internal_col; col >= 1; --col) { // Find the first element with row greater than or equal to in_row + 1. const uword col_offset = iterator_base::M->col_ptrs[col - 1]; const uword next_col_offset = iterator_base::M->col_ptrs[col ]; - + const uword* start_ptr = &iterator_base::M->row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->row_indices[next_col_offset]; - - if (start_ptr != end_ptr) + + if(start_ptr != end_ptr) { // There are elements in this column. const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, internal_row + 1); - - if (pos_ptr != start_ptr) + + if(pos_ptr != start_ptr) { // The element before pos_ptr is the one we are interested in. - if (*(pos_ptr - 1) > max_row) + if(*(pos_ptr - 1) > max_row) { max_row = *(pos_ptr - 1); max_col = col - 1; next_actual_pos = col_offset + (pos_ptr - 1 - start_ptr); } - else if (*(pos_ptr - 1) == max_row && (col - 1) > max_col) + else if(*(pos_ptr - 1) == max_row && (col - 1) > max_col) { max_col = col - 1; next_actual_pos = col_offset + (pos_ptr - 1 - start_ptr); @@ -765,49 +767,49 @@ } } } - + // Now loop around to the columns at the end of the matrix. - for (uword col = iterator_base::M->n_cols - 1; col >= iterator_base::internal_col; --col) + for(uword col = iterator_base::M->n_cols - 1; col >= iterator_base::internal_col; --col) { // Find the first element with row greater than or equal to in_row + 1. const uword col_offset = iterator_base::M->col_ptrs[col ]; const uword next_col_offset = iterator_base::M->col_ptrs[col + 1]; - + const uword* start_ptr = &iterator_base::M->row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->row_indices[next_col_offset]; - - if (start_ptr != end_ptr) + + if(start_ptr != end_ptr) { // There are elements in this column. const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, internal_row); - - if (pos_ptr != start_ptr) + + if(pos_ptr != start_ptr) { // There are elements in this column with row index < internal_row. - if (*(pos_ptr - 1) > max_row) + if(*(pos_ptr - 1) > max_row) { max_row = *(pos_ptr - 1); max_col = col; next_actual_pos = col_offset + (pos_ptr - 1 - start_ptr); } - else if (*(pos_ptr - 1) == max_row && col > max_col) + else if(*(pos_ptr - 1) == max_row && col > max_col) { max_col = col; next_actual_pos = col_offset + (pos_ptr - 1 - start_ptr); } } } - - if (col == 0) // Catch edge case that the loop termination condition won't. + + if(col == 0) // Catch edge case that the loop termination condition won't. { break; } } - + iterator_base::internal_col = max_col; internal_row = max_row; actual_pos = next_actual_pos; - + return *this; } @@ -823,9 +825,9 @@ SpMat::const_row_iterator::operator--(int) { typename SpMat::const_row_iterator tmp(*this); - + --(*this); - + return tmp; } @@ -926,10 +928,10 @@ template inline arma_hot -SpValProxy > +SpValProxy< SpMat > SpMat::row_iterator::operator*() { - return SpValProxy >( + return SpValProxy< SpMat >( const_row_iterator::internal_row, iterator_base::internal_col, access::rw(*iterator_base::M), @@ -945,6 +947,7 @@ SpMat::row_iterator::operator++() { const_row_iterator::operator++(); + return *this; } @@ -957,9 +960,9 @@ SpMat::row_iterator::operator++(int) { typename SpMat::row_iterator tmp(*this); - + const_row_iterator::operator++(); - + return tmp; } @@ -972,6 +975,7 @@ SpMat::row_iterator::operator--() { const_row_iterator::operator--(); + return *this; } @@ -984,10 +988,11 @@ SpMat::row_iterator::operator--(int) { typename SpMat::row_iterator tmp(*this); - + const_row_iterator::operator--(); - + return tmp; } + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpMat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpMat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,9 +31,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -67,12 +69,12 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); - + init_cold(in_rows, in_cols); } @@ -86,9 +88,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -105,9 +107,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -125,9 +127,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -154,12 +156,12 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); - + init(std::string(text)); } @@ -171,7 +173,7 @@ SpMat::operator=(const char* text) { arma_extra_debug_sigprint(); - + init(std::string(text)); return *this; @@ -187,12 +189,12 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint(); - + init(text); } @@ -220,52 +222,48 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); - + init(x); } -#if defined(ARMA_USE_CXX11) - - template - inline - SpMat::SpMat(SpMat&& in_mat) - : n_rows(0) - , n_cols(0) - , n_elem(0) - , n_nonzero(0) - , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) - { - arma_extra_debug_sigprint_this(this); - arma_extra_debug_sigprint(arma_str::format("this = %x in_mat = %x") % this % &in_mat); - - (*this).steal_mem(in_mat); - } - +template +inline +SpMat::SpMat(SpMat&& in_mat) + : n_rows(0) + , n_cols(0) + , n_elem(0) + , n_nonzero(0) + , vec_state(0) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) + { + arma_extra_debug_sigprint_this(this); + arma_extra_debug_sigprint(arma_str::format("this = %x in_mat = %x") % this % &in_mat); + (*this).steal_mem(in_mat); + } + + + +template +inline +SpMat& +SpMat::operator=(SpMat&& in_mat) + { + arma_extra_debug_sigprint(arma_str::format("this = %x in_mat = %x") % this % &in_mat); - template - inline - SpMat& - SpMat::operator=(SpMat&& in_mat) - { - arma_extra_debug_sigprint(arma_str::format("this = %x in_mat = %x") % this % &in_mat); - - (*this).steal_mem(in_mat); - - return *this; - } + (*this).steal_mem(in_mat); -#endif + return *this; + } @@ -277,9 +275,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -316,9 +314,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -328,7 +326,7 @@ const Mat& locs = locs_tmp.M; const Mat& vals = vals_tmp.M; - arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object is not a vector" ); + arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object must be a vector" ); arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): locations matrix must have two rows" ); arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number of locations is different than number of values" ); @@ -343,15 +341,12 @@ const uword N_old = vals.n_elem; uword N_new = 0; - for(uword i = 0; i < N_old; ++i) - { - if(vals[i] != eT(0)) { ++N_new; } - } + for(uword i=0; i < N_old; ++i) { N_new += (vals[i] != eT(0)) ? uword(1) : uword(0); } if(N_new != N_old) { - Col filtered_vals(N_new); - Mat filtered_locs(2, N_new); + Col filtered_vals( N_new, arma_nozeros_indicator()); + Mat filtered_locs(2, N_new, arma_nozeros_indicator()); uword index = 0; for(uword i = 0; i < N_old; ++i) @@ -392,9 +387,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -404,27 +399,24 @@ const Mat& locs = locs_tmp.M; const Mat& vals = vals_tmp.M; - arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object is not a vector" ); + arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object must be a vector" ); arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): locations matrix must have two rows" ); arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number of locations is different than number of values" ); init_cold(in_n_rows, in_n_cols); - + // Ensure that there are no zeros, unless the user asked not to. if(check_for_zeros) { const uword N_old = vals.n_elem; uword N_new = 0; - for(uword i = 0; i < N_old; ++i) - { - if(vals[i] != eT(0)) { ++N_new; } - } + for(uword i=0; i < N_old; ++i) { N_new += (vals[i] != eT(0)) ? uword(1) : uword(0); } if(N_new != N_old) { - Col filtered_vals(N_new); - Mat filtered_locs(2, N_new); + Col filtered_vals( N_new, arma_nozeros_indicator()); + Mat filtered_locs(2, N_new, arma_nozeros_indicator()); uword index = 0; for(uword i = 0; i < N_old; ++i) @@ -464,9 +456,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -476,27 +468,24 @@ const Mat& locs = locs_tmp.M; const Mat& vals = vals_tmp.M; - arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object is not a vector" ); + arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object must be a vector" ); arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): locations matrix must have two rows" ); arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number of locations is different than number of values" ); init_cold(in_n_rows, in_n_cols); - + // Ensure that there are no zeros, unless the user asked not to. if(check_for_zeros) { const uword N_old = vals.n_elem; uword N_new = 0; - for(uword i = 0; i < N_old; ++i) - { - if(vals[i] != eT(0)) { ++N_new; } - } + for(uword i=0; i < N_old; ++i) { N_new += (vals[i] != eT(0)) ? uword(1) : uword(0); } if(N_new != N_old) { - Col filtered_vals(N_new); - Mat filtered_locs(2, N_new); + Col filtered_vals( N_new, arma_nozeros_indicator()); + Mat filtered_locs(2, N_new, arma_nozeros_indicator()); uword index = 0; for(uword i = 0; i < N_old; ++i) @@ -550,9 +539,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -564,9 +553,9 @@ const Mat& colptr = colptr_tmp.M; const Mat& vals = vals_tmp.M; - arma_debug_check( (rowind.is_vec() == false), "SpMat::SpMat(): given 'rowind' object is not a vector" ); - arma_debug_check( (colptr.is_vec() == false), "SpMat::SpMat(): given 'colptr' object is not a vector" ); - arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object is not a vector" ); + arma_debug_check( (rowind.is_vec() == false), "SpMat::SpMat(): given 'rowind' object must be a vector" ); + arma_debug_check( (colptr.is_vec() == false), "SpMat::SpMat(): given 'colptr' object must be a vector" ); + arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object must be a vector" ); // Resize to correct number of elements (this also sets n_nonzero) init_cold(in_n_rows, in_n_cols, vals.n_elem); @@ -601,9 +590,9 @@ init(1, 1, 1); // Sets col_ptrs to 0. // Manually set element. - access::rw(values[0]) = val; + access::rw(values[0]) = val; access::rw(row_indices[0]) = 0; - access::rw(col_ptrs[1]) = 1; + access::rw(col_ptrs[1]) = 1; } else { @@ -782,16 +771,14 @@ { 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; @@ -808,17 +795,17 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); - + typedef typename T1::elem_type T; - + // Make sure the type is compatible. arma_type_check(( is_same_type< eT, T >::no )); - + op_type::apply(*this, expr); } @@ -838,9 +825,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint(); @@ -876,7 +863,7 @@ uword cur_pos = 0; - while ((x_it != x_end) || (y_it != y_end)) + while((x_it != x_end) || (y_it != y_end)) { if(x_it == y_it) // if we are at the same place { @@ -911,7 +898,7 @@ } // Now fix the column pointers; they are supposed to be a sum. - for (uword c = 1; c <= n_cols; ++c) + for(uword c = 1; c <= n_cols; ++c) { access::rw(col_ptrs[c]) += col_ptrs[c - 1]; } @@ -929,12 +916,12 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); - + (*this).operator=(x); } @@ -978,10 +965,7 @@ const eT* x_mem = x.memptr(); - for(uword i = 0; i < x_n_elem; ++i) - { - n += (x_mem[i] != eT(0)) ? uword(1) : uword(0); - } + for(uword i=0; i < x_n_elem; ++i) { n += (x_mem[i] != eT(0)) ? uword(1) : uword(0); } init(x_n_rows, x_n_cols, n); @@ -1051,13 +1035,13 @@ SpMat::operator*=(const Base& y) { arma_extra_debug_sigprint(); - + sync_csc(); const Proxy p(y.get_ref()); - + arma_debug_assert_mul_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "matrix multiplication"); - + // We assume the matrix structure is such that we will end up with a sparse // matrix. Assuming that every entry in the dense matrix is nonzero (which is // a fairly valid assumption), each row with any nonzero elements in it (in this @@ -1066,7 +1050,7 @@ // (using the quasi-linked-list idea from SYMBMM -- see spglue_times_meat.hpp). podarray index(n_rows); index.fill(n_rows); // Fill with invalid links. - + uword last_index = n_rows + 1; for(uword i = 0; i < n_nonzero; ++i) { @@ -1076,7 +1060,7 @@ last_index = row_indices[i]; } } - + // Now count the number of rows which have nonzero elements. uword nonzero_rows = 0; while(last_index != n_rows + 1) @@ -1084,29 +1068,29 @@ ++nonzero_rows; last_index = index[last_index]; } - + SpMat z(arma_reserve_indicator(), n_rows, p.get_n_cols(), (nonzero_rows * p.get_n_cols())); // upper bound on size - + // Now we have to fill all the elements using a modification of the NUMBMM algorithm. uword cur_pos = 0; - + podarray partial_sums(n_rows); partial_sums.zeros(); - + for(uword lcol = 0; lcol < n_cols; ++lcol) { const_iterator it = begin(); const_iterator it_end = end(); - + while(it != it_end) { const eT value = (*it); - + partial_sums[it.row()] += (value * p.at(it.col(), lcol)); - + ++it; } - + // Now add all partial sums to the matrix. for(uword i = 0; i < n_rows; ++i) { @@ -1121,13 +1105,13 @@ } } } - + // Now fix the column pointers. for(uword c = 1; c <= z.n_cols; ++c) { access::rw(z.col_ptrs[c]) += z.col_ptrs[c - 1]; } - + // Resize to final correct size. z.mem_resize(z.col_ptrs[z.n_cols]); @@ -1139,10 +1123,7 @@ -/** - * Don't use this function. It's not mathematically well-defined and wastes - * cycles to trash all your data. This is dumb. - */ +// NOTE: use of this function is not advised; it is implemented only for completeness template template inline @@ -1150,7 +1131,7 @@ SpMat::operator/=(const Base& x) { arma_extra_debug_sigprint(); - + sync_csc(); SpMat tmp = (*this) / x.get_ref(); @@ -1169,59 +1150,15 @@ SpMat::operator%=(const Base& x) { arma_extra_debug_sigprint(); - - sync_csc(); - - const Proxy p(x.get_ref()); - - arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise multiplication"); - - // Count the number of elements we will need. - const_iterator it = begin(); - const_iterator it_end = end(); - - uword new_n_nonzero = 0; - - while(it != it_end) - { - // use_at == false can't save us any work here - if(((*it) * p.at(it.row(), it.col())) != eT(0)) - { - ++new_n_nonzero; - } - ++it; - } - - SpMat tmp(arma_reserve_indicator(), n_rows, n_cols, new_n_nonzero); - const_iterator c_it = begin(); - const_iterator c_it_end = end(); + SpMat tmp; - uword cur_pos = 0; + // Just call the other order (these operations are commutative) + // TODO: if there is a matrix size mismatch, the debug assert will print the matrix sizes in wrong order + spglue_schur_misc::dense_schur_sparse(tmp, x.get_ref(), (*this)); - while(c_it != c_it_end) - { - // use_at == false can't save us any work here - const eT val = (*c_it) * p.at(c_it.row(), c_it.col()); - if(val != eT(0)) - { - access::rw(tmp.values[cur_pos]) = val; - access::rw(tmp.row_indices[cur_pos]) = c_it.row(); - ++access::rw(tmp.col_ptrs[c_it.col() + 1]); - ++cur_pos; - } - - ++c_it; - } - - // Fix column pointers. - for(uword c = 1; c <= n_cols; ++c) - { - access::rw(tmp.col_ptrs[c]) += tmp.col_ptrs[c - 1]; - } - steal_mem(tmp); - + return *this; } @@ -1236,9 +1173,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -1255,51 +1192,38 @@ { arma_extra_debug_sigprint(); - const Proxy P(expr.m); + const diagmat_proxy P(expr.m); - const uword P_n_rows = P.get_n_rows(); - const uword P_n_cols = P.get_n_cols(); + const uword max_n_nonzero = (std::min)(P.n_rows, P.n_cols); - const bool P_is_vec = (P_n_rows == 1) || (P_n_cols == 1); + // resize memory to upper bound + init(P.n_rows, P.n_cols, max_n_nonzero); - if(P_is_vec) // generate diagonal sparse matrix from dense vector + uword count = 0; + + for(uword i=0; i < max_n_nonzero; ++i) { - const uword N = (P_n_rows == 1) ? P_n_cols : P_n_rows; - - (*this).eye(N,N); + const eT val = P[i]; - eT* this_values = access::rwp(values); - - if(Proxy::use_at == false) - { - typename Proxy::ea_type P_ea = P.get_ea(); - - for(uword i=0; i < N; ++i) { this_values[i] = P_ea[i]; } - } - else + if(val != eT(0)) { - if(P_n_rows == 1) - { - for(uword i=0; i < N; ++i) { this_values[i] = P.at(0,i); } - } - else - { - for(uword i=0; i < N; ++i) { this_values[i] = P.at(i,0); } - } + access::rw(values[count]) = val; + access::rw(row_indices[count]) = i; + access::rw(col_ptrs[i + 1])++; + ++count; } } - else // generate diagonal sparse matrix from dense matrix + + // fix column pointers to be cumulative + for(uword i = 1; i < n_cols + 1; ++i) { - (*this).eye(P_n_rows, P_n_cols); - - eT* this_values = access::rwp(values); - - const uword N = (std::min)(P_n_rows, P_n_cols); - - for(uword i=0; i < N; ++i) { this_values[i] = P.at(i,i); } + access::rw(col_ptrs[i]) += col_ptrs[i - 1]; } - remove_zeros(); + // quick resize without reallocating memory and copying data + access::rw( n_nonzero) = count; + access::rw( values[count]) = eT(0); + access::rw(row_indices[count]) = uword(0); return *this; } @@ -1392,12 +1316,12 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); - + (*this).operator=(X); } @@ -1415,35 +1339,62 @@ X.m.sync_csc(); const bool alias = (this == &(X.m)); - - if(alias == false) + + if(alias) + { + SpMat tmp(X); + + steal_mem(tmp); + } + else { init(X.n_rows, X.n_cols, X.n_nonzero); - - typename SpSubview::const_iterator it = X.begin(); - typename SpSubview::const_iterator it_end = X.end(); - - while(it != it_end) + + if(X.n_rows == X.m.n_rows) { - access::rw(row_indices[it.pos()]) = it.row(); - access::rw(values[it.pos()]) = (*it); - ++access::rw(col_ptrs[it.col() + 1]); - ++it; + const uword sv_col_start = X.aux_col1; + const uword sv_col_end = X.aux_col1 + X.n_cols - 1; + + typename SpMat::const_col_iterator m_it = X.m.begin_col(sv_col_start); + typename SpMat::const_col_iterator m_it_end = X.m.end_col(sv_col_end); + + uword count = 0; + + while(m_it != m_it_end) + { + const uword m_it_col_adjusted = m_it.col() - sv_col_start; + + access::rw(row_indices[count]) = m_it.row(); + access::rw(values[count]) = (*m_it); + ++access::rw(col_ptrs[m_it_col_adjusted + 1]); + + count++; + + ++m_it; + } } - + else + { + typename SpSubview::const_iterator it = X.begin(); + typename SpSubview::const_iterator it_end = X.end(); + + while(it != it_end) + { + const uword it_pos = it.pos(); + + access::rw(row_indices[it_pos]) = it.row(); + access::rw(values[it_pos]) = (*it); + ++access::rw(col_ptrs[it.col() + 1]); + ++it; + } + } + // Now sum column pointers. for(uword c = 1; c <= n_cols; ++c) { access::rw(col_ptrs[c]) += col_ptrs[c - 1]; } } - else - { - // Create it in a temporary. - SpMat tmp(X); - - steal_mem(tmp); - } return *this; } @@ -1543,32 +1494,45 @@ template +template inline -SpMat::SpMat(const spdiagview& X) +SpMat::SpMat(const SpSubview_col_list& X) : n_rows(0) , n_cols(0) , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); - - spdiagview::extract(*this, X); + + SpSubview_col_list::extract(*this, X); } template +template inline SpMat& -SpMat::operator=(const spdiagview& X) +SpMat::operator=(const SpSubview_col_list& X) { arma_extra_debug_sigprint(); - spdiagview::extract(*this, X); + const bool alias = (this == &(X.m)); + + if(alias == false) + { + SpSubview_col_list::extract(*this, X); + } + else + { + SpMat tmp(X); + + steal_mem(tmp); + } return *this; } @@ -1576,113 +1540,225 @@ template +template inline SpMat& -SpMat::operator+=(const spdiagview& X) +SpMat::operator+=(const SpSubview_col_list& X) { arma_extra_debug_sigprint(); - const SpMat tmp(X); + SpSubview_col_list::plus_inplace(*this, X); - return (*this).operator+=(tmp); + return *this; } template +template inline SpMat& -SpMat::operator-=(const spdiagview& X) +SpMat::operator-=(const SpSubview_col_list& X) { arma_extra_debug_sigprint(); - const SpMat tmp(X); + SpSubview_col_list::minus_inplace(*this, X); - return (*this).operator-=(tmp); + return *this; } template +template inline SpMat& -SpMat::operator*=(const spdiagview& X) +SpMat::operator*=(const SpSubview_col_list& X) { arma_extra_debug_sigprint(); - const SpMat tmp(X); + sync_csc(); - return (*this).operator*=(tmp); + SpMat z = (*this) * X; + + steal_mem(z); + + return *this; } template +template inline SpMat& -SpMat::operator%=(const spdiagview& X) +SpMat::operator%=(const SpSubview_col_list& X) { arma_extra_debug_sigprint(); - const SpMat tmp(X); + SpSubview_col_list::schur_inplace(*this, X); - return (*this).operator%=(tmp); + return *this; } template +template inline SpMat& -SpMat::operator/=(const spdiagview& X) +SpMat::operator/=(const SpSubview_col_list& X) { arma_extra_debug_sigprint(); - const SpMat tmp(X); + SpSubview_col_list::div_inplace(*this, X); - return (*this).operator/=(tmp); + return *this; } template -template inline -SpMat::SpMat(const SpOp& X) +SpMat::SpMat(const spdiagview& X) : n_rows(0) , n_cols(0) , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) // set in application of sparse operation - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); - arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); - - spop_type::apply(*this, X); - - sync_csc(); // in case apply() used element accessors - invalidate_cache(); // in case apply() modified the CSC representation + spdiagview::extract(*this, X); } template -template inline SpMat& -SpMat::operator=(const SpOp& X) +SpMat::operator=(const spdiagview& X) { arma_extra_debug_sigprint(); - arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); - - spop_type::apply(*this, X); + spdiagview::extract(*this, X); - sync_csc(); // in case apply() used element accessors + return *this; + } + + + +template +inline +SpMat& +SpMat::operator+=(const spdiagview& X) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(X); + + return (*this).operator+=(tmp); + } + + + +template +inline +SpMat& +SpMat::operator-=(const spdiagview& X) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(X); + + return (*this).operator-=(tmp); + } + + + +template +inline +SpMat& +SpMat::operator*=(const spdiagview& X) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(X); + + return (*this).operator*=(tmp); + } + + + +template +inline +SpMat& +SpMat::operator%=(const spdiagview& X) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(X); + + return (*this).operator%=(tmp); + } + + + +template +inline +SpMat& +SpMat::operator/=(const spdiagview& X) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(X); + + return (*this).operator/=(tmp); + } + + + +template +template +inline +SpMat::SpMat(const SpOp& X) + : n_rows(0) + , n_cols(0) + , n_elem(0) + , n_nonzero(0) + , vec_state(0) + , values(nullptr) // set in application of sparse operation + , row_indices(nullptr) + , col_ptrs(nullptr) + { + arma_extra_debug_sigprint_this(this); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + + spop_type::apply(*this, X); + + sync_csc(); // in case apply() used element accessors + invalidate_cache(); // in case apply() modified the CSC representation + } + + + +template +template +inline +SpMat& +SpMat::operator=(const SpOp& X) + { + arma_extra_debug_sigprint(); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + + spop_type::apply(*this, X); + + sync_csc(); // in case apply() used element accessors invalidate_cache(); // in case apply() modified the CSC representation return *this; @@ -1794,9 +1870,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -1934,9 +2010,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -1960,7 +2036,7 @@ sync_csc(); // in case apply() used element accessors invalidate_cache(); // in case apply() modified the CSC representation - + return *this; } @@ -1977,7 +2053,7 @@ sync_csc(); const SpMat m(X); - + return (*this).operator+=(m); } @@ -1994,7 +2070,7 @@ sync_csc(); const SpMat m(X); - + return (*this).operator-=(m); } @@ -2011,7 +2087,7 @@ sync_csc(); const SpMat m(X); - + return (*this).operator*=(m); } @@ -2028,7 +2104,7 @@ sync_csc(); const SpMat m(X); - + return (*this).operator%=(m); } @@ -2045,7 +2121,7 @@ sync_csc(); const SpMat m(X); - + return (*this).operator/=(m); } @@ -2060,9 +2136,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(0) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2179,35 +2255,35 @@ template arma_inline -SpSubview +SpSubview_row SpMat::row(const uword row_num) { arma_extra_debug_sigprint(); - arma_debug_check(row_num >= n_rows, "SpMat::row(): out of bounds"); - - return SpSubview(*this, row_num, 0, 1, n_cols); + arma_debug_check_bounds(row_num >= n_rows, "SpMat::row(): out of bounds"); + + return SpSubview_row(*this, row_num); } template arma_inline -const SpSubview +const SpSubview_row SpMat::row(const uword row_num) const { arma_extra_debug_sigprint(); - arma_debug_check(row_num >= n_rows, "SpMat::row(): out of bounds"); - - return SpSubview(*this, row_num, 0, 1, n_cols); + arma_debug_check_bounds(row_num >= n_rows, "SpMat::row(): out of bounds"); + + return SpSubview_row(*this, row_num); } template inline -SpSubview +SpSubview_row SpMat::operator()(const uword row_num, const span& col_span) { arma_extra_debug_sigprint(); @@ -2220,7 +2296,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( (row_num >= n_rows) || @@ -2229,14 +2305,14 @@ "SpMat::operator(): indices out of bounds or incorrectly used" ); - return SpSubview(*this, row_num, in_col1, 1, submat_n_cols); + return SpSubview_row(*this, row_num, in_col1, submat_n_cols); } template inline -const SpSubview +const SpSubview_row SpMat::operator()(const uword row_num, const span& col_span) const { arma_extra_debug_sigprint(); @@ -2249,7 +2325,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( (row_num >= n_rows) || @@ -2258,42 +2334,42 @@ "SpMat::operator(): indices out of bounds or incorrectly used" ); - return SpSubview(*this, row_num, in_col1, 1, submat_n_cols); + return SpSubview_row(*this, row_num, in_col1, submat_n_cols); } template arma_inline -SpSubview +SpSubview_col SpMat::col(const uword col_num) { arma_extra_debug_sigprint(); - arma_debug_check(col_num >= n_cols, "SpMat::col(): out of bounds"); - - return SpSubview(*this, 0, col_num, n_rows, 1); + arma_debug_check_bounds(col_num >= n_cols, "SpMat::col(): out of bounds"); + + return SpSubview_col(*this, col_num); } template arma_inline -const SpSubview +const SpSubview_col SpMat::col(const uword col_num) const { arma_extra_debug_sigprint(); - arma_debug_check(col_num >= n_cols, "SpMat::col(): out of bounds"); - - return SpSubview(*this, 0, col_num, n_rows, 1); + arma_debug_check_bounds(col_num >= n_cols, "SpMat::col(): out of bounds"); + + return SpSubview_col(*this, col_num); } template inline -SpSubview +SpSubview_col SpMat::operator()(const span& row_span, const uword col_num) { arma_extra_debug_sigprint(); @@ -2306,7 +2382,7 @@ const uword in_row2 = row_span.b; const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; - arma_debug_check + arma_debug_check_bounds ( (col_num >= n_cols) || @@ -2315,14 +2391,14 @@ "SpMat::operator(): indices out of bounds or incorrectly used" ); - return SpSubview(*this, in_row1, col_num, submat_n_rows, 1); + return SpSubview_col(*this, col_num, in_row1, submat_n_rows); } template inline -const SpSubview +const SpSubview_col SpMat::operator()(const span& row_span, const uword col_num) const { arma_extra_debug_sigprint(); @@ -2335,7 +2411,7 @@ const uword in_row2 = row_span.b; const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; - arma_debug_check + arma_debug_check_bounds ( (col_num >= n_cols) || @@ -2344,7 +2420,7 @@ "SpMat::operator(): indices out of bounds or incorrectly used" ); - return SpSubview(*this, in_row1, col_num, submat_n_rows, 1); + return SpSubview_col(*this, col_num, in_row1, submat_n_rows); } @@ -2356,14 +2432,14 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "SpMat::rows(): indices out of bounds or incorrectly used" ); - + const uword subview_n_rows = in_row2 - in_row1 + 1; - + return SpSubview(*this, in_row1, 0, subview_n_rows, n_cols); } @@ -2376,14 +2452,14 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "SpMat::rows(): indices out of bounds or incorrectly used" ); - + const uword subview_n_rows = in_row2 - in_row1 + 1; - + return SpSubview(*this, in_row1, 0, subview_n_rows, n_cols); } @@ -2396,14 +2472,14 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "SpMat::cols(): indices out of bounds or incorrectly used" ); - + const uword subview_n_cols = in_col2 - in_col1 + 1; - + return SpSubview(*this, 0, in_col1, n_rows, subview_n_cols); } @@ -2416,14 +2492,14 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "SpMat::cols(): indices out of bounds or incorrectly used" ); - + const uword subview_n_cols = in_col2 - in_col1 + 1; - + return SpSubview(*this, 0, in_col1, n_rows, subview_n_cols); } @@ -2436,15 +2512,15 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "SpMat::submat(): indices out of bounds or incorrectly used" ); - + const uword subview_n_rows = in_row2 - in_row1 + 1; const uword subview_n_cols = in_col2 - in_col1 + 1; - + return SpSubview(*this, in_row1, in_col1, subview_n_rows, subview_n_cols); } @@ -2457,15 +2533,15 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "SpMat::submat(): indices out of bounds or incorrectly used" ); - + const uword subview_n_rows = in_row2 - in_row1 + 1; const uword subview_n_cols = in_col2 - in_col1 + 1; - + return SpSubview(*this, in_row1, in_col1, subview_n_rows, subview_n_cols); } @@ -2484,7 +2560,7 @@ const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)), "SpMat::submat(): indices or size out of bounds" @@ -2508,7 +2584,7 @@ const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - arma_debug_check + arma_debug_check_bounds ( ((in_row1 >= l_n_rows) || (in_col1 >= l_n_cols) || ((in_row1 + s_n_rows) > l_n_rows) || ((in_col1 + s_n_cols) > l_n_cols)), "SpMat::submat(): indices or size out of bounds" @@ -2540,7 +2616,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -2575,7 +2651,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -2644,7 +2720,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_rows), "SpMat::head_rows(): size out of bounds"); + arma_debug_check_bounds( (N > n_rows), "SpMat::head_rows(): size out of bounds" ); return SpSubview(*this, 0, 0, N, n_cols); } @@ -2658,7 +2734,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_rows), "SpMat::head_rows(): size out of bounds"); + arma_debug_check_bounds( (N > n_rows), "SpMat::head_rows(): size out of bounds" ); return SpSubview(*this, 0, 0, N, n_cols); } @@ -2672,7 +2748,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_rows), "SpMat::tail_rows(): size out of bounds"); + arma_debug_check_bounds( (N > n_rows), "SpMat::tail_rows(): size out of bounds" ); const uword start_row = n_rows - N; @@ -2688,7 +2764,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_rows), "SpMat::tail_rows(): size out of bounds"); + arma_debug_check_bounds( (N > n_rows), "SpMat::tail_rows(): size out of bounds" ); const uword start_row = n_rows - N; @@ -2704,7 +2780,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_cols), "SpMat::head_cols(): size out of bounds"); + arma_debug_check_bounds( (N > n_cols), "SpMat::head_cols(): size out of bounds" ); return SpSubview(*this, 0, 0, n_rows, N); } @@ -2718,7 +2794,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_cols), "SpMat::head_cols(): size out of bounds"); + arma_debug_check_bounds( (N > n_cols), "SpMat::head_cols(): size out of bounds" ); return SpSubview(*this, 0, 0, n_rows, N); } @@ -2732,7 +2808,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_cols), "SpMat::tail_cols(): size out of bounds"); + arma_debug_check_bounds( (N > n_cols), "SpMat::tail_cols(): size out of bounds" ); const uword start_col = n_cols - N; @@ -2748,7 +2824,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > n_cols), "SpMat::tail_cols(): size out of bounds"); + arma_debug_check_bounds( (N > n_cols), "SpMat::tail_cols(): size out of bounds" ); const uword start_col = n_cols - N; @@ -2757,6 +2833,32 @@ +template +template +arma_inline +SpSubview_col_list +SpMat::cols(const Base& indices) + { + arma_extra_debug_sigprint(); + + return SpSubview_col_list(*this, indices); + } + + + +template +template +arma_inline +const SpSubview_col_list +SpMat::cols(const Base& indices) const + { + arma_extra_debug_sigprint(); + + return SpSubview_col_list(*this, indices); + } + + + //! creation of spdiagview (diagonal) template inline @@ -2768,7 +2870,7 @@ const uword row_offset = (in_id < 0) ? uword(-in_id) : 0; const uword col_offset = (in_id > 0) ? uword( in_id) : 0; - arma_debug_check + arma_debug_check_bounds ( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "SpMat::diag(): requested diagonal out of bounds" @@ -2792,7 +2894,7 @@ const uword row_offset = uword( (in_id < 0) ? -in_id : 0 ); const uword col_offset = uword( (in_id > 0) ? in_id : 0 ); - arma_debug_check + arma_debug_check_bounds ( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "SpMat::diag(): requested diagonal out of bounds" @@ -2812,7 +2914,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ((in_row1 >= n_rows) || (in_row2 >= n_rows)), "SpMat::swap_rows(): out of bounds" ); + arma_debug_check_bounds( ((in_row1 >= n_rows) || (in_row2 >= n_rows)), "SpMat::swap_rows(): out of bounds" ); if(in_row1 == in_row2) { return; } @@ -2824,85 +2926,85 @@ // We will try to avoid using the at() call since it is expensive, instead preferring to use an iterator to track our position. uword col1 = (in_row1 < in_row2) ? in_row1 : in_row2; uword col2 = (in_row1 < in_row2) ? in_row2 : in_row1; - - for (uword lcol = 0; lcol < n_cols; lcol++) + + for(uword lcol = 0; lcol < n_cols; lcol++) { // If there is nothing in this column we can ignore it. - if (col_ptrs[lcol] == col_ptrs[lcol + 1]) + if(col_ptrs[lcol] == col_ptrs[lcol + 1]) { continue; } - + // These will represent the positions of the items themselves. uword loc1 = n_nonzero + 1; uword loc2 = n_nonzero + 1; - - for (uword search_pos = col_ptrs[lcol]; search_pos < col_ptrs[lcol + 1]; search_pos++) + + for(uword search_pos = col_ptrs[lcol]; search_pos < col_ptrs[lcol + 1]; search_pos++) { - if (row_indices[search_pos] == col1) + if(row_indices[search_pos] == col1) { loc1 = search_pos; } - - if (row_indices[search_pos] == col2) + + if(row_indices[search_pos] == col2) { loc2 = search_pos; break; // No need to look any further. } } - + // There are four cases: we found both elements; we found one element (loc1); we found one element (loc2); we found zero elements. // If we found zero elements no work needs to be done and we can continue to the next column. - if ((loc1 != (n_nonzero + 1)) && (loc2 != (n_nonzero + 1))) + if((loc1 != (n_nonzero + 1)) && (loc2 != (n_nonzero + 1))) { // This is an easy case: just swap the values. No index modifying necessary. eT tmp = values[loc1]; access::rw(values[loc1]) = values[loc2]; access::rw(values[loc2]) = tmp; } - else if (loc1 != (n_nonzero + 1)) // We only found loc1 and not loc2. + else if(loc1 != (n_nonzero + 1)) // We only found loc1 and not loc2. { // We need to find the correct place to move our value to. It will be forward (not backwards) because in_row2 > in_row1. // Each iteration of the loop swaps the current value (loc1) with (loc1 + 1); in this manner we move our value down to where it should be. - while (((loc1 + 1) < col_ptrs[lcol + 1]) && (row_indices[loc1 + 1] < in_row2)) + while(((loc1 + 1) < col_ptrs[lcol + 1]) && (row_indices[loc1 + 1] < in_row2)) { // Swap both the values and the indices. The column should not change. eT tmp = values[loc1]; access::rw(values[loc1]) = values[loc1 + 1]; access::rw(values[loc1 + 1]) = tmp; - + uword tmp_index = row_indices[loc1]; access::rw(row_indices[loc1]) = row_indices[loc1 + 1]; access::rw(row_indices[loc1 + 1]) = tmp_index; - + loc1++; // And increment the counter. } - + // Now set the row index correctly. access::rw(row_indices[loc1]) = in_row2; - + } - else if (loc2 != (n_nonzero + 1)) + else if(loc2 != (n_nonzero + 1)) { // We need to find the correct place to move our value to. It will be backwards (not forwards) because in_row1 < in_row2. // Each iteration of the loop swaps the current value (loc2) with (loc2 - 1); in this manner we move our value up to where it should be. - while (((loc2 - 1) >= col_ptrs[lcol]) && (row_indices[loc2 - 1] > in_row1)) + while(((loc2 - 1) >= col_ptrs[lcol]) && (row_indices[loc2 - 1] > in_row1)) { // Swap both the values and the indices. The column should not change. eT tmp = values[loc2]; access::rw(values[loc2]) = values[loc2 - 1]; access::rw(values[loc2 - 1]) = tmp; - + uword tmp_index = row_indices[loc2]; access::rw(row_indices[loc2]) = row_indices[loc2 - 1]; access::rw(row_indices[loc2 - 1]) = tmp_index; - + loc2--; // And decrement the counter. } - + // Now set the row index correctly. access::rw(row_indices[loc2]) = in_row1; - + } /* else: no need to swap anything; both values are zero */ } @@ -2917,7 +3019,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ((in_col1 >= n_cols) || (in_col2 >= n_cols)), "SpMat::swap_cols(): out of bounds" ); + arma_debug_check_bounds( ((in_col1 >= n_cols) || (in_col2 >= n_cols)), "SpMat::swap_cols(): out of bounds" ); if(in_col1 == in_col2) { return; } @@ -2947,8 +3049,8 @@ { arma_extra_debug_sigprint(); - arma_debug_check (row_num >= n_rows, "SpMat::shed_row(): out of bounds"); - + arma_debug_check_bounds(row_num >= n_rows, "SpMat::shed_row(): out of bounds"); + shed_rows (row_num, row_num); } @@ -2961,8 +3063,8 @@ { arma_extra_debug_sigprint(); - arma_debug_check (col_num >= n_cols, "SpMat::shed_col(): out of bounds"); - + arma_debug_check_bounds(col_num >= n_cols, "SpMat::shed_col(): out of bounds"); + shed_cols(col_num, col_num); } @@ -2975,7 +3077,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "SpMat::shed_rows(): indices out of bounds or incorectly used" @@ -2987,10 +3089,10 @@ // First, count the number of elements we will be removing. uword removing = 0; - for (uword i = 0; i < n_nonzero; ++i) + for(uword i = 0; i < n_nonzero; ++i) { const uword lrow = row_indices[i]; - if (lrow >= in_row1 && lrow <= in_row2) + if(lrow >= in_row1 && lrow <= in_row2) { ++removing; } @@ -2998,7 +3100,7 @@ // Obtain counts of the number of points in each column and store them as the // (invalid) column pointers of the new matrix. - for (uword i = 1; i < n_cols + 1; ++i) + for(uword i = 1; i < n_cols + 1; ++i) { access::rw(newmat.col_ptrs[i]) = col_ptrs[i] - col_ptrs[i - 1]; } @@ -3012,12 +3114,12 @@ const_iterator it_end = end(); uword j = 0; // The index in the new matrix. - while (it != it_end) + while(it != it_end) { const uword lrow = it.row(); const uword lcol = it.col(); - if (lrow >= in_row1 && lrow <= in_row2) + if(lrow >= in_row1 && lrow <= in_row2) { // This element is being removed. Subtract it from the column counts. --access::rw(newmat.col_ptrs[lcol + 1]); @@ -3026,7 +3128,7 @@ { // This element is being kept. We may need to map the row index, // if it is past the section of rows we are removing. - if (lrow > in_row2) + if(lrow > in_row2) { access::rw(newmat.row_indices[j]) = lrow - (in_row2 - in_row1 + 1); } @@ -3043,7 +3145,7 @@ } // Finally, sum the column counts so they are correct column pointers. - for (uword i = 1; i < n_cols + 1; ++i) + for(uword i = 1; i < n_cols + 1; ++i) { access::rw(newmat.col_ptrs[i]) += newmat.col_ptrs[i - 1]; } @@ -3061,7 +3163,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "SpMat::shed_cols(): indices out of bounds or incorrectly used" @@ -3073,35 +3175,35 @@ // First we find the locations in values and row_indices for the column entries. uword col_beg = col_ptrs[in_col1]; uword col_end = col_ptrs[in_col2 + 1]; - + // Then we find the number of entries in the column. uword diff = col_end - col_beg; - - if (diff > 0) + + if(diff > 0) { eT* new_values = memory::acquire (n_nonzero - diff); uword* new_row_indices = memory::acquire(n_nonzero - diff); - + // Copy first part. - if (col_beg != 0) + if(col_beg != 0) { arrayops::copy(new_values, values, col_beg); arrayops::copy(new_row_indices, row_indices, col_beg); } - + // Copy second part. - if (col_end != n_nonzero) + if(col_end != n_nonzero) { arrayops::copy(new_values + col_beg, values + col_end, n_nonzero - col_end); arrayops::copy(new_row_indices + col_beg, row_indices + col_end, n_nonzero - col_end); } - + if(values) { memory::release(access::rw(values)); } if(row_indices) { memory::release(access::rw(row_indices)); } - + access::rw(values) = new_values; access::rw(row_indices) = new_row_indices; - + // Update counts and such. access::rw(n_nonzero) -= diff; } @@ -3113,14 +3215,14 @@ new_col_ptrs[new_n_cols + 1] = std::numeric_limits::max(); // Copy first set of columns (no manipulation required). - if (in_col1 != 0) + if(in_col1 != 0) { arrayops::copy(new_col_ptrs, col_ptrs, in_col1); } // Copy second set of columns (manipulation required). uword cur_col = in_col1; - for (uword i = in_col2 + 1; i <= n_cols; ++i, ++cur_col) + for(uword i = in_col2 + 1; i <= n_cols; ++i, ++cur_col) { new_col_ptrs[cur_col] = col_ptrs[i] - diff; } @@ -3196,7 +3298,7 @@ SpMat_MapMat_val SpMat::operator()(const uword i) { - arma_debug_check( (i >= n_elem), "SpMat::operator(): out of bounds"); + arma_debug_check_bounds( (i >= n_elem), "SpMat::operator(): out of bounds" ); const uword in_col = i / n_rows; const uword in_row = i % n_rows; @@ -3212,7 +3314,7 @@ eT SpMat::operator()(const uword i) const { - arma_debug_check( (i >= n_elem), "SpMat::operator(): out of bounds"); + arma_debug_check_bounds( (i >= n_elem), "SpMat::operator(): out of bounds" ); return get_value(i); } @@ -3252,7 +3354,7 @@ SpMat_MapMat_val SpMat::operator()(const uword in_row, const uword in_col) { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "SpMat::operator(): out of bounds"); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "SpMat::operator(): out of bounds" ); return SpMat_MapMat_val((*this), cache, in_row, in_col); } @@ -3265,7 +3367,7 @@ eT SpMat::operator()(const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "SpMat::operator(): out of bounds"); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "SpMat::operator(): out of bounds" ); return get_value(in_row, in_col); } @@ -3495,8 +3597,8 @@ SpMat::in_range(const span& x) const { arma_extra_debug_sigprint(); - - if(x.whole == true) + + if(x.whole) { return true; } @@ -3504,7 +3606,7 @@ { const uword a = x.a; const uword b = x.b; - + return ( (a <= b) && (b < n_elem) ); } } @@ -3530,8 +3632,8 @@ SpMat::in_range(const span& row_span, const uword in_col) const { arma_extra_debug_sigprint(); - - if(row_span.whole == true) + + if(row_span.whole) { return (in_col < n_cols); } @@ -3539,7 +3641,7 @@ { const uword in_row1 = row_span.a; const uword in_row2 = row_span.b; - + return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) ); } } @@ -3553,8 +3655,8 @@ SpMat::in_range(const uword in_row, const span& col_span) const { arma_extra_debug_sigprint(); - - if(col_span.whole == true) + + if(col_span.whole) { return (in_row < n_rows); } @@ -3562,7 +3664,7 @@ { const uword in_col1 = col_span.a; const uword in_col2 = col_span.b; - + return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) ); } } @@ -3576,17 +3678,17 @@ SpMat::in_range(const span& row_span, const span& col_span) const { arma_extra_debug_sigprint(); - + const uword in_row1 = row_span.a; const uword in_row2 = row_span.b; - + const uword in_col1 = col_span.a; const uword in_col2 = col_span.b; - + const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) ); const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) ); - - return ( (rows_ok == true) && (cols_ok == true) ); + + return ( rows_ok && cols_ok ); } @@ -3603,206 +3705,11 @@ if( (in_row >= l_n_rows) || (in_col >= l_n_cols) || ((in_row + s.n_rows) > l_n_rows) || ((in_col + s.n_cols) > l_n_cols) ) { return false; - } - else - { - return true; - } - } - - - -template -arma_cold -inline -void -SpMat::impl_print(const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = get_cout_stream().width(); - - get_cout_stream() << extra_text << '\n'; - - get_cout_stream().width(orig_width); - } - - arma_ostream::print(get_cout_stream(), *this, true); - } - - - -template -arma_cold -inline -void -SpMat::impl_print(std::ostream& user_stream, const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = user_stream.width(); - - user_stream << extra_text << '\n'; - - user_stream.width(orig_width); - } - - arma_ostream::print(user_stream, *this, true); - } - - - -template -arma_cold -inline -void -SpMat::impl_raw_print(const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = get_cout_stream().width(); - - get_cout_stream() << extra_text << '\n'; - - get_cout_stream().width(orig_width); - } - - arma_ostream::print(get_cout_stream(), *this, false); - } - - -template -arma_cold -inline -void -SpMat::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = user_stream.width(); - - user_stream << extra_text << '\n'; - - user_stream.width(orig_width); - } - - arma_ostream::print(user_stream, *this, false); - } - - - -/** - * Matrix printing, prepends supplied text. - * Prints 0 wherever no element exists. - */ -template -arma_cold -inline -void -SpMat::impl_print_dense(const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = get_cout_stream().width(); - - get_cout_stream() << extra_text << '\n'; - - get_cout_stream().width(orig_width); - } - - arma_ostream::print_dense(get_cout_stream(), *this, true); - } - - - -template -arma_cold -inline -void -SpMat::impl_print_dense(std::ostream& user_stream, const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = user_stream.width(); - - user_stream << extra_text << '\n'; - - user_stream.width(orig_width); - } - - arma_ostream::print_dense(user_stream, *this, true); - } - - - -template -arma_cold -inline -void -SpMat::impl_raw_print_dense(const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - if(extra_text.length() != 0) - { - const std::streamsize orig_width = get_cout_stream().width(); - - get_cout_stream() << extra_text << '\n'; - - get_cout_stream().width(orig_width); - } - - arma_ostream::print_dense(get_cout_stream(), *this, false); - } - - - -template -arma_cold -inline -void -SpMat::impl_raw_print_dense(std::ostream& user_stream, const std::string& extra_text) const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - if(extra_text.length() != 0) + } + else { - const std::streamsize orig_width = user_stream.width(); - - user_stream << extra_text << '\n'; - - user_stream.width(orig_width); + return true; } - - arma_ostream::print_dense(user_stream, *this, false); } @@ -3828,7 +3735,7 @@ SpMat::copy_size(const Mat& m) { arma_extra_debug_sigprint(); - + set_size(m.n_rows, m.n_cols); } @@ -4067,44 +3974,6 @@ -//! NOTE: don't use this form; it's deprecated and will be removed -template -arma_deprecated -inline -void -SpMat::reshape(const uword in_rows, const uword in_cols, const uword dim) - { - arma_extra_debug_sigprint(); - - arma_debug_check( (dim > 1), "SpMat::reshape(): parameter 'dim' must be 0 or 1" ); - - if(dim == 0) - { - (*this).reshape(in_rows, in_cols); - } - else - if(dim == 1) - { - arma_check( ((in_rows*in_cols) != n_elem), "SpMat::reshape(): changing the number of elements in a sparse matrix is currently not supported" ); - - sync_csc(); - - // Row-wise reshaping. This is more tedious and we will use a separate sparse matrix to do it. - SpMat tmp(in_rows, in_cols); - - for(const_row_iterator it = begin_row(); it.pos() < n_nonzero; ++it) - { - uword vector_position = (it.row() * n_cols) + it.col(); - - tmp((vector_position / in_cols), (vector_position % in_cols)) = (*it); - } - - steal_mem(tmp); - } - } - - - //! apply a functor to each non-zero element template template @@ -4192,7 +4061,7 @@ } if(has_zero) { remove_zeros(); } - + return *this; } @@ -4207,7 +4076,7 @@ if(old_val == eT(0)) { - arma_debug_warn("SpMat::replace(): replacement not done, as old_val = 0"); + arma_debug_warn_level(1, "SpMat::replace(): replacement not done, as old_val = 0"); } else { @@ -4248,6 +4117,37 @@ template inline const SpMat& +SpMat::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + if(is_cx::no) + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): min_val must be less than max_val" ); + } + else + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" ); + } + + if(n_nonzero == 0) { return *this; } + + sync_csc(); + invalidate_cache(); + + arrayops::clamp(access::rwp(values), n_nonzero, min_val, max_val); + + if( (min_val == eT(0)) || (max_val == eT(0)) ) { remove_zeros(); } + + return *this; + } + + + +template +inline +const SpMat& SpMat::zeros() { arma_extra_debug_sigprint(); @@ -4270,7 +4170,7 @@ SpMat::zeros(const uword in_elem) { arma_extra_debug_sigprint(); - + if(vec_state == 2) { zeros(1, in_elem); // Row vector @@ -4279,7 +4179,7 @@ { zeros(in_elem, 1); } - + return *this; } @@ -4322,7 +4222,7 @@ SpMat::eye() { arma_extra_debug_sigprint(); - + return (*this).eye(n_rows, n_cols); } @@ -4373,7 +4273,7 @@ SpMat::speye() { arma_extra_debug_sigprint(); - + return (*this).eye(n_rows, n_cols); } @@ -4603,6 +4503,45 @@ template inline void +SpMat::reset_cache() + { + arma_extra_debug_sigprint(); + + sync_csc(); + + #if defined(ARMA_USE_OPENMP) + { + #pragma omp critical (arma_SpMat_cache) + { + cache.reset(); + + sync_state = 0; + } + } + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + { + cache_mutex.lock(); + + cache.reset(); + + sync_state = 0; + + cache_mutex.unlock(); + } + #else + { + cache.reset(); + + sync_state = 0; + } + #endif + } + + + +template +inline +void SpMat::reserve(const uword in_rows, const uword in_cols, const uword new_n_nonzero) { arma_extra_debug_sigprint(); @@ -4643,7 +4582,7 @@ inline arma_cold bool -SpMat::save(const std::string name, const file_type type, const bool print_status) const +SpMat::save(const std::string name, const file_type type) const { arma_extra_debug_sigprint(); @@ -4654,7 +4593,11 @@ switch(type) { case csv_ascii: - save_okay = diskio::save_csv_ascii(*this, name); + return (*this).save(csv_name(name), type); + break; + + case ssv_ascii: + return (*this).save(csv_name(name), type); break; case arma_binary: @@ -4666,11 +4609,89 @@ break; default: - if(print_status) { arma_debug_warn("SpMat::save(): unsupported file type"); } + arma_debug_warn_level(1, "SpMat::save(): unsupported file type"); save_okay = false; } - if(print_status && (save_okay == false)) { arma_debug_warn("SpMat::save(): couldn't write to ", name); } + if(save_okay == false) { arma_debug_warn_level(3, "SpMat::save(): couldn't write; file: ", name); } + + return save_okay; + } + + + +template +inline +arma_cold +bool +SpMat::save(const csv_name& spec, const file_type type) const + { + arma_extra_debug_sigprint(); + + if( (type != csv_ascii) && (type != ssv_ascii) ) + { + arma_stop_runtime_error("SpMat::save(): unsupported file type for csv_name()"); + return false; + } + + const bool do_trans = bool(spec.opts.flags & csv_opts::flag_trans ); + const bool no_header = bool(spec.opts.flags & csv_opts::flag_no_header ); + bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header); + const bool use_semicolon = bool(spec.opts.flags & csv_opts::flag_semicolon ) || (type == ssv_ascii); + + arma_extra_debug_print("SpMat::save(csv_name): enabled flags:"); + + if(do_trans ) { arma_extra_debug_print("trans"); } + if(no_header ) { arma_extra_debug_print("no_header"); } + if(with_header ) { arma_extra_debug_print("with_header"); } + if(use_semicolon) { arma_extra_debug_print("semicolon"); } + + const char separator = (use_semicolon) ? char(';') : char(','); + + if(no_header) { with_header = false; } + + if(with_header) + { + if( (spec.header_ro.n_cols != 1) && (spec.header_ro.n_rows != 1) ) + { + arma_debug_warn_level(1, "SpMat::save(): given header must have a vector layout"); + return false; + } + + for(uword i=0; i < spec.header_ro.n_elem; ++i) + { + const std::string& token = spec.header_ro.at(i); + + if(token.find(separator) != std::string::npos) + { + arma_debug_warn_level(1, "SpMat::save(): token within the header contains the separator character: '", token, "'"); + return false; + } + } + + const uword save_n_cols = (do_trans) ? (*this).n_rows : (*this).n_cols; + + if(spec.header_ro.n_elem != save_n_cols) + { + arma_debug_warn_level(1, "SpMat::save(): size mistmach between header and matrix"); + return false; + } + } + + bool save_okay = false; + + if(do_trans) + { + const SpMat tmp = (*this).st(); + + save_okay = diskio::save_csv_ascii(tmp, spec.filename, spec.header_ro, with_header, separator); + } + else + { + save_okay = diskio::save_csv_ascii(*this, spec.filename, spec.header_ro, with_header, separator); + } + + if(save_okay == false) { arma_debug_warn_level(3, "SpMat::save(): couldn't write; file: ", spec.filename); } return save_okay; } @@ -4682,7 +4703,7 @@ inline arma_cold bool -SpMat::save(std::ostream& os, const file_type type, const bool print_status) const +SpMat::save(std::ostream& os, const file_type type) const { arma_extra_debug_sigprint(); @@ -4693,7 +4714,11 @@ switch(type) { case csv_ascii: - save_okay = diskio::save_csv_ascii(*this, os); + save_okay = diskio::save_csv_ascii(*this, os, char(',')); + break; + + case ssv_ascii: + save_okay = diskio::save_csv_ascii(*this, os, char(';')); break; case arma_binary: @@ -4705,11 +4730,11 @@ break; default: - if(print_status) { arma_debug_warn("SpMat::save(): unsupported file type"); } + arma_debug_warn_level(1, "SpMat::save(): unsupported file type"); save_okay = false; } - if(print_status && (save_okay == false)) { arma_debug_warn("SpMat::save(): couldn't write to the given stream"); } + if(save_okay == false) { arma_debug_warn_level(3, "SpMat::save(): couldn't write to stream"); } return save_okay; } @@ -4721,7 +4746,7 @@ inline arma_cold bool -SpMat::load(const std::string name, const file_type type, const bool print_status) +SpMat::load(const std::string name, const file_type type) { arma_extra_debug_sigprint(); @@ -4737,7 +4762,11 @@ // break; case csv_ascii: - load_okay = diskio::load_csv_ascii(*this, name, err_msg); + return (*this).load(csv_name(name), type); + break; + + case ssv_ascii: + return (*this).load(csv_name(name), type); break; case arma_binary: @@ -4749,27 +4778,112 @@ break; default: - if(print_status) { arma_debug_warn("SpMat::load(): unsupported file type"); } + arma_debug_warn_level(1, "SpMat::load(): unsupported file type"); load_okay = false; } - if(print_status && (load_okay == false)) + if(load_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("SpMat::load(): ", err_msg, name); + arma_debug_warn_level(3, "SpMat::load(): ", err_msg, "; file: ", name); } else { - arma_debug_warn("SpMat::load(): couldn't read ", name); + arma_debug_warn_level(3, "SpMat::load(): couldn't read; file: ", name); + } + } + + if(load_okay == false) { (*this).reset(); } + + return load_okay; + } + + + +template +inline +arma_cold +bool +SpMat::load(const csv_name& spec, const file_type type) + { + arma_extra_debug_sigprint(); + + if( (type != csv_ascii) && (type != ssv_ascii) ) + { + arma_stop_runtime_error("SpMat::load(): unsupported file type for csv_name()"); + return false; + } + + const bool do_trans = bool(spec.opts.flags & csv_opts::flag_trans ); + const bool no_header = bool(spec.opts.flags & csv_opts::flag_no_header ); + bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header); + const bool use_semicolon = bool(spec.opts.flags & csv_opts::flag_semicolon ) || (type == ssv_ascii); + + arma_extra_debug_print("SpMat::load(csv_name): enabled flags:"); + + if(do_trans ) { arma_extra_debug_print("trans"); } + if(no_header ) { arma_extra_debug_print("no_header"); } + if(with_header ) { arma_extra_debug_print("with_header"); } + if(use_semicolon) { arma_extra_debug_print("semicolon"); } + + const char separator = (use_semicolon) ? char(';') : char(','); + + if(no_header) { with_header = false; } + + bool load_okay = false; + std::string err_msg; + + if(do_trans) + { + SpMat tmp_mat; + + load_okay = diskio::load_csv_ascii(tmp_mat, spec.filename, err_msg, spec.header_rw, with_header, separator); + + if(load_okay) + { + (*this) = tmp_mat.st(); + + if(with_header) + { + // field::set_size() preserves data if the number of elements hasn't changed + spec.header_rw.set_size(spec.header_rw.n_elem, 1); + } } } + else + { + load_okay = diskio::load_csv_ascii(*this, spec.filename, err_msg, spec.header_rw, with_header, separator); + } if(load_okay == false) { - (*this).reset(); + if(err_msg.length() > 0) + { + arma_debug_warn_level(3, "SpMat::load(): ", err_msg, "; file: ", spec.filename); + } + else + { + arma_debug_warn_level(3, "SpMat::load(): couldn't read; file: ", spec.filename); + } + } + else + { + const uword load_n_cols = (do_trans) ? (*this).n_rows : (*this).n_cols; + + if(with_header && (spec.header_rw.n_elem != load_n_cols)) + { + arma_debug_warn_level(3, "SpMat::load(): size mistmach between header and matrix"); + } } + + if(load_okay == false) + { + (*this).reset(); + if(with_header) { spec.header_rw.reset(); } + } + return load_okay; } @@ -4780,7 +4894,7 @@ inline arma_cold bool -SpMat::load(std::istream& is, const file_type type, const bool print_status) +SpMat::load(std::istream& is, const file_type type) { arma_extra_debug_sigprint(); @@ -4796,7 +4910,11 @@ // break; case csv_ascii: - load_okay = diskio::load_csv_ascii(*this, is, err_msg); + load_okay = diskio::load_csv_ascii(*this, is, err_msg, char(',')); + break; + + case ssv_ascii: + load_okay = diskio::load_csv_ascii(*this, is, err_msg, char(';')); break; case arma_binary: @@ -4808,27 +4926,24 @@ break; default: - if(print_status) { arma_debug_warn("SpMat::load(): unsupported file type"); } + arma_debug_warn_level(1, "SpMat::load(): unsupported file type"); load_okay = false; } - if(print_status && (load_okay == false)) + if(load_okay == false) { if(err_msg.length() > 0) { - arma_debug_warn("SpMat::load(): ", err_msg, "the given stream"); + arma_debug_warn_level(3, "SpMat::load(): ", err_msg); } else { - arma_debug_warn("SpMat::load(): couldn't load from the given stream"); + arma_debug_warn_level(3, "SpMat::load(): couldn't load from stream"); } } - if(load_okay == false) - { - (*this).reset(); - } - + if(load_okay == false) { (*this).reset(); } + return load_okay; } @@ -4843,7 +4958,7 @@ { arma_extra_debug_sigprint(); - return (*this).save(name, type, false); + return (*this).save(name, type); } @@ -4857,7 +4972,7 @@ { arma_extra_debug_sigprint(); - return (*this).save(os, type, false); + return (*this).save(os, type); } @@ -4871,7 +4986,7 @@ { arma_extra_debug_sigprint(); - return (*this).load(name, type, false); + return (*this).load(name, type); } @@ -4885,7 +5000,7 @@ { arma_extra_debug_sigprint(); - return (*this).load(is, type, false); + return (*this).load(is, type); } @@ -4907,6 +5022,15 @@ if(row_indices) { memory::release(access::rw(row_indices)); } if(col_ptrs ) { memory::release(access::rw(col_ptrs)); } + // in case init_cold() throws an exception + access::rw(n_rows) = 0; + access::rw(n_cols) = 0; + access::rw(n_elem) = 0; + access::rw(n_nonzero) = 0; + access::rw(values) = nullptr; + access::rw(row_indices) = nullptr; + access::rw(col_ptrs) = nullptr; + init_cold(in_rows, in_cols, new_n_nonzero); } @@ -4935,10 +5059,10 @@ } } - #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD)) + #if defined(ARMA_64BIT_WORD) const char* error_message = "SpMat::init(): requested size is too large"; #else - const char* error_message = "SpMat::init(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD"; + const char* error_message = "SpMat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif // Ensure that n_elem can hold the result of (n_rows * n_cols) @@ -5028,7 +5152,7 @@ init_done = true; } } - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) if(x.sync_state == 1) { x.cache_mutex.lock(); @@ -5181,13 +5305,13 @@ bool actually_sorted = true; - if(sort_locations == true) + if(sort_locations) { // check if we really need a time consuming sort const uword locs_n_cols = locs.n_cols; - for (uword i = 1; i < locs_n_cols; ++i) + for(uword i = 1; i < locs_n_cols; ++i) { const uword* locs_i = locs.colptr(i ); const uword* locs_im1 = locs.colptr(i-1); @@ -5213,7 +5337,7 @@ const uword* locs_mem = locs.memptr(); - for (uword i = 0; i < locs_n_cols; ++i) + for(uword i = 0; i < locs_n_cols; ++i) { const uword row = (*locs_mem); locs_mem++; const uword col = (*locs_mem); locs_mem++; @@ -5227,7 +5351,7 @@ std::sort( packet_vec.begin(), packet_vec.end(), comparator ); // insert the elements in the sorted order - for (uword i = 0; i < locs_n_cols; ++i) + for(uword i = 0; i < locs_n_cols; ++i) { const uword index = packet_vec[i].index; @@ -5298,7 +5422,7 @@ } // Now fix the column pointers. - for (uword i = 0; i < n_cols; ++i) + for(uword i = 0; i < n_cols; ++i) { access::rw(col_ptrs[i + 1]) += col_ptrs[i]; } @@ -5324,11 +5448,11 @@ bool actually_sorted = true; - if(sort_locations == true) + if(sort_locations) { // sort_index() uses std::sort() which may use quicksort... so we better // make sure it's not already sorted before taking an O(N^2) sort penalty. - for (uword i = 1; i < locs.n_cols; ++i) + for(uword i = 1; i < locs.n_cols; ++i) { const uword* locs_i = locs.colptr(i ); const uword* locs_im1 = locs.colptr(i-1); @@ -5343,9 +5467,9 @@ if(actually_sorted == false) { // This may not be the fastest possible implementation but it maximizes code reuse. - Col abslocs(locs.n_cols); + Col abslocs(locs.n_cols, arma_nozeros_indicator()); - for (uword i = 0; i < locs.n_cols; ++i) + for(uword i = 0; i < locs.n_cols; ++i) { const uword* locs_i = locs.colptr(i); @@ -5471,7 +5595,7 @@ } // Now fix the column pointers. - for (uword i = 0; i < n_cols; ++i) + for(uword i = 0; i < n_cols; ++i) { access::rw(col_ptrs[i + 1]) += col_ptrs[i]; } @@ -5488,9 +5612,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(in_vec_state) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -5511,9 +5635,9 @@ , n_elem(0) , n_nonzero(0) , vec_state(in_vec_state) - , values(NULL) - , row_indices(NULL) - , col_ptrs(NULL) + , values(nullptr) + , row_indices(nullptr) + , col_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -5697,16 +5821,15 @@ access::rw(x.n_elem) = 0; access::rw(x.n_nonzero) = 0; - access::rw(x.values) = NULL; - access::rw(x.row_indices) = NULL; - access::rw(x.col_ptrs) = NULL; + access::rw(x.values) = nullptr; + access::rw(x.row_indices) = nullptr; + access::rw(x.col_ptrs) = nullptr; } template template -arma_hot inline void SpMat::init_xform(const SpBase& A, const Functor& func) @@ -5745,7 +5868,6 @@ template template -arma_hot inline void SpMat::init_xform_mt(const SpBase& A, const Functor& func) @@ -5754,7 +5876,7 @@ const SpProxy P(A.get_ref()); - if( (P.is_alias(*this) == true) || (is_SpMat::stored_type>::value == true) ) + if( P.is_alias(*this) || (is_SpMat::stored_type>::value) ) { // NOTE: unwrap_spmat will convert a submatrix to a matrix, which in effect takes care of aliasing with submatrices; // NOTE: however, when more delayed ops are implemented, more elaborate handling of aliasing will be necessary @@ -5806,8 +5928,10 @@ if(val == eT(0)) { has_zero = true; } - access::rw(row_indices[it.pos()]) = it.row(); - access::rw(values[it.pos()]) = val; + const uword it_pos = it.pos(); + + access::rw(row_indices[it_pos]) = it.row(); + access::rw(values[it_pos]) = val; ++access::rw(col_ptrs[it.col() + 1]); ++it; } @@ -6150,6 +6274,58 @@ template +arma_inline +arma_warn_unused +SpMat_MapMat_val +SpMat::front() + { + arma_debug_check( (n_elem == 0), "SpMat::front(): matrix is empty" ); + + return SpMat_MapMat_val((*this), cache, 0, 0); + } + + + +template +arma_inline +arma_warn_unused +eT +SpMat::front() const + { + arma_debug_check( (n_elem == 0), "SpMat::front(): matrix is empty" ); + + return get_value(0,0); + } + + + +template +arma_inline +arma_warn_unused +SpMat_MapMat_val +SpMat::back() + { + arma_debug_check( (n_elem == 0), "SpMat::back(): matrix is empty" ); + + return SpMat_MapMat_val((*this), cache, n_rows-1, n_cols-1); + } + + + +template +arma_inline +arma_warn_unused +eT +SpMat::back() const + { + arma_debug_check( (n_elem == 0), "SpMat::back(): matrix is empty" ); + + return get_value(n_rows-1, n_cols-1); + } + + + +template inline arma_hot arma_warn_unused @@ -6220,7 +6396,7 @@ return &(values[index]); } - return NULL; + return nullptr; } @@ -6234,7 +6410,7 @@ { const eT* val_ptr = find_value_csc(in_row, in_col); - return (val_ptr != NULL) ? eT(*val_ptr) : eT(0); + return (val_ptr != nullptr) ? eT(*val_ptr) : eT(0); } @@ -6249,7 +6425,7 @@ const eT* val_ptr = find_value_csc(in_row, in_col); // element not found, ie. it's zero; fail if trying to set it to non-zero value - if(val_ptr == NULL) { return (in_val == eT(0)); } + if(val_ptr == nullptr) { return (in_val == eT(0)); } // fail if trying to erase an existing element if(in_val == eT(0)) { return false; } @@ -6273,7 +6449,7 @@ const eT* val_ptr = find_value_csc(in_row, in_col); // element not found, ie. it's zero; fail if trying to add a non-zero value - if(val_ptr == NULL) { return (in_val == eT(0)); } + if(val_ptr == nullptr) { return (in_val == eT(0)); } const eT new_val = eT(*val_ptr) + in_val; @@ -6299,7 +6475,7 @@ const eT* val_ptr = find_value_csc(in_row, in_col); // element not found, ie. it's zero; fail if trying to subtract a non-zero value - if(val_ptr == NULL) { return (in_val == eT(0)); } + if(val_ptr == nullptr) { return (in_val == eT(0)); } const eT new_val = eT(*val_ptr) - in_val; @@ -6325,7 +6501,7 @@ const eT* val_ptr = find_value_csc(in_row, in_col); // element not found, ie. it's zero; succeed if given value is finite; zero multiplied by anything is zero, except for nan and inf - if(val_ptr == NULL) { return arma_isfinite(in_val); } + if(val_ptr == nullptr) { return arma_isfinite(in_val); } const eT new_val = eT(*val_ptr) * in_val; @@ -6351,7 +6527,7 @@ const eT* val_ptr = find_value_csc(in_row, in_col); // element not found, ie. it's zero; succeed if given value is not zero and not nan; zero divided by anything is zero, except for zero and nan - if(val_ptr == NULL) { return ((in_val != eT(0)) && (arma_isnan(in_val) == false)); } + if(val_ptr == nullptr) { return ((in_val != eT(0)) && (arma_isnan(in_val) == false)); } const eT new_val = eT(*val_ptr) / in_val; @@ -6371,10 +6547,6 @@ * Insert an element at the given position, and return a reference to it. * The element will be set to 0, unless otherwise specified. * If the element already exists, its value will be overwritten. - * - * @param in_row Row of new element. - * @param in_col Column of new element. - * @param in_val Value to set new element to (default 0). */ template inline @@ -6395,18 +6567,18 @@ uword pos = colptr; // The position in the matrix of this value. - if (colptr != next_colptr) + if(colptr != next_colptr) { // There are other elements in this column, so we must find where this // element will fit as compared to those. - while (pos < next_colptr && in_row > row_indices[pos]) + while(pos < next_colptr && in_row > row_indices[pos]) { pos++; } // We aren't inserting into the last position, so it is still possible // that the element may exist. - if (pos != next_colptr && row_indices[pos] == in_row) + if(pos != next_colptr && row_indices[pos] == in_row) { // It already exists. Then, just overwrite it. access::rw(values[pos]) = val; @@ -6421,7 +6593,7 @@ // // We have to update the rest of the column pointers. - for (uword i = in_col + 1; i < n_cols + 1; i++) + for(uword i = in_col + 1; i < n_cols + 1; i++) { access::rw(col_ptrs[i])++; // We are only inserting one new element. } @@ -6435,7 +6607,7 @@ uword* new_row_indices = memory::acquire(n_nonzero + 1); // Copy things over, before the new element. - if (pos > 0) + if(pos > 0) { arrayops::copy(new_values, values, pos); arrayops::copy(new_row_indices, row_indices, pos); @@ -6463,9 +6635,6 @@ /** * Delete an element at the given position. - * - * @param in_row Row of element to be deleted. - * @param in_col Column of element to be deleted. */ template inline @@ -6482,13 +6651,13 @@ uword colptr = col_ptrs[in_col]; uword next_colptr = col_ptrs[in_col + 1]; - if (colptr != next_colptr) + if(colptr != next_colptr) { // There's at least one element in this column. // Let's see if we are one of them. - for (uword pos = colptr; pos < next_colptr; pos++) + for(uword pos = colptr; pos < next_colptr; pos++) { - if (in_row == row_indices[pos]) + if(in_row == row_indices[pos]) { --access::rw(n_nonzero); // Remove one from the count of nonzero elements. @@ -6498,7 +6667,7 @@ eT* new_values = memory::acquire (n_nonzero + 1); uword* new_row_indices = memory::acquire(n_nonzero + 1); - if (pos > 0) + if(pos > 0) { arrayops::copy(new_values, values, pos); arrayops::copy(new_row_indices, row_indices, pos); @@ -6514,7 +6683,7 @@ access::rw(row_indices) = new_row_indices; // And lastly, update all the column pointers (decrement by one). - for (uword i = in_col + 1; i < n_cols + 1; i++) + for(uword i = in_col + 1; i < n_cols + 1; i++) { --access::rw(col_ptrs[i]); // We only removed one element. } @@ -6586,7 +6755,7 @@ } } } - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { if(sync_state == 0) { @@ -6639,7 +6808,7 @@ sync_csc_simple(); } } - #elif defined(ARMA_USE_CXX11) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) if(sync_state == 1) { cache_mutex.lock(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpOp_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpOp_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpOp_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpOp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,16 +22,16 @@ template -class SpOp : public SpBase > +class SpOp : public SpBase< typename T1::elem_type, SpOp > { public: typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = op_type::template traits::is_row; - static const bool is_col = op_type::template traits::is_col; - static const bool is_xvec = op_type::template traits::is_xvec; + static constexpr bool is_row = op_type::template traits::is_row; + static constexpr bool is_col = op_type::template traits::is_col; + static constexpr bool is_xvec = op_type::template traits::is_xvec; inline explicit SpOp(const T1& in_m); inline SpOp(const T1& in_m, const elem_type in_aux); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_diagmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_diagmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_diagmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_diagmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_diagmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_diagmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_diagmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_diagmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -425,7 +427,7 @@ } else // generate a diagonal matrix out of a matrix { - arma_debug_check + arma_debug_check_bounds ( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "diagmat(): requested diagonal out of bounds" diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_htrans_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_htrans_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_htrans_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_htrans_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,16 +29,16 @@ template struct traits { - static const bool is_row = T1::is_col; // deliberately swapped - static const bool is_col = T1::is_row; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_col; // deliberately swapped + static constexpr bool is_col = T1::is_row; + static constexpr bool is_xvec = T1::is_xvec; }; template - inline static void apply(SpMat& out, const SpOp& in, const typename arma_not_cx::result* junk = 0); + inline static void apply(SpMat& out, const SpOp& in, const typename arma_not_cx::result* junk = nullptr); template - inline static void apply(SpMat& out, const SpOp& in, const typename arma_cx_only::result* junk = 0); + inline static void apply(SpMat& out, const SpOp& in, const typename arma_cx_only::result* junk = nullptr); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_htrans_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_htrans_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_htrans_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_htrans_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_max_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_max_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_max_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_max_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,10 +31,10 @@ // template - inline static void apply_proxy(SpMat& out, const SpProxy& p, const uword dim, const typename arma_not_cx::result* junk = 0); + inline static void apply_proxy(SpMat& out, const SpProxy& p, const uword dim, const typename arma_not_cx::result* junk = nullptr); template - inline static typename T1::elem_type vector_max(const T1& X, const typename arma_not_cx::result* junk = 0); + inline static typename T1::elem_type vector_max(const T1& X, const typename arma_not_cx::result* junk = nullptr); template inline static typename arma_not_cx::result max(const SpBase& X); @@ -43,10 +45,10 @@ // template - inline static void apply_proxy(SpMat& out, const SpProxy& p, const uword dim, const typename arma_cx_only::result* junk = 0); + inline static void apply_proxy(SpMat& out, const SpProxy& p, const uword dim, const typename arma_cx_only::result* junk = nullptr); template - inline static typename T1::elem_type vector_max(const T1& X, const typename arma_cx_only::result* junk = 0); + inline static typename T1::elem_type vector_max(const T1& X, const typename arma_cx_only::result* junk = nullptr); template inline static typename arma_cx_only::result max(const SpBase& X); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_max_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_max_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_max_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_max_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -71,8 +73,8 @@ if(dim == 0) // find the maximum in each column { - Row value(p_n_cols, fill::zeros); - urowvec count(p_n_cols, fill::zeros); + Row value(p_n_cols, arma_zeros_indicator()); + urowvec count(p_n_cols, arma_zeros_indicator()); while(it != it_end) { @@ -93,8 +95,8 @@ else if(dim == 1) // find the maximum in each row { - Col value(p_n_rows, fill::zeros); - ucolvec count(p_n_rows, fill::zeros); + Col value(p_n_rows, arma_zeros_indicator()); + ucolvec count(p_n_rows, arma_zeros_indicator()); while(it != it_end) { @@ -150,7 +152,7 @@ } else { - return std::max(eT(0), op_max::direct_max(p.get_values(), p.get_n_nonzero())); + return (std::max)(eT(0), op_max::direct_max(p.get_values(), p.get_n_nonzero())); } } else @@ -175,7 +177,7 @@ } else { - return std::max(eT(0), result); + return (std::max)(eT(0), result); } } } @@ -213,9 +215,9 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { - if ((*it) > max_val) { max_val = *it; } + if((*it) > max_val) { max_val = *it; } ++it; } @@ -234,7 +236,7 @@ } else { - return std::max(eT(0), max_val); + return (std::max)(eT(0), max_val); } } @@ -272,9 +274,9 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { - if ((*it) > max_val) + if((*it) > max_val) { max_val = *it; index_of_max_val = it.row() + it.col() * n_rows; @@ -291,14 +293,14 @@ // Convert to actual position in matrix. const uword row = P.get_row_indices()[index_of_max_val]; uword col = 0; - while (P.get_col_ptrs()[++col] <= index_of_max_val) { } + while(P.get_col_ptrs()[++col] <= index_of_max_val) { } index_of_max_val = (col - 1) * n_rows + row; } if(n_elem != n_nonzero) { - max_val = std::max(eT(0), max_val); + max_val = (std::max)(eT(0), max_val); // If the max_val is a nonzero element, we need its actual position in the matrix. if(max_val == eT(0)) @@ -312,25 +314,25 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { // Have we moved more than one position from the last place? - if ((it.col() == last_col) && (it.row() - last_row > 1)) + if((it.col() == last_col) && (it.row() - last_row > 1)) { index_of_max_val = it.col() * n_rows + last_row + 1; break; } - else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1)) + else if((it.col() >= last_col + 1) && (last_row < n_rows - 1)) { index_of_max_val = last_col * n_rows + last_row + 1; break; } - else if ((it.col() == last_col + 1) && (it.row() > 0)) + else if((it.col() == last_col + 1) && (it.row() > 0)) { index_of_max_val = it.col() * n_rows; break; } - else if (it.col() > last_col + 1) + else if(it.col() > last_col + 1) { index_of_max_val = (last_col + 1) * n_rows; break; @@ -373,8 +375,8 @@ if(dim == 0) // find the maximum in each column { - Row rawval(p_n_cols, fill::zeros); - Row< T> absval(p_n_cols, fill::zeros); + Row rawval(p_n_cols, arma_zeros_indicator()); + Row< T> absval(p_n_cols, arma_zeros_indicator()); while(it != it_end) { @@ -397,8 +399,8 @@ else if(dim == 1) // find the maximum in each row { - Col rawval(p_n_rows, fill::zeros); - Col< T> absval(p_n_rows, fill::zeros); + Col rawval(p_n_rows, arma_zeros_indicator()); + Col< T> absval(p_n_rows, arma_zeros_indicator()); while(it != it_end) { @@ -536,11 +538,11 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { const T tmp_val = std::abs(*it); - if (tmp_val > max_val) + if(tmp_val > max_val) { max_val = tmp_val; ret_val = *it; @@ -603,11 +605,11 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { const T tmp_val = std::abs(*it); - if (tmp_val > max_val) + if(tmp_val > max_val) { max_val = tmp_val; index_of_max_val = it.row() + it.col() * n_rows; @@ -624,14 +626,14 @@ // Convert to actual position in matrix. const uword row = P.get_row_indices()[index_of_max_val]; uword col = 0; - while (P.get_col_ptrs()[++col] <= index_of_max_val) { } + while(P.get_col_ptrs()[++col] <= index_of_max_val) { } index_of_max_val = (col - 1) * n_rows + row; } if(n_elem != n_nonzero) { - max_val = std::max(T(0), max_val); + max_val = (std::max)(T(0), max_val); // If the max_val is a nonzero element, we need its actual position in the matrix. if(max_val == T(0)) @@ -645,25 +647,25 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { // Have we moved more than one position from the last place? - if ((it.col() == last_col) && (it.row() - last_row > 1)) + if((it.col() == last_col) && (it.row() - last_row > 1)) { index_of_max_val = it.col() * n_rows + last_row + 1; break; } - else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1)) + else if((it.col() >= last_col + 1) && (last_row < n_rows - 1)) { index_of_max_val = last_col * n_rows + last_row + 1; break; } - else if ((it.col() == last_col + 1) && (it.row() > 0)) + else if((it.col() == last_col + 1) && (it.row() > 0)) { index_of_max_val = it.col() * n_rows; break; } - else if (it.col() > last_col + 1) + else if(it.col() > last_col + 1) { index_of_max_val = (last_col + 1) * n_rows; break; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_mean_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_mean_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_mean_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_mean_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_mean_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_mean_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_mean_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_mean_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -77,7 +79,7 @@ if(dim == 0) // find the mean in each column { - Row acc(p_n_cols, fill::zeros); + Row acc(p_n_cols, arma_zeros_indicator()); eT* acc_mem = acc.memptr(); @@ -108,7 +110,7 @@ else if(dim == 1) // find the mean in each row { - Col acc(p_n_rows, fill::zeros); + Col acc(p_n_rows, arma_zeros_indicator()); eT* acc_mem = acc.memptr(); @@ -331,7 +333,7 @@ const uword it_begin_pos = it.pos(); - while (it != end) + while(it != end) { acc += (*it); ++it; @@ -360,7 +362,7 @@ const uword it_begin_pos = it.pos(); - while (it != end) + while(it != end) { r_mean += ((*it - r_mean) / T(n_zero + (it.pos() - it_begin_pos) + 1)); ++it; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpOp_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpOp_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpOp_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpOp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_min_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_min_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_min_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_min_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -29,10 +31,10 @@ // template - inline static void apply_proxy(SpMat& out, const SpProxy& p, const uword dim, const typename arma_not_cx::result* junk = 0); + inline static void apply_proxy(SpMat& out, const SpProxy& p, const uword dim, const typename arma_not_cx::result* junk = nullptr); template - inline static typename T1::elem_type vector_min(const T1& X, const typename arma_not_cx::result* junk = 0); + inline static typename T1::elem_type vector_min(const T1& X, const typename arma_not_cx::result* junk = nullptr); template inline static typename arma_not_cx::result min(const SpBase& X); @@ -43,10 +45,10 @@ // template - inline static void apply_proxy(SpMat& out, const SpProxy& p, const uword dim, const typename arma_cx_only::result* junk = 0); + inline static void apply_proxy(SpMat& out, const SpProxy& p, const uword dim, const typename arma_cx_only::result* junk = nullptr); template - inline static typename T1::elem_type vector_min(const T1& X, const typename arma_cx_only::result* junk = 0); + inline static typename T1::elem_type vector_min(const T1& X, const typename arma_cx_only::result* junk = nullptr); template inline static typename arma_cx_only::result min(const SpBase& X); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_min_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_min_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_min_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_min_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -71,8 +73,8 @@ if(dim == 0) // find the minimum in each column { - Row value(p_n_cols, fill::zeros); - urowvec count(p_n_cols, fill::zeros); + Row value(p_n_cols, arma_zeros_indicator()); + urowvec count(p_n_cols, arma_zeros_indicator()); while(it != it_end) { @@ -93,8 +95,8 @@ else if(dim == 1) // find the minimum in each row { - Col value(p_n_rows, fill::zeros); - ucolvec count(p_n_rows, fill::zeros); + Col value(p_n_rows, arma_zeros_indicator()); + ucolvec count(p_n_rows, arma_zeros_indicator()); while(it != it_end) { @@ -150,7 +152,7 @@ } else { - return std::min(eT(0), op_min::direct_min(p.get_values(), p.get_n_nonzero())); + return (std::min)(eT(0), op_min::direct_min(p.get_values(), p.get_n_nonzero())); } } else @@ -175,7 +177,7 @@ } else { - return std::min(eT(0), result); + return (std::min)(eT(0), result); } } } @@ -213,9 +215,9 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { - if ((*it) < min_val) { min_val = *it; } + if((*it) < min_val) { min_val = *it; } ++it; } @@ -234,7 +236,7 @@ } else { - return std::min(eT(0), min_val); + return (std::min)(eT(0), min_val); } } @@ -272,9 +274,9 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { - if ((*it) < min_val) + if((*it) < min_val) { min_val = *it; index_of_min_val = it.row() + it.col() * n_rows; @@ -291,14 +293,14 @@ // Convert to actual position in matrix. const uword row = P.get_row_indices()[index_of_min_val]; uword col = 0; - while (P.get_col_ptrs()[++col] < index_of_min_val + 1) { } + while(P.get_col_ptrs()[++col] < index_of_min_val + 1) { } index_of_min_val = (col - 1) * n_rows + row; } if(n_elem != n_nonzero) { - min_val = std::min(eT(0), min_val); + min_val = (std::min)(eT(0), min_val); // If the min_val is a nonzero element, we need its actual position in the matrix. if(min_val == eT(0)) @@ -312,25 +314,25 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { // Have we moved more than one position from the last place? - if ((it.col() == last_col) && (it.row() - last_row > 1)) + if((it.col() == last_col) && (it.row() - last_row > 1)) { index_of_min_val = it.col() * n_rows + last_row + 1; break; } - else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1)) + else if((it.col() >= last_col + 1) && (last_row < n_rows - 1)) { index_of_min_val = last_col * n_rows + last_row + 1; break; } - else if ((it.col() == last_col + 1) && (it.row() > 0)) + else if((it.col() == last_col + 1) && (it.row() > 0)) { index_of_min_val = it.col() * n_rows; break; } - else if (it.col() > last_col + 1) + else if(it.col() > last_col + 1) { index_of_min_val = (last_col + 1) * n_rows; break; @@ -373,9 +375,9 @@ if(dim == 0) // find the minimum in each column { - Row rawval(p_n_cols, fill::zeros); - Row< T> absval(p_n_cols, fill::zeros); - urowvec count(p_n_cols, fill::zeros); + Row rawval(p_n_cols, arma_zeros_indicator()); + Row< T> absval(p_n_cols, arma_zeros_indicator()); + urowvec count(p_n_cols, arma_zeros_indicator()); while(it != it_end) { @@ -415,9 +417,9 @@ else if(dim == 1) // find the minimum in each row { - Col rawval(p_n_rows, fill::zeros); - Col< T> absval(p_n_rows, fill::zeros); - ucolvec count(p_n_rows, fill::zeros); + Col rawval(p_n_rows, arma_zeros_indicator()); + Col< T> absval(p_n_rows, arma_zeros_indicator()); + ucolvec count(p_n_rows, arma_zeros_indicator()); while(it != it_end) { @@ -572,11 +574,11 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { const T tmp_val = std::abs(*it); - if (tmp_val < min_val) + if(tmp_val < min_val) { min_val = tmp_val; ret_val = *it; @@ -639,11 +641,11 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { const T tmp_val = std::abs(*it); - if (tmp_val < min_val) + if(tmp_val < min_val) { min_val = tmp_val; index_of_min_val = it.row() + it.col() * n_rows; @@ -660,14 +662,14 @@ // Convert to actual position in matrix. const uword row = P.get_row_indices()[index_of_min_val]; uword col = 0; - while (P.get_col_ptrs()[++col] < index_of_min_val + 1) { } + while(P.get_col_ptrs()[++col] < index_of_min_val + 1) { } index_of_min_val = (col - 1) * n_rows + row; } if(n_elem != n_nonzero) { - min_val = std::min(T(0), min_val); + min_val = (std::min)(T(0), min_val); // If the min_val is a nonzero element, we need its actual position in the matrix. if(min_val == T(0)) @@ -681,25 +683,25 @@ it_type it = P.begin(); it_type it_end = P.end(); - while (it != it_end) + while(it != it_end) { // Have we moved more than one position from the last place? - if ((it.col() == last_col) && (it.row() - last_row > 1)) + if((it.col() == last_col) && (it.row() - last_row > 1)) { index_of_min_val = it.col() * n_rows + last_row + 1; break; } - else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1)) + else if((it.col() >= last_col + 1) && (last_row < n_rows - 1)) { index_of_min_val = last_col * n_rows + last_row + 1; break; } - else if ((it.col() == last_col + 1) && (it.row() > 0)) + else if((it.col() == last_col + 1) && (it.row() > 0)) { index_of_min_val = it.col() * n_rows; break; } - else if (it.col() > last_col + 1) + else if(it.col() > last_col + 1) { index_of_min_val = (last_col + 1) * n_rows; break; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_misc_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_misc_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_misc_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_misc_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_misc_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_misc_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_misc_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_misc_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -326,8 +328,8 @@ if( (out_n_rows > 0) && (out_n_cols > 0) && (out_nnz > 0) ) { - umat locs(2, out_nnz); - Col vals( out_nnz); + umat locs(2, out_nnz, arma_nozeros_indicator()); + Col vals( out_nnz, arma_nozeros_indicator()); uword* locs_mem = locs.memptr(); eT* vals_mem = vals.memptr(); @@ -524,7 +526,7 @@ const uword row_offset = (b > 0) ? a : 0; const uword col_offset = (b == 0) ? a : 0; - arma_debug_check + arma_debug_check_bounds ( ((row_offset > 0) && (row_offset >= X.n_rows)) || ((col_offset > 0) && (col_offset >= X.n_cols)), "diagvec(): requested diagonal out of bounds" @@ -532,7 +534,7 @@ const uword len = (std::min)(X.n_rows - row_offset, X.n_cols - col_offset); - Col cache(len); + Col cache(len, arma_nozeros_indicator()); eT* cache_mem = cache.memptr(); uword n_nonzero = 0; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_normalise_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_normalise_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_normalise_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_normalise_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,7 +29,7 @@ inline static void apply(SpMat& out, const SpOp& expr); template - inline static void apply_direct(SpMat& out, const SpMat& X, const uword p, const uword dim); + inline static void apply_direct(SpMat& out, const SpMat& X, const uword p); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_normalise_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_normalise_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_normalise_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_normalise_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,6 +28,8 @@ { arma_extra_debug_sigprint(); + typedef typename T1::elem_type eT; + const uword p = expr.aux_uword_a; const uword dim = expr.aux_uword_b; @@ -34,7 +38,28 @@ const unwrap_spmat U(expr.m); - spop_normalise::apply_direct(out, U.M, p, dim); + const SpMat& X = U.M; + + X.sync(); + + if( X.is_empty() || (X.n_nonzero == 0) ) { out.zeros(X.n_rows, X.n_cols); return; } + + if(dim == 0) + { + spop_normalise::apply_direct(out, X, p); + } + else + if(dim == 1) + { + SpMat tmp1; + SpMat tmp2; + + spop_strans::apply_noalias(tmp1, X); + + spop_normalise::apply_direct(tmp2, tmp1, p); + + spop_strans::apply_noalias(out, tmp2); + } } @@ -42,162 +67,65 @@ template inline void -spop_normalise::apply_direct(SpMat& out, const SpMat& X, const uword p, const uword dim) +spop_normalise::apply_direct(SpMat& out, const SpMat& X, const uword p) { arma_extra_debug_sigprint(); typedef typename get_pod_type::result T; - X.sync(); + SpMat tmp(arma_reserve_indicator(), X.n_rows, X.n_cols, X.n_nonzero); - if( X.is_empty() || (X.n_nonzero == 0) ) { return; } + bool has_zero = false; - if(dim == 0) + podarray norm_vals(X.n_cols); + + T* norm_vals_mem = norm_vals.memptr(); + + for(uword col=0; col < X.n_cols; ++col) { - podarray norm_vals(X.n_cols); + const uword col_offset = X.col_ptrs[col ]; + const uword next_col_offset = X.col_ptrs[col + 1]; - T* norm_vals_mem = norm_vals.memptr(); + const eT* start_ptr = &X.values[ col_offset]; + const eT* end_ptr = &X.values[next_col_offset]; - for(uword i=0; i < norm_vals.n_elem; ++i) - { - const uword col_offset = X.col_ptrs[i ]; - const uword next_col_offset = X.col_ptrs[i + 1]; - - const eT* start_ptr = &X.values[ col_offset]; - const eT* end_ptr = &X.values[next_col_offset]; - - const uword n_elem = end_ptr - start_ptr; - - const Col fake_vec(const_cast(start_ptr), n_elem, false, false); - - const T norm_val = norm(fake_vec, p); - - norm_vals_mem[i] = (norm_val != T(0)) ? norm_val : T(1); - } - - const uword N = X.n_nonzero; - - umat locs(2, N); - Col vals( N); - - uword* locs_mem = locs.memptr(); - eT* vals_mem = vals.memptr(); - - typename SpMat::const_iterator it = X.begin(); - - uword new_n_nonzero = 0; - - for(uword i=0; i < N; ++i) - { - const uword row = it.row(); - const uword col = it.col(); - - const eT val = (*it) / norm_vals_mem[col]; - - if(val != eT(0)) - { - (*vals_mem) = val; vals_mem++; - - (*locs_mem) = row; locs_mem++; - (*locs_mem) = col; locs_mem++; - - new_n_nonzero++; - } - - ++it; - } + const uword n_elem = end_ptr - start_ptr; - const umat tmp_locs(locs.memptr(), 2, new_n_nonzero, false, false); - const Col tmp_vals(vals.memptr(), new_n_nonzero, false, false); + const Col fake_vec(const_cast(start_ptr), n_elem, false, false); - SpMat tmp(tmp_locs, tmp_vals, X.n_rows, X.n_cols, false, false); + const T norm_val = norm(fake_vec, p); - out.steal_mem(tmp); + norm_vals_mem[col] = (norm_val != T(0)) ? norm_val : T(1); } - else - if(dim == 1) + + const uword N = X.n_nonzero; + + typename SpMat::const_iterator it = X.begin(); + + for(uword i=0; i < N; ++i) { - podarray< T> norm_vals(X.n_rows); - podarray row_vals(X.n_cols); // worst case scenario - - T* norm_vals_mem = norm_vals.memptr(); - eT* row_vals_mem = row_vals.memptr(); + const uword row = it.row(); + const uword col = it.col(); - for(uword i=0; i < norm_vals.n_elem; ++i) - { - // typename SpMat::const_row_iterator row_it = X.begin_row(i); - // typename SpMat::const_row_iterator row_it_end = X.end_row(i); - // - // uword count = 0; - // - // for(; row_it != row_it_end; ++row_it) - // { - // row_vals_mem[count] = (*row_it); - // ++count; - // } - - - // using the .at() accessor, as it's faster than const_row_iterator for accessing a single row - - uword count = 0; - - for(uword col=0; col < X.n_cols; ++col) - { - const eT val = X.at(i,col); - - if(val != eT(0)) - { - row_vals_mem[count] = val; - ++count; - } - } - - const Row fake_vec(row_vals_mem, count, false, false); - - const T norm_val = norm(fake_vec, p); - - norm_vals_mem[i] = (norm_val != T(0)) ? norm_val : T(1); - } - - const uword N = X.n_nonzero; - - umat locs(2, N); - Col vals( N); - - uword* locs_mem = locs.memptr(); - eT* vals_mem = vals.memptr(); - - typename SpMat::const_iterator it = X.begin(); - - uword new_n_nonzero = 0; - - for(uword i=0; i < N; ++i) - { - const uword row = it.row(); - const uword col = it.col(); - - const eT val = (*it) / norm_vals_mem[row]; - - if(val != eT(0)) - { - (*vals_mem) = val; vals_mem++; - - (*locs_mem) = row; locs_mem++; - (*locs_mem) = col; locs_mem++; - - new_n_nonzero++; - } - - ++it; - } + const eT val = (*it) / norm_vals_mem[col]; - const umat tmp_locs(locs.memptr(), 2, new_n_nonzero, false, false); - const Col tmp_vals(vals.memptr(), new_n_nonzero, false, false); + if(val == eT(0)) { has_zero = true; } - SpMat tmp(tmp_locs, tmp_vals, X.n_rows, X.n_cols, false, false); + access::rw(tmp.values[i]) = val; + access::rw(tmp.row_indices[i]) = row; + access::rw(tmp.col_ptrs[col + 1])++; - out.steal_mem(tmp); + ++it; } + + for(uword c=0; c < tmp.n_cols; ++c) + { + access::rw(tmp.col_ptrs[c + 1]) += tmp.col_ptrs[c]; + } + + if(has_zero) { tmp.remove_zeros(); } + + out.steal_mem(tmp); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_norm_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_norm_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_norm_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_norm_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup spop_norm +//! @{ + + +class spop_norm + : public traits_op_default + { + public: + + template inline static typename get_pod_type::result mat_norm_1(const SpMat& X); + + template inline static typename get_pod_type::result mat_norm_2(const SpMat& X, const typename arma_real_only::result* junk = nullptr); + template inline static typename get_pod_type::result mat_norm_2(const SpMat& X, const typename arma_cx_only::result* junk = nullptr); + + template inline static typename get_pod_type::result mat_norm_inf(const SpMat& X); + }; + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_norm_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_norm_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_norm_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_norm_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup op_norm +//! @{ + + + +template +inline +typename get_pod_type::result +spop_norm::mat_norm_1(const SpMat& X) + { + arma_extra_debug_sigprint(); + + // TODO: this can be sped up with a dedicated implementation + return as_scalar( max( sum(abs(X), 0), 1) ); + } + + + +template +inline +typename get_pod_type::result +spop_norm::mat_norm_2(const SpMat& X, const typename arma_real_only::result* junk) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + // norm = sqrt( largest eigenvalue of (A^H)*A ), where ^H is the conjugate transpose + // http://math.stackexchange.com/questions/4368/computing-the-largest-eigenvalue-of-a-very-large-sparse-matrix + + typedef typename get_pod_type::result T; + + const SpMat& A = X; + const SpMat B = trans(A); + + const SpMat C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A); + + Col eigval; + eigs_sym(eigval, C, 1); + + return (eigval.n_elem > 0) ? T(std::sqrt(eigval[0])) : T(0); + } + + + +template +inline +typename get_pod_type::result +spop_norm::mat_norm_2(const SpMat& X, const typename arma_cx_only::result* junk) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + typedef typename get_pod_type::result T; + + // we're calling eigs_gen(), which currently requires ARPACK + #if !defined(ARMA_USE_ARPACK) + { + arma_stop_logic_error("norm(): use of ARPACK must be enabled for norm of complex matrices"); + return T(0); + } + #endif + + const SpMat& A = X; + const SpMat B = trans(A); + + const SpMat C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A); + + Col eigval; + eigs_gen(eigval, C, 1); + + return (eigval.n_elem > 0) ? T(std::sqrt(std::real(eigval[0]))) : T(0); + } + + + +template +inline +typename get_pod_type::result +spop_norm::mat_norm_inf(const SpMat& X) + { + arma_extra_debug_sigprint(); + + // TODO: this can be sped up with a dedicated implementation + return as_scalar( max( sum(abs(X), 1), 0) ); + } + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_repmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_repmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_repmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_repmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_repmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_repmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_repmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_repmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -126,8 +128,8 @@ // // if( (out_n_rows > 0) && (out_n_cols > 0) && (out_nnz > 0) ) // { -// umat locs(2, out_nnz); -// Col vals( out_nnz); +// umat locs(2, out_nnz, arma_nozeros_indicator()); +// Col vals( out_nnz, arma_nozeros_indicator()); // // uword* locs_mem = locs.memptr(); // eT* vals_mem = vals.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_reverse_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_reverse_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_reverse_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_reverse_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_reverse_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_reverse_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_reverse_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_reverse_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -40,7 +42,7 @@ return; } - umat locs(2, N); + umat locs(2, N, arma_nozeros_indicator()); uword* locs_mem = locs.memptr(); @@ -108,8 +110,8 @@ return; } - umat locs(2, N); - Col vals( N); + umat locs(2, N, arma_nozeros_indicator()); + Col vals( N, arma_nozeros_indicator()); uword* locs_mem = locs.memptr(); eT* vals_mem = vals.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_strans_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_strans_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_strans_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_strans_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ template struct traits { - static const bool is_row = T1::is_col; // deliberately swapped - static const bool is_col = T1::is_row; - static const bool is_xvec = T1::is_xvec; + static constexpr bool is_row = T1::is_col; // deliberately swapped + static constexpr bool is_col = T1::is_row; + static constexpr bool is_xvec = T1::is_xvec; }; template diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_strans_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_strans_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_strans_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_strans_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_sum_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_sum_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_sum_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_sum_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_sum_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_sum_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_sum_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_sum_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -47,7 +49,7 @@ if(dim == 0) // find the sum in each column { - Row acc(p_n_cols, fill::zeros); + Row acc(p_n_cols, arma_zeros_indicator()); eT* acc_mem = acc.memptr(); @@ -80,7 +82,7 @@ else if(dim == 1) // find the sum in each row { - Col acc(p_n_rows, fill::zeros); + Col acc(p_n_rows, arma_zeros_indicator()); eT* acc_mem = acc.memptr(); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_symmat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_symmat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_symmat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_symmat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_symmat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_symmat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_symmat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_symmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_trimat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_trimat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_trimat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_trimat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -32,5 +34,33 @@ }; + +class spop_trimatu_ext + : public traits_op_default + { + public: + + template + inline static void apply_noalias(SpMat& out, const SpMat& A, const uword row_offset, const uword col_offset); + + template + inline static void apply(SpMat& out, const SpOp& in); + }; + + + +class spop_trimatl_ext + : public traits_op_default + { + public: + + template + inline static void apply_noalias(SpMat& out, const SpMat& A, const uword row_offset, const uword col_offset); + + template + inline static void apply(SpMat& out, const SpOp& in); + }; + + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_trimat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_trimat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_trimat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_trimat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -137,6 +139,228 @@ } } + + +// + + + +template +inline +void +spop_trimatu_ext::apply_noalias(SpMat& out, const SpMat& A, const uword row_offset, const uword col_offset) + { + arma_extra_debug_sigprint(); + + const uword n_rows = A.n_rows; + const uword n_cols = A.n_cols; + + arma_debug_check_bounds( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatu(): requested diagonal is out of bounds" ); + + if(A.n_nonzero == 0) { out.zeros(n_rows, n_cols); return; } + + out.reserve(n_rows, n_cols, A.n_nonzero); // upper bound on n_nonzero + + uword count = 0; + + const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset); + + for(uword i=0; i < n_cols; ++i) + { + const uword col = i + col_offset; + + if(i < N) + { + typename SpMat::const_col_iterator it = A.begin_col_no_sync(col); + typename SpMat::const_col_iterator it_end = A.end_col_no_sync(col); + + const uword end_row = i + row_offset; + + for(; it != it_end; ++it) + { + const uword it_row = it.row(); + + if(it_row <= end_row) + { + const uword it_col = it.col(); + + access::rw(out.values[count]) = (*it); + access::rw(out.row_indices[count]) = it_row; + access::rw(out.col_ptrs[it_col + 1])++; + ++count; + } + else + { + break; + } + } + } + else + { + if(col < n_cols) + { + typename SpMat::const_col_iterator it = A.begin_col_no_sync(col); + typename SpMat::const_col_iterator it_end = A.end_col_no_sync(col); + + for(; it != it_end; ++it) + { + const uword it_row = it.row(); + const uword it_col = it.col(); + + access::rw(out.values[count]) = (*it); + access::rw(out.row_indices[count]) = it_row; + access::rw(out.col_ptrs[it_col + 1])++; + ++count; + } + } + } + } + + for(uword i=0; i < n_cols; ++i) + { + access::rw(out.col_ptrs[i + 1]) += out.col_ptrs[i]; + } + + if(count < A.n_nonzero) { out.mem_resize(count); } + } + + + +template +inline +void +spop_trimatu_ext::apply(SpMat& out, const SpOp& in) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_spmat U(in.m); + const SpMat& A = U.M; + + arma_debug_check( (A.is_square() == false), "trimatu(): given matrix must be square sized" ); + + const uword row_offset = in.aux_uword_a; + const uword col_offset = in.aux_uword_b; + + if(U.is_alias(out)) + { + SpMat tmp; + spop_trimatu_ext::apply_noalias(tmp, A, row_offset, col_offset); + out.steal_mem(tmp); + } + else + { + spop_trimatu_ext::apply_noalias(out, A, row_offset, col_offset); + } + } + + + +// + + + +template +inline +void +spop_trimatl_ext::apply_noalias(SpMat& out, const SpMat& A, const uword row_offset, const uword col_offset) + { + arma_extra_debug_sigprint(); + + const uword n_rows = A.n_rows; + const uword n_cols = A.n_cols; + + arma_debug_check_bounds( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatl(): requested diagonal is out of bounds" ); + + if(A.n_nonzero == 0) { out.zeros(n_rows, n_cols); return; } + + out.reserve(n_rows, n_cols, A.n_nonzero); // upper bound on n_nonzero + + uword count = 0; + + if(col_offset > 0) + { + typename SpMat::const_col_iterator it = A.begin_col_no_sync(0); + typename SpMat::const_col_iterator it_end = A.end_col_no_sync(col_offset-1); + + for(; it != it_end; ++it) + { + const uword it_row = it.row(); + const uword it_col = it.col(); + + access::rw(out.values[count]) = (*it); + access::rw(out.row_indices[count]) = it_row; + access::rw(out.col_ptrs[it_col + 1])++; + ++count; + } + } + + const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset); + + for(uword i=0; i < N; ++i) + { + const uword start_row = i + row_offset; + const uword col = i + col_offset; + + typename SpMat::const_col_iterator it = A.begin_col_no_sync(col); + typename SpMat::const_col_iterator it_end = A.end_col_no_sync(col); + + for(; it != it_end; ++it) + { + const uword it_row = it.row(); + + if(it_row >= start_row) + { + const uword it_col = it.col(); + + access::rw(out.values[count]) = (*it); + access::rw(out.row_indices[count]) = it_row; + access::rw(out.col_ptrs[it_col + 1])++; + ++count; + } + } + } + + for(uword i=0; i < n_cols; ++i) + { + access::rw(out.col_ptrs[i + 1]) += out.col_ptrs[i]; + } + + if(count < A.n_nonzero) { out.mem_resize(count); } + } + + + +template +inline +void +spop_trimatl_ext::apply(SpMat& out, const SpOp& in) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_spmat U(in.m); + const SpMat& A = U.M; + + arma_debug_check( (A.is_square() == false), "trimatl(): given matrix must be square sized" ); + + const uword row_offset = in.aux_uword_a; + const uword col_offset = in.aux_uword_b; + + if(U.is_alias(out)) + { + SpMat tmp; + spop_trimatl_ext::apply_noalias(tmp, A, row_offset, col_offset); + out.steal_mem(tmp); + } + else + { + spop_trimatl_ext::apply_noalias(out, A, row_offset, col_offset); + } + } + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_var_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_var_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_var_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_var_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -48,11 +50,11 @@ // Calculate the variance using iterators, for non-complex numbers. template - inline static eT iterator_var(T1& it, const T1& end, const uword n_zero, const uword norm_type, const eT junk1, const typename arma_not_cx::result* junk2 = 0); + inline static eT iterator_var(T1& it, const T1& end, const uword n_zero, const uword norm_type, const eT junk1, const typename arma_not_cx::result* junk2 = nullptr); // Calculate the variance using iterators, for complex numbers. template - inline static typename get_pod_type::result iterator_var(T1& it, const T1& end, const uword n_zero, const uword norm_type, const eT junk1, const typename arma_cx_only::result* junk2 = 0); + inline static typename get_pod_type::result iterator_var(T1& it, const T1& end, const uword n_zero, const uword norm_type, const eT junk1, const typename arma_cx_only::result* junk2 = nullptr); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_var_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_var_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_var_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_var_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -251,7 +253,7 @@ T acc2 = T(0); eT acc3 = eT(0); - for (uword i = 0; i < length; ++i) + for(uword i = 0; i < length; ++i) { const eT tmp = acc1 - X[i]; @@ -315,7 +317,7 @@ const uword it_begin_pos = it.pos(); - while (it != end) + while(it != end) { const eT tmp = mean - (*it); @@ -326,12 +328,12 @@ } const uword n_nonzero = (it.pos() - it_begin_pos); - if (n_nonzero == 0) + if(n_nonzero == 0) { return eT(0); } - if (n_nonzero + n_zero == 1) + if(n_nonzero + n_zero == 1) { return eT(0); // only one element } @@ -376,7 +378,7 @@ const uword it_begin_pos = it.pos(); - while (it != end) + while(it != end) { eT tmp = mean - (*it); @@ -387,12 +389,12 @@ } const uword n_nonzero = (it.pos() - it_begin_pos); - if (n_nonzero == 0) + if(n_nonzero == 0) { return T(0); } - if (n_nonzero + n_zero == 1) + if(n_nonzero + n_zero == 1) { return T(0); // only one element } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_vectorise_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_vectorise_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_vectorise_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_vectorise_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/spop_vectorise_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/spop_vectorise_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/spop_vectorise_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/spop_vectorise_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpProxy.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpProxy.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpProxy.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpProxy.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -64,10 +66,8 @@ template -class SpProxy< SpMat > +struct SpProxy< SpMat > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef SpMat stored_type; @@ -75,12 +75,12 @@ typedef typename SpMat::const_iterator const_iterator_type; typedef typename SpMat::const_row_iterator const_row_iterator_type; - static const bool use_iterator = false; - static const bool Q_is_generated = false; + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = false; - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const SpMat& Q; @@ -118,10 +118,8 @@ template -class SpProxy< SpCol > +struct SpProxy< SpCol > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef SpCol stored_type; @@ -129,12 +127,12 @@ typedef typename SpCol::const_iterator const_iterator_type; typedef typename SpCol::const_row_iterator const_row_iterator_type; - static const bool use_iterator = false; - static const bool Q_is_generated = false; + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = false; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const SpCol& Q; @@ -172,10 +170,8 @@ template -class SpProxy< SpRow > +struct SpProxy< SpRow > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef SpRow stored_type; @@ -183,12 +179,12 @@ typedef typename SpRow::const_iterator const_iterator_type; typedef typename SpRow::const_row_iterator const_row_iterator_type; - static const bool use_iterator = false; - static const bool Q_is_generated = false; + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = false; - static const bool is_row = true; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const SpRow& Q; @@ -226,10 +222,8 @@ template -class SpProxy< SpSubview > +struct SpProxy< SpSubview > { - public: - typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef SpSubview stored_type; @@ -237,12 +231,12 @@ typedef typename SpSubview::const_iterator const_iterator_type; typedef typename SpSubview::const_row_iterator const_row_iterator_type; - static const bool use_iterator = true; - static const bool Q_is_generated = false; + static constexpr bool use_iterator = true; + static constexpr bool Q_is_generated = false; - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const SpSubview& Q; @@ -280,10 +274,163 @@ template -class SpProxy< spdiagview > +struct SpProxy< SpSubview_col > + { + typedef eT elem_type; + typedef typename get_pod_type::result pod_type; + typedef SpSubview_col stored_type; + + typedef typename SpSubview::const_iterator const_iterator_type; + typedef typename SpSubview::const_row_iterator const_row_iterator_type; + + static constexpr bool use_iterator = true; + static constexpr bool Q_is_generated = false; + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; + + arma_aligned const SpSubview_col& Q; + + inline explicit SpProxy(const SpSubview_col& A) + : Q(A) + { + arma_extra_debug_sigprint(); + Q.m.sync(); + } + + arma_inline uword get_n_rows() const { return Q.n_rows; } + arma_inline uword get_n_cols() const { return 1; } + arma_inline uword get_n_elem() const { return Q.n_elem; } + arma_inline uword get_n_nonzero() const { return Q.n_nonzero; } + + arma_inline elem_type operator[](const uword i) const { return Q.at(i, 0); } + arma_inline elem_type at (const uword row, const uword) const { return Q.at(row, 0); } + + arma_inline const eT* get_values() const { return Q.m.values; } + arma_inline const uword* get_row_indices() const { return Q.m.row_indices; } + arma_inline const uword* get_col_ptrs() const { return Q.m.col_ptrs; } + + arma_inline const_iterator_type begin() const { return Q.begin(); } + arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); } + arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); } + + arma_inline const_iterator_type end() const { return Q.end(); } + arma_inline const_row_iterator_type end_row() const { return Q.end_row(); } + arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); } + + template + arma_inline bool is_alias(const SpMat& X) const { return (void_ptr(&Q.m) == void_ptr(&X)); } + }; + + + +template +struct SpProxy< SpSubview_col_list > + { + typedef eT elem_type; + typedef typename get_pod_type::result pod_type; + typedef SpMat stored_type; + + typedef typename SpMat::const_iterator const_iterator_type; + typedef typename SpMat::const_row_iterator const_row_iterator_type; + + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = true; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; + + arma_aligned const SpMat Q; + + inline explicit SpProxy(const SpSubview_col_list& A) + : Q(A) + { + arma_extra_debug_sigprint(); + } + + arma_inline uword get_n_rows() const { return Q.n_rows; } + arma_inline uword get_n_cols() const { return Q.n_cols; } + arma_inline uword get_n_elem() const { return Q.n_elem; } + arma_inline uword get_n_nonzero() const { return Q.n_nonzero; } + + arma_inline elem_type operator[](const uword i) const { return Q[i]; } + arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } + + arma_inline const eT* get_values() const { return Q.values; } + arma_inline const uword* get_row_indices() const { return Q.row_indices; } + arma_inline const uword* get_col_ptrs() const { return Q.col_ptrs; } + + arma_inline const_iterator_type begin() const { return Q.begin(); } + arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); } + arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); } + + arma_inline const_iterator_type end() const { return Q.end(); } + arma_inline const_row_iterator_type end_row() const { return Q.end_row(); } + arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); } + + template + constexpr bool is_alias(const SpMat&) const { return false; } + }; + + + +template +struct SpProxy< SpSubview_row > { - public: + typedef eT elem_type; + typedef typename get_pod_type::result pod_type; + typedef SpSubview_row stored_type; + + typedef typename SpSubview::const_iterator const_iterator_type; + typedef typename SpSubview::const_row_iterator const_row_iterator_type; + + static constexpr bool use_iterator = true; + static constexpr bool Q_is_generated = false; + + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; + + arma_aligned const SpSubview_row& Q; + + inline explicit SpProxy(const SpSubview_row& A) + : Q(A) + { + arma_extra_debug_sigprint(); + Q.m.sync(); + } + + arma_inline uword get_n_rows() const { return 1; } + arma_inline uword get_n_cols() const { return Q.n_cols; } + arma_inline uword get_n_elem() const { return Q.n_elem; } + arma_inline uword get_n_nonzero() const { return Q.n_nonzero; } + + arma_inline elem_type operator[](const uword i) const { return Q.at(0, i ); } + arma_inline elem_type at (const uword, const uword col) const { return Q.at(0, col); } + + arma_inline const eT* get_values() const { return Q.m.values; } + arma_inline const uword* get_row_indices() const { return Q.m.row_indices; } + arma_inline const uword* get_col_ptrs() const { return Q.m.col_ptrs; } + + arma_inline const_iterator_type begin() const { return Q.begin(); } + arma_inline const_iterator_type begin_col(const uword col_num) const { return Q.begin_col(col_num); } + arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); } + arma_inline const_iterator_type end() const { return Q.end(); } + arma_inline const_row_iterator_type end_row() const { return Q.end_row(); } + arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); } + + template + arma_inline bool is_alias(const SpMat& X) const { return (void_ptr(&Q.m) == void_ptr(&X)); } + }; + + + +template +struct SpProxy< spdiagview > + { typedef eT elem_type; typedef typename get_pod_type::result pod_type; typedef SpMat stored_type; @@ -291,12 +438,12 @@ typedef typename SpMat::const_iterator const_iterator_type; typedef typename SpMat::const_row_iterator const_row_iterator_type; - static const bool use_iterator = false; - static const bool Q_is_generated = true; + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = true; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const SpMat Q; @@ -327,16 +474,14 @@ arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); } template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; template -class SpProxy< SpOp > +struct SpProxy< SpOp > { - public: - typedef typename T1::elem_type elem_type; typedef typename T1::elem_type eT; typedef typename get_pod_type::result pod_type; @@ -345,12 +490,12 @@ typedef typename SpMat::const_iterator const_iterator_type; typedef typename SpMat::const_row_iterator const_row_iterator_type; - static const bool use_iterator = false; - static const bool Q_is_generated = true; + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = true; - static const bool is_row = SpOp::is_row; - static const bool is_col = SpOp::is_col; - static const bool is_xvec = SpOp::is_xvec; + static constexpr bool is_row = SpOp::is_row; + static constexpr bool is_col = SpOp::is_col; + static constexpr bool is_xvec = SpOp::is_xvec; arma_aligned const SpMat Q; @@ -381,16 +526,14 @@ arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); } template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; template -class SpProxy< SpGlue > +struct SpProxy< SpGlue > { - public: - typedef typename T1::elem_type elem_type; typedef typename T1::elem_type eT; typedef typename get_pod_type::result pod_type; @@ -399,12 +542,12 @@ typedef typename SpMat::const_iterator const_iterator_type; typedef typename SpMat::const_row_iterator const_row_iterator_type; - static const bool use_iterator = false; - static const bool Q_is_generated = true; + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = true; - static const bool is_row = SpGlue::is_row; - static const bool is_col = SpGlue::is_col; - static const bool is_xvec = SpGlue::is_xvec; + static constexpr bool is_row = SpGlue::is_row; + static constexpr bool is_col = SpGlue::is_col; + static constexpr bool is_xvec = SpGlue::is_xvec; arma_aligned const SpMat Q; @@ -435,16 +578,14 @@ arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); } template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; template -class SpProxy< mtSpOp > +struct SpProxy< mtSpOp > { - public: - typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; typedef SpMat stored_type; @@ -452,12 +593,12 @@ typedef typename SpMat::const_iterator const_iterator_type; typedef typename SpMat::const_row_iterator const_row_iterator_type; - static const bool use_iterator = false; - static const bool Q_is_generated = true; + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = true; - static const bool is_row = mtSpOp::is_row; - static const bool is_col = mtSpOp::is_col; - static const bool is_xvec = mtSpOp::is_xvec; + static constexpr bool is_row = mtSpOp::is_row; + static constexpr bool is_col = mtSpOp::is_col; + static constexpr bool is_xvec = mtSpOp::is_xvec; arma_aligned const SpMat Q; @@ -488,16 +629,14 @@ arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); } template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; template -class SpProxy< mtSpGlue > +struct SpProxy< mtSpGlue > { - public: - typedef out_eT elem_type; typedef typename get_pod_type::result pod_type; typedef SpMat stored_type; @@ -505,12 +644,12 @@ typedef typename SpMat::const_iterator const_iterator_type; typedef typename SpMat::const_row_iterator const_row_iterator_type; - static const bool use_iterator = false; - static const bool Q_is_generated = true; + static constexpr bool use_iterator = false; + static constexpr bool Q_is_generated = true; - static const bool is_row = mtSpGlue::is_row; - static const bool is_col = mtSpGlue::is_col; - static const bool is_xvec = mtSpGlue::is_xvec; + static constexpr bool is_row = mtSpGlue::is_row; + static constexpr bool is_col = mtSpGlue::is_col; + static constexpr bool is_xvec = mtSpGlue::is_xvec; arma_aligned const SpMat Q; @@ -541,7 +680,7 @@ arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); } template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpRow_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpRow_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpRow_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpRow_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -27,9 +29,9 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = true; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; inline SpRow(); @@ -54,6 +56,10 @@ template inline explicit SpRow(const SpBase& A, const SpBase& B); + inline arma_warn_unused const SpOp,spop_htrans> t() const; + inline arma_warn_unused const SpOp,spop_htrans> ht() const; + inline arma_warn_unused const SpOp,spop_strans> st() const; + inline void shed_col (const uword col_num); inline void shed_cols(const uword in_col1, const uword in_col2); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpRow_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpRow_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpRow_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpRow_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -200,6 +202,39 @@ +template +inline +arma_warn_unused +const SpOp,spop_htrans> +SpRow::t() const + { + return SpOp,spop_htrans>(*this); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_htrans> +SpRow::ht() const + { + return SpOp,spop_htrans>(*this); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_strans> +SpRow::st() const + { + return SpOp,spop_strans>(*this); + } + + + //! remove specified columns template inline @@ -208,7 +243,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= SpMat::n_cols, "SpRow::shed_col(): out of bounds"); + arma_debug_check_bounds( col_num >= SpMat::n_cols, "SpRow::shed_col(): out of bounds" ); shed_cols(col_num, col_num); } @@ -223,7 +258,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= SpMat::n_cols), "SpRow::shed_cols(): indices out of bounds or incorrectly used" @@ -237,7 +272,7 @@ const uword start = SpMat::col_ptrs[in_col1]; const uword end = SpMat::col_ptrs[in_col2 + 1]; - if (start != end) + if(start != end) { const uword elem_diff = end - start; @@ -245,14 +280,14 @@ uword* new_row_indices = memory::acquire(SpMat::n_nonzero - elem_diff); // Copy first set of elements, if necessary. - if (start > 0) + if(start > 0) { arrayops::copy(new_values, SpMat::values, start); arrayops::copy(new_row_indices, SpMat::row_indices, start); } // Copy last set of elements, if necessary. - if (end != SpMat::n_nonzero) + if(end != SpMat::n_nonzero) { arrayops::copy(new_values + start, SpMat::values + end, (SpMat::n_nonzero - end)); arrayops::copy(new_row_indices + start, SpMat::row_indices + end, (SpMat::n_nonzero - end)); @@ -271,13 +306,13 @@ uword* new_col_ptrs = memory::acquire(SpMat::n_cols - diff + 1); // Copy first part of column pointers. - if (in_col1 > 0) + if(in_col1 > 0) { arrayops::copy(new_col_ptrs, SpMat::col_ptrs, in_col1); } // Copy last part of column pointers (and adjust their values as necessary). - if (in_col2 < SpMat::n_cols - 1) + if(in_col2 < SpMat::n_cols - 1) { arrayops::copy(new_col_ptrs + in_col1, SpMat::col_ptrs + in_col2 + 1, SpMat::n_cols - in_col2); // Modify their values. @@ -306,9 +341,9 @@ // arma_extra_debug_sigprint(); // // // insertion at col_num == n_cols is in effect an append operation -// arma_debug_check( (col_num > SpMat::n_cols), "SpRow::insert_cols(): out of bounds"); +// arma_debug_check_bounds( (col_num > SpMat::n_cols), "SpRow::insert_cols(): out of bounds" ); // -// arma_debug_check( (set_to_zero == false), "SpRow::insert_cols(): cannot set elements to nonzero values"); +// arma_debug_check( (set_to_zero == false), "SpRow::insert_cols(): cannot set elements to nonzero values" ); // // uword newVal = (col_num == 0) ? 0 : SpMat::col_ptrs[col_num]; // SpMat::col_ptrs.insert(col_num, N, newVal); @@ -336,7 +371,7 @@ // Since this is a row, row_num can only be 0. But the option is provided for // compatibility. - arma_debug_check((row_num >= 1), "SpRow::begin_row(): index out of bounds"); + arma_debug_check_bounds((row_num >= 1), "SpRow::begin_row(): index out of bounds"); return SpMat::begin(); } @@ -352,7 +387,7 @@ // Since this is a row, row_num can only be 0. But the option is provided for // compatibility. - arma_debug_check((row_num >= 1), "SpRow::begin_row(): index out of bounds"); + arma_debug_check_bounds((row_num >= 1), "SpRow::begin_row(): index out of bounds"); return SpMat::begin(); } @@ -368,7 +403,7 @@ // Since this is a row, row_num can only be 0. But the option is provided for // compatibility. - arma_debug_check((row_num >= 1), "SpRow::end_row(): index out of bounds"); + arma_debug_check_bounds((row_num >= 1), "SpRow::end_row(): index out of bounds"); return SpMat::end(); } @@ -384,7 +419,7 @@ // Since this is a row, row_num can only be 0. But the option is provided for // compatibility. - arma_debug_check((row_num >= 1), "SpRow::end_row(): index out of bounds"); + arma_debug_check_bounds((row_num >= 1), "SpRow::end_row(): index out of bounds"); return SpMat::end(); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,7 +21,7 @@ template -class SpSubview : public SpBase > +class SpSubview : public SpBase< eT, SpSubview > { public: @@ -28,9 +30,9 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; const uword aux_row1; const uword aux_col1; @@ -39,31 +41,32 @@ const uword n_elem; const uword n_nonzero; - friend class SpValProxy< SpSubview >; // allow SpValProxy to call insert_element() and delete_element() - protected: - - arma_inline SpSubview(const SpMat& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols); - arma_inline SpSubview( SpMat& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols); - + + inline SpSubview(const SpMat& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols); + public: - + inline ~SpSubview(); - + inline SpSubview() = delete; + + inline SpSubview(const SpSubview& in); + inline SpSubview( SpSubview&& in); + inline const SpSubview& operator+= (const eT val); inline const SpSubview& operator-= (const eT val); inline const SpSubview& operator*= (const eT val); inline const SpSubview& operator/= (const eT val); - + inline const SpSubview& operator=(const SpSubview& x); - + template inline const SpSubview& operator= (const Base& x); template inline const SpSubview& operator+=(const Base& x); template inline const SpSubview& operator-=(const Base& x); template inline const SpSubview& operator*=(const Base& x); template inline const SpSubview& operator%=(const Base& x); template inline const SpSubview& operator/=(const Base& x); - + template inline const SpSubview& operator_equ_common(const SpBase& x); template inline const SpSubview& operator= (const SpBase& x); @@ -75,7 +78,7 @@ /* inline static void extract(SpMat& out, const SpSubview& in); - + inline static void plus_inplace(Mat& out, const subview& in); inline static void minus_inplace(Mat& out, const subview& in); inline static void schur_inplace(Mat& out, const subview& in); @@ -91,205 +94,210 @@ inline void clean(const pod_type threshold); + inline void clamp(const eT min_val, const eT max_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); inline void eye(); - + inline void randu(); + inline void randn(); + + arma_hot inline SpSubview_MapMat_val operator[](const uword i); arma_hot inline eT operator[](const uword i) const; - + arma_hot inline SpSubview_MapMat_val operator()(const uword i); arma_hot inline eT operator()(const uword i) const; - + arma_hot inline SpSubview_MapMat_val operator()(const uword in_row, const uword in_col); arma_hot inline eT operator()(const uword in_row, const uword in_col) const; - + arma_hot inline SpSubview_MapMat_val at(const uword i); arma_hot inline eT at(const uword i) const; - + arma_hot inline SpSubview_MapMat_val at(const uword in_row, const uword in_col); arma_hot inline eT at(const uword in_row, const uword in_col) const; - + inline bool check_overlap(const SpSubview& x) const; - + inline bool is_vec() const; - - inline SpSubview row(const uword row_num); - inline const SpSubview row(const uword row_num) const; - - inline SpSubview col(const uword col_num); - inline const SpSubview col(const uword col_num) const; - + + inline SpSubview_row row(const uword row_num); + inline const SpSubview_row row(const uword row_num) const; + + inline SpSubview_col col(const uword col_num); + inline const SpSubview_col col(const uword col_num) const; + inline SpSubview rows(const uword in_row1, const uword in_row2); inline const SpSubview rows(const uword in_row1, const uword in_row2) const; - + inline SpSubview cols(const uword in_col1, const uword in_col2); inline const SpSubview cols(const uword in_col1, const uword in_col2) const; - + inline SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2); inline const SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const; - + inline SpSubview submat(const span& row_span, const span& col_span); inline const SpSubview submat(const span& row_span, const span& col_span) const; - + inline SpSubview operator()(const uword row_num, const span& col_span); inline const SpSubview operator()(const uword row_num, const span& col_span) const; - + inline SpSubview operator()(const span& row_span, const uword col_num); inline const SpSubview operator()(const span& row_span, const uword col_num) const; - + inline SpSubview operator()(const span& row_span, const span& col_span); inline const SpSubview operator()(const span& row_span, const span& col_span) const; inline void swap_rows(const uword in_row1, const uword in_row2); inline void swap_cols(const uword in_col1, const uword in_col2); - + // Forward declarations. class iterator_base; class const_iterator; class iterator; class const_row_iterator; class row_iterator; - + // Similar to SpMat iterators but automatically iterates past and ignores values not in the subview. class iterator_base { public: - + inline iterator_base(const SpSubview& in_M); inline iterator_base(const SpSubview& in_M, const uword col, const uword pos); - + arma_inline uword col() const { return internal_col; } arma_inline uword pos() const { return internal_pos; } - + arma_aligned const SpSubview* M; arma_aligned uword internal_col; arma_aligned uword internal_pos; - + typedef std::bidirectional_iterator_tag iterator_category; typedef eT value_type; typedef std::ptrdiff_t difference_type; // TODO: not certain on this one typedef const eT* pointer; typedef const eT& reference; }; - + class const_iterator : public iterator_base { public: - + inline const_iterator(const SpSubview& in_M, uword initial_pos = 0); inline const_iterator(const SpSubview& in_M, uword in_row, uword in_col); inline const_iterator(const SpSubview& in_M, uword in_row, uword in_col, uword in_pos, uword skip_pos); inline const_iterator(const const_iterator& other); - + arma_inline eT operator*() const; - + // Don't hold location internally; call "dummy" methods to get that information. arma_inline uword row() const { return iterator_base::M->m.row_indices[iterator_base::internal_pos + skip_pos] - iterator_base::M->aux_row1; } - + inline arma_hot const_iterator& operator++(); inline arma_warn_unused const_iterator operator++(int); - + inline arma_hot const_iterator& operator--(); inline arma_warn_unused const_iterator operator--(int); - + inline arma_hot bool operator!=(const const_iterator& rhs) const; inline arma_hot bool operator==(const const_iterator& rhs) const; - + inline arma_hot bool operator!=(const typename SpMat::const_iterator& rhs) const; inline arma_hot bool operator==(const typename SpMat::const_iterator& rhs) const; - + inline arma_hot bool operator!=(const const_row_iterator& rhs) const; inline arma_hot bool operator==(const const_row_iterator& rhs) const; - + inline arma_hot bool operator!=(const typename SpMat::const_row_iterator& rhs) const; inline arma_hot bool operator==(const typename SpMat::const_row_iterator& rhs) const; - + arma_aligned uword skip_pos; // not used in row_iterator or const_row_iterator }; - + class iterator : public const_iterator { public: - + inline iterator(SpSubview& in_M, const uword initial_pos = 0) : const_iterator(in_M, initial_pos) { } inline iterator(SpSubview& in_M, const uword in_row, const uword in_col) : const_iterator(in_M, in_row, in_col) { } inline iterator(SpSubview& in_M, const uword in_row, const uword in_col, const uword in_pos, const uword in_skip_pos) : const_iterator(in_M, in_row, in_col, in_pos, in_skip_pos) { } inline iterator(const iterator& other) : const_iterator(other) { } - - inline arma_hot SpValProxy > operator*(); - + + inline arma_hot SpValProxy< SpSubview > operator*(); + // overloads needed for return type correctness inline arma_hot iterator& operator++(); inline arma_warn_unused iterator operator++(int); - + inline arma_hot iterator& operator--(); inline arma_warn_unused iterator operator--(int); - + // This has a different value_type than iterator_base. - typedef SpValProxy > value_type; - typedef const SpValProxy >* pointer; - typedef const SpValProxy >& reference; + typedef SpValProxy< SpSubview > value_type; + typedef const SpValProxy< SpSubview >* pointer; + typedef const SpValProxy< SpSubview >& reference; }; - + class const_row_iterator : public iterator_base { public: - + inline const_row_iterator(); inline const_row_iterator(const SpSubview& in_M, uword initial_pos = 0); inline const_row_iterator(const SpSubview& in_M, uword in_row, uword in_col); inline const_row_iterator(const const_row_iterator& other); - + inline arma_hot const_row_iterator& operator++(); inline arma_warn_unused const_row_iterator operator++(int); - + inline arma_hot const_row_iterator& operator--(); inline arma_warn_unused const_row_iterator operator--(int); - + uword internal_row; // Hold row internally because we use internal_pos differently. uword actual_pos; // Actual position in subview's parent matrix. - + arma_inline eT operator*() const { return iterator_base::M->m.values[actual_pos]; } - + arma_inline uword row() const { return internal_row; } - + inline arma_hot bool operator!=(const const_iterator& rhs) const; inline arma_hot bool operator==(const const_iterator& rhs) const; - + inline arma_hot bool operator!=(const typename SpMat::const_iterator& rhs) const; inline arma_hot bool operator==(const typename SpMat::const_iterator& rhs) const; - + inline arma_hot bool operator!=(const const_row_iterator& rhs) const; inline arma_hot bool operator==(const const_row_iterator& rhs) const; - + inline arma_hot bool operator!=(const typename SpMat::const_row_iterator& rhs) const; inline arma_hot bool operator==(const typename SpMat::const_row_iterator& rhs) const; }; - + class row_iterator : public const_row_iterator { public: - + inline row_iterator(SpSubview& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { } inline row_iterator(SpSubview& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { } inline row_iterator(const row_iterator& other) : const_row_iterator(other) { } - - inline arma_hot SpValProxy > operator*(); - + + inline arma_hot SpValProxy< SpSubview > operator*(); + // overloads needed for return type correctness inline arma_hot row_iterator& operator++(); inline arma_warn_unused row_iterator operator++(int); - + inline arma_hot row_iterator& operator--(); inline arma_warn_unused row_iterator operator--(int); - + // This has a different value_type than iterator_base. - typedef SpValProxy > value_type; - typedef const SpValProxy >* pointer; - typedef const SpValProxy >& reference; + typedef SpValProxy< SpSubview > value_type; + typedef const SpValProxy< SpSubview >* pointer; + typedef const SpValProxy< SpSubview >& reference; }; inline iterator begin(); @@ -298,27 +306,30 @@ inline iterator begin_col(const uword col_num); inline const_iterator begin_col(const uword col_num) const; - + inline row_iterator begin_row(const uword row_num = 0); inline const_row_iterator begin_row(const uword row_num = 0) const; - + inline iterator end(); inline const_iterator end() const; inline const_iterator cend() const; - + inline row_iterator end_row(); inline const_row_iterator end_row() const; - + inline row_iterator end_row(const uword row_num); 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& X) const; - - + + private: + friend class SpMat; - SpSubview(); + friend class SpSubview_col; + friend class SpSubview_row; + friend class SpValProxy< SpSubview >; // allow SpValProxy to call insert_element() and delete_element() inline arma_warn_unused eT& insert_element(const uword in_row, const uword in_col, const eT in_val = eT(0)); inline void delete_element(const uword in_row, const uword in_col); @@ -326,84 +337,82 @@ inline void invalidate_cache() const; }; -/* + + template class SpSubview_col : public SpSubview { public: - + typedef eT elem_type; typedef typename get_pod_type::result pod_type; - + + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; + inline void operator= (const SpSubview& x); inline void operator= (const SpSubview_col& x); - - template - inline void operator= (const Base& x); - - inline SpSubview_col rows(const uword in_row1, const uword in_row2); - inline const SpSubview_col rows(const uword in_row1, const uword in_row2) const; - - inline SpSubview_col subvec(const uword in_row1, const uword in_row2); - inline const SpSubview_col subvec(const uword in_row1, const uword in_row2) const; - - + + template inline void operator= (const SpBase& x); + template inline void operator= (const Base& x); + + inline arma_warn_unused const SpOp,spop_htrans> t() const; + inline arma_warn_unused const SpOp,spop_htrans> ht() const; + inline arma_warn_unused const SpOp,spop_strans> st() const; + + protected: - - inline SpSubview_col(const Mat& in_m, const uword in_col); - inline SpSubview_col( Mat& in_m, const uword in_col); - - inline SpSubview_col(const Mat& in_m, const uword in_col, const uword in_row1, const uword in_n_rows); - inline SpSubview_col( Mat& in_m, const uword in_col, const uword in_row1, const uword in_n_rows); - - + + inline SpSubview_col(const SpMat& in_m, const uword in_col); + inline SpSubview_col(const SpMat& in_m, const uword in_col, const uword in_row1, const uword in_n_rows); + inline SpSubview_col() = delete; + + private: - - friend class Mat; - friend class Col; + + friend class SpMat; friend class SpSubview; - - SpSubview_col(); }; + + template class SpSubview_row : public SpSubview { public: - + typedef eT elem_type; typedef typename get_pod_type::result pod_type; - + + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; + inline void operator= (const SpSubview& x); inline void operator= (const SpSubview_row& x); - - template - inline void operator= (const Base& x); - - inline SpSubview_row cols(const uword in_col1, const uword in_col2); - inline const SpSubview_row cols(const uword in_col1, const uword in_col2) const; - - inline SpSubview_row subvec(const uword in_col1, const uword in_col2); - inline const SpSubview_row subvec(const uword in_col1, const uword in_col2) const; - - + + template inline void operator= (const SpBase& x); + template inline void operator= (const Base& x); + + inline arma_warn_unused const SpOp,spop_htrans> t() const; + inline arma_warn_unused const SpOp,spop_htrans> ht() const; + inline arma_warn_unused const SpOp,spop_strans> st() const; + + protected: - - inline SpSubview_row(const Mat& in_m, const uword in_row); - inline SpSubview_row( Mat& in_m, const uword in_row); - - inline SpSubview_row(const Mat& in_m, const uword in_row, const uword in_col1, const uword in_n_cols); - inline SpSubview_row( Mat& in_m, const uword in_row, const uword in_col1, const uword in_n_cols); - - + + inline SpSubview_row(const SpMat& in_m, const uword in_row); + inline SpSubview_row(const SpMat& in_m, const uword in_row, const uword in_col1, const uword in_n_cols); + inline SpSubview_row() = delete; + + private: - - friend class Mat; - friend class Row; + + friend class SpMat; friend class SpSubview; - - SpSubview_row(); }; -*/ + + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_col_list_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_col_list_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_col_list_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_col_list_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup SpSubview_col_list +//! @{ + + + +template +class SpSubview_col_list : public SpBase< eT, SpSubview_col_list > + { + public: + + typedef eT elem_type; + typedef typename get_pod_type::result pod_type; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; + + const SpMat& m; + const quasi_unwrap U_ci; + + + protected: + + arma_inline SpSubview_col_list(const SpMat& in_m, const Base& in_ci); + + + public: + + inline ~SpSubview_col_list(); + inline SpSubview_col_list() = delete; + + template inline void for_each(functor F); + template inline void for_each(functor F) const; + + template inline void transform(functor F); + + inline void replace(const eT old_val, const eT new_val); + + inline void clean(const pod_type threshold); + + inline void fill(const eT val); + inline void zeros(); + inline void ones(); + + inline void operator+= (const eT val); + inline void operator-= (const eT val); + inline void operator*= (const eT val); + inline void operator/= (const eT val); + + template inline void operator= (const Base& x); + template inline void operator+=(const Base& x); + template inline void operator-=(const Base& x); + template inline void operator%=(const Base& x); + template inline void operator/=(const Base& x); + + inline void operator= (const SpSubview_col_list& x); + template inline void operator= (const SpSubview_col_list& x); + + template inline void operator= (const SpBase& x); + template inline void operator+= (const SpBase& x); + template inline void operator-= (const SpBase& x); + template inline void operator%= (const SpBase& x); + template inline void operator/= (const SpBase& x); + + inline static void extract(SpMat& out, const SpSubview_col_list& in); + + inline static void plus_inplace(SpMat& out, const SpSubview_col_list& in); + inline static void minus_inplace(SpMat& out, const SpSubview_col_list& in); + inline static void schur_inplace(SpMat& out, const SpSubview_col_list& in); + inline static void div_inplace(SpMat& out, const SpSubview_col_list& in); + + + friend class SpMat; + }; + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_col_list_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_col_list_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_col_list_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_col_list_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,719 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup SpSubview_col_list +//! @{ + + + +template +inline +SpSubview_col_list::~SpSubview_col_list() + { + arma_extra_debug_sigprint(); + } + + + +template +arma_inline +SpSubview_col_list::SpSubview_col_list + ( + const SpMat& in_m, + const Base& in_ci + ) + : m (in_m ) + , U_ci(in_ci.get_ref()) + { + arma_extra_debug_sigprint(); + + const umat& ci = U_ci.M; + const uword* ci_mem = ci.memptr(); + const uword ci_n_elem = ci.n_elem; + + arma_debug_check + ( + ( (ci.is_vec() == false) && (ci.is_empty() == false) ), + "SpMat::cols(): given object must be a vector" + ); + + for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) + { + const uword i = ci_mem[ci_count]; + + arma_debug_check_bounds( (i >= in_m.n_cols), "SpMat::cols(): index out of bounds" ); + } + } + + + +//! apply a functor to each element +template +template +inline +void +SpSubview_col_list::for_each(functor F) + { + arma_extra_debug_sigprint(); + + SpMat tmp(*this); + + tmp.for_each(F); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::for_each(functor F) const + { + arma_extra_debug_sigprint(); + + const SpMat tmp(*this); + + tmp.for_each(F); + } + + + +//! transform each element using a functor +template +template +inline +void +SpSubview_col_list::transform(functor F) + { + arma_extra_debug_sigprint(); + + SpMat tmp(*this); + + tmp.transform(F); + + (*this).operator=(tmp); + } + + + +template +inline +void +SpSubview_col_list::replace(const eT old_val, const eT new_val) + { + arma_extra_debug_sigprint(); + + SpMat tmp(*this); + + tmp.replace(old_val, new_val); + + (*this).operator=(tmp); + } + + + +template +inline +void +SpSubview_col_list::clean(const typename get_pod_type::result threshold) + { + arma_extra_debug_sigprint(); + + SpMat tmp(*this); + + tmp.clean(threshold); + + (*this).operator=(tmp); + } + + + +template +inline +void +SpSubview_col_list::fill(const eT val) + { + arma_extra_debug_sigprint(); + + Mat tmp(m.n_rows, U_ci.M.n_elem, arma_nozeros_indicator()); tmp.fill(val); + + (*this).operator=(tmp); + } + + + +template +inline +void +SpSubview_col_list::zeros() + { + arma_extra_debug_sigprint(); + + SpMat& m_local = const_cast< SpMat& >(m); + + const umat& ci = U_ci.M; + const uword* ci_mem = ci.memptr(); + const uword ci_n_elem = ci.n_elem; + + m_local.sync_csc(); + m_local.invalidate_cache(); + + for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) + { + const uword i = ci_mem[ci_count]; + + const uword col_n_nonzero = m_local.col_ptrs[i+1] - m_local.col_ptrs[i]; + + uword offset = m_local.col_ptrs[i]; + + for(uword j=0; j < col_n_nonzero; ++j) + { + access::rw(m_local.values[offset]) = eT(0); + + ++offset; + } + } + + m_local.remove_zeros(); + } + + + +template +inline +void +SpSubview_col_list::ones() + { + arma_extra_debug_sigprint(); + + const Mat tmp(m.n_rows, U_ci.M.n_elem, fill::ones); + + (*this).operator=(tmp); + } + + + +template +inline +void +SpSubview_col_list::operator+= (const eT val) + { + arma_extra_debug_sigprint(); + + const SpMat tmp1(*this); + + Mat tmp2(tmp1.n_rows, tmp1.n_cols, arma_nozeros_indicator()); tmp2.fill(val); + + const Mat tmp3 = tmp1 + tmp2; + + (*this).operator=(tmp3); + } + + + +template +inline +void +SpSubview_col_list::operator-= (const eT val) + { + arma_extra_debug_sigprint(); + + const SpMat tmp1(*this); + + Mat tmp2(tmp1.n_rows, tmp1.n_cols, arma_nozeros_indicator()); tmp2.fill(val); + + const Mat tmp3 = tmp1 - tmp2; + + (*this).operator=(tmp3); + } + + + +template +inline +void +SpSubview_col_list::operator*= (const eT val) + { + arma_extra_debug_sigprint(); + + if(val == eT(0)) { (*this).zeros(); return; } + + SpMat& m_local = const_cast< SpMat& >(m); + + const umat& ci = U_ci.M; + const uword* ci_mem = ci.memptr(); + const uword ci_n_elem = ci.n_elem; + + m_local.sync_csc(); + m_local.invalidate_cache(); + + bool has_zero = false; + + for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) + { + const uword i = ci_mem[ci_count]; + + const uword col_n_nonzero = m_local.col_ptrs[i+1] - m_local.col_ptrs[i]; + + uword offset = m_local.col_ptrs[i]; + + for(uword j=0; j < col_n_nonzero; ++j) + { + eT& m_local_val = access::rw(m_local.values[offset]); + + m_local_val *= val; + + if(m_local_val == eT(0)) { has_zero = true; } + + ++offset; + } + } + + if(has_zero) { m_local.remove_zeros(); } + } + + + +template +inline +void +SpSubview_col_list::operator/= (const eT val) + { + arma_extra_debug_sigprint(); + + const SpMat tmp1(*this); + + Mat tmp2(tmp1.n_rows, tmp1.n_cols, arma_nozeros_indicator()); tmp2.fill(val); + + const SpMat tmp3 = tmp1 / tmp2; + + (*this).operator=(tmp3); + } + + + +template +template +inline +void +SpSubview_col_list::operator= (const Base& x) + { + arma_extra_debug_sigprint(); + + const quasi_unwrap U(x.get_ref()); + const Mat& X = U.M; + + SpMat& m_local = const_cast< SpMat& >(m); + + const umat& ci = U_ci.M; + const uword* ci_mem = ci.memptr(); + const uword ci_n_elem = ci.n_elem; + + arma_debug_assert_same_size( m_local.n_rows, ci_n_elem, X.n_rows, X.n_cols, "SpMat::cols()" ); + + const uword X_n_elem = X.n_elem; + const eT* X_mem = X.memptr(); + + uword X_n_nonzero = 0; + + for(uword i=0; i < X_n_elem; ++i) { X_n_nonzero += (X_mem[i] != eT(0)) ? uword(1) : uword(0); } + + SpMat Y(arma_reserve_indicator(), X.n_rows, m_local.n_cols, X_n_nonzero); + + uword count = 0; + + for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) + { + const uword i = ci_mem[ci_count]; + + for(uword row=0; row < X.n_rows; ++row) + { + const eT X_val = (*X_mem); ++X_mem; + + if(X_val != eT(0)) + { + access::rw(Y.row_indices[count]) = row; + access::rw(Y.values [count]) = X_val; + ++count; + ++access::rw(Y.col_ptrs[i + 1]); + } + } + } + + // fix the column pointers + for(uword i = 0; i < Y.n_cols; ++i) + { + access::rw(Y.col_ptrs[i+1]) += Y.col_ptrs[i]; + } + + (*this).zeros(); + + SpMat tmp = m_local + Y; + + m_local.steal_mem(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator+= (const Base& x) + { + arma_extra_debug_sigprint(); + + const Mat tmp = SpMat(*this) + x.get_ref(); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator-= (const Base& x) + { + arma_extra_debug_sigprint(); + + const Mat tmp = SpMat(*this) - x.get_ref(); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator%= (const Base& x) + { + arma_extra_debug_sigprint(); + + const SpMat tmp = SpMat(*this) % x.get_ref(); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator/= (const Base& x) + { + arma_extra_debug_sigprint(); + + const SpMat tmp = SpMat(*this) / x.get_ref(); + + (*this).operator=(tmp); + } + + + +template +inline +void +SpSubview_col_list::operator= (const SpSubview_col_list& x) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(x); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator= (const SpSubview_col_list& x) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(x); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const unwrap_spmat U(x.get_ref()); + const SpMat& X = U.M; + + if(U.is_alias(m)) + { + const SpMat tmp(X); + + (*this).operator=(tmp); + + return; + } + + SpMat& m_local = const_cast< SpMat& >(m); + + const umat& ci = U_ci.M; + const uword* ci_mem = ci.memptr(); + const uword ci_n_elem = ci.n_elem; + + arma_debug_assert_same_size( m_local.n_rows, ci_n_elem, X.n_rows, X.n_cols, "SpMat::cols()" ); + + SpMat Y(arma_reserve_indicator(), X.n_rows, m_local.n_cols, X.n_nonzero); + + uword count = 0; + + for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) + { + const uword i = ci_mem[ci_count]; + + typename SpMat::const_col_iterator X_col_it = X.begin_col(ci_count); + typename SpMat::const_col_iterator X_col_it_end = X.end_col(ci_count); + + while(X_col_it != X_col_it_end) + { + access::rw(Y.row_indices[count]) = X_col_it.row(); + access::rw(Y.values [count]) = (*X_col_it); + ++count; + ++access::rw(Y.col_ptrs[i + 1]); + ++X_col_it; + } + } + + // fix the column pointers + for(uword i = 0; i < Y.n_cols; ++i) + { + access::rw(Y.col_ptrs[i+1]) += Y.col_ptrs[i]; + } + + (*this).zeros(); + + SpMat tmp = m_local + Y; + + m_local.steal_mem(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator+= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const SpMat tmp = SpMat(*this) + x.get_ref(); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator-= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const SpMat tmp = SpMat(*this) - x.get_ref(); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator%= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const SpMat tmp = SpMat(*this) % x.get_ref(); + + (*this).operator=(tmp); + } + + + +template +template +inline +void +SpSubview_col_list::operator/= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + SpMat tmp(*this); + + tmp /= x.get_ref(); + + (*this).operator=(tmp); + } + + + +// +// + + + +template +inline +void +SpSubview_col_list::extract(SpMat& out, const SpSubview_col_list& in) + { + arma_extra_debug_sigprint(); + + // NOTE: aliasing is handled by SpMat::operator=(const SpSubview_col_list& in) + + const umat& ci = in.U_ci.M; + const uword* ci_mem = ci.memptr(); + const uword ci_n_elem = ci.n_elem; + + const SpMat& in_m = in.m; + + in_m.sync_csc(); + + uword total_n_nonzero = 0; + + for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) + { + const uword i = ci_mem[ci_count]; + + const uword col_n_nonzero = in_m.col_ptrs[i+1] - in_m.col_ptrs[i]; + + total_n_nonzero += col_n_nonzero; + } + + out.reserve(in.m.n_rows, ci_n_elem, total_n_nonzero); + + uword out_n_nonzero = 0; + uword out_col_count = 0; + + for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) + { + const uword i = ci_mem[ci_count]; + + const uword col_n_nonzero = in_m.col_ptrs[i+1] - in_m.col_ptrs[i]; + + uword offset = in_m.col_ptrs[i]; + + for(uword j=0; j < col_n_nonzero; ++j) + { + const eT val = in_m.values [ offset ]; + const uword row = in_m.row_indices[ offset ]; + + ++offset; + + access::rw(out.values [out_n_nonzero]) = val; + access::rw(out.row_indices[out_n_nonzero]) = row; + + access::rw(out.col_ptrs[out_col_count+1])++; + + ++out_n_nonzero; + } + + ++out_col_count; + } + + // fix the column pointers + for(uword i = 0; i < out.n_cols; ++i) + { + access::rw(out.col_ptrs[i+1]) += out.col_ptrs[i]; + } + } + + + +template +inline +void +SpSubview_col_list::plus_inplace(SpMat& out, const SpSubview_col_list& in) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(in); + + out += tmp; + } + + + +template +inline +void +SpSubview_col_list::minus_inplace(SpMat& out, const SpSubview_col_list& in) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(in); + + out -= tmp; + } + + + +template +inline +void +SpSubview_col_list::schur_inplace(SpMat& out, const SpSubview_col_list& in) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(in); + + out %= tmp; + } + + + +template +inline +void +SpSubview_col_list::div_inplace(SpMat& out, const SpSubview_col_list& in) + { + arma_extra_debug_sigprint(); + + const SpMat tmp(in); + + out /= tmp; + } + + + +//! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_iterators_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_iterators_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_iterators_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_iterators_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -516,10 +518,10 @@ template inline arma_hot -SpValProxy > +SpValProxy< SpSubview > SpSubview::iterator::operator*() { - return SpValProxy >( + return SpValProxy< SpSubview >( const_iterator::row(), iterator_base::col(), access::rw(*iterator_base::M), @@ -625,9 +627,9 @@ // Since we don't know where the elements are in each row, we have to loop // across all columns looking for elements in row 0 and add to our sum, then // in row 1, and so forth, until we get to the desired position. - for (uword row = 0; row < iterator_base::M->n_rows; ++row) + for(uword row = 0; row < iterator_base::M->n_rows; ++row) { - for (uword col = 0; col < iterator_base::M->n_cols; ++col) + for(uword col = 0; col < iterator_base::M->n_cols; ++col) { // Find the first element with row greater than or equal to row + aux_row. const uword col_offset = iterator_base::M->m.col_ptrs[col + aux_col ]; @@ -636,24 +638,24 @@ const uword* start_ptr = &iterator_base::M->m.row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->m.row_indices[next_col_offset]; - if (start_ptr != end_ptr) + if(start_ptr != end_ptr) { const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, row + aux_row); const uword offset = uword(pos_ptr - start_ptr); - if (iterator_base::M->m.row_indices[col_offset + offset] == row + aux_row) + if(iterator_base::M->m.row_indices[col_offset + offset] == row + aux_row) { cur_actual_pos = col_offset + offset; // Increment position portably. - if (cur_pos == std::numeric_limits::max()) + if(cur_pos == std::numeric_limits::max()) cur_pos = 0; else ++cur_pos; // Do we terminate? - if (cur_pos == initial_pos) + if(cur_pos == initial_pos) { internal_row = row; iterator_base::internal_col = col; @@ -702,7 +704,7 @@ uword cur_min_col = 0; uword cur_actual_pos = 0; - for (uword col = 0; col < iterator_base::M->n_cols; ++col) + for(uword col = 0; col < iterator_base::M->n_cols; ++col) { // Find the first element with row greater than or equal to in_row. const uword col_offset = iterator_base::M->m.col_ptrs[col + aux_col ]; @@ -711,12 +713,12 @@ const uword* start_ptr = &iterator_base::M->m.row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->m.row_indices[next_col_offset]; - if (start_ptr != end_ptr) + if(start_ptr != end_ptr) { // First let us find the first element that is in the subview. const uword* first_subview_ptr = std::lower_bound(start_ptr, end_ptr, aux_row); - if (first_subview_ptr != end_ptr && (*first_subview_ptr) < aux_row + iterator_base::M->n_rows) + if(first_subview_ptr != end_ptr && (*first_subview_ptr) < aux_row + iterator_base::M->n_rows) { // There exists at least one element in the subview. const uword* pos_ptr = std::lower_bound(first_subview_ptr, end_ptr, aux_row + in_row); @@ -725,15 +727,15 @@ // than in_row. cur_pos += uword(pos_ptr - first_subview_ptr); - if (pos_ptr != end_ptr && (*pos_ptr) < aux_row + iterator_base::M->n_rows) + if(pos_ptr != end_ptr && (*pos_ptr) < aux_row + iterator_base::M->n_rows) { // This is the row index of the first element in the column with row // index greater than or equal to in_row + aux_row. - if ((*pos_ptr) - aux_row < cur_min_row) + if((*pos_ptr) - aux_row < cur_min_row) { // If we are in the desired row but before the desired column, we // can't take this. - if (col >= in_col) + if(col >= in_col) { cur_min_row = (*pos_ptr) - aux_row; cur_min_col = col; @@ -795,7 +797,7 @@ uword next_min_col = 0; uword next_actual_pos = 0; - for (uword col = iterator_base::internal_col + 1; col < M_n_cols; ++col) + for(uword col = iterator_base::internal_col + 1; col < M_n_cols; ++col) { // Find the first element with row greater than or equal to row. const uword col_offset = iterator_base::M->m.col_ptrs[col + aux_col ]; @@ -804,24 +806,24 @@ const uword* start_ptr = &iterator_base::M->m.row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->m.row_indices[next_col_offset]; - if (start_ptr != end_ptr) + if(start_ptr != end_ptr) { // Find the first element in the column with row greater than or equal to // the current row. Since this is a subview, it's possible that we may // find rows past the end of the subview. const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, internal_row + aux_row); - if (pos_ptr != end_ptr) + if(pos_ptr != end_ptr) { // We found something; is the row index correct? - if ((*pos_ptr) == internal_row + aux_row && (*pos_ptr) < aux_row + iterator_base::M->n_rows) + if((*pos_ptr) == internal_row + aux_row && (*pos_ptr) < aux_row + iterator_base::M->n_rows) { // Exact match---so we are done. iterator_base::internal_col = col; actual_pos = col_offset + (pos_ptr - start_ptr); return *this; } - else if ((*pos_ptr) < next_min_row + aux_row && (*pos_ptr) < aux_row + iterator_base::M->n_rows) + else if((*pos_ptr) < next_min_row + aux_row && (*pos_ptr) < aux_row + iterator_base::M->n_rows) { // The first element in this column is in a subsequent row, but it's // the minimum row we've seen so far. @@ -829,7 +831,7 @@ next_min_col = col; next_actual_pos = col_offset + (pos_ptr - start_ptr); } - else if ((*pos_ptr) == next_min_row + aux_row && col < next_min_col && (*pos_ptr) < aux_row + iterator_base::M->n_rows) + else if((*pos_ptr) == next_min_row + aux_row && col < next_min_col && (*pos_ptr) < aux_row + iterator_base::M->n_rows) { // The first element in this column is in a subsequent row that we // already have another elemnt for, but the column index is less so @@ -842,7 +844,7 @@ } // Restart the search in the next row. - for (uword col = 0; col <= iterator_base::internal_col; ++col) + for(uword col = 0; col <= iterator_base::internal_col; ++col) { // Find the first element with row greater than or equal to row + 1. const uword col_offset = iterator_base::M->m.col_ptrs[col + aux_col ]; @@ -851,14 +853,14 @@ const uword* start_ptr = &iterator_base::M->m.row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->m.row_indices[next_col_offset]; - if (start_ptr != end_ptr) + if(start_ptr != end_ptr) { const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, internal_row + aux_row + 1); - if (pos_ptr != end_ptr) + if(pos_ptr != end_ptr) { // We found something in the column, but is the row index correct? - if ((*pos_ptr) == internal_row + aux_row + 1 && (*pos_ptr) < aux_row + iterator_base::M->n_rows) + if((*pos_ptr) == internal_row + aux_row + 1 && (*pos_ptr) < aux_row + iterator_base::M->n_rows) { // Exact match---so we are done. iterator_base::internal_col = col; @@ -866,7 +868,7 @@ actual_pos = col_offset + (pos_ptr - start_ptr); return *this; } - else if ((*pos_ptr) < next_min_row + aux_row && (*pos_ptr) < aux_row + iterator_base::M->n_rows) + else if((*pos_ptr) < next_min_row + aux_row && (*pos_ptr) < aux_row + iterator_base::M->n_rows) { // The first element in this column is in a subsequent row, but it's // the minimum row we've seen so far. @@ -874,7 +876,7 @@ next_min_col = col; next_actual_pos = col_offset + (pos_ptr - start_ptr); } - else if ((*pos_ptr) == next_min_row + aux_row && col < next_min_col && (*pos_ptr) < aux_row + iterator_base::M->n_rows) + else if((*pos_ptr) == next_min_row + aux_row && col < next_min_col && (*pos_ptr) < aux_row + iterator_base::M->n_rows) { // We've found a better column. next_min_col = col; @@ -914,7 +916,7 @@ typename SpSubview::const_row_iterator& SpSubview::const_row_iterator::operator--() { - if (iterator_base::internal_pos == 0) + if(iterator_base::internal_pos == 0) { // We are already at the beginning. return *this; @@ -930,7 +932,7 @@ uword max_col = 0; uword next_actual_pos = 0; - for (uword col = iterator_base::internal_col; col >= 1; --col) + for(uword col = iterator_base::internal_col; col >= 1; --col) { // Find the first element with row greater than or equal to in_row + 1. const uword col_offset = iterator_base::M->m.col_ptrs[col + aux_col - 1]; @@ -939,21 +941,21 @@ const uword* start_ptr = &iterator_base::M->m.row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->m.row_indices[next_col_offset]; - if (start_ptr != end_ptr) + if(start_ptr != end_ptr) { // There are elements in this column. const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, internal_row + aux_row + 1); - if (pos_ptr != start_ptr) + if(pos_ptr != start_ptr) { - if (*(pos_ptr - 1) > max_row + aux_row) + if(*(pos_ptr - 1) > max_row + aux_row) { // There are elements in this column with row index < internal_row. max_row = *(pos_ptr - 1) - aux_row; max_col = col - 1; next_actual_pos = col_offset + (pos_ptr - 1 - start_ptr); } - else if (*(pos_ptr - 1) == max_row + aux_row && (col - 1) >= max_col) + else if(*(pos_ptr - 1) == max_row + aux_row && (col - 1) >= max_col) { max_col = col - 1; next_actual_pos = col_offset + (pos_ptr - 1 - start_ptr); @@ -962,7 +964,7 @@ } } - for (uword col = iterator_base::M->n_cols - 1; col >= iterator_base::internal_col; --col) + for(uword col = iterator_base::M->n_cols - 1; col >= iterator_base::internal_col; --col) { // Find the first element with row greater than or equal to row + 1. const uword col_offset = iterator_base::M->m.col_ptrs[col + aux_col ]; @@ -971,21 +973,21 @@ const uword* start_ptr = &iterator_base::M->m.row_indices[ col_offset]; const uword* end_ptr = &iterator_base::M->m.row_indices[next_col_offset]; - if (start_ptr != end_ptr) + if(start_ptr != end_ptr) { // There are elements in this column. const uword* pos_ptr = std::lower_bound(start_ptr, end_ptr, internal_row + aux_row); - if (pos_ptr != start_ptr) + if(pos_ptr != start_ptr) { // There are elements in this column with row index < internal_row. - if (*(pos_ptr - 1) > max_row + aux_row) + if(*(pos_ptr - 1) > max_row + aux_row) { max_row = *(pos_ptr - 1) - aux_row; max_col = col; next_actual_pos = col_offset + (pos_ptr - 1 - start_ptr); } - else if (*(pos_ptr - 1) == max_row + aux_row && col >= max_col) + else if(*(pos_ptr - 1) == max_row + aux_row && col >= max_col) { max_col = col; next_actual_pos = col_offset + (pos_ptr - 1 - start_ptr); @@ -993,7 +995,7 @@ } } - if (col == 0) // Catch edge case that the loop termination condition won't. + if(col == 0) // Catch edge case that the loop termination condition won't. { break; } @@ -1118,10 +1120,10 @@ template inline arma_hot -SpValProxy > +SpValProxy< SpSubview > SpSubview::row_iterator::operator*() { - return SpValProxy >( + return SpValProxy< SpSubview >( const_row_iterator::internal_row, iterator_base::internal_col, access::rw(*iterator_base::M), @@ -1182,4 +1184,5 @@ return tmp; } + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpSubview_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,7 +21,16 @@ template -arma_inline +inline +SpSubview::~SpSubview() + { + arma_extra_debug_sigprint_this(this); + } + + + +template +inline SpSubview::SpSubview(const SpMat& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols) : m(in_m) , aux_row1(in_row1) @@ -29,7 +40,7 @@ , n_elem(in_n_rows * in_n_cols) , n_nonzero(0) { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); m.sync_csc(); @@ -53,44 +64,42 @@ template -arma_inline -SpSubview::SpSubview(SpMat& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols) - : m(in_m) - , aux_row1(in_row1) - , aux_col1(in_col1) - , n_rows(in_n_rows) - , n_cols(in_n_cols) - , n_elem(in_n_rows * in_n_cols) - , n_nonzero(0) +inline +SpSubview::SpSubview(const SpSubview& in) + : m (in.m ) + , aux_row1 (in.aux_row1 ) + , aux_col1 (in.aux_col1 ) + , n_rows (in.n_rows ) + , n_cols (in.n_cols ) + , n_elem (in.n_elem ) + , n_nonzero(in.n_nonzero) { - arma_extra_debug_sigprint(); - - m.sync_csc(); - - // There must be a O(1) way to do this - uword lend = m.col_ptrs[in_col1 + in_n_cols]; - uword lend_row = in_row1 + in_n_rows; - uword count = 0; - - for(uword i = m.col_ptrs[in_col1]; i < lend; ++i) - { - const uword m_row_indices_i = m.row_indices[i]; - - const bool condition = (m_row_indices_i >= in_row1) && (m_row_indices_i < lend_row); - - count += condition ? uword(1) : uword(0); - } - - access::rw(n_nonzero) = count; + arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in); } template inline -SpSubview::~SpSubview() +SpSubview::SpSubview(SpSubview&& in) + : m (in.m ) + , aux_row1 (in.aux_row1 ) + , aux_col1 (in.aux_col1 ) + , n_rows (in.n_rows ) + , n_cols (in.n_cols ) + , n_elem (in.n_elem ) + , n_nonzero(in.n_nonzero) { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in); + + // for paranoia + + access::rw(in.aux_row1 ) = 0; + access::rw(in.aux_col1 ) = 0; + access::rw(in.n_rows ) = 0; + access::rw(in.n_cols ) = 0; + access::rw(in.n_elem ) = 0; + access::rw(in.n_nonzero) = 0; } @@ -102,12 +111,9 @@ { arma_extra_debug_sigprint(); - if(val == eT(0)) - { - return *this; - } + if(val == eT(0)) { return *this; } - Mat tmp( (*this).n_rows, (*this).n_cols ); + Mat tmp( (*this).n_rows, (*this).n_cols, arma_nozeros_indicator() ); tmp.fill(val); @@ -122,13 +128,10 @@ SpSubview::operator-=(const eT val) { arma_extra_debug_sigprint(); - - if(val == eT(0)) - { - return *this; - } - - Mat tmp( (*this).n_rows, (*this).n_cols ); + + if(val == eT(0)) { return *this; } + + Mat tmp( (*this).n_rows, (*this).n_cols, arma_nozeros_indicator() ); tmp.fill(val); @@ -320,7 +323,7 @@ SpSubview::operator-=(const Base& x) { arma_extra_debug_sigprint(); - + return (*this).operator=( (*this) - x.get_ref() ); } @@ -350,7 +353,7 @@ SpSubview::operator%=(const Base& x) { arma_extra_debug_sigprint(); - + return (*this).operator=( (*this) % x.get_ref() ); } @@ -363,7 +366,7 @@ SpSubview::operator/=(const Base& x) { arma_extra_debug_sigprint(); - + return (*this).operator=( (*this) / x.get_ref() ); } @@ -404,16 +407,18 @@ const unwrap_spmat U(in.get_ref()); + arma_debug_assert_same_size(n_rows, n_cols, U.M.n_rows, U.M.n_cols, "insertion into sparse submatrix"); + if(U.is_alias(m)) { const SpMat tmp(U.M); - return (*this).operator_equ_common(tmp); + spglue_merge::subview_merge(*this, tmp); + } + else + { + spglue_merge::subview_merge(*this, U.M); } - - arma_debug_assert_same_size(n_rows, n_cols, U.M.n_rows, U.M.n_cols, "insertion into sparse submatrix"); - - spglue_merge::subview_merge(*this, U.M); return *this; } @@ -455,7 +460,7 @@ SpSubview::operator*=(const SpBase& x) { arma_extra_debug_sigprint(); - + return (*this).operator=( (*this) * x.get_ref() ); } @@ -475,7 +480,6 @@ -//! If you are using this function, you are probably misguided. template template inline @@ -484,6 +488,8 @@ { arma_extra_debug_sigprint(); + // NOTE: use of this function is not advised; it is implemented only for completeness + SpProxy p(x.get_ref()); arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division"); @@ -771,13 +777,43 @@ template inline void +SpSubview::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + if(is_cx::no) + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): min_val must be less than max_val" ); + } + else + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpSubview::clamp(): imag(min_val) must be less than imag(max_val)" ); + } + + if((n_elem == 0) || (n_nonzero == 0)) { return; } + + // TODO: replace with a more efficient implementation + + SpMat tmp(*this); + + tmp.clamp(min_val, max_val); + + (*this).operator=(tmp); + } + + + +template +inline +void SpSubview::fill(const eT val) { arma_extra_debug_sigprint(); if(val != eT(0)) { - Mat tmp( (*this).n_rows, (*this).n_cols ); + Mat tmp( (*this).n_rows, (*this).n_cols, arma_nozeros_indicator() ); tmp.fill(val); @@ -854,7 +890,7 @@ SpSubview::ones() { arma_extra_debug_sigprint(); - + (*this).fill(eT(1)); } @@ -877,6 +913,34 @@ template +inline +void +SpSubview::randu() + { + arma_extra_debug_sigprint(); + + Mat tmp( (*this).n_rows, (*this).n_cols, fill::randu ); + + (*this).operator=(tmp); + } + + + +template +inline +void +SpSubview::randn() + { + arma_extra_debug_sigprint(); + + Mat tmp( (*this).n_rows, (*this).n_cols, fill::randn ); + + (*this).operator=(tmp); + } + + + +template arma_hot inline SpSubview_MapMat_val @@ -884,7 +948,7 @@ { const uword lrow = i % n_rows; const uword lcol = i / n_rows; - + return (*this).at(lrow, lcol); } @@ -898,7 +962,7 @@ { const uword lrow = i % n_rows; const uword lcol = i / n_rows; - + return (*this).at(lrow, lcol); } @@ -910,11 +974,11 @@ SpSubview_MapMat_val SpSubview::operator()(const uword i) { - arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bounds"); - + arma_debug_check_bounds( (i >= n_elem), "SpSubview::operator(): index out of bounds" ); + const uword lrow = i % n_rows; const uword lcol = i / n_rows; - + return (*this).at(lrow, lcol); } @@ -926,11 +990,11 @@ eT SpSubview::operator()(const uword i) const { - arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bounds"); - + arma_debug_check_bounds( (i >= n_elem), "SpSubview::operator(): index out of bounds" ); + const uword lrow = i % n_rows; const uword lcol = i / n_rows; - + return (*this).at(lrow, lcol); } @@ -942,8 +1006,8 @@ SpSubview_MapMat_val SpSubview::operator()(const uword in_row, const uword in_col) { - arma_debug_check( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds"); - + arma_debug_check_bounds( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds" ); + return (*this).at(in_row, in_col); } @@ -955,8 +1019,8 @@ eT SpSubview::operator()(const uword in_row, const uword in_col) const { - arma_debug_check( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds"); - + arma_debug_check_bounds( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds" ); + return (*this).at(in_row, in_col); } @@ -970,7 +1034,7 @@ { const uword lrow = i % n_rows; const uword lcol = i / n_cols; - + return (*this).at(lrow, lcol); } @@ -984,7 +1048,7 @@ { const uword lrow = i % n_rows; const uword lcol = i / n_cols; - + return (*this).at(lrow, lcol); } @@ -1017,8 +1081,8 @@ bool SpSubview::check_overlap(const SpSubview& x) const { - const subview& t = *this; - + const SpSubview& t = *this; + if(&t.m != &x.m) { return false; @@ -1033,19 +1097,19 @@ { const uword t_row_start = t.aux_row1; const uword t_row_end_p1 = t_row_start + t.n_rows; - + const uword t_col_start = t.aux_col1; const uword t_col_end_p1 = t_col_start + t.n_cols; - + const uword x_row_start = x.aux_row1; const uword x_row_end_p1 = x_row_start + x.n_rows; - + const uword x_col_start = x.aux_col1; const uword x_col_end_p1 = x_col_start + x.n_cols; - + const bool outside_rows = ( (x_row_start >= t_row_end_p1) || (t_row_start >= x_row_end_p1) ); const bool outside_cols = ( (x_col_start >= t_col_end_p1) || (t_col_start >= x_col_end_p1) ); - + return ( (outside_rows == false) && (outside_cols == false) ); } } @@ -1065,56 +1129,56 @@ template inline -SpSubview +SpSubview_row SpSubview::row(const uword row_num) { arma_extra_debug_sigprint(); - - arma_debug_check(row_num >= n_rows, "SpSubview::row(): out of bounds"); - - return submat(row_num, 0, row_num, n_cols - 1); + + arma_debug_check_bounds(row_num >= n_rows, "SpSubview::row(): out of bounds"); + + return SpSubview_row(const_cast< SpMat& >(m), row_num + aux_row1, aux_col1, n_cols); } template inline -const SpSubview +const SpSubview_row SpSubview::row(const uword row_num) const { arma_extra_debug_sigprint(); - - arma_debug_check(row_num >= n_rows, "SpSubview::row(): out of bounds"); - - return submat(row_num, 0, row_num, n_cols - 1); + + arma_debug_check_bounds(row_num >= n_rows, "SpSubview::row(): out of bounds"); + + return SpSubview_row(m, row_num + aux_row1, aux_col1, n_cols); } template inline -SpSubview +SpSubview_col SpSubview::col(const uword col_num) { arma_extra_debug_sigprint(); - - arma_debug_check(col_num >= n_cols, "SpSubview::col(): out of bounds"); - - return submat(0, col_num, n_rows - 1, col_num); + + arma_debug_check_bounds(col_num >= n_cols, "SpSubview::col(): out of bounds"); + + return SpSubview_col(const_cast< SpMat& >(m), col_num + aux_col1, aux_row1, n_rows); } template inline -const SpSubview +const SpSubview_col SpSubview::col(const uword col_num) const { arma_extra_debug_sigprint(); - - arma_debug_check(col_num >= n_cols, "SpSubview::col(): out of bounds"); - - return submat(0, col_num, n_rows - 1, col_num); + + arma_debug_check_bounds(col_num >= n_cols, "SpSubview::col(): out of bounds"); + + return SpSubview_col(m, col_num + aux_col1, aux_row1, n_rows); } @@ -1125,13 +1189,13 @@ SpSubview::rows(const uword in_row1, const uword in_row2) { arma_extra_debug_sigprint(); - - arma_debug_check + + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "SpSubview::rows(): indices out of bounds or incorrectly used" ); - + return submat(in_row1, 0, in_row2, n_cols - 1); } @@ -1143,8 +1207,8 @@ SpSubview::rows(const uword in_row1, const uword in_row2) const { arma_extra_debug_sigprint(); - - arma_debug_check + + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "SpSubview::rows(): indices out of bounds or incorrectly used" @@ -1161,13 +1225,13 @@ SpSubview::cols(const uword in_col1, const uword in_col2) { arma_extra_debug_sigprint(); - - arma_debug_check + + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "SpSubview::cols(): indices out of bounds or incorrectly used" ); - + return submat(0, in_col1, n_rows - 1, in_col2); } @@ -1179,13 +1243,13 @@ SpSubview::cols(const uword in_col1, const uword in_col2) const { arma_extra_debug_sigprint(); - - arma_debug_check + + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "SpSubview::cols(): indices out of bounds or incorrectly used" ); - + return submat(0, in_col1, n_rows - 1, in_col2); } @@ -1197,13 +1261,13 @@ SpSubview::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) { arma_extra_debug_sigprint(); - - arma_debug_check + + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "SpSubview::submat(): indices out of bounds or incorrectly used" ); - + return access::rw(m).submat(in_row1 + aux_row1, in_col1 + aux_col1, in_row2 + aux_row1, in_col2 + aux_col1); } @@ -1215,13 +1279,13 @@ SpSubview::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const { arma_extra_debug_sigprint(); - - arma_debug_check + + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "SpSubview::submat(): indices out of bounds or incorrectly used" ); - + return m.submat(in_row1 + aux_row1, in_col1 + aux_col1, in_row2 + aux_row1, in_col2 + aux_col1); } @@ -1233,24 +1297,24 @@ SpSubview::submat(const span& row_span, const span& col_span) { arma_extra_debug_sigprint(); - + const bool row_all = row_span.whole; const bool col_all = row_span.whole; - + const uword in_row1 = row_all ? 0 : row_span.a; const uword in_row2 = row_all ? n_rows : row_span.b; - + const uword in_col1 = col_all ? 0 : col_span.a; const uword in_col2 = col_all ? n_cols : col_span.b; - - arma_debug_check + + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= n_rows))) || ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= n_cols))), "SpSubview::submat(): indices out of bounds or incorrectly used" ); - + return submat(in_row1, in_col1, in_row2, in_col2); } @@ -1262,24 +1326,24 @@ SpSubview::submat(const span& row_span, const span& col_span) const { arma_extra_debug_sigprint(); - + const bool row_all = row_span.whole; const bool col_all = row_span.whole; - + const uword in_row1 = row_all ? 0 : row_span.a; const uword in_row2 = row_all ? n_rows - 1 : row_span.b; - + const uword in_col1 = col_all ? 0 : col_span.a; const uword in_col2 = col_all ? n_cols - 1 : col_span.b; - - arma_debug_check + + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= n_rows))) || ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= n_cols))), "SpSubview::submat(): indices out of bounds or incorrectly used" ); - + return submat(in_row1, in_col1, in_row2, in_col2); } @@ -1291,7 +1355,7 @@ SpSubview::operator()(const uword row_num, const span& col_span) { arma_extra_debug_sigprint(); - + return submat(span(row_num, row_num), col_span); } @@ -1303,7 +1367,7 @@ SpSubview::operator()(const uword row_num, const span& col_span) const { arma_extra_debug_sigprint(); - + return submat(span(row_num, row_num), col_span); } @@ -1315,7 +1379,7 @@ SpSubview::operator()(const span& row_span, const uword col_num) { arma_extra_debug_sigprint(); - + return submat(row_span, span(col_num, col_num)); } @@ -1327,7 +1391,7 @@ SpSubview::operator()(const span& row_span, const uword col_num) const { arma_extra_debug_sigprint(); - + return submat(row_span, span(col_num, col_num)); } @@ -1339,7 +1403,7 @@ SpSubview::operator()(const span& row_span, const span& col_span) { arma_extra_debug_sigprint(); - + return submat(row_span, col_span); } @@ -1351,7 +1415,7 @@ SpSubview::operator()(const span& row_span, const span& col_span) const { arma_extra_debug_sigprint(); - + return submat(row_span, col_span); } @@ -1363,12 +1427,12 @@ SpSubview::swap_rows(const uword in_row1, const uword in_row2) { arma_extra_debug_sigprint(); - + arma_debug_check((in_row1 >= n_rows) || (in_row2 >= n_rows), "SpSubview::swap_rows(): invalid row index"); - + const uword lstart_col = aux_col1; const uword lend_col = aux_col1 + n_cols; - + for(uword c = lstart_col; c < lend_col; ++c) { const eT val = access::rw(m).at(in_row1 + aux_row1, c); @@ -1385,12 +1449,12 @@ SpSubview::swap_cols(const uword in_col1, const uword in_col2) { arma_extra_debug_sigprint(); - + arma_debug_check((in_col1 >= n_cols) || (in_col2 >= n_cols), "SpSubview::swap_cols(): invalid column index"); - + const uword lstart_row = aux_row1; const uword lend_row = aux_row1 + n_rows; - + for(uword r = lstart_row; r < lend_row; ++r) { const eT val = access::rw(m).at(r, in_col1 + aux_col1); @@ -1583,13 +1647,13 @@ SpSubview::insert_element(const uword in_row, const uword in_col, const eT in_val) { arma_extra_debug_sigprint(); - + // This may not actually insert an element. const uword old_n_nonzero = m.n_nonzero; eT& retval = access::rw(m).insert_element(in_row + aux_row1, in_col + aux_col1, in_val); // Update n_nonzero (if necessary). access::rw(n_nonzero) += (m.n_nonzero - old_n_nonzero); - + return retval; } @@ -1601,7 +1665,7 @@ SpSubview::delete_element(const uword in_row, const uword in_col) { arma_extra_debug_sigprint(); - + // This may not actually delete an element. const uword old_n_nonzero = m.n_nonzero; access::rw(m).delete_element(in_row + aux_row1, in_col + aux_col1); @@ -1622,69 +1686,222 @@ -/** - * Sparse subview col - * +// +// +// + + + template inline -SpSubview_col::SpSubview_col(const Mat& in_m, const uword in_col) +SpSubview_col::SpSubview_col(const SpMat& in_m, const uword in_col) + : SpSubview(in_m, 0, in_col, in_m.n_rows, 1) { arma_extra_debug_sigprint(); } + + template inline -SpSubview_col::SpSubview_col(Mat& in_m, const uword in_col) +SpSubview_col::SpSubview_col(const SpMat& in_m, const uword in_col, const uword in_row1, const uword in_n_rows) + : SpSubview(in_m, in_row1, in_col, in_n_rows, 1) { arma_extra_debug_sigprint(); } + + template inline -SpSubview_col::SpSubview_col(const Mat& in_m, const uword in_col, const uword in_row1, const uword in_n_rows) +void +SpSubview_col::operator=(const SpSubview& x) { arma_extra_debug_sigprint(); + + SpSubview::operator=(x); } + + template inline -SpSubview_col::SpSubview_col(Mat& in_m, const uword in_col, const uword in_row1, const uword in_n_rows) +void +SpSubview_col::operator=(const SpSubview_col& x) { arma_extra_debug_sigprint(); + + SpSubview::operator=(x); // interprets 'SpSubview_col' as 'SpSubview' } -*/ -/** - * Sparse subview row - * + + template +template inline -SpSubview_row::SpSubview_row(const Mat& in_m, const uword in_row) +void +SpSubview_col::operator=(const SpBase& x) { arma_extra_debug_sigprint(); + + SpSubview::operator=(x); } + + template +template inline -SpSubview_row::SpSubview_row(Mat& in_m, const uword in_row) +void +SpSubview_col::operator=(const Base& x) { arma_extra_debug_sigprint(); + + SpSubview::operator=(x); } + + template inline -SpSubview_row::SpSubview_row(const Mat& in_m, const uword in_row, const uword in_col1, const uword in_n_cols) +arma_warn_unused +const SpOp,spop_htrans> +SpSubview_col::t() const + { + return SpOp,spop_htrans>(*this); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_htrans> +SpSubview_col::ht() const + { + return SpOp,spop_htrans>(*this); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_strans> +SpSubview_col::st() const + { + return SpOp,spop_strans>(*this); + } + + + +// +// +// + + + +template +inline +SpSubview_row::SpSubview_row(const SpMat& in_m, const uword in_row) + : SpSubview(in_m, in_row, 0, 1, in_m.n_cols) + { + arma_extra_debug_sigprint(); + } + + + +template +inline +SpSubview_row::SpSubview_row(const SpMat& in_m, const uword in_row, const uword in_col1, const uword in_n_cols) + : SpSubview(in_m, in_row, in_col1, 1, in_n_cols) { arma_extra_debug_sigprint(); } + + template inline -SpSubview_row::SpSubview_row(Mat& in_m, const uword in_row, const uword in_col1, const uword in_n_cols) +void +SpSubview_row::operator=(const SpSubview& x) { arma_extra_debug_sigprint(); + + SpSubview::operator=(x); } -*/ + + + +template +inline +void +SpSubview_row::operator=(const SpSubview_row& x) + { + arma_extra_debug_sigprint(); + + SpSubview::operator=(x); // interprets 'SpSubview_row' as 'SpSubview' + } + + + +template +template +inline +void +SpSubview_row::operator=(const SpBase& x) + { + arma_extra_debug_sigprint(); + + SpSubview::operator=(x); + } + + + +template +template +inline +void +SpSubview_row::operator=(const Base& x) + { + arma_extra_debug_sigprint(); + + SpSubview::operator=(x); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_htrans> +SpSubview_row::t() const + { + return SpOp,spop_htrans>(*this); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_htrans> +SpSubview_row::ht() const + { + return SpOp,spop_htrans>(*this); + } + + + +template +inline +arma_warn_unused +const SpOp,spop_strans> +SpSubview_row::st() const + { + return SpOp,spop_strans>(*this); + } + //! @} diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpToDOp_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpToDOp_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpToDOp_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpToDOp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -21,7 +23,7 @@ //! Class for storing data required for delayed unary operations on a sparse //! matrix that produce a dense matrix; the data for storage may include -//! the operand (e.g. the matrix to which the operation is to be applied) and the unary operator (e.g. inverse). +//! the operand (eg. the matrix to which the operation is to be applied) and the unary operator (eg. inverse). //! The operand is stored as a reference (which can be optimised away), //! while the operator is "stored" through the template definition (op_type). //! The operands can be 'SpMat', 'SpRow', 'SpCol', 'SpOp', and 'SpGlue'. @@ -31,24 +33,23 @@ //! SpToDOp< SpGlue< SpMat, SpMat, sp_glue_times >, op_sp_plus > template -class SpToDOp : public Base > +class SpToDOp : public Base< typename T1::elem_type, SpToDOp > { public: - + typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - + inline explicit SpToDOp(const T1& in_m); inline SpToDOp(const T1& in_m, const elem_type in_aux); inline ~SpToDOp(); - + arma_aligned const T1& m; //!< the operand; must be derived from SpBase arma_aligned elem_type aux; //!< auxiliary data, using the element type as used by T1 - - static const bool is_row = op_type::template traits::is_row; - static const bool is_col = op_type::template traits::is_col; - static const bool is_xvec = op_type::template traits::is_xvec; - + + static constexpr bool is_row = op_type::template traits::is_row; + static constexpr bool is_col = op_type::template traits::is_col; + static constexpr bool is_xvec = op_type::template traits::is_xvec; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpToDOp_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpToDOp_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpToDOp_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpToDOp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpValProxy_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpValProxy_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpValProxy_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpValProxy_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -36,7 +38,8 @@ * Create the sparse value proxy. * Otherwise, pass a pointer to a reference of the value. */ - arma_inline SpValProxy(uword row, uword col, T1& in_parent, eT* in_val_ptr = NULL); + arma_inline SpValProxy(uword row, uword col, T1& in_parent, eT* in_val_ptr = nullptr); + inline SpValProxy() = delete; //! For swapping operations. arma_inline SpValProxy& operator=(const SpValProxy& rhs); @@ -66,7 +69,7 @@ private: - // Deletes the element if it is zero. Does not check if val_ptr == NULL! + // Deletes the element if it is zero; NOTE: does not check if val_ptr == nullptr arma_inline void check_zero(); arma_aligned const uword row; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/SpValProxy_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/SpValProxy_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/SpValProxy_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/SpValProxy_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -58,10 +60,10 @@ SpValProxy& SpValProxy::operator=(const eT rhs) { - if (rhs != eT(0)) // A nonzero element is being assigned. + if(rhs != eT(0)) // A nonzero element is being assigned. { - if (val_ptr) + if(val_ptr) { // The value exists and merely needs to be updated. *val_ptr = rhs; @@ -78,11 +80,11 @@ else // A zero is being assigned.~ { - if (val_ptr) + if(val_ptr) { // The element exists, but we need to remove it, because it is being set to 0. parent.delete_element(row, col); - val_ptr = NULL; + val_ptr = nullptr; } // If the element does not exist, we do not need to do anything at all. @@ -99,7 +101,7 @@ SpValProxy& SpValProxy::operator+=(const eT rhs) { - if (val_ptr) + if(val_ptr) { // The value already exists and merely needs to be updated. *val_ptr += rhs; @@ -108,7 +110,7 @@ } else { - if (rhs != eT(0)) + if(rhs != eT(0)) { // The value does not exist and must be inserted. val_ptr = &parent.insert_element(row, col, rhs); @@ -125,7 +127,7 @@ SpValProxy& SpValProxy::operator-=(const eT rhs) { - if (val_ptr) + if(val_ptr) { // The value already exists and merely needs to be updated. *val_ptr -= rhs; @@ -134,7 +136,7 @@ } else { - if (rhs != eT(0)) + if(rhs != eT(0)) { // The value does not exist and must be inserted. val_ptr = &parent.insert_element(row, col, -rhs); @@ -151,10 +153,10 @@ SpValProxy& SpValProxy::operator*=(const eT rhs) { - if (rhs != eT(0)) + if(rhs != eT(0)) { - if (val_ptr) + if(val_ptr) { // The value already exists and merely needs to be updated. *val_ptr *= rhs; @@ -166,11 +168,11 @@ else { - if (val_ptr) + if(val_ptr) { // Since we are multiplying by zero, the value can be deleted. parent.delete_element(row, col); - val_ptr = NULL; + val_ptr = nullptr; } } @@ -185,10 +187,10 @@ SpValProxy& SpValProxy::operator/=(const eT rhs) { - if (rhs != eT(0)) // I hope this is true! + if(rhs != eT(0)) // I hope this is true! { - if (val_ptr) + if(val_ptr) { *val_ptr /= rhs; parent.invalidate_cache(); @@ -199,14 +201,14 @@ else { - if (val_ptr) + if(val_ptr) { *val_ptr /= rhs; // That is where it gets ugly. // Now check if it's 0. - if (*val_ptr == eT(0)) + if(*val_ptr == eT(0)) { parent.delete_element(row, col); - val_ptr = NULL; + val_ptr = nullptr; } } @@ -214,7 +216,7 @@ { eT val = eT(0) / rhs; // This may vary depending on type and implementation. - if (val != eT(0)) + if(val != eT(0)) { // Ok, now we have to insert it. val_ptr = &parent.insert_element(row, col, val); @@ -233,7 +235,7 @@ SpValProxy& SpValProxy::operator++() { - if (val_ptr) + if(val_ptr) { (*val_ptr) += eT(1); parent.invalidate_cache(); @@ -255,7 +257,7 @@ SpValProxy& SpValProxy::operator--() { - if (val_ptr) + if(val_ptr) { (*val_ptr) -= eT(1); parent.invalidate_cache(); @@ -277,7 +279,7 @@ typename T1::elem_type SpValProxy::operator++(const int) { - if (val_ptr) + if(val_ptr) { (*val_ptr) += eT(1); parent.invalidate_cache(); @@ -289,7 +291,7 @@ val_ptr = &parent.insert_element(row, col, eT(1)); } - if (val_ptr) // It may have changed to now be 0. + if(val_ptr) // It may have changed to now be 0. { return *(val_ptr) - eT(1); } @@ -306,7 +308,7 @@ typename T1::elem_type SpValProxy::operator--(const int) { - if (val_ptr) + if(val_ptr) { (*val_ptr) -= eT(1); parent.invalidate_cache(); @@ -318,7 +320,7 @@ val_ptr = &parent.insert_element(row, col, eT(-1)); } - if (val_ptr) // It may have changed to now be 0. + if(val_ptr) // It may have changed to now be 0. { return *(val_ptr) + eT(1); } @@ -368,10 +370,10 @@ void SpValProxy::check_zero() { - if (*val_ptr == eT(0)) + if(*val_ptr == eT(0)) { parent.delete_element(row, col); - val_ptr = NULL; + val_ptr = nullptr; } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/strip.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/strip.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/strip.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/strip.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -31,7 +33,7 @@ arma_extra_debug_sigprint(); } - static const bool do_diagmat = false; + static constexpr bool do_diagmat = false; const T1& M; }; @@ -50,7 +52,7 @@ arma_extra_debug_sigprint(); } - static const bool do_diagmat = true; + static constexpr bool do_diagmat = true; const T1& M; }; @@ -71,8 +73,8 @@ const T1& M; - static const bool do_inv = false; - static const bool do_inv_sympd = false; + static constexpr bool do_inv = false; + static constexpr bool do_inv_sympd = false; }; @@ -91,8 +93,8 @@ const T1& M; - static const bool do_inv = true; - static const bool do_inv_sympd = false; + static constexpr bool do_inv = true; + static constexpr bool do_inv_sympd = false; }; @@ -111,8 +113,8 @@ const T1& M; - static const bool do_inv = true; - static const bool do_inv_sympd = true; + static constexpr bool do_inv = true; + static constexpr bool do_inv_sympd = true; }; @@ -124,9 +126,9 @@ const T1& M; - static const bool do_trimat = false; - static const bool do_triu = false; - static const bool do_tril = false; + static constexpr bool do_trimat = false; + static constexpr bool do_triu = false; + static constexpr bool do_tril = false; inline strip_trimat(const T1& X) @@ -145,9 +147,10 @@ const T1& M; - static const bool do_trimat = true; - const bool do_triu; - const bool do_tril; + static constexpr bool do_trimat = true; + + const bool do_triu; + const bool do_tril; inline strip_trimat(const Op& X) diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,9 +21,9 @@ //! Class for storing data required to construct or apply operations to a submatrix -//! (i.e. where the submatrix starts and ends as well as a reference/pointer to the original matrix), +//! (ie. where the submatrix starts and ends as well as a reference/pointer to the original matrix), template -class subview : public Base > +class subview : public Base< eT, subview > { public: @@ -30,9 +32,9 @@ arma_aligned const Mat& m; - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; const uword aux_row1; const uword aux_col1; @@ -49,6 +51,10 @@ public: inline ~subview(); + inline subview() = delete; + + inline subview(const subview& in); + inline subview( subview&& in); template inline void inplace_op(const eT val ); template inline void inplace_op(const Base& x, const char* identifier); @@ -83,6 +89,9 @@ template inline typename enable_if2< is_same_type::value, void>::result operator=(const Gen& x); + inline void operator=(const std::initializer_list& list); + inline void operator=(const std::initializer_list< std::initializer_list >& list); + inline static void extract(Mat& out, const subview& in); @@ -101,6 +110,8 @@ inline void clean(const pod_type threshold); + inline void clamp(const eT min_val, const eT max_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); @@ -108,19 +119,25 @@ inline void randu(); inline void randn(); - inline eT at_alt (const uword ii) const; + inline arma_warn_unused eT at_alt (const uword ii) const; - inline eT& operator[](const uword ii); - inline eT operator[](const uword ii) const; + inline arma_warn_unused eT& operator[](const uword ii); + inline arma_warn_unused eT operator[](const uword ii) const; - inline eT& operator()(const uword ii); - inline eT operator()(const uword ii) const; + inline arma_warn_unused eT& operator()(const uword ii); + inline arma_warn_unused eT operator()(const uword ii) const; - inline eT& operator()(const uword in_row, const uword in_col); - inline eT operator()(const uword in_row, const uword in_col) const; + inline arma_warn_unused eT& operator()(const uword in_row, const uword in_col); + inline arma_warn_unused eT operator()(const uword in_row, const uword in_col) const; - inline eT& at(const uword in_row, const uword in_col); - inline eT at(const uword in_row, const uword in_col) const; + inline arma_warn_unused eT& at(const uword in_row, const uword in_col); + inline arma_warn_unused eT at(const uword in_row, const uword in_col) const; + + inline arma_warn_unused eT& front(); + inline arma_warn_unused eT front() const; + + inline arma_warn_unused eT& back(); + inline arma_warn_unused eT back() const; arma_inline eT* colptr(const uword in_col); arma_inline const eT* colptr(const uword in_col) const; @@ -130,6 +147,7 @@ inline arma_warn_unused bool is_vec() const; inline arma_warn_unused bool is_finite() const; + inline arma_warn_unused bool is_zero(const pod_type tol = 0) const; inline arma_warn_unused bool has_inf() const; inline arma_warn_unused bool has_nan() const; @@ -170,13 +188,11 @@ template inline subview_each2< subview, 0, T1 > each_col(const Base& indices); template inline subview_each2< subview, 1, T1 > each_row(const Base& indices); - #if defined(ARMA_USE_CXX11) inline void each_col(const std::function< void( Col&) >& F); inline void each_col(const std::function< void(const Col&) >& F) const; inline void each_row(const std::function< void( Row&) >& F); inline void each_row(const std::function< void(const Row&) >& F) const; - #endif inline diagview diag(const sword in_id = 0); inline const diagview diag(const sword in_id = 0) const; @@ -336,10 +352,7 @@ inline const_iterator cend() const; - private: - friend class Mat; - subview(); }; @@ -352,27 +365,28 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; const eT* colmem; inline void operator= (const subview& x); inline void operator= (const subview_col& x); inline void operator= (const eT val); + inline void operator= (const std::initializer_list& list); - template - inline void operator= (const Base& x); + template inline void operator= (const Base& x); + template inline void operator= (const SpBase& x); template inline typename enable_if2< is_same_type::value, void>::result operator=(const Gen& x); - arma_inline const Op,op_htrans> t() const; - arma_inline const Op,op_htrans> ht() const; - arma_inline const Op,op_strans> st() const; + arma_inline arma_warn_unused const Op,op_htrans> t() const; + arma_inline arma_warn_unused const Op,op_htrans> ht() const; + arma_inline arma_warn_unused const Op,op_strans> st() const; - arma_inline const Op,op_strans> as_row() const; + arma_inline arma_warn_unused const Op,op_strans> as_row() const; inline void fill(const eT val); inline void zeros(); @@ -419,20 +433,81 @@ inline arma_warn_unused uword index_min() const; inline arma_warn_unused uword index_max() const; + inline subview_col(const subview_col& in); + inline subview_col( subview_col&& in); + protected: inline subview_col(const Mat& in_m, const uword in_col); inline subview_col(const Mat& in_m, const uword in_col, const uword in_row1, const uword in_n_rows); + inline subview_col() = delete; - private: - friend class Mat; friend class Col; friend class subview; + }; + + + +template +class subview_cols : public subview + { + public: + + typedef eT elem_type; + typedef typename get_pod_type::result pod_type; + + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; + + inline subview_cols(const subview_cols& in); + inline subview_cols( subview_cols&& in); + + inline void operator= (const subview& x); + inline void operator= (const subview_cols& x); + inline void operator= (const eT val); + inline void operator= (const std::initializer_list& list); + inline void operator= (const std::initializer_list< std::initializer_list >& list); - subview_col(); + template inline void operator= (const Base& x); + template inline void operator= (const SpBase& x); + + template + inline typename enable_if2< is_same_type::value, void>::result operator=(const Gen& x); + + arma_inline arma_warn_unused const Op,op_htrans> t() const; + arma_inline arma_warn_unused const Op,op_htrans> ht() const; + arma_inline arma_warn_unused const Op,op_strans> st() const; + + arma_inline arma_warn_unused const Op,op_vectorise_col> as_col() const; + + inline arma_warn_unused eT at_alt (const uword ii) const; + + inline arma_warn_unused eT& operator[](const uword ii); + inline arma_warn_unused eT operator[](const uword ii) const; + + inline arma_warn_unused eT& operator()(const uword ii); + inline arma_warn_unused eT operator()(const uword ii) const; + + inline arma_warn_unused eT& operator()(const uword in_row, const uword in_col); + inline arma_warn_unused eT operator()(const uword in_row, const uword in_col) const; + + inline arma_warn_unused eT& at(const uword in_row, const uword in_col); + inline arma_warn_unused eT at(const uword in_row, const uword in_col) const; + + arma_inline eT* colptr(const uword in_col); + arma_inline const eT* colptr(const uword in_col) const; + + protected: + + inline subview_cols(const Mat& in_m, const uword in_col1, const uword in_n_cols); + inline subview_cols() = delete; + + friend class Mat; + friend class subview; }; @@ -445,25 +520,26 @@ typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = true; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = true; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; inline void operator= (const subview& x); inline void operator= (const subview_row& x); inline void operator= (const eT val); + inline void operator= (const std::initializer_list& list); - template - inline void operator= (const Base& x); + template inline void operator= (const Base& x); + template inline void operator= (const SpBase& x); template inline typename enable_if2< is_same_type::value, void>::result operator=(const Gen& x); - arma_inline const Op,op_htrans> t() const; - arma_inline const Op,op_htrans> ht() const; - arma_inline const Op,op_strans> st() const; + arma_inline arma_warn_unused const Op,op_htrans> t() const; + arma_inline arma_warn_unused const Op,op_htrans> ht() const; + arma_inline arma_warn_unused const Op,op_strans> st() const; - arma_inline const Op,op_strans> as_col() const; + arma_inline arma_warn_unused const Op,op_strans> as_col() const; inline eT at_alt (const uword i) const; @@ -505,40 +581,42 @@ inline typename subview::const_row_iterator end() const; inline typename subview::const_row_iterator cend() const; + inline subview_row(const subview_row& in); + inline subview_row( subview_row&& in); + + protected: inline subview_row(const Mat& in_m, const uword in_row); inline subview_row(const Mat& in_m, const uword in_row, const uword in_col1, const uword in_n_cols); + inline subview_row() = delete; - private: - friend class Mat; friend class Row; friend class subview; - - subview_row(); }; template -class subview_row_strans : public Base > +class subview_row_strans : public Base< eT, subview_row_strans > { public: typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_row& sv_row; - const uword n_rows; // equal to n_elem - const uword n_elem; - static const uword n_cols = 1; + const uword n_rows; // equal to n_elem + const uword n_elem; + + static constexpr uword n_cols = 1; inline explicit subview_row_strans(const subview_row& in_sv_row); @@ -557,22 +635,23 @@ template -class subview_row_htrans : public Base > +class subview_row_htrans : public Base< eT, subview_row_htrans > { public: typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const subview_row& sv_row; - const uword n_rows; // equal to n_elem - const uword n_elem; - static const uword n_cols = 1; + const uword n_rows; // equal to n_elem + const uword n_elem; + + static constexpr uword n_cols = 1; inline explicit subview_row_htrans(const subview_row& in_sv_row); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,9 +21,9 @@ //! Class for storing data required to construct or apply operations to a subcube -//! (i.e. where the subcube starts and ends as well as a reference/pointer to the original cube), +//! (ie. where the subcube starts and ends as well as a reference/pointer to the original cube), template -class subview_cube : public BaseCube > +class subview_cube : public BaseCube< eT, subview_cube > { public: @@ -49,6 +51,14 @@ public: inline ~subview_cube(); + inline subview_cube() = delete; + + inline subview_cube(const subview_cube& in); + inline subview_cube( subview_cube&& in); + + template inline void inplace_op(const eT val ); + template inline void inplace_op(const BaseCube& x, const char* identifier); + template inline void inplace_op(const subview_cube& x, const char* identifier); inline void operator= (const eT val); inline void operator+= (const eT val); @@ -95,15 +105,15 @@ template inline void transform(functor F); template inline void imbue(functor F); - #if defined(ARMA_USE_CXX11) inline void each_slice(const std::function< void( Mat&) >& F); inline void each_slice(const std::function< void(const Mat&) >& F) const; - #endif inline void replace(const eT old_val, const eT new_val); inline void clean(const pod_type threshold); + inline void clamp(const eT min_val, const eT max_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); @@ -111,6 +121,7 @@ inline void randn(); inline arma_warn_unused bool is_finite() const; + inline arma_warn_unused bool is_zero(const pod_type tol = 0) const; inline arma_warn_unused bool has_inf() const; inline arma_warn_unused bool has_nan() const; @@ -132,8 +143,10 @@ arma_inline eT* slice_colptr(const uword in_slice, const uword in_col); arma_inline const eT* slice_colptr(const uword in_slice, const uword in_col) const; - inline bool check_overlap(const subview_cube& x) const; - inline bool check_overlap(const Mat& x) const; + template + inline bool check_overlap(const subview_cube& x) const; + + inline bool check_overlap(const Mat& x) const; class const_iterator; @@ -225,12 +238,8 @@ inline const_iterator cend() const; - private: - friend class Mat; friend class Cube; - - subview_cube(); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_each_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_each_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_each_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_each_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -32,13 +34,9 @@ protected: arma_inline subview_cube_each_common(const Cube& in_p); + inline subview_cube_each_common() = delete; arma_cold inline const std::string incompat_size_string(const Mat& A) const; - - - private: - - subview_cube_each_common(); }; @@ -50,6 +48,7 @@ protected: arma_inline subview_cube_each1(const Cube& in_p); + inline subview_cube_each1() = delete; public: @@ -65,8 +64,6 @@ template inline void operator*= (const Base& x); - private: - friend class Cube; }; @@ -78,6 +75,7 @@ protected: inline subview_cube_each2(const Cube& in_p, const Base& in_indices); + inline subview_cube_each2() = delete; public: @@ -95,8 +93,6 @@ template inline void operator/= (const Base& x); - private: - friend class Cube; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_each_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_each_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_each_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_each_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -295,7 +297,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::copy(p.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -334,7 +336,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_plus(p.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -373,7 +375,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_minus(p.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -412,7 +414,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_mul(p.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -451,7 +453,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_div(p.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -482,7 +484,7 @@ const uword p_n_cols = p.n_cols; const uword p_n_slices = p.n_slices; - Cube out(p_n_rows, p_n_cols, p_n_slices); + Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); const unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; @@ -519,7 +521,7 @@ const uword p_n_cols = p.n_cols; const uword p_n_slices = p.n_slices; - Cube out(p_n_rows, p_n_cols, p_n_slices); + Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); const unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; @@ -556,7 +558,7 @@ const uword p_n_cols = p.n_cols; const uword p_n_slices = p.n_slices; - Cube out(p_n_rows, p_n_cols, p_n_slices); + Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); const unwrap tmp(X.get_ref()); const Mat& A = tmp.M; @@ -593,7 +595,7 @@ const uword p_n_cols = p.n_cols; const uword p_n_slices = p.n_slices; - Cube out(p_n_rows, p_n_cols, p_n_slices); + Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); const unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; @@ -630,7 +632,7 @@ const uword p_n_cols = p.n_cols; const uword p_n_slices = p.n_slices; - Cube out(p_n_rows, p_n_cols, p_n_slices); + Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); const unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; @@ -667,7 +669,7 @@ const uword p_n_cols = p.n_cols; const uword p_n_slices = p.n_slices; - Cube out(p_n_rows, p_n_cols, p_n_slices); + Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); const unwrap tmp(X.get_ref()); const Mat& A = tmp.M; @@ -703,7 +705,7 @@ const unwrap tmp(Y.get_ref()); const Mat& M = tmp.M; - Cube out(C.n_rows, M.n_cols, C.n_slices); + Cube out(C.n_rows, M.n_cols, C.n_slices, arma_nozeros_indicator()); for(uword i=0; i < C.n_slices; ++i) { @@ -734,7 +736,7 @@ const Cube& C = Y.P; - Cube out(M.n_rows, C.n_cols, C.n_slices); + Cube out(M.n_rows, C.n_cols, C.n_slices, arma_nozeros_indicator()); for(uword i=0; i < C.n_slices; ++i) { @@ -790,7 +792,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_plus(out.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -835,7 +837,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_minus(out.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -879,7 +881,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); Mat out_slice( out.slice_memptr(slice), p_n_rows, p_n_cols, false, true); const Mat p_slice(const_cast(p.slice_memptr(slice)), p_n_rows, p_n_cols, false, true); @@ -927,7 +929,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_mul(out.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -972,7 +974,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_div(out.slice_memptr(slice), A_mem, p_n_elem_slice); } @@ -1016,7 +1018,7 @@ { const uword slice = indices_mem[i]; - arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); + arma_debug_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" ); Mat out_slice( out.slice_memptr(slice), p_n_rows, p_n_cols, false, true); const Mat p_slice(const_cast(p.slice_memptr(slice)), p_n_rows, p_n_cols, false, true); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,7 +24,7 @@ inline subview_cube::~subview_cube() { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); } @@ -49,68 +51,178 @@ , n_slices (in_n_slices) , n_elem (n_elem_slice * in_n_slices) { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); } template inline -void -subview_cube::operator= (const eT val) +subview_cube::subview_cube(const subview_cube& in) + : m (in.m ) + , aux_row1 (in.aux_row1 ) + , aux_col1 (in.aux_col1 ) + , aux_slice1 (in.aux_slice1 ) + , n_rows (in.n_rows ) + , n_cols (in.n_cols ) + , n_elem_slice(in.n_elem_slice) + , n_slices (in.n_slices ) + , n_elem (in.n_elem ) { - arma_extra_debug_sigprint(); - - if(n_elem != 1) - { - arma_debug_assert_same_size(n_rows, n_cols, n_slices, 1, 1, 1, "copy into subcube"); - } + arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in); + } + + + +template +inline +subview_cube::subview_cube(subview_cube&& in) + : m (in.m ) + , aux_row1 (in.aux_row1 ) + , aux_col1 (in.aux_col1 ) + , aux_slice1 (in.aux_slice1 ) + , n_rows (in.n_rows ) + , n_cols (in.n_cols ) + , n_elem_slice(in.n_elem_slice) + , n_slices (in.n_slices ) + , n_elem (in.n_elem ) + { + arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in); - Cube& Q = const_cast< Cube& >(m); + // for paranoia - Q.at(aux_row1, aux_col1, aux_slice1) = val; + access::rw(in.aux_row1 ) = 0; + access::rw(in.aux_col1 ) = 0; + access::rw(in.aux_slice1 ) = 0; + access::rw(in.n_rows ) = 0; + access::rw(in.n_cols ) = 0; + access::rw(in.n_elem_slice) = 0; + access::rw(in.n_slices ) = 0; + access::rw(in.n_elem ) = 0; } template +template inline void -subview_cube::operator+= (const eT val) +subview_cube::inplace_op(const eT val) { arma_extra_debug_sigprint(); - const uword local_n_rows = n_rows; - const uword local_n_cols = n_cols; - const uword local_n_slices = n_slices; + subview_cube& t = *this; - for(uword slice = 0; slice < local_n_slices; ++slice) + const uword t_n_rows = t.n_rows; + const uword t_n_cols = t.n_cols; + const uword t_n_slices = t.n_slices; + + for(uword s=0; s < t_n_slices; ++s) + for(uword c=0; c < t_n_cols; ++c) { - for(uword col = 0; col < local_n_cols; ++col) - { - arrayops::inplace_plus( slice_colptr(slice,col), val, local_n_rows ); - } + if(is_same_type::yes) { arrayops::inplace_plus ( slice_colptr(s,c), val, t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_minus( slice_colptr(s,c), val, t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_mul ( slice_colptr(s,c), val, t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_div ( slice_colptr(s,c), val, t_n_rows ); } } } + + + template +template inline void -subview_cube::operator-= (const eT val) +subview_cube::inplace_op(const BaseCube& in, const char* identifier) { arma_extra_debug_sigprint(); - const uword local_n_rows = n_rows; - const uword local_n_cols = n_cols; - const uword local_n_slices = n_slices; + const ProxyCube P(in.get_ref()); - for(uword slice = 0; slice < local_n_slices; ++slice) + subview_cube& t = *this; + + const uword t_n_rows = t.n_rows; + const uword t_n_cols = t.n_cols; + const uword t_n_slices = t.n_slices; + + arma_debug_assert_same_size(t, P, identifier); + + const bool use_mp = arma_config::openmp && ProxyCube::use_mp && mp_gate::eval(t.n_elem); + const bool has_overlap = P.has_overlap(t); + + if(has_overlap) { arma_extra_debug_print("aliasing or overlap detected"); } + + if( (is_Cube::stored_type>::value) || (use_mp) || (has_overlap) ) { - for(uword col = 0; col < local_n_cols; ++col) + const unwrap_cube_check::stored_type> tmp(P.Q, has_overlap); + const Cube& B = tmp.M; + + if( (is_same_type::yes) && (t.aux_row1 == 0) && (t_n_rows == t.m.n_rows) ) + { + for(uword s=0; s < t_n_slices; ++s) + { + arrayops::copy( t.slice_colptr(s,0), B.slice_colptr(s,0), t.n_elem_slice ); + } + } + else + { + for(uword s=0; s < t_n_slices; ++s) + for(uword c=0; c < t_n_cols; ++c) + { + if(is_same_type::yes) { arrayops::copy ( t.slice_colptr(s,c), B.slice_colptr(s,c), t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_plus ( t.slice_colptr(s,c), B.slice_colptr(s,c), t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_minus( t.slice_colptr(s,c), B.slice_colptr(s,c), t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_mul ( t.slice_colptr(s,c), B.slice_colptr(s,c), t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_div ( t.slice_colptr(s,c), B.slice_colptr(s,c), t_n_rows ); } + } + } + } + else // use the Proxy + { + if(ProxyCube::use_at) + { + for(uword s=0; s < t_n_slices; ++s) + for(uword c=0; c < t_n_cols; ++c) + { + eT* t_col_data = t.slice_colptr(s,c); + + for(uword r=0; r < t_n_rows; ++r) + { + const eT tmp = P.at(r,c,s); + + if(is_same_type::yes) { (*t_col_data) = tmp; t_col_data++; } + if(is_same_type::yes) { (*t_col_data) += tmp; t_col_data++; } + if(is_same_type::yes) { (*t_col_data) -= tmp; t_col_data++; } + if(is_same_type::yes) { (*t_col_data) *= tmp; t_col_data++; } + if(is_same_type::yes) { (*t_col_data) /= tmp; t_col_data++; } + } + } + } + else { - arrayops::inplace_minus( slice_colptr(slice,col), val, local_n_rows ); + typename ProxyCube::ea_type Pea = P.get_ea(); + + uword count = 0; + + for(uword s=0; s < t_n_slices; ++s) + for(uword c=0; c < t_n_cols; ++c) + { + eT* t_col_data = t.slice_colptr(s,c); + + for(uword r=0; r < t_n_rows; ++r) + { + const eT tmp = Pea[count]; count++; + + if(is_same_type::yes) { (*t_col_data) = tmp; t_col_data++; } + if(is_same_type::yes) { (*t_col_data) += tmp; t_col_data++; } + if(is_same_type::yes) { (*t_col_data) -= tmp; t_col_data++; } + if(is_same_type::yes) { (*t_col_data) *= tmp; t_col_data++; } + if(is_same_type::yes) { (*t_col_data) /= tmp; t_col_data++; } + } + } } } } @@ -118,22 +230,42 @@ template +template inline void -subview_cube::operator*= (const eT val) +subview_cube::inplace_op(const subview_cube& x, const char* identifier) { arma_extra_debug_sigprint(); - const uword local_n_rows = n_rows; - const uword local_n_cols = n_cols; - const uword local_n_slices = n_slices; + if(check_overlap(x)) + { + const Cube tmp(x); + + if(is_same_type::yes) { (*this).operator= (tmp); } + if(is_same_type::yes) { (*this).operator+=(tmp); } + if(is_same_type::yes) { (*this).operator-=(tmp); } + if(is_same_type::yes) { (*this).operator%=(tmp); } + if(is_same_type::yes) { (*this).operator/=(tmp); } + + return; + } - for(uword slice = 0; slice < local_n_slices; ++slice) + subview_cube& t = *this; + + arma_debug_assert_same_size(t, x, identifier); + + const uword t_n_rows = t.n_rows; + const uword t_n_cols = t.n_cols; + const uword t_n_slices = t.n_slices; + + for(uword s=0; s < t_n_slices; ++s) + for(uword c=0; c < t_n_cols; ++c) { - for(uword col = 0; col < local_n_cols; ++col) - { - arrayops::inplace_mul( slice_colptr(slice,col), val, local_n_rows ); - } + if(is_same_type::yes) { arrayops::copy ( t.slice_colptr(s,c), x.slice_colptr(s,c), t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_plus ( t.slice_colptr(s,c), x.slice_colptr(s,c), t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_minus( t.slice_colptr(s,c), x.slice_colptr(s,c), t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_mul ( t.slice_colptr(s,c), x.slice_colptr(s,c), t_n_rows ); } + if(is_same_type::yes) { arrayops::inplace_div ( t.slice_colptr(s,c), x.slice_colptr(s,c), t_n_rows ); } } } @@ -142,51 +274,79 @@ template inline void -subview_cube::operator/= (const eT val) +subview_cube::operator= (const eT val) { arma_extra_debug_sigprint(); - const uword local_n_rows = n_rows; - const uword local_n_cols = n_cols; - const uword local_n_slices = n_slices; - - for(uword slice = 0; slice < local_n_slices; ++slice) + if(n_elem != 1) { - for(uword col = 0; col < local_n_cols; ++col) - { - arrayops::inplace_div( slice_colptr(slice,col), val, local_n_rows ); - } + arma_debug_assert_same_size(n_rows, n_cols, n_slices, 1, 1, 1, "copy into subcube"); } + + Cube& Q = const_cast< Cube& >(m); + + Q.at(aux_row1, aux_col1, aux_slice1) = val; } template -template inline void -subview_cube::operator= (const BaseCube& in) +subview_cube::operator+= (const eT val) { arma_extra_debug_sigprint(); - const unwrap_cube tmp(in.get_ref()); + inplace_op(val); + } + + + +template +inline +void +subview_cube::operator-= (const eT val) + { + arma_extra_debug_sigprint(); - const Cube& x = tmp.M; - subview_cube& t = *this; + inplace_op(val); + } + + + +template +inline +void +subview_cube::operator*= (const eT val) + { + arma_extra_debug_sigprint(); - arma_debug_assert_same_size(t, x, "copy into subcube"); + inplace_op(val); + } + + + +template +inline +void +subview_cube::operator/= (const eT val) + { + arma_extra_debug_sigprint(); - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; + inplace_op(val); + } + + + +template +template +inline +void +subview_cube::operator= (const BaseCube& in) + { + arma_extra_debug_sigprint(); - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(in, "copy into subcube"); } @@ -199,24 +359,7 @@ { arma_extra_debug_sigprint(); - const unwrap_cube tmp(in.get_ref()); - - const Cube& x = tmp.M; - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "addition"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(in, "addition"); } @@ -229,24 +372,7 @@ { arma_extra_debug_sigprint(); - const unwrap_cube tmp(in.get_ref()); - - const Cube& x = tmp.M; - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "subtraction"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(in, "subtraction"); } @@ -259,24 +385,7 @@ { arma_extra_debug_sigprint(); - const unwrap_cube tmp(in.get_ref()); - - const Cube& x = tmp.M; - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "element-wise multiplication"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(in, "element-wise multiplication"); } @@ -289,24 +398,7 @@ { arma_extra_debug_sigprint(); - const unwrap_cube tmp(in.get_ref()); - - const Cube& x = tmp.M; - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "element-wise division"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(in, "element-wise division"); } @@ -319,30 +411,7 @@ { arma_extra_debug_sigprint(); - if(check_overlap(x)) - { - const Cube tmp(x); - - (*this).operator=(tmp); - - return; - } - - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "copy into subcube"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(x, "copy into subcube"); } @@ -354,30 +423,7 @@ { arma_extra_debug_sigprint(); - if(check_overlap(x)) - { - const Cube tmp(x); - - (*this).operator+=(tmp); - - return; - } - - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "addition"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(x, "addition"); } @@ -389,30 +435,7 @@ { arma_extra_debug_sigprint(); - if(check_overlap(x)) - { - const Cube tmp(x); - - (*this).operator-=(tmp); - - return; - } - - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "subtraction"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(x, "subtraction"); } @@ -424,30 +447,7 @@ { arma_extra_debug_sigprint(); - if(check_overlap(x)) - { - const Cube tmp(x); - - (*this).operator%=(tmp); - - return; - } - - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "element-wise multiplication"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(x, "element-wise multiplication"); } @@ -459,30 +459,7 @@ { arma_extra_debug_sigprint(); - if(check_overlap(x)) - { - const Cube tmp(x); - - (*this).operator/=(tmp); - - return; - } - - subview_cube& t = *this; - - arma_debug_assert_same_size(t, x, "element-wise division"); - - const uword t_n_rows = t.n_rows; - const uword t_n_cols = t.n_cols; - const uword t_n_slices = t.n_slices; - - for(uword slice = 0; slice < t_n_slices; ++slice) - { - for(uword col = 0; col < t_n_cols; ++col) - { - arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); - } - } + inplace_op(x, "element-wise division"); } @@ -495,7 +472,7 @@ { arma_extra_debug_sigprint(); - const unwrap tmp(in.get_ref()); + const quasi_unwrap tmp(in.get_ref()); const Mat& x = tmp.M; subview_cube& t = *this; @@ -600,7 +577,7 @@ { arma_extra_debug_sigprint(); - const unwrap tmp(in.get_ref()); + const quasi_unwrap tmp(in.get_ref()); const Mat& x = tmp.M; subview_cube& t = *this; @@ -703,7 +680,7 @@ { arma_extra_debug_sigprint(); - const unwrap tmp(in.get_ref()); + const quasi_unwrap tmp(in.get_ref()); const Mat& x = tmp.M; subview_cube& t = *this; @@ -806,7 +783,7 @@ { arma_extra_debug_sigprint(); - const unwrap tmp(in.get_ref()); + const quasi_unwrap tmp(in.get_ref()); const Mat& x = tmp.M; subview_cube& t = *this; @@ -909,7 +886,7 @@ { arma_extra_debug_sigprint(); - const unwrap tmp(in.get_ref()); + const quasi_unwrap tmp(in.get_ref()); const Mat& x = tmp.M; subview_cube& t = *this; @@ -1134,59 +1111,55 @@ -#if defined(ARMA_USE_CXX11) +//! apply a lambda function to each slice, where each slice is interpreted as a matrix +template +inline +void +subview_cube::each_slice(const std::function< void(Mat&) >& F) + { + arma_extra_debug_sigprint(); - //! apply a lambda function to each slice, where each slice is interpreted as a matrix - template - inline - void - subview_cube::each_slice(const std::function< void(Mat&) >& F) + Mat tmp1(n_rows, n_cols, arma_nozeros_indicator()); + Mat tmp2('j', tmp1.memptr(), n_rows, n_cols); + + for(uword slice_id=0; slice_id < n_slices; ++slice_id) { - arma_extra_debug_sigprint(); + for(uword col_id=0; col_id < n_cols; ++col_id) + { + arrayops::copy( tmp1.colptr(col_id), slice_colptr(slice_id, col_id), n_rows ); + } - Mat tmp1(n_rows, n_cols); - Mat tmp2('j', tmp1.memptr(), n_rows, n_cols); + F(tmp2); - for(uword slice_id=0; slice_id < n_slices; ++slice_id) + for(uword col_id=0; col_id < n_cols; ++col_id) { - for(uword col_id=0; col_id < n_cols; ++col_id) - { - arrayops::copy( tmp1.colptr(col_id), slice_colptr(slice_id, col_id), n_rows ); - } - - F(tmp2); - - for(uword col_id=0; col_id < n_cols; ++col_id) - { - arrayops::copy( slice_colptr(slice_id, col_id), tmp1.colptr(col_id), n_rows ); - } + arrayops::copy( slice_colptr(slice_id, col_id), tmp1.colptr(col_id), n_rows ); } } + } + + + +template +inline +void +subview_cube::each_slice(const std::function< void(const Mat&) >& F) const + { + arma_extra_debug_sigprint(); + Mat tmp1(n_rows, n_cols, arma_nozeros_indicator()); + const Mat tmp2('j', tmp1.memptr(), n_rows, n_cols); - - template - inline - void - subview_cube::each_slice(const std::function< void(const Mat&) >& F) const + for(uword slice_id=0; slice_id < n_slices; ++slice_id) { - arma_extra_debug_sigprint(); - - Mat tmp1(n_rows, n_cols); - const Mat tmp2('j', tmp1.memptr(), n_rows, n_cols); - - for(uword slice_id=0; slice_id < n_slices; ++slice_id) + for(uword col_id=0; col_id < n_cols; ++col_id) { - for(uword col_id=0; col_id < n_cols; ++col_id) - { - arrayops::copy( tmp1.colptr(col_id), slice_colptr(slice_id, col_id), n_rows ); - } - - F(tmp2); + arrayops::copy( tmp1.colptr(col_id), slice_colptr(slice_id, col_id), n_rows ); } + + F(tmp2); } - -#endif + } @@ -1237,6 +1210,38 @@ template inline void +subview_cube::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + if(is_cx::no) + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview_cube::clamp(): min_val must be less than max_val" ); + } + else + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview_cube::clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "subview_cube::clamp(): imag(min_val) must be less than imag(max_val)" ); + } + + const uword local_n_rows = n_rows; + const uword local_n_cols = n_cols; + const uword local_n_slices = n_slices; + + for(uword slice = 0; slice < local_n_slices; ++slice) + { + for(uword col = 0; col < local_n_cols; ++col) + { + arrayops::clamp( slice_colptr(slice,col), local_n_rows, min_val, max_val ); + } + } + } + + + +template +inline +void subview_cube::fill(const eT val) { arma_extra_debug_sigprint(); @@ -1363,6 +1368,31 @@ inline arma_warn_unused bool +subview_cube::is_zero(const typename get_pod_type::result tol) const + { + arma_extra_debug_sigprint(); + + const uword local_n_rows = n_rows; + const uword local_n_cols = n_cols; + const uword local_n_slices = n_slices; + + for(uword slice = 0; slice < local_n_slices; ++slice) + { + for(uword col = 0; col < local_n_cols; ++col) + { + if(arrayops::is_zero(slice_colptr(slice,col), local_n_rows, tol) == false) { return false; } + } + } + + return true; + } + + + +template +inline +arma_warn_unused +bool subview_cube::has_inf() const { arma_extra_debug_sigprint(); @@ -1462,7 +1492,7 @@ eT& subview_cube::operator()(const uword i) { - arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds" ); + arma_debug_check_bounds( (i >= n_elem), "subview_cube::operator(): index out of bounds" ); const uword in_slice = i / n_elem_slice; const uword offset = in_slice * n_elem_slice; @@ -1483,7 +1513,7 @@ eT subview_cube::operator()(const uword i) const { - arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds" ); + arma_debug_check_bounds( (i >= n_elem), "subview_cube::operator(): index out of bounds" ); const uword in_slice = i / n_elem_slice; const uword offset = in_slice * n_elem_slice; @@ -1504,7 +1534,7 @@ eT& subview_cube::operator()(const uword in_row, const uword in_col, const uword in_slice) { - arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds" ); + arma_debug_check_bounds( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds" ); const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; @@ -1518,7 +1548,7 @@ eT subview_cube::operator()(const uword in_row, const uword in_col, const uword in_slice) const { - arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds" ); + arma_debug_check_bounds( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds" ); const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; @@ -1572,51 +1602,44 @@ template +template inline bool -subview_cube::check_overlap(const subview_cube& x) const +subview_cube::check_overlap(const subview_cube& x) const { - const subview_cube& t = *this; + if(is_same_type::value == false) { return false; } - if(&t.m != &x.m) - { - return false; - } - else - { - if( (t.n_elem == 0) || (x.n_elem == 0) ) - { - return false; - } - else - { - const uword t_row_start = t.aux_row1; - const uword t_row_end_p1 = t_row_start + t.n_rows; - - const uword t_col_start = t.aux_col1; - const uword t_col_end_p1 = t_col_start + t.n_cols; - - const uword t_slice_start = t.aux_slice1; - const uword t_slice_end_p1 = t_slice_start + t.n_slices; - - - const uword x_row_start = x.aux_row1; - const uword x_row_end_p1 = x_row_start + x.n_rows; - - const uword x_col_start = x.aux_col1; - const uword x_col_end_p1 = x_col_start + x.n_cols; - - const uword x_slice_start = x.aux_slice1; - const uword x_slice_end_p1 = x_slice_start + x.n_slices; - - - const bool outside_rows = ( (x_row_start >= t_row_end_p1 ) || (t_row_start >= x_row_end_p1 ) ); - const bool outside_cols = ( (x_col_start >= t_col_end_p1 ) || (t_col_start >= x_col_end_p1 ) ); - const bool outside_slices = ( (x_slice_start >= t_slice_end_p1) || (t_slice_start >= x_slice_end_p1) ); - - return ( (outside_rows == false) && (outside_cols == false) && (outside_slices == false) ); - } - } + const subview_cube& t = (*this); + + if(void_ptr(&(t.m)) != void_ptr(&(x.m))) { return false; } + + if( (t.n_elem == 0) || (x.n_elem == 0) ) { return false; } + + const uword t_row_start = t.aux_row1; + const uword t_row_end_p1 = t_row_start + t.n_rows; + + const uword t_col_start = t.aux_col1; + const uword t_col_end_p1 = t_col_start + t.n_cols; + + const uword t_slice_start = t.aux_slice1; + const uword t_slice_end_p1 = t_slice_start + t.n_slices; + + + const uword x_row_start = x.aux_row1; + const uword x_row_end_p1 = x_row_start + x.n_rows; + + const uword x_col_start = x.aux_col1; + const uword x_col_end_p1 = x_col_start + x.n_cols; + + const uword x_slice_start = x.aux_slice1; + const uword x_slice_end_p1 = x_slice_start + x.n_slices; + + + const bool outside_rows = ( (x_row_start >= t_row_end_p1 ) || (t_row_start >= x_row_end_p1 ) ); + const bool outside_cols = ( (x_col_start >= t_col_end_p1 ) || (t_col_start >= x_col_end_p1 ) ); + const bool outside_slices = ( (x_slice_start >= t_slice_end_p1) || (t_slice_start >= x_slice_end_p1) ); + + return ( (outside_rows == false) && (outside_cols == false) && (outside_slices == false) ); } @@ -1633,7 +1656,7 @@ for(uword slice = t_aux_slice1; slice < t_aux_slice2_plus_1; ++slice) { - if(t.m.mat_ptrs[slice] != NULL) + if(t.m.mat_ptrs[slice] != nullptr) { const Mat& y = *(t.m.mat_ptrs[slice]); @@ -1663,13 +1686,20 @@ arma_extra_debug_print(arma_str::format("out.n_rows = %d out.n_cols = %d out.n_slices = %d in.m.n_rows = %d in.m.n_cols = %d in.m.n_slices = %d") % out.n_rows % out.n_cols % out.n_slices % in.m.n_rows % in.m.n_cols % in.m.n_slices); - - for(uword slice = 0; slice < n_slices; ++slice) + if( (in.aux_row1 == 0) && (n_rows == in.m.n_rows) ) { - for(uword col = 0; col < n_cols; ++col) + for(uword s=0; s < n_slices; ++s) { - arrayops::copy( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows ); + arrayops::copy( out.slice_colptr(s,0), in.slice_colptr(s,0), in.n_elem_slice ); } + + return; + } + + for(uword s=0; s < n_slices; ++s) + for(uword c=0; c < n_cols; ++c) + { + arrayops::copy( out.slice_colptr(s,c), in.slice_colptr(s,c), n_rows ); } } @@ -2342,15 +2372,15 @@ template inline subview_cube::iterator::iterator() - : M (NULL) - , current_ptr (NULL) - , current_row (0 ) - , current_col (0 ) - , current_slice(0 ) - , aux_row1 (0 ) - , aux_col1 (0 ) - , aux_row2_p1 (0 ) - , aux_col2_p1 (0 ) + : M (nullptr) + , current_ptr (nullptr) + , current_row (0 ) + , current_col (0 ) + , current_slice(0 ) + , aux_row1 (0 ) + , aux_col1 (0 ) + , aux_row2_p1 (0 ) + , aux_col2_p1 (0 ) { arma_extra_debug_sigprint(); // Technically this iterator is invalid (it does not point to a valid element) @@ -2503,8 +2533,8 @@ template inline subview_cube::const_iterator::const_iterator() - : M (NULL) - , current_ptr (NULL) + : M (nullptr) + , current_ptr (nullptr) , current_row (0 ) , current_col (0 ) , current_slice(0 ) diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_slices_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_slices_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_slices_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_slices_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,15 +22,14 @@ template -class subview_cube_slices : public BaseCube > +class subview_cube_slices : public BaseCube< eT, subview_cube_slices > { public: typedef eT elem_type; typedef typename get_pod_type::result pod_type; - arma_aligned const Cube& m; - + arma_aligned const Cube& m; arma_aligned const Base& base_si; @@ -40,6 +41,7 @@ public: inline ~subview_cube_slices(); + inline subview_cube_slices() = delete; inline void inplace_rand(const uword rand_mode); @@ -82,11 +84,7 @@ inline static void div_inplace(Cube& out, const subview_cube_slices& in); - - private: - friend class Cube; - subview_cube_slices(); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_slices_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_slices_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_cube_slices_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_slices_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -59,7 +61,7 @@ arma_debug_check ( ( (si.is_vec() == false) && (si.is_empty() == false) ), - "Cube::slices(): given object is not a vector" + "Cube::slices(): given object must be a vector" ); const uword* si_mem = si.memptr(); @@ -69,7 +71,7 @@ { const uword i = si_mem[si_count]; - arma_debug_check( (i >= m_n_slices), "Cube::slices(): index out of bounds" ); + arma_debug_check_bounds( (i >= m_n_slices), "Cube::slices(): index out of bounds" ); eT* m_slice_ptr = m_local.slice_memptr(i); @@ -99,7 +101,7 @@ arma_debug_check ( ( (si.is_vec() == false) && (si.is_empty() == false) ), - "Cube::slices(): given object is not a vector" + "Cube::slices(): given object must be a vector" ); const uword* si_mem = si.memptr(); @@ -109,7 +111,7 @@ { const uword i = si_mem[si_count]; - arma_debug_check( (i >= m_n_slices), "Cube::slices(): index out of bounds" ); + arma_debug_check_bounds( (i >= m_n_slices), "Cube::slices(): index out of bounds" ); eT* m_slice_ptr = m_local.slice_memptr(i); @@ -142,7 +144,7 @@ arma_debug_check ( ( (si.is_vec() == false) && (si.is_empty() == false) ), - "Cube::slices(): given object is not a vector" + "Cube::slices(): given object must be a vector" ); const uword* si_mem = si.memptr(); @@ -157,7 +159,7 @@ { const uword i = si_mem[si_count]; - arma_debug_check( (i >= m_n_slices), "Cube::slices(): index out of bounds" ); + arma_debug_check_bounds( (i >= m_n_slices), "Cube::slices(): index out of bounds" ); eT* m_slice_ptr = m_local.slice_memptr(i); const eT* X_slice_ptr = X.slice_memptr(si_count); @@ -470,7 +472,7 @@ arma_debug_check ( ( (si.is_vec() == false) && (si.is_empty() == false) ), - "Cube::slices(): given object is not a vector" + "Cube::slices(): given object must be a vector" ); const uword* si_mem = si.memptr(); @@ -482,7 +484,7 @@ { const uword i = si_mem[si_count]; - arma_debug_check( (i >= m_n_slices), "Cube::slices(): index out of bounds" ); + arma_debug_check_bounds( (i >= m_n_slices), "Cube::slices(): index out of bounds" ); eT* out_slice_ptr = out.slice_memptr(si_count); const eT* m_slice_ptr = m_local.slice_memptr(i); diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_each_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_each_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_each_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_each_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -34,6 +36,7 @@ protected: arma_inline subview_each_common(const parent& in_P); + inline subview_each_common() = delete; arma_inline const Mat& get_mat_ref_helper(const Mat & X) const; arma_inline const Mat& get_mat_ref_helper(const subview& X) const; @@ -41,11 +44,6 @@ arma_inline const Mat& get_mat_ref() const; arma_cold inline const std::string incompat_size_string(const Mat& A) const; - - - private: - - subview_each_common(); }; @@ -64,6 +62,7 @@ typedef typename parent::elem_type eT; inline ~subview_each1(); + inline subview_each1() = delete; // deliberately returning void template inline void operator= (const Base& x); @@ -73,8 +72,6 @@ template inline void operator/= (const Base& x); - private: - friend class Mat; friend class subview; }; @@ -96,7 +93,9 @@ typedef typename parent::elem_type eT; inline void check_indices(const Mat& indices) const; + inline ~subview_each2(); + inline subview_each2() = delete; // deliberately returning void template inline void operator= (const Base& x); @@ -106,8 +105,6 @@ template inline void operator/= (const Base& x); - private: - friend class Mat; friend class subview; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_each_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_each_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_each_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_each_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -395,7 +397,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::copy( p.colptr(col), A_mem, p_n_rows ); } @@ -406,7 +408,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); for(uword col=0; col < p_n_cols; ++col) { @@ -451,7 +453,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::inplace_plus( p.colptr(col), A_mem, p_n_rows ); } @@ -462,7 +464,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); p.row(row) += A; } @@ -504,7 +506,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::inplace_minus( p.colptr(col), A_mem, p_n_rows ); } @@ -515,7 +517,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); p.row(row) -= A; } @@ -557,7 +559,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::inplace_mul( p.colptr(col), A_mem, p_n_rows ); } @@ -568,7 +570,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); p.row(row) %= A; } @@ -610,7 +612,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::inplace_div( p.colptr(col), A_mem, p_n_rows ); } @@ -621,7 +623,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); p.row(row) /= A; } @@ -654,7 +656,7 @@ const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; - Mat out(p_n_rows, p_n_cols); + Mat out(p_n_rows, p_n_cols, arma_nozeros_indicator()); const quasi_unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; @@ -716,7 +718,7 @@ const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; - Mat out(p_n_rows, p_n_cols); + Mat out(p_n_rows, p_n_cols, arma_nozeros_indicator()); const quasi_unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; @@ -778,7 +780,7 @@ const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; - Mat out(p_n_rows, p_n_cols); + Mat out(p_n_rows, p_n_cols, arma_nozeros_indicator()); const quasi_unwrap tmp(X.get_ref()); const Mat& A = tmp.M; @@ -840,7 +842,7 @@ const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; - Mat out(p_n_rows, p_n_cols); + Mat out(p_n_rows, p_n_cols, arma_nozeros_indicator()); const quasi_unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; @@ -902,7 +904,7 @@ const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; - Mat out(p_n_rows, p_n_cols); + Mat out(p_n_rows, p_n_cols, arma_nozeros_indicator()); const quasi_unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; @@ -964,7 +966,7 @@ const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; - Mat out(p_n_rows, p_n_cols); + Mat out(p_n_rows, p_n_cols, arma_nozeros_indicator()); const quasi_unwrap tmp(X.get_ref()); const Mat& A = tmp.M; @@ -1053,7 +1055,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::inplace_plus( out.colptr(col), A_mem, p_n_rows ); } @@ -1065,7 +1067,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); out.row(row) += A; } @@ -1115,7 +1117,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::inplace_minus( out.colptr(col), A_mem, p_n_rows ); } @@ -1127,7 +1129,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); out.row(row) -= A; } @@ -1177,7 +1179,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); const eT* p_mem = p.colptr(col); eT* out_mem = out.colptr(col); @@ -1195,7 +1197,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); out.row(row) = A - p.row(row); } @@ -1245,7 +1247,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::inplace_mul( out.colptr(col), A_mem, p_n_rows ); } @@ -1257,7 +1259,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); out.row(row) %= A; } @@ -1307,7 +1309,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); arrayops::inplace_div( out.colptr(col), A_mem, p_n_rows ); } @@ -1319,7 +1321,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); out.row(row) /= A; } @@ -1369,7 +1371,7 @@ { const uword col = indices_mem[i]; - arma_debug_check( (col >= p_n_cols), "each_col(): index out of bounds" ); + arma_debug_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" ); const eT* p_mem = p.colptr(col); eT* out_mem = out.colptr(col); @@ -1387,7 +1389,7 @@ { const uword row = indices_mem[i]; - arma_debug_check( (row >= p_n_rows), "each_row(): index out of bounds" ); + arma_debug_check_bounds( (row >= p_n_rows), "each_row(): index out of bounds" ); out.row(row) = A / p.row(row); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_elem1_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem1_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_elem1_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem1_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,16 +22,16 @@ template -class subview_elem1 : public Base > +class subview_elem1 : public Base< eT, subview_elem1 > { public: typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = true; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = true; + static constexpr bool is_xvec = false; arma_aligned const Mat fake_m; arma_aligned const Mat& m; @@ -45,6 +47,7 @@ public: inline ~subview_elem1(); + inline subview_elem1() = delete; template inline void inplace_op(const eT val); template inline void inplace_op(const subview_elem1& x ); @@ -56,6 +59,10 @@ inline void replace(const eT old_val, const eT new_val); + inline void clean(const pod_type threshold); + + inline void clamp(const eT min_val, const eT max_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); @@ -93,13 +100,8 @@ inline static void div_inplace(Mat& out, const subview_elem1& in); - - private: - friend class Mat; friend class Cube; - - subview_elem1(); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_elem1_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem1_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_elem1_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem1_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -33,8 +35,6 @@ , a(in_a) { arma_extra_debug_sigprint(); - - // TODO: refactor to unwrap 'in_a' instead of storing a ref to it; this will allow removal of carrying T1 around and repetition of size checks } @@ -70,7 +70,7 @@ arma_debug_check ( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* aa_mem = aa.memptr(); @@ -82,7 +82,7 @@ const uword ii = aa_mem[iq]; const uword jj = aa_mem[jq]; - arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_mem[ii] = val; m_mem[jj] = val; } if(is_same_type::yes) { m_mem[ii] += val; m_mem[jj] += val; } @@ -95,7 +95,7 @@ { const uword ii = aa_mem[iq]; - arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_mem[ii] = val; } if(is_same_type::yes) { m_mem[ii] += val; } @@ -143,7 +143,7 @@ arma_debug_check ( ( ((s_aa.is_vec() == false) && (s_aa.is_empty() == false)) || ((x_aa.is_vec() == false) && (x_aa.is_empty() == false)) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* s_aa_mem = s_aa.memptr(); @@ -169,7 +169,7 @@ const uword x_ii = x_aa_mem[iq]; const uword x_jj = x_aa_mem[jq]; - arma_debug_check + arma_debug_check_bounds ( (s_ii >= s_m_n_elem) || (s_jj >= s_m_n_elem) || (x_ii >= x_m_n_elem) || (x_jj >= x_m_n_elem), "Mat::elem(): index out of bounds" @@ -187,7 +187,7 @@ const uword s_ii = s_aa_mem[iq]; const uword x_ii = x_aa_mem[iq]; - arma_debug_check + arma_debug_check_bounds ( ( (s_ii >= s_m_n_elem) || (x_ii >= x_m_n_elem) ), "Mat::elem(): index out of bounds" @@ -223,7 +223,7 @@ arma_debug_check ( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* aa_mem = aa.memptr(); @@ -245,7 +245,7 @@ const uword ii = aa_mem[iq]; const uword jj = aa_mem[jq]; - arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_mem[ii] = X[iq]; m_mem[jj] = X[jq]; } if(is_same_type::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; } @@ -258,7 +258,7 @@ { const uword ii = aa_mem[iq]; - arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_mem[ii] = X[iq]; } if(is_same_type::yes) { m_mem[ii] += X[iq]; } @@ -282,7 +282,7 @@ const uword ii = aa_mem[iq]; const uword jj = aa_mem[jq]; - arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_mem[ii] = X[iq]; m_mem[jj] = X[jq]; } if(is_same_type::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; } @@ -295,7 +295,7 @@ { const uword ii = aa_mem[iq]; - arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_mem[ii] = X[iq]; } if(is_same_type::yes) { m_mem[ii] += X[iq]; } @@ -361,7 +361,7 @@ arma_debug_check ( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* aa_mem = aa.memptr(); @@ -373,7 +373,7 @@ { const uword ii = aa_mem[iq]; - arma_debug_check( (ii >= m_n_elem), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem), "Mat::elem(): index out of bounds" ); eT& val = m_mem[ii]; @@ -386,7 +386,7 @@ { const uword ii = aa_mem[iq]; - arma_debug_check( (ii >= m_n_elem), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem), "Mat::elem(): index out of bounds" ); eT& val = m_mem[ii]; @@ -400,6 +400,38 @@ template inline void +subview_elem1::clean(const pod_type threshold) + { + arma_extra_debug_sigprint(); + + Mat tmp(*this); + + tmp.clean(threshold); + + (*this).operator=(tmp); + } + + + +template +inline +void +subview_elem1::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + Mat tmp(*this); + + tmp.clamp(min_val, max_val); + + (*this).operator=(tmp); + } + + + +template +inline +void subview_elem1::fill(const eT val) { arma_extra_debug_sigprint(); @@ -451,7 +483,7 @@ arma_debug_check ( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* aa_mem = aa.memptr(); @@ -463,7 +495,7 @@ const uword ii = aa_mem[iq]; const uword jj = aa_mem[jq]; - arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); const eT val1 = eT(arma_rng::randu()); const eT val2 = eT(arma_rng::randu()); @@ -476,7 +508,7 @@ { const uword ii = aa_mem[iq]; - arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); m_mem[ii] = eT(arma_rng::randu()); } @@ -502,7 +534,7 @@ arma_debug_check ( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* aa_mem = aa.memptr(); @@ -514,7 +546,7 @@ const uword ii = aa_mem[iq]; const uword jj = aa_mem[jq]; - arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); arma_rng::randn::dual_val( m_mem[ii], m_mem[jj] ); } @@ -523,7 +555,7 @@ { const uword ii = aa_mem[iq]; - arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); m_mem[ii] = eT(arma_rng::randn()); } @@ -759,7 +791,7 @@ arma_debug_check ( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* aa_mem = aa.memptr(); @@ -787,7 +819,7 @@ const uword ii = aa_mem[i]; const uword jj = aa_mem[j]; - arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); out_mem[i] = m_mem[ii]; out_mem[j] = m_mem[jj]; @@ -797,7 +829,7 @@ { const uword ii = aa_mem[i]; - arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); out_mem[i] = m_mem[ii]; } @@ -825,7 +857,7 @@ arma_debug_check ( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* aa_mem = aa.memptr(); @@ -847,7 +879,7 @@ const uword ii = aa_mem[i]; const uword jj = aa_mem[j]; - arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { out_mem[i] += m_mem[ii]; out_mem[j] += m_mem[jj]; } if(is_same_type::yes) { out_mem[i] -= m_mem[ii]; out_mem[j] -= m_mem[jj]; } @@ -859,7 +891,7 @@ { const uword ii = aa_mem[i]; - arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { out_mem[i] += m_mem[ii]; } if(is_same_type::yes) { out_mem[i] -= m_mem[ii]; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_elem2_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem2_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_elem2_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem2_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,16 +22,16 @@ template -class subview_elem2 : public Base > +class subview_elem2 : public Base< eT, subview_elem2 > { public: typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; arma_aligned const Mat& m; @@ -48,6 +50,7 @@ public: inline ~subview_elem2(); + inline subview_elem2() = delete; template inline void inplace_op(const eT val); @@ -55,6 +58,12 @@ template inline void inplace_op(const Base& x); + inline void replace(const eT old_val, const eT new_val); + + inline void clean(const pod_type threshold); + + inline void clamp(const eT min_val, const eT max_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); @@ -81,6 +90,12 @@ template inline void operator%= (const Base& x); template inline void operator/= (const Base& x); + template inline void operator= (const SpBase& x); + template inline void operator+= (const SpBase& x); + template inline void operator-= (const SpBase& x); + template inline void operator%= (const SpBase& x); + template inline void operator/= (const SpBase& x); + inline static void extract(Mat& out, const subview_elem2& in); inline static void plus_inplace(Mat& out, const subview_elem2& in); @@ -89,11 +104,7 @@ inline static void div_inplace(Mat& out, const subview_elem2& in); - - private: - friend class Mat; - subview_elem2(); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_elem2_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem2_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_elem2_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem2_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -71,7 +73,7 @@ arma_debug_check ( ( ((ri.is_vec() == false) && (ri.is_empty() == false)) || ((ci.is_vec() == false) && (ci.is_empty() == false)) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ri_mem = ri.memptr(); @@ -84,13 +86,13 @@ { const uword col = ci_mem[ci_count]; - arma_debug_check( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count) { const uword row = ri_mem[ri_count]; - arma_debug_check( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_local.at(row,col) = val; } if(is_same_type::yes) { m_local.at(row,col) += val; } @@ -110,7 +112,7 @@ arma_debug_check ( ( (ci.is_vec() == false) && (ci.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ci_mem = ci.memptr(); @@ -120,7 +122,7 @@ { const uword col = ci_mem[ci_count]; - arma_debug_check( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); eT* colptr = m_local.colptr(col); @@ -141,7 +143,7 @@ arma_debug_check ( ( (ri.is_vec() == false) && (ri.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ri_mem = ri.memptr(); @@ -153,7 +155,7 @@ { const uword row = ri_mem[ri_count]; - arma_debug_check( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_local.at(row,col) = val; } if(is_same_type::yes) { m_local.at(row,col) += val; } @@ -194,7 +196,7 @@ arma_debug_check ( ( ((ri.is_vec() == false) && (ri.is_empty() == false)) || ((ci.is_vec() == false) && (ci.is_empty() == false)) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ri_mem = ri.memptr(); @@ -209,13 +211,13 @@ { const uword col = ci_mem[ci_count]; - arma_debug_check( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count) { const uword row = ri_mem[ri_count]; - arma_debug_check( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_local.at(row,col) = X.at(ri_count, ci_count); } if(is_same_type::yes) { m_local.at(row,col) += X.at(ri_count, ci_count); } @@ -235,7 +237,7 @@ arma_debug_check ( ( (ci.is_vec() == false) && (ci.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ci_mem = ci.memptr(); @@ -247,7 +249,7 @@ { const uword col = ci_mem[ci_count]; - arma_debug_check( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); eT* m_colptr = m_local.colptr(col); const eT* X_colptr = X.colptr(ci_count); @@ -269,7 +271,7 @@ arma_debug_check ( ( (ri.is_vec() == false) && (ri.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ri_mem = ri.memptr(); @@ -283,7 +285,7 @@ { const uword row = ri_mem[ri_count]; - arma_debug_check( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); if(is_same_type::yes) { m_local.at(row,col) = X.at(ri_count, col); } if(is_same_type::yes) { m_local.at(row,col) += X.at(ri_count, col); } @@ -305,6 +307,54 @@ template inline void +subview_elem2::replace(const eT old_val, const eT new_val) + { + arma_extra_debug_sigprint(); + + Mat tmp(*this); + + tmp.replace(old_val, new_val); + + (*this).operator=(tmp); + } + + + +template +inline +void +subview_elem2::clean(const pod_type threshold) + { + arma_extra_debug_sigprint(); + + Mat tmp(*this); + + tmp.clean(threshold); + + (*this).operator=(tmp); + } + + + +template +inline +void +subview_elem2::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + Mat tmp(*this); + + tmp.clamp(min_val, max_val); + + (*this).operator=(tmp); + } + + + +template +inline +void subview_elem2::fill(const eT val) { arma_extra_debug_sigprint(); @@ -554,6 +604,86 @@ template +template +inline +void +subview_elem2::operator= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const Mat tmp(x); + + inplace_op(tmp); + } + + + +template +template +inline +void +subview_elem2::operator+= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const Mat tmp(x); + + inplace_op(tmp); + } + + + +template +template +inline +void +subview_elem2::operator-= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const Mat tmp(x); + + inplace_op(tmp); + } + + + +template +template +inline +void +subview_elem2::operator%= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const Mat tmp(x); + + inplace_op(tmp); + } + + + +template +template +inline +void +subview_elem2::operator/= (const SpBase& x) + { + arma_extra_debug_sigprint(); + + const Mat tmp(x); + + inplace_op(tmp); + } + + + +// +// + + + +template inline void subview_elem2::extract(Mat& actual_out, const subview_elem2& in) @@ -583,7 +713,7 @@ arma_debug_check ( ( ((ri.is_vec() == false) && (ri.is_empty() == false)) || ((ci.is_vec() == false) && (ci.is_empty() == false)) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ri_mem = ri.memptr(); @@ -601,13 +731,13 @@ { const uword col = ci_mem[ci_count]; - arma_debug_check( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count) { const uword row = ri_mem[ri_count]; - arma_debug_check( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); out_mem[out_count] = m_local.at(row,col); ++out_count; @@ -624,7 +754,7 @@ arma_debug_check ( ( (ci.is_vec() == false) && (ci.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ci_mem = ci.memptr(); @@ -636,7 +766,7 @@ { const uword col = ci_mem[ci_count]; - arma_debug_check( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); arrayops::copy( out.colptr(ci_count), m_local.colptr(col), m_n_rows ); } @@ -651,7 +781,7 @@ arma_debug_check ( ( (ri.is_vec() == false) && (ri.is_empty() == false) ), - "Mat::elem(): given object is not a vector" + "Mat::elem(): given object must be a vector" ); const uword* ri_mem = ri.memptr(); @@ -665,7 +795,7 @@ { const uword row = ri_mem[ri_count]; - arma_debug_check( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); + arma_debug_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); out.at(ri_count,col) = m_local.at(row,col); } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_field_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_field_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_field_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_field_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,7 +21,7 @@ //! Class for storing data required to construct or apply operations to a subfield -//! (i.e. where the subfield starts and ends as well as a reference/pointer to the original field), +//! (ie. where the subfield starts and ends as well as a reference/pointer to the original field), template class subview_field { @@ -48,6 +50,7 @@ public: inline ~subview_field(); + inline subview_field() = delete; inline void operator= (const field& x); inline void operator= (const subview_field& x); @@ -85,13 +88,7 @@ inline static void extract(field& out, const subview_field& in); - private: - friend class field; - - - subview_field(); - //subview_field(const subview_field&); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_field_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_field_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_field_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_field_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -198,7 +200,7 @@ oT& subview_field::operator()(const uword i) { - arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds" ); + arma_debug_check_bounds( (i >= n_elem), "subview_field::operator(): index out of bounds" ); return operator[](i); } @@ -210,7 +212,7 @@ const oT& subview_field::operator()(const uword i) const { - arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds" ); + arma_debug_check_bounds( (i >= n_elem), "subview_field::operator(): index out of bounds" ); return operator[](i); } @@ -242,7 +244,7 @@ oT& subview_field::operator()(const uword in_row, const uword in_col, const uword in_slice) { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "subview_field::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "subview_field::operator(): index out of bounds" ); const uword index = (in_slice + aux_slice1)*(f.n_rows*f.n_cols) + (in_col + aux_col1)*f.n_rows + aux_row1 + in_row; @@ -256,7 +258,7 @@ const oT& subview_field::operator()(const uword in_row, const uword in_col, const uword in_slice) const { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "subview_field::operator(): index out of bounds" ); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "subview_field::operator(): index out of bounds" ); const uword index = (in_slice + aux_slice1)*(f.n_rows*f.n_cols) + (in_col + aux_col1)*f.n_rows + aux_row1 + in_row; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/subview_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/subview_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/subview_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/subview_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,40 +24,60 @@ inline subview::~subview() { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); } + template inline subview::subview(const Mat& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols) - : m(in_m) - , aux_row1(in_row1) - , aux_col1(in_col1) - , n_rows(in_n_rows) - , n_cols(in_n_cols) - , n_elem(in_n_rows*in_n_cols) + : m (in_m ) + , aux_row1(in_row1 ) + , aux_col1(in_col1 ) + , n_rows (in_n_rows) + , n_cols (in_n_cols) + , n_elem (in_n_rows*in_n_cols) { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); } template inline -void -subview::operator= (const eT val) +subview::subview(const subview& in) + : m (in.m ) + , aux_row1(in.aux_row1) + , aux_col1(in.aux_col1) + , n_rows (in.n_rows ) + , n_cols (in.n_cols ) + , n_elem (in.n_elem ) { - arma_extra_debug_sigprint(); - - if(n_elem != 1) - { - arma_debug_assert_same_size(n_rows, n_cols, 1, 1, "copy into submatrix"); - } + arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in); + } + + + +template +inline +subview::subview(subview&& in) + : m (in.m ) + , aux_row1(in.aux_row1) + , aux_col1(in.aux_col1) + , n_rows (in.n_rows ) + , n_cols (in.n_cols ) + , n_elem (in.n_elem ) + { + arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in); - Mat& X = const_cast< Mat& >(m); + // for paranoia - X.at(aux_row1, aux_col1) = val; + access::rw(in.aux_row1) = 0; + access::rw(in.aux_col1) = 0; + access::rw(in.n_rows ) = 0; + access::rw(in.n_cols ) = 0; + access::rw(in.n_elem ) = 0; } @@ -129,7 +151,7 @@ arma_debug_assert_same_size(s, P, identifier); - const bool use_mp = arma_config::cxx11 && arma_config::openmp && Proxy::use_mp && mp_gate::eval(s.n_elem); + const bool use_mp = arma_config::openmp && Proxy::use_mp && mp_gate::eval(s.n_elem); const bool has_overlap = P.has_overlap(s); if(has_overlap) { arma_extra_debug_print("aliasing or overlap detected"); } @@ -172,9 +194,13 @@ } else // not a row vector { - if( (is_same_type::yes) && (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) + if((s.aux_row1 == 0) && (s_n_rows == s.m.n_rows)) { - arrayops::copy( s.colptr(0), B.memptr(), s.n_elem ); + if(is_same_type::yes) { arrayops::copy ( s.colptr(0), B.memptr(), s.n_elem ); } + if(is_same_type::yes) { arrayops::inplace_plus ( s.colptr(0), B.memptr(), s.n_elem ); } + if(is_same_type::yes) { arrayops::inplace_minus( s.colptr(0), B.memptr(), s.n_elem ); } + if(is_same_type::yes) { arrayops::inplace_mul ( s.colptr(0), B.memptr(), s.n_elem ); } + if(is_same_type::yes) { arrayops::inplace_div ( s.colptr(0), B.memptr(), s.n_elem ); } } else { @@ -376,6 +402,25 @@ template inline void +subview::operator= (const eT val) + { + arma_extra_debug_sigprint(); + + if(n_elem != 1) + { + arma_debug_assert_same_size(n_rows, n_cols, 1, 1, "copy into submatrix"); + } + + Mat& X = const_cast< Mat& >(m); + + X.at(aux_row1, aux_col1) = val; + } + + + +template +inline +void subview::operator+= (const eT val) { arma_extra_debug_sigprint(); @@ -687,8 +732,8 @@ // This is probably going to fill your subview with a bunch of NaNs, // so I'm not going to bother to implement it fast. // You can have slow NaNs. They're fine too. - for (uword c = 0; c < n_cols; ++c) - for (uword r = 0; r < n_rows; ++r) + for(uword c = 0; c < n_cols; ++c) + for(uword r = 0; r < n_rows; ++r) { at(r, c) /= p.at(r, c); } @@ -711,6 +756,50 @@ +template +inline +void +subview::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + + arma_debug_check( (is_vec() == false), "copy into submatrix: size mismatch" ); + + const uword N = uword(list.size()); + + if(n_rows == 1) + { + arma_debug_assert_same_size(1, n_cols, 1, N, "copy into submatrix"); + + auto it = list.begin(); + + for(uword ii=0; ii < N; ++ii) { (*this).at(0,ii) = (*it); ++it; } + } + else + if(n_cols == 1) + { + arma_debug_assert_same_size(n_rows, 1, N, 1, "copy into submatrix"); + + arrayops::copy( (*this).colptr(0), list.begin(), N ); + } + } + + + +template +inline +void +subview::operator=(const std::initializer_list< std::initializer_list >& list) + { + arma_extra_debug_sigprint(); + + const Mat tmp(list); + + (*this).operator=(tmp); + } + + + //! apply a functor to each element template template @@ -943,6 +1032,36 @@ template inline void +subview::clamp(const eT min_val, const eT max_val) + { + arma_extra_debug_sigprint(); + + if(is_cx::no) + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview::clamp(): min_val must be less than max_val" ); + } + else + { + arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview::clamp(): real(min_val) must be less than real(max_val)" ); + arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "subview::clamp(): imag(min_val) must be less than imag(max_val)" ); + } + + subview& s = *this; + + const uword s_n_cols = s.n_cols; + const uword s_n_rows = s.n_rows; + + for(uword ucol=0; ucol < s_n_cols; ++ucol) + { + arrayops::clamp( s.colptr(ucol), s_n_rows, min_val, max_val ); + } + } + + + +template +inline +void subview::fill(const eT val) { arma_extra_debug_sigprint(); @@ -977,13 +1096,13 @@ if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) { arrayops::inplace_set( s.colptr(0), val, s.n_elem ); - - return; } - - for(uword ucol=0; ucol < s_n_cols; ++ucol) + else { - arrayops::inplace_set( s.colptr(ucol), val, s_n_rows ); + for(uword ucol=0; ucol < s_n_cols; ++ucol) + { + arrayops::inplace_set( s.colptr(ucol), val, s_n_rows ); + } } } } @@ -1040,21 +1159,33 @@ { arma_extra_debug_sigprint(); - const uword local_n_rows = n_rows; - const uword local_n_cols = n_cols; + subview& s = (*this); + + const uword s_n_rows = s.n_rows; + const uword s_n_cols = s.n_cols; - if(local_n_rows == 1) + if(s_n_rows == 1) { - for(uword ii=0; ii < local_n_cols; ++ii) - { - at(0,ii) = eT(arma_rng::randu()); - } + podarray tmp(s_n_cols); + + eT* tmp_mem = tmp.memptr(); + + arma_rng::randu::fill( tmp_mem, s_n_cols ); + + for(uword ii=0; ii < s_n_cols; ++ii) { at(0,ii) = tmp_mem[ii]; } } else { - for(uword ii=0; ii < local_n_cols; ++ii) + if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) + { + arma_rng::randu::fill( s.colptr(0), s.n_elem ); + } + else { - arma_rng::randu::fill( colptr(ii), local_n_rows ); + for(uword ii=0; ii < s_n_cols; ++ii) + { + arma_rng::randu::fill( s.colptr(ii), s_n_rows ); + } } } } @@ -1068,21 +1199,33 @@ { arma_extra_debug_sigprint(); - const uword local_n_rows = n_rows; - const uword local_n_cols = n_cols; + subview& s = (*this); + + const uword s_n_rows = s.n_rows; + const uword s_n_cols = s.n_cols; - if(local_n_rows == 1) + if(s_n_rows == 1) { - for(uword ii=0; ii < local_n_cols; ++ii) - { - at(0,ii) = eT(arma_rng::randn()); - } + podarray tmp(s_n_cols); + + eT* tmp_mem = tmp.memptr(); + + arma_rng::randn::fill( tmp_mem, s_n_cols ); + + for(uword ii=0; ii < s_n_cols; ++ii) { at(0,ii) = tmp_mem[ii]; } } else { - for(uword ii=0; ii < local_n_cols; ++ii) + if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) { - arma_rng::randn::fill( colptr(ii), local_n_rows ); + arma_rng::randn::fill( s.colptr(0), s.n_elem ); + } + else + { + for(uword ii=0; ii < s_n_cols; ++ii) + { + arma_rng::randn::fill( s.colptr(ii), s_n_rows ); + } } } } @@ -1091,6 +1234,7 @@ template inline +arma_warn_unused eT subview::at_alt(const uword ii) const { @@ -1101,6 +1245,7 @@ template inline +arma_warn_unused eT& subview::operator[](const uword ii) { @@ -1116,6 +1261,7 @@ template inline +arma_warn_unused eT subview::operator[](const uword ii) const { @@ -1131,10 +1277,11 @@ template inline +arma_warn_unused eT& subview::operator()(const uword ii) { - arma_debug_check( (ii >= n_elem), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= n_elem), "subview::operator(): index out of bounds" ); const uword in_col = ii / n_rows; const uword in_row = ii % n_rows; @@ -1148,10 +1295,11 @@ template inline +arma_warn_unused eT subview::operator()(const uword ii) const { - arma_debug_check( (ii >= n_elem), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= n_elem), "subview::operator(): index out of bounds" ); const uword in_col = ii / n_rows; const uword in_row = ii % n_rows; @@ -1165,10 +1313,11 @@ template inline +arma_warn_unused eT& subview::operator()(const uword in_row, const uword in_col) { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds" ); const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; @@ -1179,10 +1328,11 @@ template inline +arma_warn_unused eT subview::operator()(const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds" ); const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; @@ -1193,6 +1343,7 @@ template inline +arma_warn_unused eT& subview::at(const uword in_row, const uword in_col) { @@ -1205,6 +1356,7 @@ template inline +arma_warn_unused eT subview::at(const uword in_row, const uword in_col) const { @@ -1216,6 +1368,64 @@ template +inline +arma_warn_unused +eT& +subview::front() + { + const uword index = aux_col1*m.n_rows + aux_row1; + + return access::rw( (const_cast< Mat& >(m)).mem[index] ); + } + + + +template +inline +arma_warn_unused +eT +subview::front() const + { + const uword index = aux_col1*m.n_rows + aux_row1; + + return m.mem[index]; + } + + + +template +inline +arma_warn_unused +eT& +subview::back() + { + const uword in_row = n_rows - 1; + const uword in_col = n_cols - 1; + + const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; + + return access::rw( (const_cast< Mat& >(m)).mem[index] ); + } + + + +template +inline +arma_warn_unused +eT +subview::back() const + { + const uword in_row = n_rows - 1; + const uword in_col = n_cols - 1; + + const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row; + + return m.mem[index]; + } + + + +template arma_inline eT* subview::colptr(const uword in_col) @@ -1307,6 +1517,27 @@ inline arma_warn_unused bool +subview::is_zero(const typename get_pod_type::result tol) const + { + arma_extra_debug_sigprint(); + + const uword local_n_rows = n_rows; + const uword local_n_cols = n_cols; + + for(uword ii=0; ii +inline +arma_warn_unused +bool subview::has_inf() const { arma_extra_debug_sigprint(); @@ -1362,7 +1593,7 @@ arma_extra_debug_print(arma_str::format("out.n_rows = %d out.n_cols = %d in.m.n_rows = %d in.m.n_cols = %d") % out.n_rows % out.n_cols % in.m.n_rows % in.m.n_cols ); - if(in.is_vec() == true) + if(in.is_vec()) { if(n_cols == 1) // a column vector { @@ -1405,13 +1636,13 @@ if( (in.aux_row1 == 0) && (n_rows == in.m.n_rows) ) { arrayops::copy( out.memptr(), in.colptr(0), in.n_elem ); - - return; } - - for(uword col=0; col < n_cols; ++col) + else { - arrayops::copy( out.colptr(col), in.colptr(col), n_rows ); + for(uword col=0; col < n_cols; ++col) + { + arrayops::copy( out.colptr(col), in.colptr(col), n_rows ); + } } } } @@ -1618,7 +1849,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( row_num >= n_rows, "subview::row(): out of bounds" ); + arma_debug_check_bounds( row_num >= n_rows, "subview::row(): out of bounds" ); const uword base_row = aux_row1 + row_num; @@ -1635,7 +1866,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( row_num >= n_rows, "subview::row(): out of bounds" ); + arma_debug_check_bounds( row_num >= n_rows, "subview::row(): out of bounds" ); const uword base_row = aux_row1 + row_num; @@ -1662,7 +1893,7 @@ const uword base_col1 = aux_col1 + in_col1; const uword base_row = aux_row1 + row_num; - arma_debug_check + arma_debug_check_bounds ( (row_num >= n_rows) || @@ -1694,7 +1925,7 @@ const uword base_col1 = aux_col1 + in_col1; const uword base_row = aux_row1 + row_num; - arma_debug_check + arma_debug_check_bounds ( (row_num >= n_rows) || @@ -1716,7 +1947,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "subview::col(): out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "subview::col(): out of bounds" ); const uword base_col = aux_col1 + col_num; @@ -1733,7 +1964,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "subview::col(): out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "subview::col(): out of bounds" ); const uword base_col = aux_col1 + col_num; @@ -1760,7 +1991,7 @@ const uword base_row1 = aux_row1 + in_row1; const uword base_col = aux_col1 + col_num; - arma_debug_check + arma_debug_check_bounds ( (col_num >= n_cols) || @@ -1792,7 +2023,7 @@ const uword base_row1 = aux_row1 + in_row1; const uword base_col = aux_col1 + col_num; - arma_debug_check + arma_debug_check_bounds ( (col_num >= n_cols) || @@ -1818,7 +2049,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "subview::unsafe_col(): out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "subview::unsafe_col(): out of bounds" ); return Col(colptr(col_num), n_rows, false, true); } @@ -1837,7 +2068,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( col_num >= n_cols, "subview::unsafe_col(): out of bounds"); + arma_debug_check_bounds( col_num >= n_cols, "subview::unsafe_col(): out of bounds" ); return Col(const_cast(colptr(col_num)), n_rows, false, true); } @@ -1852,7 +2083,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "subview::rows(): indices out of bounds or incorrectly used" @@ -1874,7 +2105,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_row2 >= n_rows), "subview::rows(): indices out of bounds or incorrectly used" @@ -1896,7 +2127,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "subview::cols(): indices out of bounds or incorrectly used" @@ -1918,7 +2149,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 > in_col2) || (in_col2 >= n_cols), "subview::cols(): indices out of bounds or incorrectly used" @@ -1940,7 +2171,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "subview::submat(): indices out of bounds or incorrectly used" @@ -1965,7 +2196,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), "subview::submat(): indices out of bounds or incorrectly used" @@ -2004,7 +2235,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -2043,7 +2274,7 @@ const uword in_col2 = col_span.b; const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; - arma_debug_check + arma_debug_check_bounds ( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) || @@ -2134,135 +2365,131 @@ -#if defined(ARMA_USE_CXX11) +//! apply a lambda function to each column, where each column is interpreted as a column vector +template +inline +void +subview::each_col(const std::function< void(Col&) >& F) + { + arma_extra_debug_sigprint(); - //! apply a lambda function to each column, where each column is interpreted as a column vector - template - inline - void - subview::each_col(const std::function< void(Col&) >& F) + for(uword ii=0; ii < n_cols; ++ii) { - arma_extra_debug_sigprint(); - - for(uword ii=0; ii < n_cols; ++ii) - { - Col tmp(colptr(ii), n_rows, false, true); - F(tmp); - } + Col tmp(colptr(ii), n_rows, false, true); + F(tmp); } + } + + + +template +inline +void +subview::each_col(const std::function< void(const Col&) >& F) const + { + arma_extra_debug_sigprint(); - - - template - inline - void - subview::each_col(const std::function< void(const Col&) >& F) const + for(uword ii=0; ii < n_cols; ++ii) { - arma_extra_debug_sigprint(); - - for(uword ii=0; ii < n_cols; ++ii) - { - const Col tmp(colptr(ii), n_rows, false, true); - F(tmp); - } + const Col tmp(colptr(ii), n_rows, false, true); + F(tmp); } + } + + + +//! apply a lambda function to each row, where each row is interpreted as a row vector +template +inline +void +subview::each_row(const std::function< void(Row&) >& F) + { + arma_extra_debug_sigprint(); + + podarray array1(n_cols); + podarray array2(n_cols); + + Row tmp1( array1.memptr(), n_cols, false, true ); + Row tmp2( array2.memptr(), n_cols, false, true ); + eT* tmp1_mem = tmp1.memptr(); + eT* tmp2_mem = tmp2.memptr(); + uword ii, jj; - //! apply a lambda function to each row, where each row is interpreted as a row vector - template - inline - void - subview::each_row(const std::function< void(Row&) >& F) + for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2) { - arma_extra_debug_sigprint(); - - podarray array1(n_cols); - podarray array2(n_cols); + for(uword col_id = 0; col_id < n_cols; ++col_id) + { + const eT* col_mem = colptr(col_id); + + tmp1_mem[col_id] = col_mem[ii]; + tmp2_mem[col_id] = col_mem[jj]; + } - Row tmp1( array1.memptr(), n_cols, false, true ); - Row tmp2( array2.memptr(), n_cols, false, true ); + F(tmp1); + F(tmp2); - eT* tmp1_mem = tmp1.memptr(); - eT* tmp2_mem = tmp2.memptr(); - - uword ii, jj; - - for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2) + for(uword col_id = 0; col_id < n_cols; ++col_id) { - for(uword col_id = 0; col_id < n_cols; ++col_id) - { - const eT* col_mem = colptr(col_id); - - tmp1_mem[col_id] = col_mem[ii]; - tmp2_mem[col_id] = col_mem[jj]; - } - - F(tmp1); - F(tmp2); + eT* col_mem = colptr(col_id); - for(uword col_id = 0; col_id < n_cols; ++col_id) - { - eT* col_mem = colptr(col_id); - - col_mem[ii] = tmp1_mem[col_id]; - col_mem[jj] = tmp2_mem[col_id]; - } + col_mem[ii] = tmp1_mem[col_id]; + col_mem[jj] = tmp2_mem[col_id]; } + } + + if(ii < n_rows) + { + tmp1 = (*this).row(ii); - if(ii < n_rows) - { - tmp1 = (*this).row(ii); - - F(tmp1); - - (*this).row(ii) = tmp1; - } + F(tmp1); + + (*this).row(ii) = tmp1; } + } + + + +template +inline +void +subview::each_row(const std::function< void(const Row&) >& F) const + { + arma_extra_debug_sigprint(); + podarray array1(n_cols); + podarray array2(n_cols); + Row tmp1( array1.memptr(), n_cols, false, true ); + Row tmp2( array2.memptr(), n_cols, false, true ); - template - inline - void - subview::each_row(const std::function< void(const Row&) >& F) const + eT* tmp1_mem = tmp1.memptr(); + eT* tmp2_mem = tmp2.memptr(); + + uword ii, jj; + + for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2) { - arma_extra_debug_sigprint(); - - podarray array1(n_cols); - podarray array2(n_cols); - - Row tmp1( array1.memptr(), n_cols, false, true ); - Row tmp2( array2.memptr(), n_cols, false, true ); - - eT* tmp1_mem = tmp1.memptr(); - eT* tmp2_mem = tmp2.memptr(); - - uword ii, jj; - - for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2) + for(uword col_id = 0; col_id < n_cols; ++col_id) { - for(uword col_id = 0; col_id < n_cols; ++col_id) - { - const eT* col_mem = colptr(col_id); - - tmp1_mem[col_id] = col_mem[ii]; - tmp2_mem[col_id] = col_mem[jj]; - } + const eT* col_mem = colptr(col_id); - F(tmp1); - F(tmp2); + tmp1_mem[col_id] = col_mem[ii]; + tmp2_mem[col_id] = col_mem[jj]; } - if(ii < n_rows) - { - tmp1 = (*this).row(ii); - - F(tmp1); - } + F(tmp1); + F(tmp2); } -#endif + if(ii < n_rows) + { + tmp1 = (*this).row(ii); + + F(tmp1); + } + } @@ -2277,7 +2504,7 @@ const uword row_offset = (in_id < 0) ? uword(-in_id) : 0; const uword col_offset = (in_id > 0) ? uword( in_id) : 0; - arma_debug_check + arma_debug_check_bounds ( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "subview::diag(): requested diagonal out of bounds" @@ -2304,7 +2531,7 @@ const uword row_offset = uword( (in_id < 0) ? -in_id : 0 ); const uword col_offset = uword( (in_id > 0) ? in_id : 0 ); - arma_debug_check + arma_debug_check_bounds ( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "subview::diag(): requested diagonal out of bounds" @@ -2327,7 +2554,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_row1 >= n_rows) || (in_row2 >= n_rows), "subview::swap_rows(): out of bounds" @@ -2359,7 +2586,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check + arma_debug_check_bounds ( (in_col1 >= n_cols) || (in_col2 >= n_cols), "subview::swap_cols(): out of bounds" @@ -2448,12 +2675,12 @@ template inline subview::iterator::iterator() - : M (NULL) - , current_ptr(NULL) - , current_row(0 ) - , current_col(0 ) - , aux_row1 (0 ) - , aux_row2_p1(0 ) + : M (nullptr) + , current_ptr(nullptr) + , current_row(0 ) + , current_col(0 ) + , aux_row1 (0 ) + , aux_row2_p1(0 ) { arma_extra_debug_sigprint(); // Technically this iterator is invalid (it does not point to a valid element) @@ -2594,8 +2821,8 @@ template inline subview::const_iterator::const_iterator() - : M (NULL) - , current_ptr(NULL) + : M (nullptr) + , current_ptr(nullptr) , current_row(0 ) , current_col(0 ) , aux_row1 (0 ) @@ -2755,7 +2982,7 @@ template inline subview::row_iterator::row_iterator() - : M (NULL) + : M (nullptr) , current_row(0 ) , current_col(0 ) , aux_col1 (0 ) @@ -2892,7 +3119,7 @@ template inline subview::const_row_iterator::const_row_iterator() - : M (NULL) + : M (nullptr) , current_row(0 ) , current_col(0 ) , aux_col1 (0 ) @@ -3064,6 +3291,30 @@ template inline +subview_col::subview_col(const subview_col& in) + : subview(in) // interprets 'subview_col' as 'subview' + , colmem(in.colmem) + { + arma_extra_debug_sigprint(); + } + + + +template +inline +subview_col::subview_col(subview_col&& in) + : subview(std::move(in)) // interprets 'subview_col' as 'subview' + , colmem(in.colmem) + { + arma_extra_debug_sigprint(); + + access::rw(in.colmem) = nullptr; + } + + + +template +inline void subview_col::operator=(const subview& X) { @@ -3089,6 +3340,22 @@ template inline void +subview_col::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + + const uword N = uword(list.size()); + + arma_debug_assert_same_size(subview::n_rows, subview::n_cols, N, 1, "copy into submatrix"); + + arrayops::copy( access::rwp(colmem), list.begin(), N ); + } + + + +template +inline +void subview_col::operator=(const eT val) { arma_extra_debug_sigprint(); @@ -3117,6 +3384,19 @@ template +template +inline +void +subview_col::operator=(const SpBase& X) + { + arma_extra_debug_sigprint(); + + subview::operator=(X.get_ref()); + } + + + +template template inline typename enable_if2< is_same_type::value, void>::result @@ -3133,6 +3413,7 @@ template arma_inline +arma_warn_unused const Op,op_htrans> subview_col::t() const { @@ -3143,6 +3424,7 @@ template arma_inline +arma_warn_unused const Op,op_htrans> subview_col::ht() const { @@ -3153,6 +3435,7 @@ template arma_inline +arma_warn_unused const Op,op_strans> subview_col::st() const { @@ -3163,6 +3446,7 @@ template arma_inline +arma_warn_unused const Op,op_strans> subview_col::as_row() const { @@ -3245,7 +3529,7 @@ eT& subview_col::operator()(const uword ii) { - arma_debug_check( (ii >= subview::n_elem), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= subview::n_elem), "subview::operator(): index out of bounds" ); return access::rw( colmem[ii] ); } @@ -3257,7 +3541,7 @@ eT subview_col::operator()(const uword ii) const { - arma_debug_check( (ii >= subview::n_elem), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= subview::n_elem), "subview::operator(): index out of bounds" ); return colmem[ii]; } @@ -3269,7 +3553,7 @@ eT& subview_col::operator()(const uword in_row, const uword in_col) { - arma_debug_check( ((in_row >= subview::n_rows) || (in_col > 0)), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row >= subview::n_rows) || (in_col > 0)), "subview::operator(): index out of bounds" ); return access::rw( colmem[in_row] ); } @@ -3281,7 +3565,7 @@ eT subview_col::operator()(const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row >= subview::n_rows) || (in_col > 0)), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row >= subview::n_rows) || (in_col > 0)), "subview::operator(): index out of bounds" ); return colmem[in_row]; } @@ -3333,7 +3617,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= subview::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used" ); const uword subview_n_rows = in_row2 - in_row1 + 1; @@ -3351,7 +3635,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= subview::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used" ); const uword subview_n_rows = in_row2 - in_row1 + 1; @@ -3369,7 +3653,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= subview::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used" ); const uword subview_n_rows = in_row2 - in_row1 + 1; @@ -3387,7 +3671,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= subview::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used" ); const uword subview_n_rows = in_row2 - in_row1 + 1; @@ -3407,7 +3691,7 @@ arma_debug_check( (s.n_cols != 1), "subview_col::subvec(): given size does not specify a column vector" ); - arma_debug_check( ( (start_row >= subview::n_rows) || ((start_row + s.n_rows) > subview::n_rows) ), "subview_col::subvec(): size out of bounds" ); + arma_debug_check_bounds( ( (start_row >= subview::n_rows) || ((start_row + s.n_rows) > subview::n_rows) ), "subview_col::subvec(): size out of bounds" ); const uword base_row1 = this->aux_row1 + start_row; @@ -3425,7 +3709,7 @@ arma_debug_check( (s.n_cols != 1), "subview_col::subvec(): given size does not specify a column vector" ); - arma_debug_check( ( (start_row >= subview::n_rows) || ((start_row + s.n_rows) > subview::n_rows) ), "subview_col::subvec(): size out of bounds" ); + arma_debug_check_bounds( ( (start_row >= subview::n_rows) || ((start_row + s.n_rows) > subview::n_rows) ), "subview_col::subvec(): size out of bounds" ); const uword base_row1 = this->aux_row1 + start_row; @@ -3441,7 +3725,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > subview::n_rows), "subview_col::head(): size out of bounds"); + arma_debug_check_bounds( (N > subview::n_rows), "subview_col::head(): size out of bounds" ); return subview_col(this->m, this->aux_col1, this->aux_row1, N); } @@ -3455,7 +3739,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > subview::n_rows), "subview_col::head(): size out of bounds"); + arma_debug_check_bounds( (N > subview::n_rows), "subview_col::head(): size out of bounds" ); return subview_col(this->m, this->aux_col1, this->aux_row1, N); } @@ -3469,7 +3753,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > subview::n_rows), "subview_col::tail(): size out of bounds"); + arma_debug_check_bounds( (N > subview::n_rows), "subview_col::tail(): size out of bounds" ); const uword start_row = subview::aux_row1 + subview::n_rows - N; @@ -3485,7 +3769,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > subview::n_rows), "subview_col::tail(): size out of bounds"); + arma_debug_check_bounds( (N > subview::n_rows), "subview_col::tail(): size out of bounds" ); const uword start_row = subview::aux_row1 + subview::n_rows - N; @@ -3633,6 +3917,327 @@ // +template +inline +subview_cols::subview_cols(const Mat& in_m, const uword in_col1, const uword in_n_cols) + : subview(in_m, 0, in_col1, in_m.n_rows, in_n_cols) + { + arma_extra_debug_sigprint(); + } + + + +template +inline +subview_cols::subview_cols(const subview_cols& in) + : subview(in) // interprets 'subview_cols' as 'subview' + { + arma_extra_debug_sigprint(); + } + + + +template +inline +subview_cols::subview_cols(subview_cols&& in) + : subview(std::move(in)) // interprets 'subview_cols' as 'subview' + { + arma_extra_debug_sigprint(); + } + + + +template +inline +void +subview_cols::operator=(const subview& X) + { + arma_extra_debug_sigprint(); + + subview::operator=(X); + } + + + +template +inline +void +subview_cols::operator=(const subview_cols& X) + { + arma_extra_debug_sigprint(); + + subview::operator=(X); // interprets 'subview_cols' as 'subview' + } + + + +template +inline +void +subview_cols::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + + subview::operator=(list); + } + + + +template +inline +void +subview_cols::operator=(const std::initializer_list< std::initializer_list >& list) + { + arma_extra_debug_sigprint(); + + subview::operator=(list); + } + + + +template +inline +void +subview_cols::operator=(const eT val) + { + arma_extra_debug_sigprint(); + + subview::operator=(val); + } + + + +template +template +inline +void +subview_cols::operator=(const Base& X) + { + arma_extra_debug_sigprint(); + + subview::operator=(X.get_ref()); + } + + + +template +template +inline +void +subview_cols::operator=(const SpBase& X) + { + arma_extra_debug_sigprint(); + + subview::operator=(X.get_ref()); + } + + + +template +template +inline +typename enable_if2< is_same_type::value, void>::result +subview_cols::operator= (const Gen& in) + { + arma_extra_debug_sigprint(); + + subview::operator=(in); + } + + + +template +arma_inline +arma_warn_unused +const Op,op_htrans> +subview_cols::t() const + { + return Op,op_htrans>(*this); + } + + + +template +arma_inline +arma_warn_unused +const Op,op_htrans> +subview_cols::ht() const + { + return Op,op_htrans>(*this); + } + + + +template +arma_inline +arma_warn_unused +const Op,op_strans> +subview_cols::st() const + { + return Op,op_strans>(*this); + } + + + +template +arma_inline +arma_warn_unused +const Op,op_vectorise_col> +subview_cols::as_col() const + { + return Op,op_vectorise_col>(*this); + } + + + +template +inline +arma_warn_unused +eT +subview_cols::at_alt(const uword ii) const + { + return operator[](ii); + } + + + +template +inline +arma_warn_unused +eT& +subview_cols::operator[](const uword ii) + { + const uword index = subview::aux_col1 * subview::m.n_rows + ii; + + return access::rw( (const_cast< Mat& >(subview::m)).mem[index] ); + } + + + +template +inline +arma_warn_unused +eT +subview_cols::operator[](const uword ii) const + { + const uword index = subview::aux_col1 * subview::m.n_rows + ii; + + return subview::m.mem[index]; + } + + + +template +inline +arma_warn_unused +eT& +subview_cols::operator()(const uword ii) + { + arma_debug_check_bounds( (ii >= subview::n_elem), "subview::operator(): index out of bounds" ); + + const uword index = subview::aux_col1 * subview::m.n_rows + ii; + + return access::rw( (const_cast< Mat& >(subview::m)).mem[index] ); + } + + + +template +inline +arma_warn_unused +eT +subview_cols::operator()(const uword ii) const + { + arma_debug_check_bounds( (ii >= subview::n_elem), "subview::operator(): index out of bounds" ); + + const uword index = subview::aux_col1 * subview::m.n_rows + ii; + + return subview::m.mem[index]; + } + + + +template +inline +arma_warn_unused +eT& +subview_cols::operator()(const uword in_row, const uword in_col) + { + arma_debug_check_bounds( ((in_row >= subview::n_rows) || (in_col >= subview::n_cols)), "subview::operator(): index out of bounds" ); + + const uword index = (in_col + subview::aux_col1) * subview::m.n_rows + in_row; + + return access::rw( (const_cast< Mat& >(subview::m)).mem[index] ); + } + + + +template +inline +arma_warn_unused +eT +subview_cols::operator()(const uword in_row, const uword in_col) const + { + arma_debug_check_bounds( ((in_row >= subview::n_rows) || (in_col >= subview::n_cols)), "subview::operator(): index out of bounds" ); + + const uword index = (in_col + subview::aux_col1) * subview::m.n_rows + in_row; + + return subview::m.mem[index]; + } + + + +template +inline +arma_warn_unused +eT& +subview_cols::at(const uword in_row, const uword in_col) + { + const uword index = (in_col + subview::aux_col1) * subview::m.n_rows + in_row; + + return access::rw( (const_cast< Mat& >(subview::m)).mem[index] ); + } + + + +template +inline +arma_warn_unused +eT +subview_cols::at(const uword in_row, const uword in_col) const + { + const uword index = (in_col + subview::aux_col1) * subview::m.n_rows + in_row; + + return subview::m.mem[index]; + } + + + +template +arma_inline +eT* +subview_cols::colptr(const uword in_col) + { + return & access::rw((const_cast< Mat& >(subview::m)).mem[ (in_col + subview::aux_col1) * subview::m.n_rows ]); + } + + + +template +arma_inline +const eT* +subview_cols::colptr(const uword in_col) const + { + return & subview::m.mem[ (in_col + subview::aux_col1) * subview::m.n_rows ]; + } + + + +// +// +// + + template inline @@ -3656,6 +4261,26 @@ template inline +subview_row::subview_row(const subview_row& in) + : subview(in) // interprets 'subview_row' as 'subview' + { + arma_extra_debug_sigprint(); + } + + + +template +inline +subview_row::subview_row(subview_row&& in) + : subview(std::move(in)) // interprets 'subview_row' as 'subview' + { + arma_extra_debug_sigprint(); + } + + + +template +inline void subview_row::operator=(const subview& X) { @@ -3691,6 +4316,28 @@ template +inline +void +subview_row::operator=(const std::initializer_list& list) + { + arma_extra_debug_sigprint(); + + const uword N = uword(list.size()); + + arma_debug_assert_same_size(subview::n_rows, subview::n_cols, 1, N, "copy into submatrix"); + + auto it = list.begin(); + + for(uword ii=0; ii < N; ++ii) + { + (*this).operator[](ii) = (*it); + ++it; + } + } + + + +template template inline void @@ -3704,6 +4351,19 @@ template +template +inline +void +subview_row::operator=(const SpBase& X) + { + arma_extra_debug_sigprint(); + + subview::operator=(X.get_ref()); + } + + + +template template inline typename enable_if2< is_same_type::value, void>::result @@ -3720,6 +4380,7 @@ template arma_inline +arma_warn_unused const Op,op_htrans> subview_row::t() const { @@ -3730,6 +4391,7 @@ template arma_inline +arma_warn_unused const Op,op_htrans> subview_row::ht() const { @@ -3740,6 +4402,7 @@ template arma_inline +arma_warn_unused const Op,op_strans> subview_row::st() const { @@ -3750,6 +4413,7 @@ template arma_inline +arma_warn_unused const Op,op_strans> subview_row::as_col() const { @@ -3799,7 +4463,7 @@ eT& subview_row::operator()(const uword ii) { - arma_debug_check( (ii >= subview::n_elem), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= subview::n_elem), "subview::operator(): index out of bounds" ); const uword index = (ii + (subview::aux_col1))*(subview::m).n_rows + (subview::aux_row1); @@ -3813,7 +4477,7 @@ eT subview_row::operator()(const uword ii) const { - arma_debug_check( (ii >= subview::n_elem), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( (ii >= subview::n_elem), "subview::operator(): index out of bounds" ); const uword index = (ii + (subview::aux_col1))*(subview::m).n_rows + (subview::aux_row1); @@ -3827,7 +4491,7 @@ eT& subview_row::operator()(const uword in_row, const uword in_col) { - arma_debug_check( ((in_row > 0) || (in_col >= subview::n_cols)), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row > 0) || (in_col >= subview::n_cols)), "subview::operator(): index out of bounds" ); const uword index = (in_col + (subview::aux_col1))*(subview::m).n_rows + (subview::aux_row1); @@ -3841,7 +4505,7 @@ eT subview_row::operator()(const uword in_row, const uword in_col) const { - arma_debug_check( ((in_row > 0) || (in_col >= subview::n_cols)), "subview::operator(): index out of bounds"); + arma_debug_check_bounds( ((in_row > 0) || (in_col >= subview::n_cols)), "subview::operator(): index out of bounds" ); const uword index = (in_col + (subview::aux_col1))*(subview::m).n_rows + (subview::aux_row1); @@ -3881,7 +4545,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used" ); + arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= subview::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used" ); const uword subview_n_cols = in_col2 - in_col1 + 1; @@ -3899,7 +4563,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= subview::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used" ); const uword subview_n_cols = in_col2 - in_col1 + 1; @@ -3917,7 +4581,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= subview::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used" ); const uword subview_n_cols = in_col2 - in_col1 + 1; @@ -3935,7 +4599,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used"); + arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= subview::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used" ); const uword subview_n_cols = in_col2 - in_col1 + 1; @@ -3955,7 +4619,7 @@ arma_debug_check( (s.n_rows != 1), "subview_row::subvec(): given size does not specify a row vector" ); - arma_debug_check( ( (start_col >= subview::n_cols) || ((start_col + s.n_cols) > subview::n_cols) ), "subview_row::subvec(): size out of bounds" ); + arma_debug_check_bounds( ( (start_col >= subview::n_cols) || ((start_col + s.n_cols) > subview::n_cols) ), "subview_row::subvec(): size out of bounds" ); const uword base_col1 = this->aux_col1 + start_col; @@ -3973,7 +4637,7 @@ arma_debug_check( (s.n_rows != 1), "subview_row::subvec(): given size does not specify a row vector" ); - arma_debug_check( ( (start_col >= subview::n_cols) || ((start_col + s.n_cols) > subview::n_cols) ), "subview_row::subvec(): size out of bounds" ); + arma_debug_check_bounds( ( (start_col >= subview::n_cols) || ((start_col + s.n_cols) > subview::n_cols) ), "subview_row::subvec(): size out of bounds" ); const uword base_col1 = this->aux_col1 + start_col; @@ -3989,7 +4653,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > subview::n_cols), "subview_row::head(): size out of bounds"); + arma_debug_check_bounds( (N > subview::n_cols), "subview_row::head(): size out of bounds" ); return subview_row(this->m, this->aux_row1, this->aux_col1, N); } @@ -4003,7 +4667,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > subview::n_cols), "subview_row::head(): size out of bounds"); + arma_debug_check_bounds( (N > subview::n_cols), "subview_row::head(): size out of bounds" ); return subview_row(this->m, this->aux_row1, this->aux_col1, N); } @@ -4017,7 +4681,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > subview::n_cols), "subview_row::tail(): size out of bounds"); + arma_debug_check_bounds( (N > subview::n_cols), "subview_row::tail(): size out of bounds" ); const uword start_col = subview::aux_col1 + subview::n_cols - N; @@ -4033,7 +4697,7 @@ { arma_extra_debug_sigprint(); - arma_debug_check( (N > subview::n_cols), "subview_row::tail(): size out of bounds"); + arma_debug_check_bounds( (N > subview::n_cols), "subview_row::tail(): size out of bounds" ); const uword start_col = subview::aux_col1 + subview::n_cols - N; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/sympd_helper.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/sympd_helper.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/sympd_helper.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/sympd_helper.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -35,11 +37,11 @@ template inline typename enable_if2::no, bool>::result -guess_sympd(const Mat& A) +guess_sympd_worker(const Mat& A) { arma_extra_debug_sigprint(); - if((A.n_rows != A.n_cols) || (A.n_rows < 16)) { return false; } + // NOTE: assuming A is square-sized const eT tol = eT(100) * std::numeric_limits::epsilon(); // allow some leeway @@ -109,13 +111,13 @@ template inline typename enable_if2::yes, bool>::result -guess_sympd(const Mat& A) +guess_sympd_worker(const Mat& A) { arma_extra_debug_sigprint(); - typedef typename get_pod_type::result T; + // NOTE: assuming A is square-sized - if((A.n_rows != A.n_cols) || (A.n_rows < 16)) { return false; } + typedef typename get_pod_type::result T; const T tol = T(100) * std::numeric_limits::epsilon(); // allow some leeway @@ -207,6 +209,243 @@ } + +template +inline +bool +guess_sympd(const Mat& A) + { + arma_extra_debug_sigprint(); + + // analyse matrices with size >= 4x4 + + if((A.n_rows != A.n_cols) || (A.n_rows < uword(4))) { return false; } + + return guess_sympd_worker(A); + } + + + +template +inline +bool +guess_sympd(const Mat& A, const uword min_n_rows) + { + arma_extra_debug_sigprint(); + + if((A.n_rows != A.n_cols) || (A.n_rows < min_n_rows)) { return false; } + + return guess_sympd_worker(A); + } + + + +// + + + +template +inline +typename enable_if2::no, void>::result +analyse_matrix_worker(bool& is_approx_sym, bool& is_approx_sympd, const Mat& A) + { + arma_extra_debug_sigprint(); + + is_approx_sym = true; + is_approx_sympd = true; + + const eT tol = eT(100) * std::numeric_limits::epsilon(); // allow some leeway + + const uword N = A.n_rows; + + const eT* A_mem = A.memptr(); + const eT* A_col = A_mem; + + eT max_diag = eT(0); + + for(uword j=0; j < N; ++j) + { + const eT A_jj = A_col[j]; + + if(A_jj <= eT(0)) { is_approx_sympd = false; } + + max_diag = (A_jj > max_diag) ? A_jj : max_diag; + + A_col += N; + } + + A_col = A_mem; + + const uword Nm1 = N-1; + const uword Np1 = N+1; + + for(uword j=0; j < Nm1; ++j) + { + const eT A_jj = A_col[j]; + + const uword jp1 = j+1; + const eT* A_ji_ptr = &(A_mem[j + jp1*N]); // &(A.at(j,jp1)); + const eT* A_ii_ptr = &(A_mem[jp1 + jp1*N]); + + for(uword i=jp1; i < N; ++i) + { + const eT A_ij = A_col[i]; + const eT A_ji = (*A_ji_ptr); + + const eT A_ij_abs = (std::abs)(A_ij); + const eT A_ji_abs = (std::abs)(A_ji); + + const eT A_delta = (std::abs)(A_ij - A_ji); + const eT A_abs_max = (std::max)(A_ij_abs, A_ji_abs); + + if( (A_delta > tol) && (A_delta > (A_abs_max*tol)) ) { is_approx_sym = false; return; } + + if(is_approx_sympd) + { + // if( (A_ij_abs >= max_diag) || (A_ji_abs >= max_diag) ) { is_approx_sympd = false; } + if(A_ij_abs >= max_diag) { is_approx_sympd = false; } + + const eT A_ii = (*A_ii_ptr); + + if( (A_ij_abs + A_ij_abs) >= (A_ii + A_jj) ) { is_approx_sympd = false; } + } + + A_ji_ptr += N; + A_ii_ptr += Np1; + } + + A_col += N; + } + } + + + +template +inline +typename enable_if2::yes, void>::result +analyse_matrix_worker(bool& is_approx_sym, bool& is_approx_sympd, const Mat& A) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + is_approx_sym = true; + is_approx_sympd = true; + + const T tol = T(100) * std::numeric_limits::epsilon(); // allow some leeway + + const uword N = A.n_rows; + + const eT* A_mem = A.memptr(); + const eT* A_col = A_mem; + + T max_diag = T(0); + + for(uword j=0; j < N; ++j) + { + const eT& A_jj = A_col[j]; + const T A_jj_real = std::real(A_jj); + const T A_jj_imag = std::imag(A_jj); + + if( (A_jj_real <= T(0)) || (std::abs(A_jj_imag) > tol) ) { is_approx_sympd = false; } + + max_diag = (A_jj_real > max_diag) ? A_jj_real : max_diag; + + A_col += N; + } + + const T square_max_diag = max_diag * max_diag; + + if(arma_isfinite(square_max_diag) == false) { is_approx_sympd = false; } + + A_col = A_mem; + + const uword Nm1 = N-1; + const uword Np1 = N+1; + + for(uword j=0; j < Nm1; ++j) + { + const uword jp1 = j+1; + const eT* A_ji_ptr = &(A_mem[j + jp1*N]); // &(A.at(j,jp1)); + const eT* A_ii_ptr = &(A_mem[jp1 + jp1*N]); + + const T A_jj_real = std::real(A_col[j]); + + for(uword i=jp1; i < N; ++i) + { + const eT& A_ij = A_col[i]; + const T A_ij_real = std::real(A_ij); + const T A_ij_imag = std::imag(A_ij); + + const T A_ij_real_abs = (std::abs)(A_ij_real); + const T A_ij_imag_abs = (std::abs)(A_ij_imag); + + const eT& A_ji = (*A_ji_ptr); + const T A_ji_real = std::real(A_ji); + const T A_ji_imag = std::imag(A_ji); + + const T A_ji_real_abs = (std::abs)(A_ji_real); + const T A_ji_imag_abs = (std::abs)(A_ji_imag); + + const T A_real_delta = (std::abs)(A_ij_real - A_ji_real); + const T A_real_abs_max = (std::max)(A_ij_real_abs, A_ji_real_abs); + + if( (A_real_delta > tol) && (A_real_delta > (A_real_abs_max*tol)) ) { is_approx_sym = false; return; } + + const T A_imag_delta = (std::abs)(A_ij_imag + A_ji_imag); // take into account complex conjugate + const T A_imag_abs_max = (std::max)(A_ij_imag_abs, A_ji_imag_abs); + + if( (A_imag_delta > tol) && (A_imag_delta > (A_imag_abs_max*tol)) ) { is_approx_sym = false; return; } + + if(is_approx_sympd) + { + // avoid using std::abs(), as that is time consuming due to division and std::sqrt() + const T square_A_ij_abs = (A_ij_real * A_ij_real) + (A_ij_imag * A_ij_imag); + + if(arma_isfinite(square_A_ij_abs) == false) + { + is_approx_sympd = false; + } + else + { + const T A_ii_real = std::real(*A_ii_ptr); + + if( (A_ij_real_abs + A_ij_real_abs) >= (A_ii_real + A_jj_real) ) { is_approx_sympd = false; } + + if(square_A_ij_abs >= square_max_diag) { is_approx_sympd = false; } + } + } + + A_ji_ptr += N; + A_ii_ptr += Np1; + } + + A_col += N; + } + } + + + +template +inline +void +analyse_matrix(bool& is_approx_sym, bool& is_approx_sympd, const Mat& A) + { + arma_extra_debug_sigprint(); + + if((A.n_rows != A.n_cols) || (A.n_rows < uword(4))) + { + is_approx_sym = false; + is_approx_sympd = false; + return; + } + + analyse_matrix_worker(is_approx_sym, is_approx_sympd, A); + + if(is_approx_sym == false) { is_approx_sympd = false; } + } + + } // end of namespace sympd_helper diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/traits.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/traits.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/traits.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/traits.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -37,7 +39,7 @@ template static yes& check(typename X::Mat_fixed_type*); template static no& check(...); - static const bool value = ( sizeof(check(0)) == sizeof(yes) ); + static constexpr bool value = ( sizeof(check(0)) == sizeof(yes) ); }; @@ -51,7 +53,7 @@ template static yes& check(typename X::Row_fixed_type*); template static no& check(...); - static const bool value = ( sizeof(check(0)) == sizeof(yes) ); + static constexpr bool value = ( sizeof(check(0)) == sizeof(yes) ); }; @@ -65,165 +67,178 @@ template static yes& check(typename X::Col_fixed_type*); template static no& check(...); - static const bool value = ( sizeof(check(0)) == sizeof(yes) ); + static constexpr bool value = ( sizeof(check(0)) == sizeof(yes) ); }; template struct is_Mat_fixed - { static const bool value = ( is_Mat_fixed_only::value || is_Row_fixed_only::value || is_Col_fixed_only::value ); }; + { static constexpr bool value = ( is_Mat_fixed_only::value || is_Row_fixed_only::value || is_Col_fixed_only::value ); }; template struct is_Mat_only - { static const bool value = is_Mat_fixed_only::value; }; + { static constexpr bool value = is_Mat_fixed_only::value; }; template struct is_Mat_only< Mat > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Mat_only< const Mat > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Mat - { static const bool value = ( is_Mat_fixed_only::value || is_Row_fixed_only::value || is_Col_fixed_only::value ); }; + { static constexpr bool value = ( is_Mat_fixed_only::value || is_Row_fixed_only::value || is_Col_fixed_only::value ); }; template struct is_Mat< Mat > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Mat< const Mat > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Mat< Row > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Mat< const Row > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Mat< Col > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Mat< const Col > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Row - { static const bool value = is_Row_fixed_only::value; }; + { static constexpr bool value = is_Row_fixed_only::value; }; template struct is_Row< Row > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Row< const Row > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Col - { static const bool value = is_Col_fixed_only::value; }; + { static constexpr bool value = is_Col_fixed_only::value; }; template struct is_Col< Col > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Col< const Col > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_diagview - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_diagview< diagview > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_diagview< const diagview > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_subview< subview > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview< const subview > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_row - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_subview_row< subview_row > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_row< const subview_row > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_col - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_subview_col< subview_col > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_col< const subview_col > - { static const bool value = true; }; + { static constexpr bool value = true; }; + + +template +struct is_subview_cols + { static constexpr bool value = false; }; + +template +struct is_subview_cols< subview_cols > + { static constexpr bool value = true; }; + +template +struct is_subview_cols< const subview_cols > + { static constexpr bool value = true; }; template struct is_subview_elem1 - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_subview_elem1< subview_elem1 > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_elem1< const subview_elem1 > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_elem2 - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_subview_elem2< subview_elem2 > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_elem2< const subview_elem2 > - { static const bool value = true; }; + { static constexpr bool value = true; }; @@ -235,39 +250,39 @@ template struct is_Cube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_Cube< Cube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Cube< const Cube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_cube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_subview_cube< subview_cube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_cube< const subview_cube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_cube_slices - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_subview_cube_slices< subview_cube_slices > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_subview_cube_slices< const subview_cube_slices > - { static const bool value = true; }; + { static constexpr bool value = true; }; // @@ -277,119 +292,119 @@ template struct is_Gen - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_Gen< Gen > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Gen< const Gen > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Op - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_Op< Op > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Op< const Op > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_CubeToMatOp - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_CubeToMatOp< CubeToMatOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_CubeToMatOp< const CubeToMatOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpToDOp - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_SpToDOp< SpToDOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpToDOp< const SpToDOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_eOp - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_eOp< eOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_eOp< const eOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_mtOp - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_mtOp< mtOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_mtOp< const mtOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Glue - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_Glue< Glue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_Glue< const Glue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_eGlue - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_eGlue< eGlue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_eGlue< const eGlue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_mtGlue - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_mtGlue< mtGlue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_mtGlue< const mtGlue > - { static const bool value = true; }; + { static constexpr bool value = true; }; // @@ -397,29 +412,42 @@ template +struct is_glue_times + { static constexpr bool value = false; }; + +template +struct is_glue_times< Glue > + { static constexpr bool value = true; }; + +template +struct is_glue_times< const Glue > + { static constexpr bool value = true; }; + + +template struct is_glue_times_diag - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_glue_times_diag< Glue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_glue_times_diag< const Glue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_op_diagmat - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_op_diagmat< Op > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_op_diagmat< const Op > - { static const bool value = true; }; + { static constexpr bool value = true; }; // @@ -428,15 +456,15 @@ template struct is_Mat_trans - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_Mat_trans< Op > - { static const bool value = is_Mat::value; }; + { static constexpr bool value = is_Mat::value; }; template struct is_Mat_trans< Op > - { static const bool value = is_Mat::value; }; + { static constexpr bool value = is_Mat::value; }; // @@ -445,65 +473,65 @@ template struct is_GenCube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_GenCube< GenCube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_OpCube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_OpCube< OpCube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_eOpCube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_eOpCube< eOpCube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_mtOpCube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_mtOpCube< mtOpCube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_GlueCube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_GlueCube< GlueCube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_eGlueCube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_eGlueCube< eGlueCube > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_mtGlueCube - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_mtGlueCube< mtGlueCube > - { static const bool value = true; }; + { static constexpr bool value = true; }; // @@ -514,7 +542,7 @@ template struct is_arma_type2 { - static const bool value + static constexpr bool value = is_Mat::value || is_Gen::value || is_Op::value @@ -529,6 +557,7 @@ || is_subview::value || is_subview_row::value || is_subview_col::value + || is_subview_cols::value || is_subview_elem1::value || is_subview_elem2::value ; @@ -542,7 +571,7 @@ template struct is_arma_type { - static const bool value = is_arma_type2::value; + static constexpr bool value = is_arma_type2::value; }; @@ -550,7 +579,7 @@ template struct is_arma_cube_type { - static const bool value + static constexpr bool value = is_Cube::value || is_GenCube::value || is_OpCube::value @@ -574,103 +603,133 @@ template struct is_SpMat - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_SpMat< SpMat > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpMat< SpCol > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpMat< SpRow > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpRow - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_SpRow< SpRow > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpCol - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_SpCol< SpCol > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpSubview - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_SpSubview< SpSubview > - { static const bool value = true; }; + { static constexpr bool value = true; }; + + +template +struct is_SpSubview_col + { static constexpr bool value = false; }; + +template +struct is_SpSubview_col< SpSubview_col > + { static constexpr bool value = true; }; + + +template +struct is_SpSubview_col_list + { static constexpr bool value = false; }; + +template +struct is_SpSubview_col_list< SpSubview_col_list > + { static constexpr bool value = true; }; + + +template +struct is_SpSubview_row + { static constexpr bool value = false; }; + +template +struct is_SpSubview_row< SpSubview_row > + { static constexpr bool value = true; }; template struct is_spdiagview - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_spdiagview< spdiagview > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpOp - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_SpOp< SpOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_SpGlue - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_SpGlue< SpGlue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_mtSpOp - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_mtSpOp< mtSpOp > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_mtSpGlue - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_mtSpGlue< mtSpGlue > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_arma_sparse_type { - static const bool value + static constexpr bool value = is_SpMat::value || is_SpSubview::value + || is_SpSubview_col::value + || is_SpSubview_col_list::value + || is_SpSubview_row::value || is_spdiagview::value || is_SpOp::value || is_SpGlue::value @@ -689,18 +748,18 @@ template struct is_same_type { - static const bool value = false; - static const bool yes = false; - static const bool no = true; + static constexpr bool value = false; + static constexpr bool yes = false; + static constexpr bool no = true; }; template struct is_same_type { - static const bool value = true; - static const bool yes = true; - static const bool no = false; + static constexpr bool value = true; + static constexpr bool yes = true; + static constexpr bool no = false; }; @@ -712,196 +771,206 @@ template struct is_u8 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_u8 - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_s8 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_s8 - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_u16 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_u16 - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_s16 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_s16 - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_u32 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_u32 - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_s32 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_s32 - { static const bool value = true; }; + { static constexpr bool value = true; }; -#if defined(ARMA_USE_U64S64) - template - struct is_u64 - { static const bool value = false; }; +template +struct is_u64 + { static constexpr bool value = false; }; - template<> - struct is_u64 - { static const bool value = true; }; - - - template - struct is_s64 - { static const bool value = false; }; - - template<> - struct is_s64 - { static const bool value = true; }; -#endif +template<> +struct is_u64 + { static constexpr bool value = true; }; + + +template +struct is_s64 + { static constexpr bool value = false; }; + +template<> +struct is_s64 + { static constexpr bool value = true; }; template struct is_ulng_t - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_ulng_t - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_slng_t - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_slng_t - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_ulng_t_32 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_ulng_t_32 - { static const bool value = (sizeof(ulng_t) == 4); }; + { static constexpr bool value = (sizeof(ulng_t) == 4); }; template struct is_slng_t_32 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_slng_t_32 - { static const bool value = (sizeof(slng_t) == 4); }; + { static constexpr bool value = (sizeof(slng_t) == 4); }; template struct is_ulng_t_64 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_ulng_t_64 - { static const bool value = (sizeof(ulng_t) == 8); }; + { static constexpr bool value = (sizeof(ulng_t) == 8); }; template struct is_slng_t_64 - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_slng_t_64 - { static const bool value = (sizeof(slng_t) == 8); }; + { static constexpr bool value = (sizeof(slng_t) == 8); }; template struct is_uword - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_uword - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_sword - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_sword - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_float - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_float - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_double - { static const bool value = false; }; + { static constexpr bool value = false; }; template<> struct is_double - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct is_real - { static const bool value = false; }; + { + static constexpr bool value = false; + static constexpr bool yes = false; + static constexpr bool no = true; + }; template<> struct is_real - { static const bool value = true; }; + { + static constexpr bool value = true; + static constexpr bool yes = true; + static constexpr bool no = false; + }; template<> struct is_real - { static const bool value = true; }; + { + static constexpr bool value = true; + static constexpr bool yes = true; + static constexpr bool no = false; + }; @@ -909,18 +978,18 @@ template struct is_cx { - static const bool value = false; - static const bool yes = false; - static const bool no = true; + static constexpr bool value = false; + static constexpr bool yes = false; + static constexpr bool no = true; }; // template<> template struct is_cx< std::complex > { - static const bool value = true; - static const bool yes = true; - static const bool no = false; + static constexpr bool value = true; + static constexpr bool yes = true; + static constexpr bool no = false; }; @@ -928,17 +997,17 @@ template struct is_cx_float { - static const bool value = false; - static const bool yes = false; - static const bool no = true; + static constexpr bool value = false; + static constexpr bool yes = false; + static constexpr bool no = true; }; template<> struct is_cx_float< std::complex > { - static const bool value = true; - static const bool yes = true; - static const bool no = false; + static constexpr bool value = true; + static constexpr bool yes = true; + static constexpr bool no = false; }; @@ -946,17 +1015,17 @@ template struct is_cx_double { - static const bool value = false; - static const bool yes = false; - static const bool no = true; + static constexpr bool value = false; + static constexpr bool yes = false; + static constexpr bool no = true; }; template<> struct is_cx_double< std::complex > { - static const bool value = true; - static const bool yes = true; - static const bool no = false; + static constexpr bool value = true; + static constexpr bool yes = true; + static constexpr bool no = false; }; @@ -964,21 +1033,17 @@ template struct is_supported_elem_type { - static const bool value = \ + static constexpr bool value = \ is_u8::value || is_s8::value || is_u16::value || is_s16::value || is_u32::value || is_s32::value || -#if defined(ARMA_USE_U64S64) is_u64::value || is_s64::value || -#endif -#if defined(ARMA_ALLOW_LONG) is_ulng_t::value || is_slng_t::value || -#endif is_float::value || is_double::value || is_cx_float::value || @@ -990,7 +1055,7 @@ template struct is_supported_blas_type { - static const bool value = \ + static constexpr bool value = \ is_float::value || is_double::value || is_cx_float::value || @@ -1002,32 +1067,28 @@ template struct is_signed { - static const bool value = true; + static constexpr bool value = true; }; -template<> struct is_signed { static const bool value = false; }; -template<> struct is_signed { static const bool value = false; }; -template<> struct is_signed { static const bool value = false; }; -#if defined(ARMA_USE_U64S64) -template<> struct is_signed { static const bool value = false; }; -#endif -#if defined(ARMA_ALLOW_LONG) -template<> struct is_signed { static const bool value = false; }; -#endif +template<> struct is_signed { static constexpr bool value = false; }; +template<> struct is_signed { static constexpr bool value = false; }; +template<> struct is_signed { static constexpr bool value = false; }; +template<> struct is_signed { static constexpr bool value = false; }; +template<> struct is_signed { static constexpr bool value = false; }; template struct is_non_integral { - static const bool value = false; + static constexpr bool value = false; }; -template<> struct is_non_integral< float > { static const bool value = true; }; -template<> struct is_non_integral< double > { static const bool value = true; }; -template<> struct is_non_integral< std::complex > { static const bool value = true; }; -template<> struct is_non_integral< std::complex > { static const bool value = true; }; +template<> struct is_non_integral< float > { static constexpr bool value = true; }; +template<> struct is_non_integral< double > { static constexpr bool value = true; }; +template<> struct is_non_integral< std::complex > { static constexpr bool value = true; }; +template<> struct is_non_integral< std::complex > { static constexpr bool value = true; }; @@ -1059,17 +1120,17 @@ template struct resolves_to_vector_default { - static const bool value = false; - static const bool yes = false; - static const bool no = true; + static constexpr bool value = false; + static constexpr bool yes = false; + static constexpr bool no = true; }; template struct resolves_to_vector_test { - static const bool value = (T1::is_col || T1::is_row || T1::is_xvec); - static const bool yes = (T1::is_col || T1::is_row || T1::is_xvec); - static const bool no = ((T1::is_col || T1::is_row || T1::is_xvec) == false); + static constexpr bool value = (T1::is_col || T1::is_row || T1::is_xvec); + static constexpr bool yes = (T1::is_col || T1::is_row || T1::is_xvec); + static constexpr bool no = ((T1::is_col || T1::is_row || T1::is_xvec) == false); }; @@ -1092,10 +1153,10 @@ // template -struct resolves_to_rowvector_default { static const bool value = false; }; +struct resolves_to_rowvector_default { static constexpr bool value = false; }; template -struct resolves_to_rowvector_test { static const bool value = T1::is_row; }; +struct resolves_to_rowvector_test { static constexpr bool value = T1::is_row; }; template @@ -1114,10 +1175,10 @@ // template -struct resolves_to_colvector_default { static const bool value = false; }; +struct resolves_to_colvector_default { static constexpr bool value = false; }; template -struct resolves_to_colvector_test { static const bool value = T1::is_col; }; +struct resolves_to_colvector_test { static constexpr bool value = T1::is_col; }; template @@ -1137,47 +1198,47 @@ template struct is_outer_product - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct is_outer_product< Glue > - { static const bool value = (resolves_to_colvector::value && resolves_to_rowvector::value); }; + { static constexpr bool value = (resolves_to_colvector::value && resolves_to_rowvector::value); }; template struct has_op_inv - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct has_op_inv< Op > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct has_op_inv< Glue, T2, glue_times> > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct has_op_inv< Glue, glue_times> > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct has_op_inv_sympd - { static const bool value = false; }; + { static constexpr bool value = false; }; template struct has_op_inv_sympd< Op > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct has_op_inv_sympd< Glue, T2, glue_times> > - { static const bool value = true; }; + { static constexpr bool value = true; }; template struct has_op_inv_sympd< Glue, glue_times> > - { static const bool value = true; }; + { static constexpr bool value = true; }; @@ -1190,7 +1251,7 @@ template static yes& check(typename X::template traits*); template static no& check(...); - static const bool value = ( sizeof(check(0)) == sizeof(yes) ); + static constexpr bool value = ( sizeof(check(0)) == sizeof(yes) ); }; template @@ -1202,7 +1263,7 @@ template static yes& check(typename X::template traits*); template static no& check(...); - static const bool value = ( sizeof(check(0)) == sizeof(yes) ); + static constexpr bool value = ( sizeof(check(0)) == sizeof(yes) ); }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/translate_arpack.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/translate_arpack.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/translate_arpack.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/translate_arpack.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -33,12 +35,12 @@ #if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS) if( is_float::value) { typedef float T; arma_ignore(rwork); arma_fortran(arma_snaupd)(ido, bmat, n, which, nev, (T*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, info, 1, 1); } else if( is_double::value) { typedef double T; arma_ignore(rwork); arma_fortran(arma_dnaupd)(ido, bmat, n, which, nev, (T*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, info, 1, 1); } - else if (is_cx_float::value) { typedef cx_float T; typedef float xT; arma_fortran(arma_cnaupd)(ido, bmat, n, which, nev, (xT*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, (xT*) rwork, info, 1, 1); } + else if( is_cx_float::value) { typedef cx_float T; typedef float xT; arma_fortran(arma_cnaupd)(ido, bmat, n, which, nev, (xT*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, (xT*) rwork, info, 1, 1); } else if(is_cx_double::value) { typedef cx_double T; typedef double xT; arma_fortran(arma_znaupd)(ido, bmat, n, which, nev, (xT*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, (xT*) rwork, info, 1, 1); } #else if( is_float::value) { typedef float T; arma_ignore(rwork); arma_fortran(arma_snaupd)(ido, bmat, n, which, nev, (T*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, info); } else if( is_double::value) { typedef double T; arma_ignore(rwork); arma_fortran(arma_dnaupd)(ido, bmat, n, which, nev, (T*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, info); } - else if (is_cx_float::value) { typedef cx_float T; typedef float xT; arma_fortran(arma_cnaupd)(ido, bmat, n, which, nev, (xT*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, (xT*) rwork, info); } + else if( is_cx_float::value) { typedef cx_float T; typedef float xT; arma_fortran(arma_cnaupd)(ido, bmat, n, which, nev, (xT*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, (xT*) rwork, info); } else if(is_cx_double::value) { typedef cx_double T; typedef double xT; arma_fortran(arma_znaupd)(ido, bmat, n, which, nev, (xT*) tol, (T*) resid, ncv, (T*) v, ldv, iparam, ipntr, (T*) workd, (T*) workl, lworkl, (xT*) rwork, info); } #endif } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/translate_atlas.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/translate_atlas.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/translate_atlas.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/translate_atlas.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/translate_blas.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/translate_blas.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/translate_blas.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/translate_blas.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/translate_lapack.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/translate_lapack.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/translate_lapack.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/translate_lapack.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -411,6 +413,32 @@ template inline void + geqp3(blas_int* m, blas_int* n, eT* a, blas_int* lda, blas_int* jpvt, eT* tau, eT* work, blas_int* lwork, blas_int* info) + { + arma_type_check(( is_supported_blas_type::value == false )); + + if( is_float::value) { typedef float T; arma_fortran(arma_sgeqp3)(m, n, (T*)a, lda, jpvt, (T*)tau, (T*)work, lwork, info); } + else if(is_double::value) { typedef double T; arma_fortran(arma_dgeqp3)(m, n, (T*)a, lda, jpvt, (T*)tau, (T*)work, lwork, info); } + } + + + + template + inline + void + cx_geqp3(blas_int* m, blas_int* n, eT* a, blas_int* lda, blas_int* jpvt, eT* tau, eT* work, blas_int* lwork, typename eT::value_type* rwork, blas_int* info) + { + arma_type_check(( is_supported_blas_type::value == false )); + + if( is_cx_float::value) { typedef float T; typedef blas_cxf cx_T; arma_fortran(arma_cgeqp3)(m, n, (cx_T*)a, lda, jpvt, (cx_T*)tau, (cx_T*)work, lwork, (T*)rwork, info); } + else if(is_cx_double::value) { typedef double T; typedef blas_cxd cx_T; arma_fortran(arma_zgeqp3)(m, n, (cx_T*)a, lda, jpvt, (cx_T*)tau, (cx_T*)work, lwork, (T*)rwork, info); } + } + + + + template + inline + void orgqr(blas_int* m, blas_int* n, blas_int* k, eT* a, blas_int* lda, eT* tau, eT* work, blas_int* lwork, blas_int* info) { arma_type_check(( is_supported_blas_type::value == false )); @@ -418,8 +446,8 @@ if( is_float::value) { typedef float T; arma_fortran(arma_sorgqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info); } else if(is_double::value) { typedef double T; arma_fortran(arma_dorgqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info); } } - - + + template inline @@ -1303,6 +1331,28 @@ } + + template + inline + void + pstrf(const char* uplo, const blas_int* n, eT* a, const blas_int* lda, blas_int* piv, blas_int* rank, const typename get_pod_type::result* tol, const typename get_pod_type::result* work, blas_int* info) + { + arma_type_check(( is_supported_blas_type::value == false )); + + #if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS) + if( is_float::value) { typedef float pod_T; typedef float T; arma_fortran(arma_spstrf)(uplo, n, (T*)a, lda, piv, rank, (const pod_T*)tol, (pod_T*)work, info, 1); } + else if( is_double::value) { typedef double pod_T; typedef double T; arma_fortran(arma_dpstrf)(uplo, n, (T*)a, lda, piv, rank, (const pod_T*)tol, (pod_T*)work, info, 1); } + else if( is_cx_float::value) { typedef float pod_T; typedef blas_cxf T; arma_fortran(arma_cpstrf)(uplo, n, (T*)a, lda, piv, rank, (const pod_T*)tol, (pod_T*)work, info, 1); } + else if(is_cx_double::value) { typedef double pod_T; typedef blas_cxd T; arma_fortran(arma_zpstrf)(uplo, n, (T*)a, lda, piv, rank, (const pod_T*)tol, (pod_T*)work, info, 1); } + #else + if( is_float::value) { typedef float pod_T; typedef float T; arma_fortran(arma_spstrf)(uplo, n, (T*)a, lda, piv, rank, (const pod_T*)tol, (pod_T*)work, info); } + else if( is_double::value) { typedef double pod_T; typedef double T; arma_fortran(arma_dpstrf)(uplo, n, (T*)a, lda, piv, rank, (const pod_T*)tol, (pod_T*)work, info); } + else if( is_cx_float::value) { typedef float pod_T; typedef blas_cxf T; arma_fortran(arma_cpstrf)(uplo, n, (T*)a, lda, piv, rank, (const pod_T*)tol, (pod_T*)work, info); } + else if(is_cx_double::value) { typedef double pod_T; typedef blas_cxd T; arma_fortran(arma_zpstrf)(uplo, n, (T*)a, lda, piv, rank, (const pod_T*)tol, (pod_T*)work, info); } + #endif + } + + } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/translate_superlu.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/translate_superlu.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/translate_superlu.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/translate_superlu.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -97,6 +99,146 @@ + template + inline + void + gstrf(superlu_options_t* options, + SuperMatrix* A, + int relax, + int panel_size, int *etree, + void *work, int lwork, + int* perm_c, int* perm_r, + SuperMatrix* L, SuperMatrix* U, + GlobalLU_t* Glu, SuperLUStat_t* stat, int* info + ) + { + arma_type_check(( is_supported_blas_type::value == false )); + + if(is_float::value) + { + arma_wrapper(sgstrf)(options, A, relax, panel_size, etree, work, lwork, perm_c, perm_r, L, U, Glu, stat, info); + } + else + if(is_double::value) + { + arma_wrapper(dgstrf)(options, A, relax, panel_size, etree, work, lwork, perm_c, perm_r, L, U, Glu, stat, info); + } + else + if(is_cx_float::value) + { + arma_wrapper(cgstrf)(options, A, relax, panel_size, etree, work, lwork, perm_c, perm_r, L, U, Glu, stat, info); + } + else + if(is_cx_double::value) + { + arma_wrapper(zgstrf)(options, A, relax, panel_size, etree, work, lwork, perm_c, perm_r, L, U, Glu, stat, info); + } + } + + + + template + inline + void + gstrs(trans_t trans, + SuperMatrix* L, SuperMatrix* U, + int* perm_c, int* perm_r, + SuperMatrix* B, SuperLUStat_t* stat, int* info + ) + { + arma_type_check(( is_supported_blas_type::value == false )); + + if(is_float::value) + { + arma_wrapper(sgstrs)(trans, L, U, perm_c, perm_r, B, stat, info); + } + else + if(is_double::value) + { + arma_wrapper(dgstrs)(trans, L, U, perm_c, perm_r, B, stat, info); + } + else + if(is_cx_float::value) + { + arma_wrapper(cgstrs)(trans, L, U, perm_c, perm_r, B, stat, info); + } + else + if(is_cx_double::value) + { + arma_wrapper(zgstrs)(trans, L, U, perm_c, perm_r, B, stat, info); + } + } + + + + template + inline + typename get_pod_type::result + langs(char* norm, superlu::SuperMatrix* A) + { + arma_type_check(( is_supported_blas_type::value == false )); + + typedef typename get_pod_type::result T; + + if(is_float::value) + { + return arma_wrapper(slangs)(norm, A); + } + else + if(is_double::value) + { + return arma_wrapper(dlangs)(norm, A); + } + else + if(is_cx_float::value) + { + return arma_wrapper(clangs)(norm, A); + } + else + if(is_cx_double::value) + { + return arma_wrapper(zlangs)(norm, A); + } + + return T(0); // to avoid false warnigns from the compiler + } + + + + template + inline + void + gscon(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, typename get_pod_type::result anorm, typename get_pod_type::result* rcond, superlu::SuperLUStat_t* stat, int* info) + { + arma_type_check(( is_supported_blas_type::value == false )); + + if(is_float::value) + { + typedef float T; + arma_wrapper(sgscon)(norm, L, U, (T)anorm, (T*)rcond, stat, info); + } + else + if(is_double::value) + { + typedef double T; + arma_wrapper(dgscon)(norm, L, U, (T)anorm, (T*)rcond, stat, info); + } + else + if(is_cx_float::value) + { + typedef float T; + arma_wrapper(cgscon)(norm, L, U, (T)anorm, (T*)rcond, stat, info); + } + else + if(is_cx_double::value) + { + typedef double T; + arma_wrapper(zgscon)(norm, L, U, (T)anorm, (T*)rcond, stat, info); + } + } + + + inline void init_stat(SuperLUStat_t* stat) @@ -122,7 +264,33 @@ } - + inline + void + get_permutation_c(int ispec, SuperMatrix* A, int* perm_c) + { + arma_wrapper(get_perm_c)(ispec, A, perm_c); + } + + + + inline + void + sp_preorder_mat(superlu_options_t* opts, SuperMatrix* A, int* perm_c, int* etree, SuperMatrix* AC) + { + arma_wrapper(sp_preorder)(opts, A, perm_c, etree, AC); + } + + + + inline + int + sp_ispec_environ(int ispec) + { + return arma_wrapper(sp_ienv)(ispec); + } + + + inline void destroy_supernode_mat(SuperMatrix* a) @@ -140,6 +308,15 @@ } + + inline + void + destroy_compcolperm_mat(SuperMatrix* a) + { + arma_wrapper(Destroy_CompCol_Permuted)(a); + } + + inline void diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/trimat_helper.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/trimat_helper.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/trimat_helper.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/trimat_helper.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -37,19 +39,15 @@ if(N < 2) { return false; } - const eT* A_mem = A.memptr(); + const eT* A_col = A.memptr(); const eT eT_zero = eT(0); - // quickly check bottom-left corner - const eT* A_col0 = A_mem; - const eT* A_col1 = A_col0 + N; + // quickly check element at bottom-left - if( (A_col0[N-2] != eT_zero) || (A_col0[Nm1] != eT_zero) || (A_col1[Nm1] != eT_zero) ) { return false; } + if(A_col[Nm1] != eT_zero) { return false; } // if we got to this point, do a thorough check - const eT* A_col = A_mem; - for(uword j=0; j < Nm1; ++j) { for(uword i=(j+1); i < N; ++i) @@ -82,11 +80,11 @@ const eT eT_zero = eT(0); - // quickly check top-right corner - const eT* A_colNm2 = A.colptr(N-2); - const eT* A_colNm1 = A_colNm2 + N; + // quickly check element at top-right + + const eT* A_colNm1 = A.colptr(N-1); - if( (A_colNm2[0] != eT_zero) || (A_colNm1[0] != eT_zero) || (A_colNm1[1] != eT_zero) ) { return false; } + if(A_colNm1[0] != eT_zero) { return false; } // if we got to this point, do a thorough check diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/typedef_elem_check.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/typedef_elem_check.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/typedef_elem_check.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/typedef_elem_check.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -22,29 +24,23 @@ { struct arma_elem_size_test { + arma_static_check( (sizeof(u8) != 1), "error: type 'u8' has unsupported size" ); + arma_static_check( (sizeof(s8) != 1), "error: type 's8' has unsupported size" ); - // arma_static_check( (sizeof(size_t) < sizeof(uword)), ERROR___TYPE_SIZE_T_IS_SMALLER_THAN_UWORD ); - - arma_static_check( (sizeof(u8) != 1), ERROR___TYPE_U8_HAS_UNSUPPORTED_SIZE ); - arma_static_check( (sizeof(s8) != 1), ERROR___TYPE_S8_HAS_UNSUPPORTED_SIZE ); - - arma_static_check( (sizeof(u16) != 2), ERROR___TYPE_U16_HAS_UNSUPPORTED_SIZE ); - arma_static_check( (sizeof(s16) != 2), ERROR___TYPE_S16_HAS_UNSUPPORTED_SIZE ); - - arma_static_check( (sizeof(u32) != 4), ERROR___TYPE_U32_HAS_UNSUPPORTED_SIZE ); - arma_static_check( (sizeof(s32) != 4), ERROR___TYPE_S32_HAS_UNSUPPORTED_SIZE ); + arma_static_check( (sizeof(u16) != 2), "error: type 'u16' has unsupported size" ); + arma_static_check( (sizeof(s16) != 2), "error: type 's16' has unsupported size" ); - #if defined(ARMA_USE_U64S64) - arma_static_check( (sizeof(u64) != 8), ERROR___TYPE_U64_HAS_UNSUPPORTED_SIZE ); - arma_static_check( (sizeof(s64) != 8), ERROR___TYPE_S64_HAS_UNSUPPORTED_SIZE ); - #endif + arma_static_check( (sizeof(u32) != 4), "error: type 'u32' has unsupported size" ); + arma_static_check( (sizeof(s32) != 4), "error: type 's32' has unsupported size" ); - arma_static_check( (sizeof(float) != 4), ERROR___TYPE_FLOAT_HAS_UNSUPPORTED_SIZE ); - arma_static_check( (sizeof(double) != 8), ERROR___TYPE_DOUBLE_HAS_UNSUPPORTED_SIZE ); + arma_static_check( (sizeof(u64) != 8), "error: type 'u64' has unsupported size" ); + arma_static_check( (sizeof(s64) != 8), "error: type 's64' has unsupported size" ); - arma_static_check( (sizeof(std::complex) != 8), ERROR___TYPE_COMPLEX_FLOAT_HAS_UNSUPPORTED_SIZE ); - arma_static_check( (sizeof(std::complex) != 16), ERROR___TYPE_COMPLEX_DOUBLE_HAS_UNSUPPORTED_SIZE ); + arma_static_check( (sizeof(float) != 4), "error: type 'float' has unsupported size" ); + arma_static_check( (sizeof(double) != 8), "error: type 'double' has unsupported size" ); + arma_static_check( (sizeof(std::complex) != 8), "type 'std::complex' has unsupported size" ); + arma_static_check( (sizeof(std::complex) != 16), "type 'std::complex' has unsupported size" ); }; } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/typedef_elem.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/typedef_elem.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/typedef_elem.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/typedef_elem.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -60,28 +62,18 @@ #endif -#if defined(ARMA_USE_U64S64) - #if ULLONG_MAX >= 0xffffffffffffffff - typedef unsigned long long u64; - typedef long long s64; - #elif ULONG_MAX >= 0xffffffffffffffff - typedef unsigned long u64; - typedef long s64; - #define ARMA_U64_IS_LONG - #elif defined(UINT64_MAX) - typedef uint64_t u64; - typedef int64_t s64; - #else - #error "don't know how to typedef 'u64' on this system; please disable ARMA_64BIT_WORD" - #endif -#endif - - -#if !defined(ARMA_USE_U64S64) || (defined(ARMA_USE_U64S64) && !defined(ARMA_U64_IS_LONG)) - #define ARMA_ALLOW_LONG +#if ULLONG_MAX >= 0xffffffffffffffff + typedef unsigned long long u64; + typedef long long s64; +#elif defined(UINT64_MAX) + typedef uint64_t u64; + typedef int64_t s64; +#else + #error "don't know how to typedef 'u64' on this system" #endif +// for compatibility with earlier versions of Armadillo typedef unsigned long ulng_t; typedef long slng_t; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/typedef_mat_fixed.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/typedef_mat_fixed.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/typedef_mat_fixed.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/typedef_mat_fixed.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/typedef_mat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/typedef_mat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/typedef_mat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/typedef_mat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -36,19 +38,17 @@ typedef Row s32_rowvec; typedef Cube s32_cube; -#if defined(ARMA_USE_U64S64) - typedef Mat u64_mat; - typedef Col u64_vec; - typedef Col u64_colvec; - typedef Row u64_rowvec; - typedef Cube u64_cube; - - typedef Mat s64_mat; - typedef Col s64_vec; - typedef Col s64_colvec; - typedef Row s64_rowvec; - typedef Cube s64_cube; -#endif +typedef Mat u64_mat; +typedef Col u64_vec; +typedef Col u64_colvec; +typedef Row u64_rowvec; +typedef Cube u64_cube; + +typedef Mat s64_mat; +typedef Col s64_vec; +typedef Col s64_colvec; +typedef Row s64_rowvec; +typedef Cube s64_cube; typedef Mat umat; typedef Col uvec; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/unwrap_cube.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/unwrap_cube.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/unwrap_cube.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/unwrap_cube.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -34,7 +36,7 @@ const Cube M; template - arma_inline bool is_alias(const Cube&) const { return false; } + constexpr bool is_alias(const Cube&) const { return false; } }; @@ -77,6 +79,15 @@ arma_type_check(( is_arma_cube_type::value == false )); } + inline + unwrap_cube_check(const T1& A, const bool) + : M(A) + { + arma_extra_debug_sigprint(); + + arma_type_check(( is_arma_cube_type::value == false )); + } + const Cube M; }; @@ -87,8 +98,17 @@ { inline unwrap_cube_check(const Cube& A, const Cube& B) - : M_local( (&A == &B) ? new Cube(A) : 0 ) - , M ( (&A == &B) ? (*M_local) : A ) + : M_local( (&A == &B) ? new Cube(A) : nullptr ) + , M ( (&A == &B) ? (*M_local) : A ) + { + arma_extra_debug_sigprint(); + } + + + inline + unwrap_cube_check(const Cube& A, const bool is_alias) + : M_local( is_alias ? new Cube(A) : nullptr ) + , M ( is_alias ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -99,10 +119,7 @@ { arma_extra_debug_sigprint(); - if(M_local) - { - delete M_local; - } + if(M_local) { delete M_local; } } diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/unwrap.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/unwrap.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/unwrap.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/unwrap.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -68,11 +70,11 @@ template -struct unwrap : public unwrap_redirect::value >::result +struct unwrap : public unwrap_redirect::value>::result { inline unwrap(const T1& A) - : unwrap_redirect< T1, is_Mat_fixed::value >::result(A) + : unwrap_redirect::value>::result(A) { } }; @@ -130,6 +132,40 @@ +template +struct unwrap< subview_col > + { + typedef Col stored_type; + + inline + unwrap(const subview_col& A) + : M(A.colmem, A.n_rows) + { + arma_extra_debug_sigprint(); + } + + const Col M; + }; + + + +template +struct unwrap< subview_cols > + { + typedef Mat stored_type; + + inline + unwrap(const subview_cols& A) + : M(A.colptr(0), A.n_rows, A.n_cols) + { + arma_extra_debug_sigprint(); + } + + const Mat M; + }; + + + template struct unwrap< mtGlue > { @@ -185,12 +221,12 @@ // NOTE: DO NOT DIRECTLY CHECK FOR ALIASING BY TAKING THE ADDRESS OF THE "M" OBJECT IN ANY quasi_unwrap CLASS !!! Mat M; - static const bool is_const = false; - static const bool has_subview = false; - static const bool has_orig_mem = false; + static constexpr bool is_const = false; + static constexpr bool has_subview = false; + static constexpr bool has_orig_mem = false; template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } }; @@ -209,9 +245,9 @@ const T1& M; - static const bool is_const = true; - static const bool has_subview = false; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = false; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } @@ -230,9 +266,9 @@ template -struct quasi_unwrap : public quasi_unwrap_redirect::value >::result +struct quasi_unwrap : public quasi_unwrap_redirect::value>::result { - typedef typename quasi_unwrap_redirect::value >::result quasi_unwrap_extra; + typedef typename quasi_unwrap_redirect::value>::result quasi_unwrap_extra; inline quasi_unwrap(const T1& A) @@ -240,9 +276,9 @@ { } - static const bool is_const = quasi_unwrap_extra::is_const; - static const bool has_subview = quasi_unwrap_extra::has_subview; - static const bool has_orig_mem = quasi_unwrap_extra::has_orig_mem; + static constexpr bool is_const = quasi_unwrap_extra::is_const; + static constexpr bool has_subview = quasi_unwrap_extra::has_subview; + static constexpr bool has_orig_mem = quasi_unwrap_extra::has_orig_mem; using quasi_unwrap_extra::M; using quasi_unwrap_extra::is_alias; @@ -262,9 +298,9 @@ const Mat& M; - static const bool is_const = true; - static const bool has_subview = false; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = false; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } @@ -285,9 +321,9 @@ const Row& M; - static const bool is_const = true; - static const bool has_subview = false; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = false; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } @@ -307,9 +343,9 @@ const Col& M; - static const bool is_const = true; - static const bool has_subview = false; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = false; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } @@ -331,9 +367,9 @@ const subview& sv; const Mat M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = false; // NOTE: set to false as this is the general case; original memory is only used when the subview is a contiguous chunk + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = false; // NOTE: set to false as this is the general case; original memory is only used when the subview is a contiguous chunk template arma_inline bool is_alias(const Mat& X) const { return ( ((sv.aux_row1 == 0) && (sv.n_rows == sv.m.n_rows)) ? (void_ptr(&(sv.m)) == void_ptr(&X)) : false ); } @@ -353,12 +389,12 @@ Row M; - static const bool is_const = false; - static const bool has_subview = false; - static const bool has_orig_mem = false; + static constexpr bool is_const = false; + static constexpr bool has_subview = false; + static constexpr bool has_orig_mem = false; template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } }; @@ -369,7 +405,7 @@ inline quasi_unwrap(const subview_col& A) : orig( A.m ) - , M ( const_cast( A.colptr(0) ), A.n_rows, false, false ) + , M ( const_cast( A.colmem ), A.n_rows, false, false ) { arma_extra_debug_sigprint(); } @@ -377,9 +413,33 @@ const Mat& orig; const Col M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; + + template + arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } + }; + + + +template +struct quasi_unwrap< subview_cols > + { + inline + quasi_unwrap(const subview_cols& A) + : orig( A.m ) + , M ( const_cast( A.colptr(0) ), A.n_rows, A.n_cols, false, false ) + { + arma_extra_debug_sigprint(); + } + + const Mat& orig; + const Mat M; + + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } @@ -399,12 +459,12 @@ Mat M; - static const bool is_const = false; - static const bool has_subview = false; - static const bool has_orig_mem = false; + static constexpr bool is_const = false; + static constexpr bool has_subview = false; + static constexpr bool has_orig_mem = false; template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } }; @@ -421,12 +481,12 @@ Mat M; - static const bool is_const = false; - static const bool has_subview = false; - static const bool has_orig_mem = false; + static constexpr bool is_const = false; + static constexpr bool has_subview = false; + static constexpr bool has_orig_mem = false; template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } }; @@ -444,15 +504,15 @@ arma_extra_debug_sigprint(); } - const unwrap U; - const Mat M; + const quasi_unwrap U; + const Mat M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template - arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&(U.M)) == void_ptr(&X)); } + arma_inline bool is_alias(const Mat& X) const { return U.is_alias(X); } }; @@ -471,9 +531,9 @@ const Col& orig; const Row M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } @@ -495,9 +555,9 @@ const Row& orig; const Col M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } @@ -511,7 +571,7 @@ inline quasi_unwrap(const Op, op_strans>& A) : orig( A.m.m ) - , M ( const_cast( A.m.colptr(0) ), A.m.n_rows, false, false ) + , M ( const_cast( A.m.colmem ), A.m.n_rows, false, false ) { arma_extra_debug_sigprint(); } @@ -519,9 +579,9 @@ const Mat& orig; const Row M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&orig)); } @@ -551,9 +611,9 @@ const Col& orig; const Row M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } @@ -583,9 +643,9 @@ { } - static const bool is_const = quasi_unwrap_Col_htrans_extra::is_const; - static const bool has_subview = quasi_unwrap_Col_htrans_extra::has_subview; - static const bool has_orig_mem = quasi_unwrap_Col_htrans_extra::has_orig_mem; + static constexpr bool is_const = quasi_unwrap_Col_htrans_extra::is_const; + static constexpr bool has_subview = quasi_unwrap_Col_htrans_extra::has_subview; + static constexpr bool has_orig_mem = quasi_unwrap_Col_htrans_extra::has_orig_mem; using quasi_unwrap_Col_htrans_extra::M; using quasi_unwrap_Col_htrans_extra::is_alias; @@ -615,9 +675,9 @@ const Row& orig; const Col M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } @@ -647,9 +707,9 @@ { } - static const bool is_const = quasi_unwrap_Row_htrans_extra::is_const; - static const bool has_subview = quasi_unwrap_Row_htrans_extra::has_subview; - static const bool has_orig_mem = quasi_unwrap_Row_htrans_extra::has_orig_mem; + static constexpr bool is_const = quasi_unwrap_Row_htrans_extra::is_const; + static constexpr bool has_subview = quasi_unwrap_Row_htrans_extra::has_subview; + static constexpr bool has_orig_mem = quasi_unwrap_Row_htrans_extra::has_orig_mem; using quasi_unwrap_Row_htrans_extra::M; using quasi_unwrap_Row_htrans_extra::is_alias; @@ -671,7 +731,7 @@ inline quasi_unwrap_subview_col_htrans(const Op, op_htrans>& A) : orig(A.m.m) - , M (const_cast(A.m.colptr(0)), A.m.n_rows, false, false) + , M (const_cast(A.m.colmem), A.m.n_rows, false, false) { arma_extra_debug_sigprint(); } @@ -679,9 +739,9 @@ const Mat& orig; const Row M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } @@ -711,9 +771,9 @@ { } - static const bool is_const = quasi_unwrap_subview_col_htrans_extra::is_const; - static const bool has_subview = quasi_unwrap_subview_col_htrans_extra::has_subview; - static const bool has_orig_mem = quasi_unwrap_subview_col_htrans_extra::has_orig_mem; + static constexpr bool is_const = quasi_unwrap_subview_col_htrans_extra::is_const; + static constexpr bool has_subview = quasi_unwrap_subview_col_htrans_extra::has_subview; + static constexpr bool has_orig_mem = quasi_unwrap_subview_col_htrans_extra::has_orig_mem; using quasi_unwrap_subview_col_htrans_extra::M; using quasi_unwrap_subview_col_htrans_extra::is_alias; @@ -737,12 +797,12 @@ const unwrap_cube U; const Mat M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } }; @@ -763,12 +823,12 @@ const unwrap_spmat U; const Mat M; - static const bool is_const = true; - static const bool has_subview = true; - static const bool has_orig_mem = true; + static constexpr bool is_const = true; + static constexpr bool has_subview = true; + static constexpr bool has_orig_mem = true; template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } }; @@ -812,16 +872,16 @@ inline unwrap_check_fixed(const T1& A, const Mat& B) - : M_local( (&A == &B) ? new T1(A) : 0 ) - , M ( (&A == &B) ? *M_local : A ) + : M_local( (&A == &B) ? new T1(A) : nullptr ) + , M ( (&A == &B) ? *M_local : A ) { arma_extra_debug_sigprint(); } inline unwrap_check_fixed(const T1& A, const bool is_alias) - : M_local( is_alias ? new T1(A) : 0 ) - , M ( is_alias ? *M_local : A ) + : M_local( is_alias ? new T1(A) : nullptr ) + , M ( is_alias ? *M_local : A ) { arma_extra_debug_sigprint(); } @@ -853,15 +913,15 @@ template -struct unwrap_check : public unwrap_check_redirect::value >::result +struct unwrap_check : public unwrap_check_redirect::value>::result { inline unwrap_check(const T1& A, const Mat& B) - : unwrap_check_redirect< T1, is_Mat_fixed::value >::result(A, B) + : unwrap_check_redirect::value>::result(A, B) { } inline unwrap_check(const T1& A, const bool is_alias) - : unwrap_check_redirect< T1, is_Mat_fixed::value >::result(A, is_alias) + : unwrap_check_redirect::value>::result(A, is_alias) { } }; @@ -875,16 +935,16 @@ inline unwrap_check(const Mat& A, const Mat& B) - : M_local( (&A == &B) ? new Mat(A) : 0 ) - , M ( (&A == &B) ? (*M_local) : A ) + : M_local( (&A == &B) ? new Mat(A) : nullptr ) + , M ( (&A == &B) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } inline unwrap_check(const Mat& A, const bool is_alias) - : M_local( is_alias ? new Mat(A) : 0 ) - , M ( is_alias ? (*M_local) : A ) + : M_local( is_alias ? new Mat(A) : nullptr ) + , M ( is_alias ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -912,16 +972,16 @@ inline unwrap_check(const Row& A, const Mat& B) - : M_local( (&A == &B) ? new Row(A) : 0 ) - , M ( (&A == &B) ? (*M_local) : A ) + : M_local( (&A == &B) ? new Row(A) : nullptr ) + , M ( (&A == &B) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } inline unwrap_check(const Row& A, const bool is_alias) - : M_local( is_alias ? new Row(A) : 0 ) - , M ( is_alias ? (*M_local) : A ) + : M_local( is_alias ? new Row(A) : nullptr ) + , M ( is_alias ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -949,16 +1009,16 @@ inline unwrap_check(const Col& A, const Mat& B) - : M_local( (&A == &B) ? new Col(A) : 0 ) - , M ( (&A == &B) ? (*M_local) : A ) + : M_local( (&A == &B) ? new Col(A) : nullptr ) + , M ( (&A == &B) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } inline unwrap_check(const Col& A, const bool is_alias) - : M_local( is_alias ? new Col(A) : 0 ) - , M ( is_alias ? (*M_local) : A ) + : M_local( is_alias ? new Col(A) : nullptr ) + , M ( is_alias ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -1017,8 +1077,8 @@ template inline unwrap_check_mixed(const Mat& A, const Mat& B) - : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Mat(A) : 0 ) - , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) + : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Mat(A) : nullptr ) + , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -1026,8 +1086,8 @@ //template inline unwrap_check_mixed(const Mat& A, const bool is_alias) - : M_local( is_alias ? new Mat(A) : 0 ) - , M ( is_alias ? (*M_local) : A ) + : M_local( is_alias ? new Mat(A) : nullptr ) + , M ( is_alias ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -1054,8 +1114,8 @@ template inline unwrap_check_mixed(const Row& A, const Mat& B) - : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Row(A) : 0 ) - , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) + : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Row(A) : nullptr ) + , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -1064,8 +1124,8 @@ //template inline unwrap_check_mixed(const Row& A, const bool is_alias) - : M_local( is_alias ? new Row(A) : 0 ) - , M ( is_alias ? (*M_local) : A ) + : M_local( is_alias ? new Row(A) : nullptr ) + , M ( is_alias ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -1092,8 +1152,8 @@ template inline unwrap_check_mixed(const Col& A, const Mat& B) - : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Col(A) : 0 ) - , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) + : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Col(A) : nullptr ) + , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -1101,8 +1161,8 @@ //template inline unwrap_check_mixed(const Col& A, const bool is_alias) - : M_local( is_alias ? new Col(A) : 0 ) - , M ( is_alias ? (*M_local) : A ) + : M_local( is_alias ? new Col(A) : nullptr ) + , M ( is_alias ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -1142,13 +1202,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const Mat M; }; @@ -1167,13 +1227,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const T1& M; }; @@ -1190,11 +1250,11 @@ struct partial_unwrap_redirect { typedef partial_unwrap_fixed result; }; template -struct partial_unwrap : public partial_unwrap_redirect::value >::result +struct partial_unwrap : public partial_unwrap_redirect::value>::result { inline partial_unwrap(const T1& A) - : partial_unwrap_redirect< T1, is_Mat_fixed::value >::result(A) + : partial_unwrap_redirect< T1, is_Mat_fixed::value>::result(A) { } }; @@ -1213,13 +1273,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const Mat& M; }; @@ -1238,13 +1298,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const Row& M; }; @@ -1263,13 +1323,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const Col& M; }; @@ -1289,13 +1349,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return ( ((sv.aux_row1 == 0) && (sv.n_rows == sv.m.n_rows)) ? (void_ptr(&(sv.m)) == void_ptr(&X)) : false ); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const subview& sv; const Mat M; @@ -1311,18 +1371,18 @@ inline partial_unwrap(const subview_col& A) : orig( A.m ) - , M ( const_cast( A.colptr(0) ), A.n_rows, false, false ) + , M ( const_cast( A.colmem ), A.n_rows, false, false ) { arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&orig)); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const Mat& orig; const Col M; @@ -1331,6 +1391,33 @@ template +struct partial_unwrap< subview_cols > + { + typedef Mat stored_type; + + inline + partial_unwrap(const subview_cols& A) + : orig( A.m ) + , M ( const_cast( A.colptr(0) ), A.n_rows, A.n_cols, false, false ) + { + arma_extra_debug_sigprint(); + } + + constexpr eT get_val() const { return eT(1); } + + template + arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&orig)); } + + static constexpr bool do_trans = false; + static constexpr bool do_times = false; + + const Mat& orig; + const Mat M; + }; + + + +template struct partial_unwrap< subview_row > { typedef Row stored_type; @@ -1342,13 +1429,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const Row M; }; @@ -1368,13 +1455,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const Mat M; }; @@ -1393,13 +1480,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const T1& M; }; @@ -1416,10 +1503,10 @@ struct partial_unwrap_htrans_redirect { typedef partial_unwrap_htrans_fixed result; }; template -struct partial_unwrap< Op > : public partial_unwrap_htrans_redirect::value >::result +struct partial_unwrap< Op > : public partial_unwrap_htrans_redirect::value>::result { inline partial_unwrap(const Op& A) - : partial_unwrap_htrans_redirect< T1, is_Mat_fixed::value >::result(A) + : partial_unwrap_htrans_redirect::value>::result(A) { } }; @@ -1438,13 +1525,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const Mat& M; }; @@ -1463,13 +1550,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const Row& M; }; @@ -1488,13 +1575,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const Col& M; }; @@ -1502,6 +1589,60 @@ template +struct partial_unwrap< Op< subview, op_htrans> > + { + typedef Mat stored_type; + + inline + partial_unwrap(const Op< subview, op_htrans>& A) + : sv( A.m ) + , M ( A.m, ((A.m.aux_row1 == 0) && (A.m.n_rows == A.m.m.n_rows)) ) // reuse memory if the subview is a contiguous chunk + { + arma_extra_debug_sigprint(); + } + + constexpr eT get_val() const { return eT(1); } + + template + arma_inline bool is_alias(const Mat& X) const { return ( ((sv.aux_row1 == 0) && (sv.n_rows == sv.m.n_rows)) ? (void_ptr(&(sv.m)) == void_ptr(&X)) : false ); } + + static constexpr bool do_trans = true; + static constexpr bool do_times = false; + + const subview& sv; + const Mat M; + }; + + + +template +struct partial_unwrap< Op< subview_cols, op_htrans> > + { + typedef Mat stored_type; + + inline + partial_unwrap(const Op< subview_cols, op_htrans>& A) + : orig( A.m.m ) + , M ( const_cast( A.m.colptr(0) ), A.m.n_rows, A.m.n_cols, false, false ) + { + arma_extra_debug_sigprint(); + } + + constexpr eT get_val() const { return eT(1); } + + template + arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } + + static constexpr bool do_trans = true; + static constexpr bool do_times = false; + + const Mat& orig; + const Mat M; + }; + + + +template struct partial_unwrap< Op< subview_col, op_htrans> > { typedef Col stored_type; @@ -1509,18 +1650,18 @@ inline partial_unwrap(const Op< subview_col, op_htrans>& A) : orig( A.m.m ) - , M ( const_cast( A.m.colptr(0) ), A.m.n_rows, false, false ) + , M ( const_cast( A.m.colmem ), A.m.n_rows, false, false ) { arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&orig)); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const Mat& orig; const Col M; @@ -1540,13 +1681,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const Row M; }; @@ -1570,10 +1711,10 @@ arma_inline eT get_val() const { return val; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const Mat M; @@ -1599,8 +1740,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const T1& M; @@ -1618,10 +1759,10 @@ struct partial_unwrap_htrans2_redirect { typedef partial_unwrap_htrans2_fixed result; }; template -struct partial_unwrap< Op > : public partial_unwrap_htrans2_redirect::value >::result +struct partial_unwrap< Op > : public partial_unwrap_htrans2_redirect::value>::result { inline partial_unwrap(const Op& A) - : partial_unwrap_htrans2_redirect< T1, is_Mat_fixed::value >::result(A) + : partial_unwrap_htrans2_redirect::value>::result(A) { } }; @@ -1646,8 +1787,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const Mat& M; @@ -1673,8 +1814,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const Row& M; @@ -1700,8 +1841,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const Col& M; @@ -1710,6 +1851,64 @@ template +struct partial_unwrap< Op< subview, op_htrans2> > + { + typedef Mat stored_type; + + inline + partial_unwrap(const Op< subview, op_htrans2>& A) + : sv ( A.m ) + , val( A.aux ) + , M ( A.m, ((A.m.aux_row1 == 0) && (A.m.n_rows == A.m.m.n_rows)) ) // reuse memory if the subview is a contiguous chunk + { + arma_extra_debug_sigprint(); + } + + inline eT get_val() const { return val; } + + template + arma_inline bool is_alias(const Mat& X) const { return ( ((sv.aux_row1 == 0) && (sv.n_rows == sv.m.n_rows)) ? (void_ptr(&(sv.m)) == void_ptr(&X)) : false ); } + + static constexpr bool do_trans = true; + static constexpr bool do_times = true; + + const subview& sv; + const eT val; + const Mat M; + }; + + + +template +struct partial_unwrap< Op< subview_cols, op_htrans2> > + { + typedef Mat stored_type; + + inline + partial_unwrap(const Op< subview_cols, op_htrans2>& A) + : orig( A.m.m ) + , val ( A.aux ) + , M ( const_cast( A.m.colptr(0) ), A.m.n_rows, A.m.n_cols, false, false ) + { + arma_extra_debug_sigprint(); + } + + inline eT get_val() const { return val; } + + template + arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&orig) == void_ptr(&X)); } + + static constexpr bool do_trans = true; + static constexpr bool do_times = true; + + const Mat& orig; + const eT val; + const Mat M; + }; + + + +template struct partial_unwrap< Op< subview_col, op_htrans2> > { typedef Col stored_type; @@ -1718,7 +1917,7 @@ partial_unwrap(const Op< subview_col, op_htrans2>& A) : orig( A.m.m ) , val ( A.aux ) - , M ( const_cast( A.m.colptr(0) ), A.m.n_rows, false, false ) + , M ( const_cast( A.m.colmem ), A.m.n_rows, false, false ) { arma_extra_debug_sigprint(); } @@ -1728,8 +1927,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&orig)); } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const Mat& orig; @@ -1755,10 +1954,10 @@ arma_inline eT get_val() const { return val; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const Row M; @@ -1783,10 +1982,10 @@ arma_inline eT get_val() const { return val; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Mat M; @@ -1813,8 +2012,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const T1& M; @@ -1833,13 +2032,13 @@ template -struct partial_unwrap< eOp > : public partial_unwrap_scalar_times_redirect::value >::result +struct partial_unwrap< eOp > : public partial_unwrap_scalar_times_redirect::value>::result { typedef typename T1::elem_type eT; inline partial_unwrap(const eOp& A) - : partial_unwrap_scalar_times_redirect< T1, is_Mat_fixed::value >::result(A) + : partial_unwrap_scalar_times_redirect< T1, is_Mat_fixed::value>::result(A) { } }; @@ -1864,8 +2063,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Mat& M; @@ -1891,8 +2090,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Row& M; @@ -1918,8 +2117,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Col& M; @@ -1936,7 +2135,7 @@ partial_unwrap(const eOp,eop_scalar_times>& A) : orig( A.P.Q.m ) , val ( A.aux ) - , M ( const_cast( A.P.Q.colptr(0) ), A.P.Q.n_rows, false, false ) + , M ( const_cast( A.P.Q.colmem ), A.P.Q.n_rows, false, false ) { arma_extra_debug_sigprint(); } @@ -1946,8 +2145,8 @@ template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&orig)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Mat& orig; @@ -1973,10 +2172,10 @@ arma_inline eT get_val() const { return val; } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Row M; @@ -1997,13 +2196,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Mat M; }; @@ -2023,13 +2222,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const T1& M; }; @@ -2047,13 +2246,13 @@ template -struct partial_unwrap< eOp > : public partial_unwrap_neg_redirect::value >::result +struct partial_unwrap< eOp > : public partial_unwrap_neg_redirect::value>::result { typedef typename T1::elem_type eT; inline partial_unwrap(const eOp& A) - : partial_unwrap_neg_redirect< T1, is_Mat_fixed::value >::result(A) + : partial_unwrap_neg_redirect< T1, is_Mat_fixed::value>::result(A) { } }; @@ -2072,13 +2271,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Mat& M; }; @@ -2097,13 +2296,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Row& M; }; @@ -2122,13 +2321,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&M)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Col& M; }; @@ -2143,18 +2342,18 @@ inline partial_unwrap(const eOp,eop_neg>& A) : orig( A.P.Q.m ) - , M ( const_cast( A.P.Q.colptr(0) ), A.P.Q.n_rows, false, false ) + , M ( const_cast( A.P.Q.colmem ), A.P.Q.n_rows, false, false ) { arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } template arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&X) == void_ptr(&orig)); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Mat& orig; const Col M; @@ -2174,13 +2373,13 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } template - arma_inline bool is_alias(const Mat&) const { return false; } + constexpr bool is_alias(const Mat&) const { return false; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Row M; }; @@ -2204,10 +2403,10 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const Mat M; }; @@ -2221,8 +2420,8 @@ inline explicit partial_unwrap_check_fixed(const T1& A, const Mat& B) - : M_local( (&A == &B) ? new T1(A) : 0 ) - , M ( (&A == &B) ? (*M_local) : A ) + : M_local( (&A == &B) ? new T1(A) : nullptr ) + , M ( (&A == &B) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -2235,10 +2434,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const T1* M_local; const T1& M; @@ -2256,12 +2455,12 @@ struct partial_unwrap_check_redirect { typedef partial_unwrap_check_fixed result; }; template -struct partial_unwrap_check : public partial_unwrap_check_redirect::value >::result +struct partial_unwrap_check : public partial_unwrap_check_redirect::value>::result { typedef typename T1::elem_type eT; inline partial_unwrap_check(const T1& A, const Mat& B) - : partial_unwrap_check_redirect< T1, is_Mat_fixed::value >::result(A, B) + : partial_unwrap_check_redirect::value>::result(A, B) { } }; @@ -2275,8 +2474,8 @@ inline partial_unwrap_check(const Mat& A, const Mat& B) - : M_local ( (&A == &B) ? new Mat(A) : 0 ) - , M ( (&A == &B) ? (*M_local) : A ) + : M_local ( (&A == &B) ? new Mat(A) : nullptr ) + , M ( (&A == &B) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -2290,10 +2489,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; // the order below is important const Mat* M_local; @@ -2309,8 +2508,8 @@ inline partial_unwrap_check(const Row& A, const Mat& B) - : M_local ( (&A == &B) ? new Row(A) : 0 ) - , M ( (&A == &B) ? (*M_local) : A ) + : M_local ( (&A == &B) ? new Row(A) : nullptr ) + , M ( (&A == &B) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -2324,10 +2523,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; // the order below is important const Row* M_local; @@ -2343,8 +2542,8 @@ inline partial_unwrap_check(const Col& A, const Mat& B) - : M_local ( (&A == &B) ? new Col(A) : 0 ) - , M ( (&A == &B) ? (*M_local) : A ) + : M_local ( (&A == &B) ? new Col(A) : nullptr ) + , M ( (&A == &B) ? (*M_local) : A ) { arma_extra_debug_sigprint(); } @@ -2358,10 +2557,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; // the order below is important const Col* M_local; @@ -2379,15 +2578,15 @@ inline partial_unwrap_check(const subview_col& A, const Mat& B) - : M ( const_cast( A.colptr(0) ), A.n_rows, (&(A.m) == &B), false ) + : M ( const_cast( A.colmem ), A.n_rows, (&(A.m) == &B), false ) { arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = false; - static const bool do_times = false; + static constexpr bool do_trans = false; + static constexpr bool do_times = false; const Col M; }; @@ -2407,10 +2606,10 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const Mat M; }; @@ -2424,8 +2623,8 @@ inline explicit partial_unwrap_check_htrans_fixed(const Op& A, const Mat& B) - : M_local( (&(A.m) == &B) ? new T1(A.m) : 0 ) - , M ( (&(A.m) == &B) ? (*M_local) : A.m ) + : M_local( (&(A.m) == &B) ? new T1(A.m) : nullptr ) + , M ( (&(A.m) == &B) ? (*M_local) : A.m ) { arma_extra_debug_sigprint(); } @@ -2438,10 +2637,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const T1* M_local; const T1& M; @@ -2460,12 +2659,12 @@ template -struct partial_unwrap_check< Op > : public partial_unwrap_check_htrans_redirect::value >::result +struct partial_unwrap_check< Op > : public partial_unwrap_check_htrans_redirect::value>::result { typedef typename T1::elem_type eT; inline partial_unwrap_check(const Op& A, const Mat& B) - : partial_unwrap_check_htrans_redirect< T1, is_Mat_fixed::value >::result(A, B) + : partial_unwrap_check_htrans_redirect::value>::result(A, B) { } }; @@ -2479,8 +2678,8 @@ inline partial_unwrap_check(const Op< Mat, op_htrans>& A, const Mat& B) - : M_local ( (&A.m == &B) ? new Mat(A.m) : 0 ) - , M ( (&A.m == &B) ? (*M_local) : A.m ) + : M_local ( (&A.m == &B) ? new Mat(A.m) : nullptr ) + , M ( (&A.m == &B) ? (*M_local) : A.m ) { arma_extra_debug_sigprint(); } @@ -2493,10 +2692,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; // the order below is important const Mat* M_local; @@ -2512,8 +2711,8 @@ inline partial_unwrap_check(const Op< Row, op_htrans>& A, const Mat& B) - : M_local ( (&A.m == &B) ? new Row(A.m) : 0 ) - , M ( (&A.m == &B) ? (*M_local) : A.m ) + : M_local ( (&A.m == &B) ? new Row(A.m) : nullptr ) + , M ( (&A.m == &B) ? (*M_local) : A.m ) { arma_extra_debug_sigprint(); } @@ -2526,10 +2725,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; // the order below is important const Row* M_local; @@ -2545,8 +2744,8 @@ inline partial_unwrap_check(const Op< Col, op_htrans>& A, const Mat& B) - : M_local ( (&A.m == &B) ? new Col(A.m) : 0 ) - , M ( (&A.m == &B) ? (*M_local) : A.m ) + : M_local ( (&A.m == &B) ? new Col(A.m) : nullptr ) + , M ( (&A.m == &B) ? (*M_local) : A.m ) { arma_extra_debug_sigprint(); } @@ -2559,10 +2758,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; // the order below is important const Col* M_local; @@ -2580,15 +2779,15 @@ inline partial_unwrap_check(const Op< subview_col, op_htrans>& A, const Mat& B) - : M ( const_cast( A.m.colptr(0) ), A.m.n_rows, (&(A.m.m) == &B), false ) + : M ( const_cast( A.m.colmem ), A.m.n_rows, (&(A.m.m) == &B), false ) { arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(1); } + constexpr eT get_val() const { return eT(1); } - static const bool do_trans = true; - static const bool do_times = false; + static constexpr bool do_trans = true; + static constexpr bool do_times = false; const Col M; }; @@ -2611,8 +2810,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const Mat M; @@ -2629,8 +2828,8 @@ inline explicit partial_unwrap_check_htrans2_fixed(const Op& A, const Mat& B) : val (A.aux) - , M_local( (&(A.m) == &B) ? new T1(A.m) : 0 ) - , M ( (&(A.m) == &B) ? (*M_local) : A.m ) + , M_local( (&(A.m) == &B) ? new T1(A.m) : nullptr ) + , M ( (&(A.m) == &B) ? (*M_local) : A.m ) { arma_extra_debug_sigprint(); } @@ -2645,8 +2844,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const T1* M_local; @@ -2666,12 +2865,12 @@ template -struct partial_unwrap_check< Op > : public partial_unwrap_check_htrans2_redirect::value >::result +struct partial_unwrap_check< Op > : public partial_unwrap_check_htrans2_redirect::value>::result { typedef typename T1::elem_type eT; inline partial_unwrap_check(const Op& A, const Mat& B) - : partial_unwrap_check_htrans2_redirect< T1, is_Mat_fixed::value >::result(A, B) + : partial_unwrap_check_htrans2_redirect::value>::result(A, B) { } }; @@ -2686,8 +2885,8 @@ inline partial_unwrap_check(const Op< Mat, op_htrans2>& A, const Mat& B) : val (A.aux) - , M_local ( (&A.m == &B) ? new Mat(A.m) : 0 ) - , M ( (&A.m == &B) ? (*M_local) : A.m ) + , M_local ( (&A.m == &B) ? new Mat(A.m) : nullptr ) + , M ( (&A.m == &B) ? (*M_local) : A.m ) { arma_extra_debug_sigprint(); } @@ -2702,8 +2901,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; // the order below is important const eT val; @@ -2721,8 +2920,8 @@ inline partial_unwrap_check(const Op< Row, op_htrans2>& A, const Mat& B) : val (A.aux) - , M_local ( (&A.m == &B) ? new Row(A.m) : 0 ) - , M ( (&A.m == &B) ? (*M_local) : A.m ) + , M_local ( (&A.m == &B) ? new Row(A.m) : nullptr ) + , M ( (&A.m == &B) ? (*M_local) : A.m ) { arma_extra_debug_sigprint(); } @@ -2737,8 +2936,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; // the order below is important const eT val; @@ -2756,8 +2955,8 @@ inline partial_unwrap_check(const Op< Col, op_htrans2>& A, const Mat& B) : val (A.aux) - , M_local ( (&A.m == &B) ? new Col(A.m) : 0 ) - , M ( (&A.m == &B) ? (*M_local) : A.m ) + , M_local ( (&A.m == &B) ? new Col(A.m) : nullptr ) + , M ( (&A.m == &B) ? (*M_local) : A.m ) { arma_extra_debug_sigprint(); } @@ -2772,8 +2971,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; // the order below is important const eT val; @@ -2793,15 +2992,15 @@ inline partial_unwrap_check(const Op< subview_col, op_htrans2>& A, const Mat& B) : val( A.aux ) - , M ( const_cast( A.m.colptr(0) ), A.m.n_rows, (&(A.m.m) == &B), false ) + , M ( const_cast( A.m.colmem ), A.m.n_rows, (&(A.m.m) == &B), false ) { arma_extra_debug_sigprint(); } arma_inline eT get_val() const { return val; } - static const bool do_trans = true; - static const bool do_times = true; + static constexpr bool do_trans = true; + static constexpr bool do_times = true; const eT val; const Col M; @@ -2825,8 +3024,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Mat M; @@ -2843,8 +3042,8 @@ inline explicit partial_unwrap_check_scalar_times_fixed(const eOp& A, const Mat& B) : val ( A.aux ) - , M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : 0 ) - , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) + , M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : nullptr ) + , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) { arma_extra_debug_sigprint(); } @@ -2859,8 +3058,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const T1* M_local; @@ -2880,12 +3079,12 @@ template -struct partial_unwrap_check< eOp > : public partial_unwrap_check_scalar_times_redirect::value >::result +struct partial_unwrap_check< eOp > : public partial_unwrap_check_scalar_times_redirect::value>::result { typedef typename T1::elem_type eT; inline partial_unwrap_check(const eOp& A, const Mat& B) - : partial_unwrap_check_scalar_times_redirect< T1, is_Mat_fixed::value >::result(A, B) + : partial_unwrap_check_scalar_times_redirect::value>::result(A, B) { } }; @@ -2900,8 +3099,8 @@ inline partial_unwrap_check(const eOp,eop_scalar_times>& A, const Mat& B) : val (A.aux) - , M_local( (&(A.P.Q) == &B) ? new Mat(A.P.Q) : 0 ) - , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) + , M_local( (&(A.P.Q) == &B) ? new Mat(A.P.Q) : nullptr ) + , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) { arma_extra_debug_sigprint(); } @@ -2916,8 +3115,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Mat* M_local; @@ -2934,8 +3133,8 @@ inline partial_unwrap_check(const eOp,eop_scalar_times>& A, const Mat& B) : val(A.aux) - , M_local( (&(A.P.Q) == &B) ? new Row(A.P.Q) : 0 ) - , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) + , M_local( (&(A.P.Q) == &B) ? new Row(A.P.Q) : nullptr ) + , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) { arma_extra_debug_sigprint(); } @@ -2950,8 +3149,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Row* M_local; @@ -2968,8 +3167,8 @@ inline partial_unwrap_check(const eOp,eop_scalar_times>& A, const Mat& B) : val ( A.aux ) - , M_local( (&(A.P.Q) == &B) ? new Col(A.P.Q) : 0 ) - , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) + , M_local( (&(A.P.Q) == &B) ? new Col(A.P.Q) : nullptr ) + , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) { arma_extra_debug_sigprint(); } @@ -2984,8 +3183,8 @@ arma_inline eT get_val() const { return val; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Col* M_local; @@ -3004,15 +3203,15 @@ inline partial_unwrap_check(const eOp,eop_scalar_times>& A, const Mat& B) : val( A.aux ) - , M ( const_cast( A.P.Q.colptr(0) ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false ) + , M ( const_cast( A.P.Q.colmem ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false ) { arma_extra_debug_sigprint(); } arma_inline eT get_val() const { return val; } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const eT val; const Col M; @@ -3033,10 +3232,10 @@ arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Mat M; }; @@ -3051,8 +3250,8 @@ inline explicit partial_unwrap_check_neg_fixed(const eOp& A, const Mat& B) - : M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : 0 ) - , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) + : M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : nullptr ) + , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) { arma_extra_debug_sigprint(); } @@ -3065,10 +3264,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const T1* M_local; const T1& M; @@ -3087,12 +3286,12 @@ template -struct partial_unwrap_check< eOp > : public partial_unwrap_check_neg_redirect::value >::result +struct partial_unwrap_check< eOp > : public partial_unwrap_check_neg_redirect::value>::result { typedef typename T1::elem_type eT; inline partial_unwrap_check(const eOp& A, const Mat& B) - : partial_unwrap_check_neg_redirect< T1, is_Mat_fixed::value >::result(A, B) + : partial_unwrap_check_neg_redirect::value>::result(A, B) { } }; @@ -3106,8 +3305,8 @@ inline partial_unwrap_check(const eOp,eop_neg>& A, const Mat& B) - : M_local( (&(A.P.Q) == &B) ? new Mat(A.P.Q) : 0 ) - , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) + : M_local( (&(A.P.Q) == &B) ? new Mat(A.P.Q) : nullptr ) + , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) { arma_extra_debug_sigprint(); } @@ -3120,10 +3319,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Mat* M_local; const Mat& M; @@ -3138,8 +3337,8 @@ inline partial_unwrap_check(const eOp,eop_neg>& A, const Mat& B) - : M_local( (&(A.P.Q) == &B) ? new Row(A.P.Q) : 0 ) - , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) + : M_local( (&(A.P.Q) == &B) ? new Row(A.P.Q) : nullptr ) + , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) { arma_extra_debug_sigprint(); } @@ -3152,10 +3351,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Row* M_local; const Row& M; @@ -3170,8 +3369,8 @@ inline partial_unwrap_check(const eOp,eop_neg>& A, const Mat& B) - : M_local( (&(A.P.Q) == &B) ? new Col(A.P.Q) : 0 ) - , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) + : M_local( (&(A.P.Q) == &B) ? new Col(A.P.Q) : nullptr ) + , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) { arma_extra_debug_sigprint(); } @@ -3184,10 +3383,10 @@ if(M_local) { delete M_local; } } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Col* M_local; const Col& M; @@ -3204,15 +3403,15 @@ inline partial_unwrap_check(const eOp,eop_neg>& A, const Mat& B) - : M ( const_cast( A.P.Q.colptr(0) ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false ) + : M ( const_cast( A.P.Q.colmem ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false ) { arma_extra_debug_sigprint(); } - arma_inline eT get_val() const { return eT(-1); } + constexpr eT get_val() const { return eT(-1); } - static const bool do_trans = false; - static const bool do_times = true; + static constexpr bool do_trans = false; + static constexpr bool do_times = true; const Col M; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/unwrap_spmat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/unwrap_spmat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/unwrap_spmat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/unwrap_spmat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -36,7 +38,7 @@ const SpMat M; template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; @@ -124,7 +126,7 @@ const SpMat M; template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; @@ -146,7 +148,7 @@ const SpMat M; template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; @@ -166,7 +168,7 @@ const SpMat M; template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; @@ -186,7 +188,7 @@ const SpMat M; template - arma_inline bool is_alias(const SpMat&) const { return false; } + constexpr bool is_alias(const SpMat&) const { return false; } }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/upgrade_val.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/upgrade_val.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/upgrade_val.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/upgrade_val.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -61,7 +63,7 @@ //! upgrade a type to allow multiplication with a complex type -//! e.g. the int in "int * complex" is upgraded to a double +//! eg. the int in "int * complex" is upgraded to a double // template<> template struct upgrade_val< std::complex, T2 > diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/wall_clock_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/wall_clock_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/wall_clock_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/wall_clock_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -26,22 +28,15 @@ inline wall_clock(); inline ~wall_clock(); - inline void tic(); //!< start the timer - inline double toc(); //!< return the number of seconds since the last call to tic() + inline void tic(); //!< start the timer + inline arma_warn_unused double toc(); //!< return the number of seconds since the last call to tic() private: - bool valid; + bool valid = false; - #if defined(ARMA_USE_CXX11) - std::chrono::steady_clock::time_point chrono_time1; - #elif defined(ARMA_HAVE_GETTIMEOFDAY) - struct timeval posix_time1; - struct timeval posix_time2; - #else - std::clock_t time1; - #endif + std::chrono::steady_clock::time_point chrono_time1; }; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/wall_clock_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/wall_clock_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/wall_clock_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/wall_clock_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -20,7 +22,6 @@ inline wall_clock::wall_clock() - : valid(false) { arma_extra_debug_sigprint(); } @@ -41,22 +42,8 @@ { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_CXX11) - { - chrono_time1 = std::chrono::steady_clock::now(); - valid = true; - } - #elif defined(ARMA_HAVE_GETTIMEOFDAY) - { - gettimeofday(&posix_time1, 0); - valid = true; - } - #else - { - time1 = std::clock(); - valid = true; - } - #endif + chrono_time1 = std::chrono::steady_clock::now(); + valid = true; } @@ -69,42 +56,17 @@ if(valid) { - #if defined(ARMA_USE_CXX11) - { - const std::chrono::steady_clock::time_point chrono_time2 = std::chrono::steady_clock::now(); - - typedef std::chrono::duration duration_type; - - const duration_type chrono_span = std::chrono::duration_cast< duration_type >(chrono_time2 - chrono_time1); - - return chrono_span.count(); - } - #elif defined(ARMA_HAVE_GETTIMEOFDAY) - { - gettimeofday(&posix_time2, 0); - - const double tmp_time1 = double(posix_time1.tv_sec) + double(posix_time1.tv_usec) * 1.0e-6; - const double tmp_time2 = double(posix_time2.tv_sec) + double(posix_time2.tv_usec) * 1.0e-6; - - return tmp_time2 - tmp_time1; - } - #else - { - std::clock_t time2 = std::clock(); - - std::clock_t diff = time2 - time1; - - return double(diff) / double(CLOCKS_PER_SEC); - } - #endif - } - else - { - return 0.0; + const std::chrono::steady_clock::time_point chrono_time2 = std::chrono::steady_clock::now(); + + typedef std::chrono::duration duration_type; // TODO: check this + + const duration_type chrono_span = std::chrono::duration_cast< duration_type >(chrono_time2 - chrono_time1); + + return chrono_span.count(); } + + return 0.0; } - //! @} - diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/xtrans_mat_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/xtrans_mat_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/xtrans_mat_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/xtrans_mat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,18 +21,18 @@ template -class xtrans_mat : public Base > +class xtrans_mat : public Base< eT, xtrans_mat > { public: typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = false; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = false; - static const bool really_do_conj = (do_conj && is_cx::yes); + static constexpr bool really_do_conj = (do_conj && is_cx::yes); arma_aligned const Mat& X; arma_aligned mutable Mat Y; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/xtrans_mat_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/xtrans_mat_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/xtrans_mat_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/xtrans_mat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/xvec_htrans_bones.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/xvec_htrans_bones.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/xvec_htrans_bones.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/xvec_htrans_bones.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -19,16 +21,16 @@ template -class xvec_htrans : public Base > +class xvec_htrans : public Base< eT, xvec_htrans > { public: typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static const bool is_row = false; - static const bool is_col = false; - static const bool is_xvec = true; + static constexpr bool is_row = false; + static constexpr bool is_col = false; + static constexpr bool is_xvec = true; arma_aligned const eT* const mem; diff -Nru armadillo-9.800.4+dfsg/include/armadillo_bits/xvec_htrans_meat.hpp armadillo-10.8.2+dfsg/include/armadillo_bits/xvec_htrans_meat.hpp --- armadillo-9.800.4+dfsg/include/armadillo_bits/xvec_htrans_meat.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/include/armadillo_bits/xvec_htrans_meat.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // diff -Nru armadillo-9.800.4+dfsg/index.html armadillo-10.8.2+dfsg/index.html --- armadillo-9.800.4+dfsg/index.html 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/index.html 2016-06-16 16:24:22.000000000 +0000 @@ -31,7 +31,15 @@
                                                                                    +
                                                                                      +
                                                                                    • Paper with details on Gaussian Mixture Models in Armadillo
                                                                                      • armadillo_spcs_2017.pdf (online copy)
                                                                                      • armadillo_spcs_2017.pdf (local copy)
                                                                                      • diff -Nru armadillo-9.800.4+dfsg/misc/armadillo.spec armadillo-10.8.2+dfsg/misc/armadillo.spec --- armadillo-9.800.4+dfsg/misc/armadillo.spec 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/misc/armadillo.spec 2016-06-16 16:24:22.000000000 +0000 @@ -1,5 +1,5 @@ Name: armadillo -Version: 9.100.0 +Version: 10.1.x Release: 1%{?dist} Summary: Fast C++ matrix library with syntax similar to MATLAB and Octave @@ -93,9 +93,9 @@ %doc README.md index.html docs.html %doc examples armadillo_icon.png %doc armadillo_joss_2016.pdf -%doc arma_spmat_icms_2018.pdf -%doc arma_gmm_joss_2017.pdf -%doc arma_gmm_spcs_2017.pdf -%doc rcpp_armadillo_csda_2014.pdf +%doc armadillo_lncs_2018.pdf %doc armadillo_nicta_2010.pdf +%doc armadillo_solver_2020.pdf +%doc armadillo_spcs_2017.pdf +%doc rcpp_armadillo_csda_2014.pdf %doc mex_interface diff -Nru armadillo-9.800.4+dfsg/misc/doxygen.config armadillo-10.8.2+dfsg/misc/doxygen.config --- armadillo-9.800.4+dfsg/misc/doxygen.config 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/misc/doxygen.config 2016-06-16 16:24:22.000000000 +0000 @@ -1,51 +1,63 @@ -# Doxyfile 1.5.8 +# Doxyfile 1.8.17 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- - DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "Armadillo Technical" -PROJECT_NUMBER = "" -OUTPUT_DIRECTORY = +PROJECT_NAME = "Doxygen Generated" +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English +OUTPUT_TEXT_DIRECTION = None BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = +ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = YES INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO +JAVADOC_BANNER = NO QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = YES INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 2 -ALIASES = +ALIASES = +TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO -EXTENSION_MAPPING = +OPTIMIZE_OUTPUT_SLICE = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +TOC_INCLUDE_HEADINGS = 5 +AUTOLINK_SUPPORT = YES BUILTIN_STL_SUPPORT = YES CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO TYPEDEF_HIDES_STRUCT = NO -SYMBOL_CACHE_SIZE = 0 - +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- - EXTRACT_ALL = YES EXTRACT_PRIVATE = YES +EXTRACT_PRIV_VIRTUAL = NO +EXTRACT_PACKAGE = NO EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO @@ -57,222 +69,239 @@ INTERNAL_DOCS = NO CASE_SENSE_NAMES = NO HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO INLINE_INFO = YES SORT_MEMBER_DOCS = NO SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = +ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = NO -SHOW_DIRECTORIES = YES SHOW_FILES = YES SHOW_NAMESPACES = YES -FILE_VERSION_FILTER = -LAYOUT_FILE = - +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = #--------------------------------------------------------------------------- -# configuration options related to warning and progress messages +# Configuration options related to warning and progress messages #--------------------------------------------------------------------------- - QUIET = YES WARNINGS = NO WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO +WARN_AS_ERROR = NO WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = - +WARN_LOGFILE = #--------------------------------------------------------------------------- -# configuration options related to the input files +# Configuration options related to the input files #--------------------------------------------------------------------------- - -INPUT = build_aux/doxygen/ \ - include/ \ - include/armadillo_bits - +INPUT = include/ include/armadillo_bits/ src/ misc/ INPUT_ENCODING = UTF-8 - -FILE_PATTERNS = armadillo \ - *.hpp \ - *.doxy - +FILE_PATTERNS = armadillo *.hpp *.cpp *.doxy RECURSIVE = NO -EXCLUDE = +EXCLUDE = EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = FILTER_SOURCE_FILES = NO - +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- -# configuration options related to source browsing +# Configuration options related to source browsing #--------------------------------------------------------------------------- - SOURCE_BROWSER = YES -INLINE_SOURCES = YES +INLINE_SOURCES = NO STRIP_CODE_COMMENTS = NO REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES USE_HTAGS = NO VERBATIM_HEADERS = YES - #--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index +# Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- - ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = - +IGNORE_PREFIX = #--------------------------------------------------------------------------- -# configuration options related to the HTML output +# Configuration options related to the HTML output #--------------------------------------------------------------------------- - GENERATE_HTML = YES -HTML_OUTPUT = docs_tech +HTML_OUTPUT = doxygen_generated HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = build_aux/doxygen/blank_footer.html -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES +HTML_HEADER = +HTML_FOOTER = misc/blank_footer.html +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = +CHM_FILE = +HHC_LOCATION = GENERATE_CHI = NO -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = BINARY_TOC = NO TOC_EXPAND = NO GENERATE_QHP = NO -QCH_FILE = -QHP_NAMESPACE = +QCH_FILE = +QHP_NAMESPACE = QHP_VIRTUAL_FOLDER = doc -QHP_CUST_FILTER_NAME = -QHP_CUST_FILTER_ATTRS = -QHP_SECT_FILTER_ATTRS = -QHG_LOCATION = +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = YES +ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 - +FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = NO +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- -# configuration options related to the LaTeX output +# Configuration options related to the LaTeX output #--------------------------------------------------------------------------- - GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex +LATEX_OUTPUT = +LATEX_CMD_NAME = MAKEINDEX_CMD_NAME = makeindex +LATEX_MAKEINDEX_CMD = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO - +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +LATEX_TIMESTAMP = NO +LATEX_EMOJI_DIRECTORY = #--------------------------------------------------------------------------- -# configuration options related to the RTF output +# Configuration options related to the RTF output #--------------------------------------------------------------------------- - GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = - +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +RTF_SOURCE_CODE = NO #--------------------------------------------------------------------------- -# configuration options related to the man page output +# Configuration options related to the man page output #--------------------------------------------------------------------------- - GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 +MAN_SUBDIR = MAN_LINKS = NO - #--------------------------------------------------------------------------- -# configuration options related to the XML output +# Configuration options related to the XML output #--------------------------------------------------------------------------- - GENERATE_XML = NO XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = XML_PROGRAMLISTING = YES - +XML_NS_MEMB_FILE_SCOPE = NO #--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- - GENERATE_AUTOGEN_DEF = NO - #--------------------------------------------------------------------------- -# configuration options related to the Perl module output +# Configuration options related to the Perl module output #--------------------------------------------------------------------------- - GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = - +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# Configuration options related to the preprocessor #--------------------------------------------------------------------------- - ENABLE_PREPROCESSING = NO MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = NO - #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration options related to external references #--------------------------------------------------------------------------- - -TAGFILES = -GENERATE_TAGFILE = +TAGFILES = +GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl - +EXTERNAL_PAGES = YES #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- - CLASS_DIAGRAMS = YES -MSCGEN_PATH = +DIA_PATH = HIDE_UNDOC_RELATIONS = NO HAVE_DOT = NO -DOT_FONTNAME = FreeSans +DOT_NUM_THREADS = 0 +DOT_FONTNAME = DOT_FONTSIZE = 10 -DOT_FONTPATH = +DOT_FONTPATH = CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 TEMPLATE_RELATIONS = YES INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES @@ -281,17 +310,17 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_CFG_FILE = +PLANTUML_INCLUDE_PATH = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -DOT_TRANSPARENT = YES +DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Options related to the search engine -#--------------------------------------------------------------------------- - -SEARCHENGINE = NO diff -Nru armadillo-9.800.4+dfsg/misc/main.doxy armadillo-10.8.2+dfsg/misc/main.doxy --- armadillo-9.800.4+dfsg/misc/main.doxy 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/misc/main.doxy 2016-06-16 16:24:22.000000000 +0000 @@ -4,16 +4,8 @@ \htmlonly
                                                                                        -See the associated technical report for an overview of the internal architecture: +Main page: http://arma.sourceforge.net
                                                                                        -
                                                                                          -Conrad Sanderson. -
                                                                                          Armadillo: An Open Source C++ Linear Algebra Library for Fast Prototyping and Computationally Intensive Experiments. -
                                                                                          Technical Report, NICTA, 2010. -
                                                                                          -
                                                                                          online PDF - -
                                                                                        \endhtmlonly */ diff -Nru armadillo-9.800.4+dfsg/NOTICE.txt armadillo-10.8.2+dfsg/NOTICE.txt --- armadillo-9.800.4+dfsg/NOTICE.txt 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/NOTICE.txt 2016-06-16 16:24:22.000000000 +0000 @@ -1,10 +1,9 @@ Armadillo C++ Linear Algebra Library -Copyright 2008-2019 Conrad Sanderson (http://conradsanderson.id.au) +Copyright 2008-2022 Conrad Sanderson (http://conradsanderson.id.au) Copyright 2008-2016 National ICT Australia (NICTA) -Copyright 2017-2019 Arroyo Consortium -Copyright 2017-2019 Data61, CSIRO +Copyright 2017-2022 Data61 / CSIRO This product includes software developed by Conrad Sanderson (http://conradsanderson.id.au) This product includes software developed at National ICT Australia (NICTA) This product includes software developed at Arroyo Consortium -This product includes software developed at Data61, CSIRO +This product includes software developed at Data61 / CSIRO diff -Nru armadillo-9.800.4+dfsg/README.md armadillo-10.8.2+dfsg/README.md --- armadillo-9.800.4+dfsg/README.md 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/README.md 2016-06-16 16:24:22.000000000 +0000 @@ -1,10 +1,9 @@ ### Armadillo: C++ Library for Linear Algebra & Scientific Computing http://arma.sourceforge.net -Copyright 2008-2019 Conrad Sanderson (http://conradsanderson.id.au) +Copyright 2008-2022 Conrad Sanderson (http://conradsanderson.id.au) Copyright 2008-2016 National ICT Australia (NICTA) -Copyright 2017-2019 Arroyo Consortium -Copyright 2017-2019 Data61, CSIRO +Copyright 2017-2022 Data61 / CSIRO --- @@ -22,7 +21,7 @@ 2. [Citation Details](#2-citation-details) 3. [Distribution License](#3-distribution-license) -4. [Compilers and External Dependencies](#4-compilers-and-external-dependencies) +4. [Prerequisites and Dependencies](#4-prerequisites-and-dependencies) 5. [Linux and macOS: Installation](#5-linux-and-macos-installation) 6. [Linux and macOS: Compiling and Linking](#6-linux-and-macos-compiling-and-linking) @@ -32,10 +31,10 @@ 9. [Support for OpenBLAS and Intel MKL](#9-support-for-openblas-and-intel-mkl) 10. [Support for ATLAS](#10-support-for-atlas) -11. [Support for C++11 / C++14 Features](#11-support-for-c11-c14-features) +11. [Caveat on use of C++11 auto Keyword](#11-caveat-on-use-of-c11-auto-keyword) 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 +56,8 @@ 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,138 +103,158 @@ --- -### 4: Compilers and External Dependencies - -Armadillo makes extensive use of template meta-programming and many other -advanced C++ features. As such, C++ compilers which do not fully implement -the C++ standard may not work correctly. +### 4: Prerequisites and Dependencies 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. - -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 - ---- +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. +Use of OpenBLAS is strongly recommended on all systems. -### 5: Linux and macOS: Installation +Armadillo 10.x requires a C++ compiler that supports at least the C++11 standard. +Use Armadillo 9.900 if your compiler only supports the old C++98/C++03 standards. -* Step 1: - Ensure a C++ compiler is installed on your system. +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 you will need to install Xcode (version 8 or later) - and then type the following command in a terminal window: - xcode-select --install +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: -* Step 2: - Ensure the CMake tool is installed on your system. - You can download it from http://www.cmake.org - or (preferably) install it using your package manager. + xcode-select --install - - On Linux-based systems, you can get CMake using dnf, yum, apt, aptitude, ... - - On macOS systems, you can get CMake through MacPorts or Homebrew. +On Windows systems, the MinGW toolset or Visual Studio C++ 2019 (MSVC) can be used. -* Step 3: - Ensure LAPACK and BLAS (or preferably OpenBLAS) are installed on your system. - On macOS this is not necessary. +--- - - For better performance, we recommend installing the OpenBLAS library. - See http://www.openblas.net/ +### 5: Linux and macOS: Installation - - If you are using sparse matrices, also install ARPACK and SuperLU. - Caveat: only SuperLU version 5.2 can be used! +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. + +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. + + +#### 5a: Installation via CMake + +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, 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: - Open a terminal window, change into the directory that was created - by unpacking the armadillo archive, and type the following command: +Change into the directory that was created by unpacking the armadillo archive +(eg. `cd armadillo-10.6.1`) and then run cmake using: cmake . - - The full stop separated from "cmake" by a space is important. +**NOTE:** the full stop (.) separated from `cmake` by a space is important. + +On macOS, to enable the detection of OpenBLAS, +use the additional `ALLOW_OPENBLAS_MACOS` option when running cmake: - - 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. - - - By default, cmake assumes that the Armadillo library and the - corresponding header files are going to be installed in the default - system directory (eg. in the /usr hierarchy in Linux-based systems). - If you wish to install the library and headers in an alternative directory, - use the additional option CMAKE_INSTALL_PREFIX in this form: + 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: + + 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: cmake . -DCMAKE_INSTALL_PREFIX:PATH=alternative_directory - - If you need to re-run cmake, it's a good idea to first delete the - "CMakeCache.txt" file (not "CMakeLists.txt"). +If cmake needs to be re-run, it's a good idea to first delete the `CMakeCache.txt` file +(not `CMakeLists.txt`). - - Caveat: out-of-tree builds are currently not fully supported; - eg, creating a sub-directory called "build" and running cmake .. - from within "build" is currently not supported. - - - Caveat: if you are installing Armadillo in a non-system directory, - make sure your 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: - To generate the run-time armadillo library, type the following command: - - make - -* Step 6: - 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: +**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 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 -The "examples" directory contains several quick example programs -that use the Armadillo library. +If you have installed Armadillo via the cmake installer, +use the following command to compile your programs: + + g++ prog.cpp -o prog -O2 -std=c++11 -larmadillo + +If you have installed Armadillo manually, link with OpenBLAS and LAPACK +instead of the Armadillo runtime library: + + g++ prog.cpp -o prog -O2 -std=c++11 -lopenblas -llapack -In general, programs which use Armadillo are compiled along these lines: +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++ example1.cpp -o example1 -O2 -larmadillo + g++ prog.cpp -o prog -O2 -std=c++11 -I /home/blah/include/ -lopenblas -llapack -If you want to use Armadillo without installation -(ie. without the runtime library generated by CMake during installation), -compile along these lines: +If you're getting linking issues (unresolved symbols), +enable the `ARMA_DONT_USE_WRAPPER` option: - g++ example1.cpp -o example1 -O2 -I /home/blah/armadillo-7.200.3/include -DARMA_DONT_USE_WRAPPER -lblas -llapack + g++ prog.cpp -o prog -O2 -std=c++11 -I /home/blah/include/ -DARMA_DONT_USE_WRAPPER -lopenblas -llapack -The above command line assumes that you have unpacked the armadillo archive into /home/blah/ -You will need to adjust this for later versions of Armadillo (ie. change the 7.200.3 part) -and/or if you have unpacked the armadillo archive into a different directory. +If you don't have OpenBLAS, on Linux change `-lopenblas` to `-lblas`; +on macOS change `-lopenblas -llapack` to `-framework Accelerate` -Replace -lblas with -lopenblas if you have OpenBLAS. -On macOS, replace -lblas -llapack with -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 --- @@ -244,56 +263,50 @@ 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, you can use the "include" folder 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 you have 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 you don't need sparse matrices, 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. - -The MSVC project was tested on 64 bit Windows 7 with Visual C++ 2012. -You may need to make adaptations for 32 bit systems, later versions of Windows -and/or the compiler. For example, you may have to enable or disable -ARMA_BLAS_LONG and ARMA_BLAS_UNDERSCORE defines in "armadillo_bits/config.hpp". - -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 - -Faster and/or alternative implementations of BLAS and LAPACK are available: - * http://www.openblas.net/ - * http://icl.cs.utk.edu/lapack-for-windows/lapack/ - * http://software.intel.com/en-us/intel-mkl/ - -OpenBLAS and Intel MKL are generally the fastest replacements for both BLAS and LAPACK. +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 10 (64 bit) with Visual Studio C++ 2019. +Adaptations may be required for 32 bit systems, later versions of Windows and/or the compiler. +For example, options such as `ARMA_BLAS_LONG` and `ARMA_BLAS_UNDERSCORE`, +defined in `include/armadillo_bits/config.hpp`, may need to be either enabled or disabled. + +The folder `examples/lib_win64` contains a copy of lib and dll files +obtained from a pre-compiled release of OpenBLAS: +https://github.com/xianyi/OpenBLAS/releases/ +The compilation was done by a third party. USE AT YOUR OWN RISK. **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/ @@ -306,10 +319,10 @@ replacements for BLAS and LAPACK. In essence this involves linking with the replacement libraries instead of BLAS and LAPACK. -You may need to make minor modifications to include/armadillo_bits/config.hpp -to make sure Armadillo uses the same integer sizes and style of function names -as used by the replacement libraries. Specifically, you may need comment or uncomment -the following defines: +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: ARMA_USE_WRAPPER ARMA_BLAS_CAPITALS @@ -319,62 +332,47 @@ 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 you modify /etc/ld.so.conf -or create /etc/ld.so.conf.d/mkl.conf, you will need to run /sbin/ldconfig -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 you have MKL installed and it is persistently giving problems -during linking, you can disable Armadillo's support for MKL by editing -the CMakeLists.txt file, deleting CMakeCache.txt and re-running -the CMake based installation. Comment out the lines containing: - - INCLUDE(ARMA_FindMKL) - INCLUDE(ARMA_FindACMLMP) - INCLUDE(ARMA_FindACML) +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 line containing: + + INCLUDE(ARMA_FindMKL) --- ### 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 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 C++11 features by defining ARMA_USE_CXX11 before -`#include ` in your code. +### 11: Caveat on use of C++11 auto Keyword -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. +Use of the C++11 `auto` keyword is not recommended with Armadillo objects and expressions. -**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. +Armadillo has a template meta-programming framework which creates lots of short lived temporaries +that are not properly handled by `auto`. --- @@ -384,21 +382,18 @@ 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. --- @@ -459,21 +454,25 @@ ### 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. --- ### 17: Related Software Using Armadillo +* ensmallen: fast non-linear numerical optimisation library + http://ensmallen.org/ + * MLPACK: extensive library of machine learning algorithms http://mlpack.org -* ensmallen: C++ library of numerical optimisation methods - http://ensmallen.org/ - -* SigPack: C++ signal processing library - http://sigpack.sourceforge.net +* CARMA: bidirectional interface between Python and Armadillo + https://github.com/RUrlus/carma * RcppArmadillo: integration of Armadillo with the R system and environment http://dirk.eddelbuettel.com/code/rcpp.armadillo.html + +* PyArmadillo: streamlined linear algebra library for Python + https://pyarma.sourceforge.io + diff -Nru armadillo-9.800.4+dfsg/src/wrapper1.cpp armadillo-10.8.2+dfsg/src/wrapper1.cpp --- armadillo-9.800.4+dfsg/src/wrapper1.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/src/wrapper1.cpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -18,11 +20,6 @@ #include #include -#if (__cplusplus >= 201103L) - #undef ARMA_USE_CXX11 - #define ARMA_USE_CXX11 -#endif - #include "armadillo_bits/config.hpp" #undef ARMA_USE_WRAPPER @@ -34,22 +31,26 @@ #include "armadillo_bits/include_superlu.hpp" -#if defined(ARMA_USE_EXTERN_CXX11_RNG) +#if defined(ARMA_USE_EXTERN_RNG) #include - #include - - #if defined(ARMA_HAVE_GETTIMEOFDAY) - #include - #endif namespace arma { + // NOTE: arma_rng_cxx11_instance is kept only for compatibility with earlier versions of armadillo + // TODO: remove arma_rng_cxx11_instance when the major version is bumped + #include "armadillo_bits/arma_rng_cxx11.hpp" thread_local arma_rng_cxx11 arma_rng_cxx11_instance; + + thread_local std::mt19937_64 mt19937_64_instance; } #endif #if defined(ARMA_USE_HDF5_ALT) + + #undef H5_USE_110_API + #define H5_USE_110_API + #include #if defined(H5_USE_16_API_DEFAULT) || defined(H5_USE_16_API) @@ -513,6 +514,29 @@ + void arma_fortran_with_prefix(arma_sgeqp3)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* jpvt, float* tau, float* work, const blas_int* lwork, blas_int* info) + { + arma_fortran_sans_prefix(arma_sgeqp3)(m, n, a, lda, jpvt, tau, work, lwork, info); + } + + void arma_fortran_with_prefix(arma_dgeqp3)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, blas_int* jpvt, double* tau, double* work, const blas_int* lwork, blas_int* info) + { + arma_fortran_sans_prefix(arma_dgeqp3)(m, n, a, lda, jpvt, tau, work, lwork, info); + } + + + void arma_fortran_with_prefix(arma_cgeqp3)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* jpvt, blas_cxf* tau, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) + { + arma_fortran_sans_prefix(arma_cgeqp3)(m, n, a, lda, jpvt, tau, work, lwork, rwork, info); + } + + void arma_fortran_with_prefix(arma_zgeqp3)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* jpvt, blas_cxd* tau, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) + { + arma_fortran_sans_prefix(arma_zgeqp3)(m, n, a, lda, jpvt, tau, work, lwork, rwork, info); + } + + + void arma_fortran_with_prefix(arma_sorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, float* a, const blas_int* lda, const float* tau, float* work, const blas_int* lwork, blas_int* info) { arma_fortran_sans_prefix(arma_sorgqr)(m, n, k, a, lda, tau, work, lwork, info); @@ -1174,6 +1198,28 @@ arma_fortran_sans_prefix(arma_zgehrd)(n, ilo, ihi, a, lda, tao, work, lwork, info); } + + + void arma_fortran_with_prefix(arma_spstrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info) + { + arma_fortran_sans_prefix(arma_spstrf)(uplo, n, a, lda, piv, rank, tol, work, info); + } + + void arma_fortran_with_prefix(arma_dpstrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info) + { + arma_fortran_sans_prefix(arma_dpstrf)(uplo, n, a, lda, piv, rank, tol, work, info); + } + + void arma_fortran_with_prefix(arma_cpstrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info) + { + arma_fortran_sans_prefix(arma_cpstrf)(uplo, n, a, lda, piv, rank, tol, work, info); + } + + void arma_fortran_with_prefix(arma_zpstrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info) + { + arma_fortran_sans_prefix(arma_zpstrf)(uplo, n, a, lda, piv, rank, tol, work, info); + } + #endif @@ -1566,6 +1612,96 @@ + void wrapper_sgstrf(superlu::superlu_options_t* a, superlu::SuperMatrix* b, int d, int e, int* f, void* g, int h, int* i, int* j, superlu::SuperMatrix* k, superlu::SuperMatrix* l, superlu::GlobalLU_t* m, superlu::SuperLUStat_t* n, int* o) + { + sgstrf(a, b, d, e, f, g, h, i, j, k, l, m, n, o); + } + + void wrapper_dgstrf(superlu::superlu_options_t* a, superlu::SuperMatrix* b, int d, int e, int* f, void* g, int h, int* i, int* j, superlu::SuperMatrix* k, superlu::SuperMatrix* l, superlu::GlobalLU_t* m, superlu::SuperLUStat_t* n, int* o) + { + dgstrf(a, b, d, e, f, g, h, i, j, k, l, m, n, o); + } + + void wrapper_cgstrf(superlu::superlu_options_t* a, superlu::SuperMatrix* b, int d, int e, int* f, void* g, int h, int* i, int* j, superlu::SuperMatrix* k, superlu::SuperMatrix* l, superlu::GlobalLU_t* m, superlu::SuperLUStat_t* n, int* o) + { + cgstrf(a, b, d, e, f, g, h, i, j, k, l, m, n, o); + } + + void wrapper_zgstrf(superlu::superlu_options_t* a, superlu::SuperMatrix* b, int d, int e, int* f, void* g, int h, int* i, int* j, superlu::SuperMatrix* k, superlu::SuperMatrix* l, superlu::GlobalLU_t* m, superlu::SuperLUStat_t* n, int* o) + { + zgstrf(a, b, d, e, f, g, h, i, j, k, l, m, n, o); + } + + + + + void wrapper_sgstrs(superlu::trans_t a, superlu::SuperMatrix* b, superlu::SuperMatrix* c, int* d, int* e, superlu::SuperMatrix* f, superlu::SuperLUStat_t* g, int* h) + { + sgstrs(a, b, c, d, e, f, g, h); + } + + void wrapper_dgstrs(superlu::trans_t a, superlu::SuperMatrix* b, superlu::SuperMatrix* c, int* d, int* e, superlu::SuperMatrix* f, superlu::SuperLUStat_t* g, int* h) + { + dgstrs(a, b, c, d, e, f, g, h); + } + + void wrapper_cgstrs(superlu::trans_t a, superlu::SuperMatrix* b, superlu::SuperMatrix* c, int* d, int* e, superlu::SuperMatrix* f, superlu::SuperLUStat_t* g, int* h) + { + cgstrs(a, b, c, d, e, f, g, h); + } + + void wrapper_zgstrs(superlu::trans_t a, superlu::SuperMatrix* b, superlu::SuperMatrix* c, int* d, int* e, superlu::SuperMatrix* f, superlu::SuperLUStat_t* g, int* h) + { + zgstrs(a, b, c, d, e, f, g, h); + } + + + + + float wrapper_slangs(char* norm, superlu::SuperMatrix* A) + { + return slangs(norm, A); + } + + double wrapper_dlangs(char* norm, superlu::SuperMatrix* A) + { + return dlangs(norm, A); + } + + float wrapper_clangs(char* norm, superlu::SuperMatrix* A) + { + return clangs(norm, A); + } + + double wrapper_zlangs(char* norm, superlu::SuperMatrix* A) + { + return zlangs(norm, A); + } + + + + void wrapper_sgscon(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, float anorm, float* rcond, superlu::SuperLUStat_t* stat, int* info) + { + sgscon(norm, L, U, anorm, rcond, stat, info); + } + + void wrapper_dgscon(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, double anorm, double* rcond, superlu::SuperLUStat_t* stat, int* info) + { + dgscon(norm, L, U, anorm, rcond, stat, info); + } + + void wrapper_cgscon(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, float anorm, float* rcond, superlu::SuperLUStat_t* stat, int* info) + { + cgscon(norm, L, U, anorm, rcond, stat, info); + } + + void wrapper_zgscon(char* norm, superlu::SuperMatrix* L, superlu::SuperMatrix* U, double anorm, double* rcond, superlu::SuperLUStat_t* stat, int* info) + { + zgscon(norm, L, U, anorm, rcond, stat, info); + } + + + void wrapper_StatInit(superlu::SuperLUStat_t* a) { StatInit(a); @@ -1580,6 +1716,21 @@ { set_default_options(a); } + + void wrapper_get_perm_c(int a, superlu::SuperMatrix* b, int* c) + { + get_perm_c(a, b, c); + } + + int wrapper_sp_ienv(int a) + { + return sp_ienv(a); + } + + void wrapper_sp_preorder(superlu::superlu_options_t* a, superlu::SuperMatrix* b, int* c, int* d, superlu::SuperMatrix* e) + { + sp_preorder(a, b, c, d, e); + } void wrapper_Destroy_SuperNode_Matrix(superlu::SuperMatrix* a) { @@ -1591,6 +1742,11 @@ Destroy_CompCol_Matrix(a); } + void wrapper_Destroy_CompCol_Permuted(superlu::SuperMatrix* a) + { + Destroy_CompCol_Permuted(a); + } + void wrapper_Destroy_SuperMatrix_Store(superlu::SuperMatrix* a) { Destroy_SuperMatrix_Store(a); diff -Nru armadillo-9.800.4+dfsg/src/wrapper2.cpp armadillo-10.8.2+dfsg/src/wrapper2.cpp --- armadillo-9.800.4+dfsg/src/wrapper2.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/src/wrapper2.cpp 2016-06-16 16:24:22.000000000 +0000 @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // @@ -465,6 +467,29 @@ + void arma_fortran_with_prefix(arma_sgeqp3)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* jpvt, float* tau, float* work, const blas_int* lwork, blas_int* info) + { + arma_fortran_sans_prefix(arma_sgeqp3)(m, n, a, lda, jpvt, tau, work, lwork, info); + } + + void arma_fortran_with_prefix(arma_dgeqp3)(const blas_int* m, const blas_int* n, double* a, const blas_int* lda, blas_int* jpvt, double* tau, double* work, const blas_int* lwork, blas_int* info) + { + arma_fortran_sans_prefix(arma_dgeqp3)(m, n, a, lda, jpvt, tau, work, lwork, info); + } + + + void arma_fortran_with_prefix(arma_cgeqp3)(const blas_int* m, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* jpvt, blas_cxf* tau, blas_cxf* work, const blas_int* lwork, float* rwork, blas_int* info) + { + arma_fortran_sans_prefix(arma_cgeqp3)(m, n, a, lda, jpvt, tau, work, lwork, rwork, info); + } + + void arma_fortran_with_prefix(arma_zgeqp3)(const blas_int* m, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* jpvt, blas_cxd* tau, blas_cxd* work, const blas_int* lwork, double* rwork, blas_int* info) + { + arma_fortran_sans_prefix(arma_zgeqp3)(m, n, a, lda, jpvt, tau, work, lwork, rwork, info); + } + + + void arma_fortran_with_prefix(arma_sorgqr)(const blas_int* m, const blas_int* n, const blas_int* k, float* a, const blas_int* lda, const float* tau, float* work, const blas_int* lwork, blas_int* info) { arma_fortran_sans_prefix(arma_sorgqr)(m, n, k, a, lda, tau, work, lwork, info); @@ -1126,6 +1151,28 @@ arma_fortran_sans_prefix(arma_zgehrd)(n, ilo, ihi, a, lda, tao, work, lwork, info); } + + + void arma_fortran_with_prefix(arma_spstrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info, blas_len uplo_len) + { + arma_fortran_sans_prefix(arma_spstrf)(uplo, n, a, lda, piv, rank, tol, work, info, uplo_len); + } + + void arma_fortran_with_prefix(arma_dpstrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info, blas_len uplo_len) + { + arma_fortran_sans_prefix(arma_dpstrf)(uplo, n, a, lda, piv, rank, tol, work, info, uplo_len); + } + + void arma_fortran_with_prefix(arma_cpstrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info, blas_len uplo_len) + { + arma_fortran_sans_prefix(arma_cpstrf)(uplo, n, a, lda, piv, rank, tol, work, info, uplo_len); + } + + void arma_fortran_with_prefix(arma_zpstrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info, blas_len uplo_len) + { + arma_fortran_sans_prefix(arma_zpstrf)(uplo, n, a, lda, piv, rank, tol, work, info, uplo_len); + } + #endif diff -Nru armadillo-9.800.4+dfsg/tests/attributes.cpp armadillo-10.8.2+dfsg/tests/attributes.cpp --- armadillo-9.800.4+dfsg/tests/attributes.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/attributes.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("attributes_1") - { - mat A(5,6); - REQUIRE(A.n_rows == 5); - REQUIRE(A.n_cols == 6); - REQUIRE(A.n_elem == 30); - - vec B(5); - REQUIRE(B.n_rows == 5); - REQUIRE(B.n_cols == 1); - REQUIRE(B.n_elem == 5); - - rowvec C(6); - REQUIRE(C.n_rows == 1); - REQUIRE(C.n_cols == 6); - REQUIRE(C.n_elem == 6); - - cube D(5,6,2); - REQUIRE(D.n_rows == 5); - REQUIRE(D.n_cols == 6); - REQUIRE(D.n_slices == 2); - REQUIRE(D.n_elem == 60); - - sp_mat E(50,60); - E(0,0) = 1.0; - E(E.n_rows-1,E.n_cols-1) = 1.0; - - REQUIRE(E.n_rows == 50); - REQUIRE(E.n_cols == 60); - REQUIRE(E.n_elem == 3000); - REQUIRE(E.n_nonzero == 2); - - field G(5,6,2); - REQUIRE(G.n_rows == 5); - REQUIRE(G.n_cols == 6); - REQUIRE(G.n_slices == 2); - REQUIRE(G.n_elem == 60); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/bounds.cpp armadillo-10.8.2+dfsg/tests/bounds.cpp --- armadillo-9.800.4+dfsg/tests/bounds.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/bounds.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("bounds_1") - { - const uword n_rows = 5; - const uword n_cols = 6; - - mat A(n_rows, n_cols, fill::zeros); - - REQUIRE_NOTHROW( A(n_rows-1,n_cols-1) = 0 ); - - // out of bounds access will throw unless ARMA_NO_DEBUG is defined - REQUIRE_THROWS( A(n_rows,n_cols) = 0 ); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/catch.hpp armadillo-10.8.2+dfsg/tests/catch.hpp --- armadillo-9.800.4+dfsg/tests/catch.hpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/catch.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,11606 +0,0 @@ -/* - * Catch v1.10.0 - * Generated: 2017-08-26 15:16:46.676990 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. - * - * 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) - */ -#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED - -#define TWOBLUECUBES_CATCH_HPP_INCLUDED - -#ifdef __clang__ -# pragma clang system_header -#elif defined __GNUC__ -# pragma GCC system_header -#endif - -// #included from: internal/catch_suppress_warnings.h - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(push) -# pragma warning(disable: 161 1682) -# else // __ICC -# pragma clang diagnostic ignored "-Wglobal-constructors" -# pragma clang diagnostic ignored "-Wvariadic-macros" -# pragma clang diagnostic ignored "-Wc99-extensions" -# pragma clang diagnostic ignored "-Wunused-variable" -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wc++98-compat" -# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -# pragma clang diagnostic ignored "-Wswitch-enum" -# pragma clang diagnostic ignored "-Wcovered-switch-default" -# endif -#elif defined __GNUC__ -# pragma GCC diagnostic ignored "-Wvariadic-macros" -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wparentheses" - -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wpadded" -#endif -#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -# define CATCH_IMPL -#endif - -#ifdef CATCH_IMPL -# ifndef CLARA_CONFIG_MAIN -# define CLARA_CONFIG_MAIN_NOT_DEFINED -# define CLARA_CONFIG_MAIN -# endif -#endif - -// #included from: internal/catch_notimplemented_exception.h -#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED - -// #included from: catch_common.h -#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED - -// #included from: catch_compiler_capabilities.h -#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED - -// Detect a number of compiler features - mostly C++11/14 conformance - by compiler -// The following features are defined: -// -// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? -// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? -// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods -// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? -// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported -// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? -// CATCH_CONFIG_CPP11_OVERRIDE : is override supported? -// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) -// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported? -// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported? - -// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? - -// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? -// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? -// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? -// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? -// **************** -// Note to maintainers: if new toggles are added please document them -// in configuration.md, too -// **************** - -// In general each macro has a _NO_ form -// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. -// Many features, at point of detection, define an _INTERNAL_ macro, so they -// can be combined, en-mass, with the _NO_ forms later. - -// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 - -#ifdef __cplusplus - -# if __cplusplus >= 201103L -# define CATCH_CPP11_OR_GREATER -# endif - -# if __cplusplus >= 201402L -# define CATCH_CPP14_OR_GREATER -# endif - -#endif - -#ifdef __clang__ - -# if __has_feature(cxx_nullptr) -# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR -# endif - -# if __has_feature(cxx_noexcept) -# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT -# endif - -# if defined(CATCH_CPP11_OR_GREATER) -# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic pop" ) -# endif - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// We know some environments not to support full POSIX signals -#if defined(__CYGWIN__) || defined(__QNX__) - -# if !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# endif - -#endif - -#ifdef __OS400__ -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# define CATCH_CONFIG_COLOUR_NONE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Cygwin -#ifdef __CYGWIN__ - -// Required for some versions of Cygwin to declare gettimeofday -// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -# define _BSD_SOURCE - -#endif // __CYGWIN__ - -//////////////////////////////////////////////////////////////////////////////// -// Borland -#ifdef __BORLANDC__ - -#endif // __BORLANDC__ - -//////////////////////////////////////////////////////////////////////////////// -// EDG -#ifdef __EDG_VERSION__ - -#endif // __EDG_VERSION__ - -//////////////////////////////////////////////////////////////////////////////// -// Digital Mars -#ifdef __DMC__ - -#endif // __DMC__ - -//////////////////////////////////////////////////////////////////////////////// -// GCC -#ifdef __GNUC__ - -# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) -# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR -# endif - -// - otherwise more recent versions define __cplusplus >= 201103L -// and will get picked up below - -#endif // __GNUC__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#ifdef _MSC_VER - -#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH - -#if (_MSC_VER >= 1600) -# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR -# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR -#endif - -#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) -#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT -#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE -#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS -#endif - -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// - -// Use variadic macros if the compiler supports them -#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ - ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ - ( defined __GNUC__ && __GNUC__ >= 3 ) || \ - ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) - -#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS - -#endif - -// Use __COUNTER__ if the compiler supports it -#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ - ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \ - ( defined __clang__ && __clang_major__ >= 3 ) - -#define CATCH_INTERNAL_CONFIG_COUNTER - -#endif - -//////////////////////////////////////////////////////////////////////////////// -// C++ language feature support - -// catch all support for C++11 -#if defined(CATCH_CPP11_OR_GREATER) - -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) -# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR -# endif - -# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT -# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT -# endif - -# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -# endif - -# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM -# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM -# endif - -# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE -# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE -# endif - -# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS -# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS -# endif - -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) -# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG -# endif - -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) -# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE -# endif -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) -# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR -# endif -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) -# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE -# endif -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) -# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS -# endif - -#endif // __cplusplus >= 201103L - -// Now set the actual defines based on the above + anything the user has configured -#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_NULLPTR -#endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_NOEXCEPT -#endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_GENERATED_METHODS -#endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_IS_ENUM -#endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_TUPLE -#endif -#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) -# define CATCH_CONFIG_VARIADIC_MACROS -#endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_LONG_LONG -#endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_OVERRIDE -#endif -#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__) -# 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) -# define CATCH_CONFIG_CPP11_SHUFFLE -#endif -# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_TYPE_TRAITS -# endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) -# define CATCH_CONFIG_WINDOWS_SEH -#endif -// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. -#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_CONFIG_POSIX_SIGNALS -#endif - -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS -#endif - -// noexcept support: -#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) -# define CATCH_NOEXCEPT noexcept -# define CATCH_NOEXCEPT_IS(x) noexcept(x) -#else -# define CATCH_NOEXCEPT throw() -# define CATCH_NOEXCEPT_IS(x) -#endif - -// nullptr support -#ifdef CATCH_CONFIG_CPP11_NULLPTR -# define CATCH_NULL nullptr -#else -# define CATCH_NULL NULL -#endif - -// override support -#ifdef CATCH_CONFIG_CPP11_OVERRIDE -# define CATCH_OVERRIDE override -#else -# define CATCH_OVERRIDE -#endif - -// unique_ptr support -#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR -# define CATCH_AUTO_PTR( T ) std::unique_ptr -#else -# define CATCH_AUTO_PTR( T ) std::auto_ptr -#endif - -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) -#ifdef CATCH_CONFIG_COUNTER -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) -#else -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) -#endif - -#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr -#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) - -#include -#include - -namespace Catch { - - struct IConfig; - - struct CaseSensitive { enum Choice { - Yes, - No - }; }; - - class NonCopyable { -#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable& operator = ( NonCopyable const& ) = delete; - NonCopyable& operator = ( NonCopyable && ) = delete; -#else - NonCopyable( NonCopyable const& info ); - NonCopyable& operator = ( NonCopyable const& ); -#endif - - protected: - NonCopyable() {} - virtual ~NonCopyable(); - }; - - class SafeBool { - public: - typedef void (SafeBool::*type)() const; - - static type makeSafe( bool value ) { - return value ? &SafeBool::trueValue : 0; - } - private: - void trueValue() const {} - }; - - template - void deleteAll( ContainerT& container ) { - typename ContainerT::const_iterator it = container.begin(); - typename ContainerT::const_iterator itEnd = container.end(); - for(; it != itEnd; ++it ) - delete *it; - } - template - void deleteAllValues( AssociativeContainerT& container ) { - typename AssociativeContainerT::const_iterator it = container.begin(); - typename AssociativeContainerT::const_iterator itEnd = container.end(); - for(; it != itEnd; ++it ) - delete it->second; - } - - bool startsWith( std::string const& s, std::string const& prefix ); - bool startsWith( std::string const& s, char prefix ); - bool endsWith( std::string const& s, std::string const& suffix ); - bool endsWith( std::string const& s, char suffix ); - bool contains( std::string const& s, std::string const& infix ); - void toLowerInPlace( std::string& s ); - std::string toLower( std::string const& s ); - std::string trim( std::string const& str ); - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); - - struct pluralise { - pluralise( std::size_t count, std::string const& label ); - - friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); - - std::size_t m_count; - std::string m_label; - }; - - struct SourceLineInfo { - - SourceLineInfo(); - SourceLineInfo( char const* _file, std::size_t _line ); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - SourceLineInfo(SourceLineInfo const& other) = default; - SourceLineInfo( SourceLineInfo && ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo& operator = ( SourceLineInfo && ) = default; -# endif - bool empty() const; - bool operator == ( SourceLineInfo const& other ) const; - bool operator < ( SourceLineInfo const& other ) const; - - char const* file; - std::size_t line; - }; - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); - - // This is just here to avoid compiler warnings with macro constants and boolean literals - inline bool isTrue( bool value ){ return value; } - inline bool alwaysTrue() { return true; } - inline bool alwaysFalse() { return false; } - - void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); - - void seedRng( IConfig const& config ); - unsigned int rngSeed(); - - // Use this in variadic streaming macros to allow - // >> +StreamEndStop - // as well as - // >> stuff +StreamEndStop - struct StreamEndStop { - std::string operator+() { - return std::string(); - } - }; - template - T const& operator + ( T const& value, StreamEndStop ) { - return value; - } -} - -#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) -#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); - -namespace Catch { - - class NotImplementedException : public std::exception - { - public: - NotImplementedException( SourceLineInfo const& lineInfo ); - - virtual ~NotImplementedException() CATCH_NOEXCEPT {} - - virtual const char* what() const CATCH_NOEXCEPT; - - private: - std::string m_what; - SourceLineInfo m_lineInfo; - }; - -} // end namespace Catch - -/////////////////////////////////////////////////////////////////////////////// -#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) - -// #included from: internal/catch_context.h -#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED - -// #included from: catch_interfaces_generators.h -#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED - -#include - -namespace Catch { - - struct IGeneratorInfo { - virtual ~IGeneratorInfo(); - virtual bool moveNext() = 0; - virtual std::size_t getCurrentIndex() const = 0; - }; - - struct IGeneratorsForTest { - virtual ~IGeneratorsForTest(); - - virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; - virtual bool moveNext() = 0; - }; - - IGeneratorsForTest* createGeneratorsForTest(); - -} // end namespace Catch - -// #included from: catch_ptr.hpp -#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - // An intrusive reference counting smart pointer. - // T must implement addRef() and release() methods - // typically implementing the IShared interface - template - class Ptr { - public: - Ptr() : m_p( CATCH_NULL ){} - Ptr( T* p ) : m_p( p ){ - if( m_p ) - m_p->addRef(); - } - Ptr( Ptr const& other ) : m_p( other.m_p ){ - if( m_p ) - m_p->addRef(); - } - ~Ptr(){ - if( m_p ) - m_p->release(); - } - void reset() { - if( m_p ) - m_p->release(); - m_p = CATCH_NULL; - } - Ptr& operator = ( T* p ){ - Ptr temp( p ); - swap( temp ); - return *this; - } - Ptr& operator = ( Ptr const& other ){ - Ptr temp( other ); - swap( temp ); - return *this; - } - void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } - T* get() const{ return m_p; } - T& operator*() const { return *m_p; } - T* operator->() const { return m_p; } - bool operator !() const { return m_p == CATCH_NULL; } - operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } - - private: - T* m_p; - }; - - struct IShared : NonCopyable { - virtual ~IShared(); - virtual void addRef() const = 0; - virtual void release() const = 0; - }; - - template - struct SharedImpl : T { - - SharedImpl() : m_rc( 0 ){} - - virtual void addRef() const { - ++m_rc; - } - virtual void release() const { - if( --m_rc == 0 ) - delete this; - } - - mutable unsigned int m_rc; - }; - -} // end namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -namespace Catch { - - class TestCase; - class Stream; - struct IResultCapture; - struct IRunner; - struct IGeneratorsForTest; - struct IConfig; - - struct IContext - { - virtual ~IContext(); - - virtual IResultCapture* getResultCapture() = 0; - virtual IRunner* getRunner() = 0; - virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; - virtual bool advanceGeneratorsForCurrentTest() = 0; - virtual Ptr getConfig() const = 0; - }; - - struct IMutableContext : IContext - { - virtual ~IMutableContext(); - virtual void setResultCapture( IResultCapture* resultCapture ) = 0; - virtual void setRunner( IRunner* runner ) = 0; - virtual void setConfig( Ptr const& config ) = 0; - }; - - IContext& getCurrentContext(); - IMutableContext& getCurrentMutableContext(); - void cleanUpContext(); - Stream createStream( std::string const& streamName ); - -} - -// #included from: internal/catch_test_registry.hpp -#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED - -// #included from: catch_interfaces_testcase.h -#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED - -#include - -namespace Catch { - - class TestSpec; - - struct ITestCase : IShared { - virtual void invoke () const = 0; - protected: - virtual ~ITestCase(); - }; - - class TestCase; - struct IConfig; - - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const& getAllTests() const = 0; - virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; - }; - - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); - std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); - std::vector const& getAllTestCasesSorted( IConfig const& config ); - -} - -namespace Catch { - -template -class MethodTestCase : public SharedImpl { - -public: - MethodTestCase( void (C::*method)() ) : m_method( method ) {} - - virtual void invoke() const { - C obj; - (obj.*m_method)(); - } - -private: - virtual ~MethodTestCase() {} - - void (C::*m_method)(); -}; - -typedef void(*TestFunction)(); - -struct NameAndDesc { - NameAndDesc( const char* _name = "", const char* _description= "" ) - : name( _name ), description( _description ) - {} - - const char* name; - const char* description; -}; - -void registerTestCase - ( ITestCase* testCase, - char const* className, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ); - -struct AutoReg { - - AutoReg - ( TestFunction function, - SourceLineInfo const& lineInfo, - NameAndDesc const& nameAndDesc ); - - template - AutoReg - ( void (C::*method)(), - char const* className, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ) { - - registerTestCase - ( new MethodTestCase( method ), - className, - nameAndDesc, - lineInfo ); - } - - ~AutoReg(); - -private: - AutoReg( AutoReg const& ); - void operator= ( AutoReg const& ); -}; - -void registerTestCaseFunction - ( TestFunction function, - SourceLineInfo const& lineInfo, - NameAndDesc const& nameAndDesc ); - -} // end namespace Catch - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ - static void TestName(); \ - CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \ - CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ - static void TestName() - #define INTERNAL_CATCH_TESTCASE( ... ) \ - INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ - CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ - CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ - CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ \ - struct TestName : ClassName{ \ - void test(); \ - }; \ - Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ - } \ - CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ - void TestName::test() - #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ - INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ - CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \ - CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS - -#else - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ - static void TestName(); \ - CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \ - CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ - static void TestName() - #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ - INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ - CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ - CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ - CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ \ - struct TestCaseName : ClassName{ \ - void test(); \ - }; \ - Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ - } \ - CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ - void TestCaseName::test() - #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ - INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ - CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \ - CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS - -#endif - -// #included from: internal/catch_capture.hpp -#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED - -// #included from: catch_result_builder.h -#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED - -// #included from: catch_result_type.h -#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED - -namespace Catch { - - // ResultWas::OfType enum - struct ResultWas { enum OfType { - Unknown = -1, - Ok = 0, - Info = 1, - Warning = 2, - - FailureBit = 0x10, - - ExpressionFailed = FailureBit | 1, - ExplicitFailure = FailureBit | 2, - - Exception = 0x100 | FailureBit, - - ThrewException = Exception | 1, - DidntThrowException = Exception | 2, - - FatalErrorCondition = 0x200 | FailureBit - - }; }; - - inline bool isOk( ResultWas::OfType resultType ) { - return ( resultType & ResultWas::FailureBit ) == 0; - } - inline bool isJustInfo( int flags ) { - return flags == ResultWas::Info; - } - - // ResultDisposition::Flags enum - struct ResultDisposition { enum Flags { - Normal = 0x01, - - ContinueOnFailure = 0x02, // Failures fail test, but execution continues - FalseTest = 0x04, // Prefix expression with ! - SuppressFail = 0x08 // Failures are reported but do not fail the test - }; }; - - inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { - return static_cast( static_cast( lhs ) | static_cast( rhs ) ); - } - - inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } - inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } - inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } - -} // end namespace Catch - -// #included from: catch_assertionresult.h -#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED - -#include - -namespace Catch { - - struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; - - struct DecomposedExpression - { - virtual ~DecomposedExpression() {} - virtual bool isBinaryExpression() const { - return false; - } - virtual void reconstructExpression( std::string& dest ) const = 0; - - // Only simple binary comparisons can be decomposed. - // If more complex check is required then wrap sub-expressions in parentheses. - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); - template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); - - private: - DecomposedExpression& operator = (DecomposedExpression const&); - }; - - struct AssertionInfo - { - AssertionInfo(); - AssertionInfo( char const * _macroName, - SourceLineInfo const& _lineInfo, - char const * _capturedExpression, - ResultDisposition::Flags _resultDisposition, - char const * _secondArg = ""); - - char const * macroName; - SourceLineInfo lineInfo; - char const * capturedExpression; - ResultDisposition::Flags resultDisposition; - char const * secondArg; - }; - - struct AssertionResultData - { - AssertionResultData() : decomposedExpression( CATCH_NULL ) - , resultType( ResultWas::Unknown ) - , negated( false ) - , parenthesized( false ) {} - - void negate( bool parenthesize ) { - negated = !negated; - parenthesized = parenthesize; - if( resultType == ResultWas::Ok ) - resultType = ResultWas::ExpressionFailed; - else if( resultType == ResultWas::ExpressionFailed ) - resultType = ResultWas::Ok; - } - - std::string const& reconstructExpression() const { - if( decomposedExpression != CATCH_NULL ) { - decomposedExpression->reconstructExpression( reconstructedExpression ); - if( parenthesized ) { - reconstructedExpression.insert( 0, 1, '(' ); - reconstructedExpression.append( 1, ')' ); - } - if( negated ) { - reconstructedExpression.insert( 0, 1, '!' ); - } - decomposedExpression = CATCH_NULL; - } - return reconstructedExpression; - } - - mutable DecomposedExpression const* decomposedExpression; - mutable std::string reconstructedExpression; - std::string message; - ResultWas::OfType resultType; - bool negated; - bool parenthesized; - }; - - class AssertionResult { - public: - AssertionResult(); - AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); - ~AssertionResult(); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - AssertionResult( AssertionResult const& ) = default; - AssertionResult( AssertionResult && ) = default; - AssertionResult& operator = ( AssertionResult const& ) = default; - AssertionResult& operator = ( AssertionResult && ) = default; -# endif - - bool isOk() const; - bool succeeded() const; - ResultWas::OfType getResultType() const; - bool hasExpression() const; - bool hasMessage() const; - std::string getExpression() const; - std::string getExpressionInMacro() const; - bool hasExpandedExpression() const; - std::string getExpandedExpression() const; - std::string getMessage() const; - SourceLineInfo getSourceInfo() const; - std::string getTestMacroName() const; - void discardDecomposedExpression() const; - void expandDecomposedExpression() const; - - protected: - AssertionInfo m_info; - AssertionResultData m_resultData; - }; - -} // end namespace Catch - -// #included from: catch_matchers.hpp -#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED - -namespace Catch { -namespace Matchers { - namespace Impl { - - template struct MatchAllOf; - template struct MatchAnyOf; - template struct MatchNotOf; - - class MatcherUntypedBase { - public: - std::string toString() const { - if( m_cachedToString.empty() ) - m_cachedToString = describe(); - return m_cachedToString; - } - - protected: - virtual ~MatcherUntypedBase(); - virtual std::string describe() const = 0; - mutable std::string m_cachedToString; - private: - MatcherUntypedBase& operator = ( MatcherUntypedBase const& ); - }; - - template - struct MatcherMethod { - virtual bool match( ObjectT const& arg ) const = 0; - }; - template - struct MatcherMethod { - virtual bool match( PtrT* arg ) const = 0; - }; - - template - struct MatcherBase : MatcherUntypedBase, MatcherMethod { - - MatchAllOf operator && ( MatcherBase const& other ) const; - MatchAnyOf operator || ( MatcherBase const& other ) const; - MatchNotOf operator ! () const; - }; - - template - struct MatchAllOf : MatcherBase { - virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { - for( std::size_t i = 0; i < m_matchers.size(); ++i ) { - if (!m_matchers[i]->match(arg)) - return false; - } - return true; - } - virtual std::string describe() const CATCH_OVERRIDE { - std::string description; - description.reserve( 4 + m_matchers.size()*32 ); - description += "( "; - for( std::size_t i = 0; i < m_matchers.size(); ++i ) { - if( i != 0 ) - description += " and "; - description += m_matchers[i]->toString(); - } - description += " )"; - return description; - } - - MatchAllOf& operator && ( MatcherBase const& other ) { - m_matchers.push_back( &other ); - return *this; - } - - std::vector const*> m_matchers; - }; - template - struct MatchAnyOf : MatcherBase { - - virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { - for( std::size_t i = 0; i < m_matchers.size(); ++i ) { - if (m_matchers[i]->match(arg)) - return true; - } - return false; - } - virtual std::string describe() const CATCH_OVERRIDE { - std::string description; - description.reserve( 4 + m_matchers.size()*32 ); - description += "( "; - for( std::size_t i = 0; i < m_matchers.size(); ++i ) { - if( i != 0 ) - description += " or "; - description += m_matchers[i]->toString(); - } - description += " )"; - return description; - } - - MatchAnyOf& operator || ( MatcherBase const& other ) { - m_matchers.push_back( &other ); - return *this; - } - - std::vector const*> m_matchers; - }; - - template - struct MatchNotOf : MatcherBase { - - MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} - - virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { - return !m_underlyingMatcher.match( arg ); - } - - virtual std::string describe() const CATCH_OVERRIDE { - return "not " + m_underlyingMatcher.toString(); - } - MatcherBase const& m_underlyingMatcher; - }; - - template - MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const { - return MatchAllOf() && *this && other; - } - template - MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const { - return MatchAnyOf() || *this || other; - } - template - MatchNotOf MatcherBase::operator ! () const { - return MatchNotOf( *this ); - } - - } // namespace Impl - - // The following functions create the actual matcher objects. - // This allows the types to be inferred - // - deprecated: prefer ||, && and ! - template - Impl::MatchNotOf Not( Impl::MatcherBase const& underlyingMatcher ) { - return Impl::MatchNotOf( underlyingMatcher ); - } - template - Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { - return Impl::MatchAllOf() && m1 && m2; - } - template - Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { - return Impl::MatchAllOf() && m1 && m2 && m3; - } - template - Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { - return Impl::MatchAnyOf() || m1 || m2; - } - template - Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { - return Impl::MatchAnyOf() || m1 || m2 || m3; - } - -} // namespace Matchers - -using namespace Matchers; -using Matchers::Impl::MatcherBase; - -} // namespace Catch - -namespace Catch { - - struct TestFailureException{}; - - template class ExpressionLhs; - - struct CopyableStream { - CopyableStream() {} - CopyableStream( CopyableStream const& other ) { - oss << other.oss.str(); - } - CopyableStream& operator=( CopyableStream const& other ) { - oss.str(std::string()); - oss << other.oss.str(); - return *this; - } - std::ostringstream oss; - }; - - class ResultBuilder : public DecomposedExpression { - public: - ResultBuilder( char const* macroName, - SourceLineInfo const& lineInfo, - char const* capturedExpression, - ResultDisposition::Flags resultDisposition, - char const* secondArg = "" ); - ~ResultBuilder(); - - template - ExpressionLhs operator <= ( T const& operand ); - ExpressionLhs operator <= ( bool value ); - - template - ResultBuilder& operator << ( T const& value ) { - stream().oss << value; - return *this; - } - - ResultBuilder& setResultType( ResultWas::OfType result ); - ResultBuilder& setResultType( bool result ); - - void endExpression( DecomposedExpression const& expr ); - - virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; - - AssertionResult build() const; - AssertionResult build( DecomposedExpression const& expr ) const; - - void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); - void captureResult( ResultWas::OfType resultType ); - void captureExpression(); - void captureExpectedException( std::string const& expectedMessage ); - void captureExpectedException( Matchers::Impl::MatcherBase const& matcher ); - void handleResult( AssertionResult const& result ); - void react(); - bool shouldDebugBreak() const; - bool allowThrows() const; - - template - void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ); - - void setExceptionGuard(); - void unsetExceptionGuard(); - - private: - AssertionInfo m_assertionInfo; - AssertionResultData m_data; - - CopyableStream &stream() - { - if(!m_usedStream) - { - m_usedStream = true; - m_stream().oss.str(""); - } - return m_stream(); - } - - static CopyableStream &m_stream() - { - static CopyableStream s; - return s; - } - - bool m_shouldDebugBreak; - bool m_shouldThrow; - bool m_guardException; - bool m_usedStream; - }; - -} // namespace Catch - -// Include after due to circular dependency: -// #included from: catch_expression_lhs.hpp -#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED - -// #included from: catch_evaluate.hpp -#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4389) // '==' : signed/unsigned mismatch -#pragma warning(disable:4018) // more "signed/unsigned mismatch" -#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) -#endif - -#include - -namespace Catch { -namespace Internal { - - enum Operator { - IsEqualTo, - IsNotEqualTo, - IsLessThan, - IsGreaterThan, - IsLessThanOrEqualTo, - IsGreaterThanOrEqualTo - }; - - template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; - template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; - template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; - template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; - template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; - template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; - template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; - - template - T& removeConst(T const &t) { return const_cast(t); } -#ifdef CATCH_CONFIG_CPP11_NULLPTR - inline std::nullptr_t removeConst(std::nullptr_t) { return nullptr; } -#endif - - // 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. - template - struct Evaluator{}; - - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs) { - return bool(removeConst(lhs) == removeConst(rhs) ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) != removeConst(rhs) ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) < removeConst(rhs) ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) > removeConst(rhs) ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) >= removeConst(rhs) ); - } - }; - template - struct Evaluator { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return bool(removeConst(lhs) <= removeConst(rhs) ); - } - }; - - // Special case for comparing a pointer to an int (deduced for p==0) - template - struct Evaluator { - static bool evaluate( int lhs, T* rhs) { - return reinterpret_cast( lhs ) == rhs; - } - }; - template - struct Evaluator { - static bool evaluate( T* lhs, int rhs) { - return lhs == reinterpret_cast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( int lhs, T* rhs) { - return reinterpret_cast( lhs ) != rhs; - } - }; - template - struct Evaluator { - static bool evaluate( T* lhs, int rhs) { - return lhs != reinterpret_cast( rhs ); - } - }; - - template - struct Evaluator { - static bool evaluate( long lhs, T* rhs) { - return reinterpret_cast( lhs ) == rhs; - } - }; - template - struct Evaluator { - static bool evaluate( T* lhs, long rhs) { - return lhs == reinterpret_cast( rhs ); - } - }; - template - struct Evaluator { - static bool evaluate( long lhs, T* rhs) { - return reinterpret_cast( lhs ) != rhs; - } - }; - template - struct Evaluator { - static bool evaluate( T* lhs, long rhs) { - return lhs != reinterpret_cast( rhs ); - } - }; - -} // end of namespace Internal -} // end of namespace Catch - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -// #included from: catch_tostring.h -#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED - -#include -#include -#include -#include -#include - -#ifdef __OBJC__ -// #included from: catch_objc_arc.hpp -#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED - -#import - -#ifdef __has_feature -#define CATCH_ARC_ENABLED __has_feature(objc_arc) -#else -#define CATCH_ARC_ENABLED 0 -#endif - -void arcSafeRelease( NSObject* obj ); -id performOptionalSelector( id obj, SEL sel ); - -#if !CATCH_ARC_ENABLED -inline void arcSafeRelease( NSObject* obj ) { - [obj release]; -} -inline id performOptionalSelector( id obj, SEL sel ) { - if( [obj respondsToSelector: sel] ) - return [obj performSelector: sel]; - return nil; -} -#define CATCH_UNSAFE_UNRETAINED -#define CATCH_ARC_STRONG -#else -inline void arcSafeRelease( NSObject* ){} -inline id performOptionalSelector( id obj, SEL sel ) { -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" -#endif - if( [obj respondsToSelector: sel] ) - return [obj performSelector: sel]; -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - return nil; -} -#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained -#define CATCH_ARC_STRONG __strong -#endif - -#endif - -#ifdef CATCH_CONFIG_CPP11_TUPLE -#include -#endif - -#ifdef CATCH_CONFIG_CPP11_IS_ENUM -#include -#endif - -namespace Catch { - -// Why we're here. -template -std::string toString( T const& value ); - -// Built in overloads - -std::string toString( std::string const& value ); -std::string toString( std::wstring const& value ); -std::string toString( const char* const value ); -std::string toString( char* const value ); -std::string toString( const wchar_t* const value ); -std::string toString( wchar_t* const value ); -std::string toString( int value ); -std::string toString( unsigned long value ); -std::string toString( unsigned int value ); -std::string toString( const double value ); -std::string toString( const float value ); -std::string toString( bool value ); -std::string toString( char value ); -std::string toString( signed char value ); -std::string toString( unsigned char value ); - -#ifdef CATCH_CONFIG_CPP11_LONG_LONG -std::string toString( long long value ); -std::string toString( unsigned long long value ); -#endif - -#ifdef CATCH_CONFIG_CPP11_NULLPTR -std::string toString( std::nullptr_t ); -#endif - -#ifdef __OBJC__ - std::string toString( NSString const * const& nsstring ); - std::string toString( NSString * CATCH_ARC_STRONG & nsstring ); - std::string toString( NSObject* const& nsObject ); -#endif - -namespace Detail { - - extern const std::string unprintableString; - - #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK) - struct BorgType { - template BorgType( T const& ); - }; - - struct TrueType { char sizer[1]; }; - struct FalseType { char sizer[2]; }; - - TrueType& testStreamable( std::ostream& ); - FalseType testStreamable( FalseType ); - - FalseType operator<<( std::ostream const&, BorgType const& ); - - template - struct IsStreamInsertable { - static std::ostream &s; - static T const&t; - enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; - }; -#else - template - class IsStreamInsertable { - template - static auto test(int) - -> decltype( std::declval() << std::declval(), std::true_type() ); - - template - static auto test(...) -> std::false_type; - - public: - static const bool value = decltype(test(0))::value; - }; -#endif - -#if defined(CATCH_CONFIG_CPP11_IS_ENUM) - template::value - > - struct EnumStringMaker - { - static std::string convert( T const& ) { return unprintableString; } - }; - - template - struct EnumStringMaker - { - static std::string convert( T const& v ) - { - return ::Catch::toString( - static_cast::type>(v) - ); - } - }; -#endif - template - struct StringMakerBase { -#if defined(CATCH_CONFIG_CPP11_IS_ENUM) - template - static std::string convert( T const& v ) - { - return EnumStringMaker::convert( v ); - } -#else - template - static std::string convert( T const& ) { return unprintableString; } -#endif - }; - - template<> - struct StringMakerBase { - template - static std::string convert( T const& _value ) { - std::ostringstream oss; - oss << _value; - return oss.str(); - } - }; - - std::string rawMemoryToString( const void *object, std::size_t size ); - - template - std::string rawMemoryToString( const T& object ) { - return rawMemoryToString( &object, sizeof(object) ); - } - -} // end namespace Detail - -template -struct StringMaker : - Detail::StringMakerBase::value> {}; - -template -struct StringMaker { - template - static std::string convert( U* p ) { - if( !p ) - return "NULL"; - else - return Detail::rawMemoryToString( p ); - } -}; - -template -struct StringMaker { - static std::string convert( R C::* p ) { - if( !p ) - return "NULL"; - else - return Detail::rawMemoryToString( p ); - } -}; - -namespace Detail { - template - std::string rangeToString( InputIterator first, InputIterator last ); -} - -//template -//struct StringMaker > { -// static std::string convert( std::vector const& v ) { -// return Detail::rangeToString( v.begin(), v.end() ); -// } -//}; - -template -std::string toString( std::vector const& v ) { - return Detail::rangeToString( v.begin(), v.end() ); -} - -#ifdef CATCH_CONFIG_CPP11_TUPLE - -// toString for tuples -namespace TupleDetail { - template< - typename Tuple, - std::size_t N = 0, - bool = (N < std::tuple_size::value) - > - struct ElementPrinter { - static void print( const Tuple& tuple, std::ostream& os ) - { - os << ( N ? ", " : " " ) - << Catch::toString(std::get(tuple)); - ElementPrinter::print(tuple,os); - } - }; - - template< - typename Tuple, - std::size_t N - > - struct ElementPrinter { - static void print( const Tuple&, std::ostream& ) {} - }; - -} - -template -struct StringMaker> { - - static std::string convert( const std::tuple& tuple ) - { - std::ostringstream os; - os << '{'; - TupleDetail::ElementPrinter>::print( tuple, os ); - os << " }"; - return os.str(); - } -}; -#endif // CATCH_CONFIG_CPP11_TUPLE - -namespace Detail { - template - std::string makeString( T const& value ) { - return StringMaker::convert( value ); - } -} // end namespace Detail - -/// \brief converts any type to a string -/// -/// The default template forwards on to ostringstream - except when an -/// ostringstream overload does not exist - in which case it attempts to detect -/// that and writes {?}. -/// Overload (not specialise) this template for custom typs that you don't want -/// to provide an ostream overload for. -template -std::string toString( T const& value ) { - return StringMaker::convert( value ); -} - - namespace Detail { - template - std::string rangeToString( InputIterator first, InputIterator last ) { - std::ostringstream oss; - oss << "{ "; - if( first != last ) { - oss << Catch::toString( *first ); - for( ++first ; first != last ; ++first ) - oss << ", " << Catch::toString( *first ); - } - oss << " }"; - return oss.str(); - } -} - -} // end namespace Catch - -namespace Catch { - -template -class BinaryExpression; - -template -class MatchExpression; - -// Wraps the LHS of an expression and overloads comparison operators -// for also capturing those and RHS (if any) -template -class ExpressionLhs : public DecomposedExpression { -public: - ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {} - - ExpressionLhs& operator = ( const ExpressionLhs& ); - - template - BinaryExpression - operator == ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - BinaryExpression - operator != ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - BinaryExpression - operator < ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - BinaryExpression - operator > ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - BinaryExpression - operator <= ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - template - BinaryExpression - operator >= ( RhsT const& rhs ) { - return captureExpression( rhs ); - } - - BinaryExpression operator == ( bool rhs ) { - return captureExpression( rhs ); - } - - BinaryExpression operator != ( bool rhs ) { - return captureExpression( rhs ); - } - - void endExpression() { - m_truthy = m_lhs ? true : false; - m_rb - .setResultType( m_truthy ) - .endExpression( *this ); - } - - virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { - dest = Catch::toString( m_lhs ); - } - -private: - template - BinaryExpression captureExpression( RhsT& rhs ) const { - return BinaryExpression( m_rb, m_lhs, rhs ); - } - - template - BinaryExpression captureExpression( bool rhs ) const { - return BinaryExpression( m_rb, m_lhs, rhs ); - } - -private: - ResultBuilder& m_rb; - T m_lhs; - bool m_truthy; -}; - -template -class BinaryExpression : public DecomposedExpression { -public: - BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs ) - : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {} - - BinaryExpression& operator = ( BinaryExpression& ); - - void endExpression() const { - m_rb - .setResultType( Internal::Evaluator::evaluate( m_lhs, m_rhs ) ) - .endExpression( *this ); - } - - virtual bool isBinaryExpression() const CATCH_OVERRIDE { - return true; - } - - virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { - std::string lhs = Catch::toString( m_lhs ); - std::string rhs = Catch::toString( m_rhs ); - char delim = lhs.size() + rhs.size() < 40 && - lhs.find('\n') == std::string::npos && - rhs.find('\n') == std::string::npos ? ' ' : '\n'; - dest.reserve( 7 + lhs.size() + rhs.size() ); - // 2 for spaces around operator - // 2 for operator - // 2 for parentheses (conditionally added later) - // 1 for negation (conditionally added later) - dest = lhs; - dest += delim; - dest += Internal::OperatorTraits::getName(); - dest += delim; - dest += rhs; - } - -private: - ResultBuilder& m_rb; - LhsT m_lhs; - RhsT m_rhs; -}; - -template -class MatchExpression : public DecomposedExpression { -public: - MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString ) - : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {} - - virtual bool isBinaryExpression() const CATCH_OVERRIDE { - return true; - } - - virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { - std::string matcherAsString = m_matcher.toString(); - dest = Catch::toString( m_arg ); - dest += ' '; - if( matcherAsString == Detail::unprintableString ) - dest += m_matcherString; - else - dest += matcherAsString; - } - -private: - ArgT m_arg; - MatcherT m_matcher; - char const* m_matcherString; -}; - -} // end namespace Catch - - -namespace Catch { - - template - ExpressionLhs ResultBuilder::operator <= ( T const& operand ) { - return ExpressionLhs( *this, operand ); - } - - inline ExpressionLhs ResultBuilder::operator <= ( bool value ) { - return ExpressionLhs( *this, value ); - } - - template - void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, - char const* matcherString ) { - MatchExpression expr( arg, matcher, matcherString ); - setResultType( matcher.match( arg ) ); - endExpression( expr ); - } - -} // namespace Catch - -// #included from: catch_message.h -#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED - -#include - -namespace Catch { - - struct MessageInfo { - MessageInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ); - - std::string macroName; - SourceLineInfo lineInfo; - ResultWas::OfType type; - std::string message; - unsigned int sequence; - - bool operator == ( MessageInfo const& other ) const { - return sequence == other.sequence; - } - bool operator < ( MessageInfo const& other ) const { - return sequence < other.sequence; - } - private: - static unsigned int globalCount; - }; - - struct MessageBuilder { - MessageBuilder( std::string const& macroName, - SourceLineInfo const& lineInfo, - ResultWas::OfType type ) - : m_info( macroName, lineInfo, type ) - {} - - template - MessageBuilder& operator << ( T const& value ) { - m_stream << value; - return *this; - } - - MessageInfo m_info; - std::ostringstream m_stream; - }; - - class ScopedMessage { - public: - ScopedMessage( MessageBuilder const& builder ); - ScopedMessage( ScopedMessage const& other ); - ~ScopedMessage(); - - MessageInfo m_info; - }; - -} // end namespace Catch - -// #included from: catch_interfaces_capture.h -#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED - -#include - -namespace Catch { - - class TestCase; - class AssertionResult; - struct AssertionInfo; - struct SectionInfo; - struct SectionEndInfo; - struct MessageInfo; - class ScopedMessageBuilder; - struct Counts; - - struct IResultCapture { - - virtual ~IResultCapture(); - - virtual void assertionEnded( AssertionResult const& result ) = 0; - virtual bool sectionStarted( SectionInfo const& sectionInfo, - Counts& assertions ) = 0; - virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; - virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; - virtual void pushScopedMessage( MessageInfo const& message ) = 0; - virtual void popScopedMessage( MessageInfo const& message ) = 0; - - virtual std::string getCurrentTestName() const = 0; - virtual const AssertionResult* getLastResult() const = 0; - - virtual void exceptionEarlyReported() = 0; - - virtual void handleFatalErrorCondition( std::string const& message ) = 0; - - virtual bool lastAssertionPassed() = 0; - virtual void assertionPassed() = 0; - virtual void assertionRun() = 0; - }; - - IResultCapture& getResultCapture(); -} - -// #included from: catch_debugger.h -#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED - -// #included from: catch_platform.h -#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED - -#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) -# define CATCH_PLATFORM_MAC -#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) -# define CATCH_PLATFORM_IPHONE -#elif defined(linux) || defined(__linux) || defined(__linux__) -# define CATCH_PLATFORM_LINUX -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) -# define CATCH_PLATFORM_WINDOWS -# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) -# define CATCH_DEFINES_NOMINMAX -# endif -# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) -# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN -# endif -#endif - -#include - -namespace Catch{ - - bool isDebuggerActive(); - void writeToDebugConsole( std::string const& text ); -} - -#ifdef CATCH_PLATFORM_MAC - - // The following code snippet based on: - // http://cocoawithlove.com/2008/03/break-into-debugger.html - #if defined(__ppc64__) || defined(__ppc__) - #define CATCH_TRAP() \ - __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ - : : : "memory","r0","r3","r4" ) /* NOLINT */ - #else - #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ ) - #endif - -#elif defined(CATCH_PLATFORM_LINUX) - // If we can use inline assembler, do it because this allows us to break - // directly at the location of the failing check instead of breaking inside - // raise() called from it, i.e. one stack frame below. - #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) - #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ - #else // Fall back to the generic way. - #include - - #define CATCH_TRAP() raise(SIGTRAP) - #endif -#elif defined(_MSC_VER) - #define CATCH_TRAP() __debugbreak() -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) void __stdcall DebugBreak(); - #define CATCH_TRAP() DebugBreak() -#endif - -#ifdef CATCH_TRAP - #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } -#else - #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); -#endif - -// #included from: catch_interfaces_runner.h -#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED - -namespace Catch { - class TestCase; - - struct IRunner { - virtual ~IRunner(); - virtual bool aborting() const = 0; - }; -} - -#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) -# define CATCH_INTERNAL_STRINGIFY(expr) #expr -#else -# define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" -#endif - -#if defined(CATCH_CONFIG_FAST_COMPILE) -/////////////////////////////////////////////////////////////////////////////// -// We can speedup compilation significantly by breaking into debugger lower in -// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER -// macro in each assertion -#define INTERNAL_CATCH_REACT( resultBuilder ) \ - resultBuilder.react(); - -/////////////////////////////////////////////////////////////////////////////// -// Another way to speed-up compilation is to omit local try-catch for REQUIRE* -// macros. -// This can potentially cause false negative, if the test code catches -// the exception before it propagates back up to the runner. -#define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ - __catchResult.setExceptionGuard(); \ - CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - ( __catchResult <= expr ).endExpression(); \ - CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - __catchResult.unsetExceptionGuard(); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look -// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. - -#define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ - __catchResult.setExceptionGuard(); \ - __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ - __catchResult.unsetExceptionGuard(); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -#else -/////////////////////////////////////////////////////////////////////////////// -// In the event of a failure works out if the debugger needs to be invoked -// and/or an exception thrown and takes appropriate action. -// This needs to be done as a macro so the debugger will stop in the user -// source code rather than in Catch library code -#define INTERNAL_CATCH_REACT( resultBuilder ) \ - if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ - resultBuilder.react(); -#endif - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ - try { \ - CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - ( __catchResult <= expr ).endExpression(); \ - CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( resultDisposition ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look - // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \ - INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ - if( Catch::getResultCapture().lastAssertionPassed() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \ - INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ - if( !Catch::getResultCapture().lastAssertionPassed() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ - try { \ - static_cast(expr); \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( resultDisposition ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \ - if( __catchResult.allowThrows() ) \ - try { \ - static_cast(expr); \ - __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ - } \ - catch( ... ) { \ - __catchResult.captureExpectedException( matcher ); \ - } \ - else \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ - if( __catchResult.allowThrows() ) \ - try { \ - static_cast(expr); \ - __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ - } \ - catch( exceptionType ) { \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( resultDisposition ); \ - } \ - else \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ - __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ - __catchResult.captureResult( messageType ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) -#else - #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ - __catchResult << log + ::Catch::StreamEndStop(); \ - __catchResult.captureResult( messageType ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) -#endif - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_INFO( macroName, log ) \ - Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ - try { \ - __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ - } catch( ... ) { \ - __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -// #included from: internal/catch_section.h -#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED - -// #included from: catch_section_info.h -#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED - -// #included from: catch_totals.hpp -#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED - -#include - -namespace Catch { - - struct Counts { - Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} - - Counts operator - ( Counts const& other ) const { - Counts diff; - diff.passed = passed - other.passed; - diff.failed = failed - other.failed; - diff.failedButOk = failedButOk - other.failedButOk; - return diff; - } - Counts& operator += ( Counts const& other ) { - passed += other.passed; - failed += other.failed; - failedButOk += other.failedButOk; - return *this; - } - - std::size_t total() const { - return passed + failed + failedButOk; - } - bool allPassed() const { - return failed == 0 && failedButOk == 0; - } - bool allOk() const { - return failed == 0; - } - - std::size_t passed; - std::size_t failed; - std::size_t failedButOk; - }; - - struct Totals { - - Totals operator - ( Totals const& other ) const { - Totals diff; - diff.assertions = assertions - other.assertions; - diff.testCases = testCases - other.testCases; - return diff; - } - - Totals delta( Totals const& prevTotals ) const { - Totals diff = *this - prevTotals; - if( diff.assertions.failed > 0 ) - ++diff.testCases.failed; - else if( diff.assertions.failedButOk > 0 ) - ++diff.testCases.failedButOk; - else - ++diff.testCases.passed; - return diff; - } - - Totals& operator += ( Totals const& other ) { - assertions += other.assertions; - testCases += other.testCases; - return *this; - } - - Counts assertions; - Counts testCases; - }; -} - -#include - -namespace Catch { - - struct SectionInfo { - SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name, - std::string const& _description = std::string() ); - - std::string name; - std::string description; - SourceLineInfo lineInfo; - }; - - struct SectionEndInfo { - SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) - : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) - {} - - SectionInfo sectionInfo; - Counts prevAssertions; - double durationInSeconds; - }; - -} // end namespace Catch - -// #included from: catch_timer.h -#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED - -#ifdef _MSC_VER - -namespace Catch { - typedef unsigned long long UInt64; -} -#else -#include -namespace Catch { - typedef uint64_t UInt64; -} -#endif - -namespace Catch { - class Timer { - public: - Timer() : m_ticks( 0 ) {} - void start(); - unsigned int getElapsedMicroseconds() const; - unsigned int getElapsedMilliseconds() const; - double getElapsedSeconds() const; - - private: - UInt64 m_ticks; - }; - -} // namespace Catch - -#include - -namespace Catch { - - class Section : NonCopyable { - public: - Section( SectionInfo const& info ); - ~Section(); - - // This indicates whether the section should be executed or not - operator bool() const; - - private: - SectionInfo m_info; - - std::string m_name; - Counts m_assertions; - bool m_sectionIncluded; - Timer m_timer; - }; - -} // end namespace Catch - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define INTERNAL_CATCH_SECTION( ... ) \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) -#else - #define INTERNAL_CATCH_SECTION( name, desc ) \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) -#endif - -// #included from: internal/catch_generators.hpp -#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED - -#include -#include -#include - -namespace Catch { - -template -struct IGenerator { - virtual ~IGenerator() {} - virtual T getValue( std::size_t index ) const = 0; - virtual std::size_t size () const = 0; -}; - -template -class BetweenGenerator : public IGenerator { -public: - BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} - - virtual T getValue( std::size_t index ) const { - return m_from+static_cast( index ); - } - - virtual std::size_t size() const { - return static_cast( 1+m_to-m_from ); - } - -private: - - T m_from; - T m_to; -}; - -template -class ValuesGenerator : public IGenerator { -public: - ValuesGenerator(){} - - void add( T value ) { - m_values.push_back( value ); - } - - virtual T getValue( std::size_t index ) const { - return m_values[index]; - } - - virtual std::size_t size() const { - return m_values.size(); - } - -private: - std::vector m_values; -}; - -template -class CompositeGenerator { -public: - CompositeGenerator() : m_totalSize( 0 ) {} - - // *** Move semantics, similar to auto_ptr *** - CompositeGenerator( CompositeGenerator& other ) - : m_fileInfo( other.m_fileInfo ), - m_totalSize( 0 ) - { - move( other ); - } - - CompositeGenerator& setFileInfo( const char* fileInfo ) { - m_fileInfo = fileInfo; - return *this; - } - - ~CompositeGenerator() { - deleteAll( m_composed ); - } - - operator T () const { - size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); - - typename std::vector*>::const_iterator it = m_composed.begin(); - typename std::vector*>::const_iterator itEnd = m_composed.end(); - for( size_t index = 0; it != itEnd; ++it ) - { - const IGenerator* generator = *it; - if( overallIndex >= index && overallIndex < index + generator->size() ) - { - return generator->getValue( overallIndex-index ); - } - index += generator->size(); - } - CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); - return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so - } - - void add( const IGenerator* generator ) { - m_totalSize += generator->size(); - m_composed.push_back( generator ); - } - - CompositeGenerator& then( CompositeGenerator& other ) { - move( other ); - return *this; - } - - CompositeGenerator& then( T value ) { - ValuesGenerator* valuesGen = new ValuesGenerator(); - valuesGen->add( value ); - add( valuesGen ); - return *this; - } - -private: - - void move( CompositeGenerator& other ) { - m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() ); - m_totalSize += other.m_totalSize; - other.m_composed.clear(); - } - - std::vector*> m_composed; - std::string m_fileInfo; - size_t m_totalSize; -}; - -namespace Generators -{ - template - CompositeGenerator between( T from, T to ) { - CompositeGenerator generators; - generators.add( new BetweenGenerator( from, to ) ); - return generators; - } - - template - CompositeGenerator values( T val1, T val2 ) { - CompositeGenerator generators; - ValuesGenerator* valuesGen = new ValuesGenerator(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - generators.add( valuesGen ); - return generators; - } - - template - CompositeGenerator values( T val1, T val2, T val3 ){ - CompositeGenerator generators; - ValuesGenerator* valuesGen = new ValuesGenerator(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - valuesGen->add( val3 ); - generators.add( valuesGen ); - return generators; - } - - template - CompositeGenerator values( T val1, T val2, T val3, T val4 ) { - CompositeGenerator generators; - ValuesGenerator* valuesGen = new ValuesGenerator(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - valuesGen->add( val3 ); - valuesGen->add( val4 ); - generators.add( valuesGen ); - return generators; - } - -} // end namespace Generators - -using namespace Generators; - -} // end namespace Catch - -#define INTERNAL_CATCH_LINESTR2( line ) #line -#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) - -#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) - -// #included from: internal/catch_interfaces_exception.h -#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED - -#include -#include - -// #included from: catch_interfaces_registry_hub.h -#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED - -#include - -namespace Catch { - - class TestCase; - struct ITestCaseRegistry; - struct IExceptionTranslatorRegistry; - struct IExceptionTranslator; - struct IReporterRegistry; - struct IReporterFactory; - struct ITagAliasRegistry; - - struct IRegistryHub { - virtual ~IRegistryHub(); - - virtual IReporterRegistry const& getReporterRegistry() const = 0; - virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; - virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; - - virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; - }; - - struct IMutableRegistryHub { - virtual ~IMutableRegistryHub(); - virtual void registerReporter( std::string const& name, Ptr const& factory ) = 0; - virtual void registerListener( Ptr const& factory ) = 0; - virtual void registerTest( TestCase const& testInfo ) = 0; - virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; - virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; - }; - - IRegistryHub& getRegistryHub(); - IMutableRegistryHub& getMutableRegistryHub(); - void cleanUp(); - std::string translateActiveException(); - -} - -namespace Catch { - - typedef std::string(*exceptionTranslateFunction)(); - - struct IExceptionTranslator; - typedef std::vector ExceptionTranslators; - - struct IExceptionTranslator { - virtual ~IExceptionTranslator(); - virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; - }; - - struct IExceptionTranslatorRegistry { - virtual ~IExceptionTranslatorRegistry(); - - virtual std::string translateActiveException() const = 0; - }; - - class ExceptionTranslatorRegistrar { - template - class ExceptionTranslator : public IExceptionTranslator { - public: - - ExceptionTranslator( std::string(*translateFunction)( T& ) ) - : m_translateFunction( translateFunction ) - {} - - virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { - try { - if( it == itEnd ) - throw; - else - return (*it)->translate( it+1, itEnd ); - } - catch( T& ex ) { - return m_translateFunction( ex ); - } - } - - protected: - std::string(*m_translateFunction)( T& ); - }; - - public: - template - ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { - getMutableRegistryHub().registerTranslator - ( new ExceptionTranslator( translateFunction ) ); - } - }; -} - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ - static std::string translatorName( signature ); \ - namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ - static std::string translatorName( signature ) - -#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) - -// #included from: internal/catch_approx.hpp -#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED - -#include -#include - -#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) -#include -#endif - -namespace Catch { -namespace Detail { - - class Approx { - public: - explicit Approx ( double value ) - : m_epsilon( std::numeric_limits::epsilon()*100 ), - m_margin( 0.0 ), - m_scale( 1.0 ), - m_value( value ) - {} - - static Approx custom() { - return Approx( 0 ); - } - -#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) - - template ::value>::type> - Approx operator()( T value ) { - Approx approx( static_cast(value) ); - approx.epsilon( m_epsilon ); - approx.margin( m_margin ); - approx.scale( m_scale ); - return approx; - } - - template ::value>::type> - explicit Approx( T value ): Approx(static_cast(value)) - {} - - template ::value>::type> - friend bool operator == ( const T& lhs, Approx const& rhs ) { - // Thanks to Richard Harris for his help refining this formula - auto lhs_v = double(lhs); - bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value))); - if (relativeOK) { - return true; - } - return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin; - } - - template ::value>::type> - friend bool operator == ( Approx const& lhs, const T& rhs ) { - return operator==( rhs, lhs ); - } - - template ::value>::type> - friend bool operator != ( T lhs, Approx const& rhs ) { - return !operator==( lhs, rhs ); - } - - template ::value>::type> - friend bool operator != ( Approx const& lhs, T rhs ) { - return !operator==( rhs, lhs ); - } - - template ::value>::type> - friend bool operator <= ( T lhs, Approx const& rhs ) { - return double(lhs) < rhs.m_value || lhs == rhs; - } - - template ::value>::type> - friend bool operator <= ( Approx const& lhs, T rhs ) { - return lhs.m_value < double(rhs) || lhs == rhs; - } - - template ::value>::type> - friend bool operator >= ( T lhs, Approx const& rhs ) { - return double(lhs) > rhs.m_value || lhs == rhs; - } - - template ::value>::type> - friend bool operator >= ( Approx const& lhs, T rhs ) { - return lhs.m_value > double(rhs) || lhs == rhs; - } - - template ::value>::type> - Approx& epsilon( T newEpsilon ) { - m_epsilon = double(newEpsilon); - return *this; - } - - template ::value>::type> - Approx& margin( T newMargin ) { - m_margin = double(newMargin); - return *this; - } - - template ::value>::type> - Approx& scale( T newScale ) { - m_scale = double(newScale); - return *this; - } - -#else - - Approx operator()( double value ) { - Approx approx( value ); - approx.epsilon( m_epsilon ); - approx.margin( m_margin ); - approx.scale( m_scale ); - return approx; - } - - friend bool operator == ( double lhs, Approx const& rhs ) { - // Thanks to Richard Harris for his help refining this formula - bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) ); - if (relativeOK) { - return true; - } - return std::fabs(lhs - rhs.m_value) < rhs.m_margin; - } - - friend bool operator == ( Approx const& lhs, double rhs ) { - return operator==( rhs, lhs ); - } - - friend bool operator != ( double lhs, Approx const& rhs ) { - return !operator==( lhs, rhs ); - } - - friend bool operator != ( Approx const& lhs, double rhs ) { - return !operator==( rhs, lhs ); - } - - friend bool operator <= ( double lhs, Approx const& rhs ) { - return lhs < rhs.m_value || lhs == rhs; - } - - friend bool operator <= ( Approx const& lhs, double rhs ) { - return lhs.m_value < rhs || lhs == rhs; - } - - friend bool operator >= ( double lhs, Approx const& rhs ) { - return lhs > rhs.m_value || lhs == rhs; - } - - friend bool operator >= ( Approx const& lhs, double rhs ) { - return lhs.m_value > rhs || lhs == rhs; - } - - Approx& epsilon( double newEpsilon ) { - m_epsilon = newEpsilon; - return *this; - } - - Approx& margin( double newMargin ) { - m_margin = newMargin; - return *this; - } - - Approx& scale( double newScale ) { - m_scale = newScale; - return *this; - } -#endif - - std::string toString() const { - std::ostringstream oss; - oss << "Approx( " << Catch::toString( m_value ) << " )"; - return oss.str(); - } - - private: - double m_epsilon; - double m_margin; - double m_scale; - double m_value; - }; -} - -template<> -inline std::string toString( Detail::Approx const& value ) { - return value.toString(); -} - -} // end namespace Catch - -// #included from: internal/catch_matchers_string.h -#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED - -namespace Catch { -namespace Matchers { - - namespace StdString { - - struct CasedString - { - CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); - std::string adjustString( std::string const& str ) const; - std::string caseSensitivitySuffix() const; - - CaseSensitive::Choice m_caseSensitivity; - std::string m_str; - }; - - struct StringMatcherBase : MatcherBase { - StringMatcherBase( std::string const& operation, CasedString const& comparator ); - virtual std::string describe() const CATCH_OVERRIDE; - - CasedString m_comparator; - std::string m_operation; - }; - - struct EqualsMatcher : StringMatcherBase { - EqualsMatcher( CasedString const& comparator ); - virtual bool match( std::string const& source ) const CATCH_OVERRIDE; - }; - struct ContainsMatcher : StringMatcherBase { - ContainsMatcher( CasedString const& comparator ); - virtual bool match( std::string const& source ) const CATCH_OVERRIDE; - }; - struct StartsWithMatcher : StringMatcherBase { - StartsWithMatcher( CasedString const& comparator ); - virtual bool match( std::string const& source ) const CATCH_OVERRIDE; - }; - struct EndsWithMatcher : StringMatcherBase { - EndsWithMatcher( CasedString const& comparator ); - virtual bool match( std::string const& source ) const CATCH_OVERRIDE; - }; - - } // namespace StdString - - // The following functions create the actual matcher objects. - // This allows the types to be inferred - - StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); - -} // namespace Matchers -} // namespace Catch - -// #included from: internal/catch_matchers_vector.h -#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED - -namespace Catch { -namespace Matchers { - - namespace Vector { - - template - struct ContainsElementMatcher : MatcherBase, T> { - - ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} - - bool match(std::vector const &v) const CATCH_OVERRIDE { - return std::find(v.begin(), v.end(), m_comparator) != v.end(); - } - - virtual std::string describe() const CATCH_OVERRIDE { - return "Contains: " + Catch::toString( m_comparator ); - } - - T const& m_comparator; - }; - - template - struct ContainsMatcher : MatcherBase, std::vector > { - - ContainsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} - - bool match(std::vector const &v) const CATCH_OVERRIDE { - // !TBD: see note in EqualsMatcher - if (m_comparator.size() > v.size()) - return false; - for (size_t i = 0; i < m_comparator.size(); ++i) - if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end()) - return false; - return true; - } - virtual std::string describe() const CATCH_OVERRIDE { - return "Contains: " + Catch::toString( m_comparator ); - } - - std::vector const& m_comparator; - }; - - template - struct EqualsMatcher : MatcherBase, std::vector > { - - EqualsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} - - bool match(std::vector const &v) const CATCH_OVERRIDE { - // !TBD: This currently works if all elements can be compared using != - // - a more general approach would be via a compare template that defaults - // to using !=. but could be specialised for, e.g. std::vector etc - // - then just call that directly - if (m_comparator.size() != v.size()) - return false; - for (size_t i = 0; i < v.size(); ++i) - if (m_comparator[i] != v[i]) - return false; - return true; - } - virtual std::string describe() const CATCH_OVERRIDE { - return "Equals: " + Catch::toString( m_comparator ); - } - std::vector const& m_comparator; - }; - - } // namespace Vector - - // The following functions create the actual matcher objects. - // This allows the types to be inferred - - template - Vector::ContainsMatcher Contains( std::vector const& comparator ) { - return Vector::ContainsMatcher( comparator ); - } - - template - Vector::ContainsElementMatcher VectorContains( T const& comparator ) { - return Vector::ContainsElementMatcher( comparator ); - } - - template - Vector::EqualsMatcher Equals( std::vector const& comparator ) { - return Vector::EqualsMatcher( comparator ); - } - -} // namespace Matchers -} // namespace Catch - -// #included from: internal/catch_interfaces_tag_alias_registry.h -#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED - -// #included from: catch_tag_alias.h -#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED - -#include - -namespace Catch { - - struct TagAlias { - TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} - - std::string tag; - SourceLineInfo lineInfo; - }; - - struct RegistrarForTagAliases { - RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - }; - -} // end namespace Catch - -#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } -// #included from: catch_option.hpp -#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED - -namespace Catch { - - // An optional type - template - class Option { - public: - Option() : nullableValue( CATCH_NULL ) {} - Option( T const& _value ) - : nullableValue( new( storage ) T( _value ) ) - {} - Option( Option const& _other ) - : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) - {} - - ~Option() { - reset(); - } - - Option& operator= ( Option const& _other ) { - if( &_other != this ) { - reset(); - if( _other ) - nullableValue = new( storage ) T( *_other ); - } - return *this; - } - Option& operator = ( T const& _value ) { - reset(); - nullableValue = new( storage ) T( _value ); - return *this; - } - - void reset() { - if( nullableValue ) - nullableValue->~T(); - nullableValue = CATCH_NULL; - } - - T& operator*() { return *nullableValue; } - T const& operator*() const { return *nullableValue; } - T* operator->() { return nullableValue; } - const T* operator->() const { return nullableValue; } - - T valueOr( T const& defaultValue ) const { - return nullableValue ? *nullableValue : defaultValue; - } - - bool some() const { return nullableValue != CATCH_NULL; } - bool none() const { return nullableValue == CATCH_NULL; } - - bool operator !() const { return nullableValue == CATCH_NULL; } - operator SafeBool::type() const { - return SafeBool::makeSafe( some() ); - } - - private: - T *nullableValue; - union { - char storage[sizeof(T)]; - - // These are here to force alignment for the storage - long double dummy1; - void (*dummy2)(); - long double dummy3; -#ifdef CATCH_CONFIG_CPP11_LONG_LONG - long long dummy4; -#endif - }; - }; - -} // end namespace Catch - -namespace Catch { - - struct ITagAliasRegistry { - virtual ~ITagAliasRegistry(); - virtual Option find( std::string const& alias ) const = 0; - virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; - - static ITagAliasRegistry const& get(); - }; - -} // end namespace Catch - -// These files are included here so the single_include script doesn't put them -// in the conditionally compiled sections -// #included from: internal/catch_test_case_info.h -#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED - -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - struct ITestCase; - - struct TestCaseInfo { - enum SpecialProperties{ - None = 0, - IsHidden = 1 << 1, - ShouldFail = 1 << 2, - MayFail = 1 << 3, - Throws = 1 << 4, - NonPortable = 1 << 5 - }; - - TestCaseInfo( std::string const& _name, - std::string const& _className, - std::string const& _description, - std::set const& _tags, - SourceLineInfo const& _lineInfo ); - - TestCaseInfo( TestCaseInfo const& other ); - - friend void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ); - - bool isHidden() const; - bool throws() const; - bool okToFail() const; - bool expectedToFail() const; - - std::string name; - std::string className; - std::string description; - std::set tags; - std::set lcaseTags; - std::string tagsAsString; - SourceLineInfo lineInfo; - SpecialProperties properties; - }; - - class TestCase : public TestCaseInfo { - public: - - TestCase( ITestCase* testCase, TestCaseInfo const& info ); - TestCase( TestCase const& other ); - - TestCase withName( std::string const& _newName ) const; - - void invoke() const; - - TestCaseInfo const& getTestCaseInfo() const; - - void swap( TestCase& other ); - bool operator == ( TestCase const& other ) const; - bool operator < ( TestCase const& other ) const; - TestCase& operator = ( TestCase const& other ); - - private: - Ptr test; - }; - - TestCase makeTestCase( ITestCase* testCase, - std::string const& className, - std::string const& name, - std::string const& description, - SourceLineInfo const& lineInfo ); -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - - -#ifdef __OBJC__ -// #included from: internal/catch_objc.hpp -#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED - -#import - -#include - -// NB. Any general catch headers included here must be included -// in catch.hpp first to make sure they are included by the single -// header for non obj-usage - -/////////////////////////////////////////////////////////////////////////////// -// This protocol is really only here for (self) documenting purposes, since -// all its methods are optional. -@protocol OcFixture - -@optional - --(void) setUp; --(void) tearDown; - -@end - -namespace Catch { - - class OcMethod : public SharedImpl { - - public: - OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} - - virtual void invoke() const { - id obj = [[m_cls alloc] init]; - - performOptionalSelector( obj, @selector(setUp) ); - performOptionalSelector( obj, m_sel ); - performOptionalSelector( obj, @selector(tearDown) ); - - arcSafeRelease( obj ); - } - private: - virtual ~OcMethod() {} - - Class m_cls; - SEL m_sel; - }; - - namespace Detail{ - - inline std::string getAnnotation( Class cls, - std::string const& annotationName, - std::string const& testCaseName ) { - NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; - SEL sel = NSSelectorFromString( selStr ); - arcSafeRelease( selStr ); - id value = performOptionalSelector( cls, sel ); - if( value ) - return [(NSString*)value UTF8String]; - return ""; - } - } - - inline size_t registerTestMethods() { - size_t noTestMethods = 0; - int noClasses = objc_getClassList( CATCH_NULL, 0 ); - - Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); - objc_getClassList( classes, noClasses ); - - for( int c = 0; c < noClasses; c++ ) { - Class cls = classes[c]; - { - u_int count; - Method* methods = class_copyMethodList( cls, &count ); - for( u_int m = 0; m < count ; m++ ) { - SEL selector = method_getName(methods[m]); - std::string methodName = sel_getName(selector); - if( startsWith( methodName, "Catch_TestCase_" ) ) { - std::string testCaseName = methodName.substr( 15 ); - std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); - std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); - const char* className = class_getName( cls ); - - getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); - noTestMethods++; - } - } - free(methods); - } - } - return noTestMethods; - } - - namespace Matchers { - namespace Impl { - namespace NSStringMatchers { - - struct StringHolder : MatcherBase{ - StringHolder( NSString* substr ) : m_substr( [substr copy] ){} - StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} - StringHolder() { - arcSafeRelease( m_substr ); - } - - virtual bool match( NSString* arg ) const CATCH_OVERRIDE { - return false; - } - - NSString* m_substr; - }; - - struct Equals : StringHolder { - Equals( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( NSString* str ) const CATCH_OVERRIDE { - return (str != nil || m_substr == nil ) && - [str isEqualToString:m_substr]; - } - - virtual std::string describe() const CATCH_OVERRIDE { - return "equals string: " + Catch::toString( m_substr ); - } - }; - - struct Contains : StringHolder { - Contains( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( NSString* str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location != NSNotFound; - } - - virtual std::string describe() const CATCH_OVERRIDE { - return "contains string: " + Catch::toString( m_substr ); - } - }; - - struct StartsWith : StringHolder { - StartsWith( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( NSString* str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location == 0; - } - - virtual std::string describe() const CATCH_OVERRIDE { - return "starts with: " + Catch::toString( m_substr ); - } - }; - struct EndsWith : StringHolder { - EndsWith( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( NSString* str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location == [str length] - [m_substr length]; - } - - virtual std::string describe() const CATCH_OVERRIDE { - return "ends with: " + Catch::toString( m_substr ); - } - }; - - } // namespace NSStringMatchers - } // namespace Impl - - inline Impl::NSStringMatchers::Equals - Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } - - inline Impl::NSStringMatchers::Contains - Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } - - inline Impl::NSStringMatchers::StartsWith - StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } - - inline Impl::NSStringMatchers::EndsWith - EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } - - } // namespace Matchers - - using namespace Matchers; - -} // namespace Catch - -/////////////////////////////////////////////////////////////////////////////// -#define OC_TEST_CASE( name, desc )\ -+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ -{\ -return @ name; \ -}\ -+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ -{ \ -return @ desc; \ -} \ --(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) - -#endif - -#ifdef CATCH_IMPL - -// !TBD: Move the leak detector code into a separate header -#ifdef CATCH_CONFIG_WINDOWS_CRTDBG -#include -class LeakDetector { -public: - LeakDetector() { - int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - flag |= _CRTDBG_LEAK_CHECK_DF; - flag |= _CRTDBG_ALLOC_MEM_DF; - _CrtSetDbgFlag(flag); - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); - // Change this to leaking allocation's number to break there - _CrtSetBreakAlloc(-1); - } -}; -#else -class LeakDetector {}; -#endif - -LeakDetector leakDetector; - -// #included from: internal/catch_impl.hpp -#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED - -// Collect all the implementation files together here -// These are the equivalent of what would usually be cpp files - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wweak-vtables" -#endif - -// #included from: ../catch_session.hpp -#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED - -// #included from: internal/catch_commandline.hpp -#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED - -// #included from: catch_config.hpp -#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED - -// #included from: catch_test_spec_parser.hpp -#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -// #included from: catch_test_spec.hpp -#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -// #included from: catch_wildcard_pattern.hpp -#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED - -#include - -namespace Catch -{ - class WildcardPattern { - enum WildcardPosition { - NoWildcard = 0, - WildcardAtStart = 1, - WildcardAtEnd = 2, - WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd - }; - - public: - - WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ) - : m_caseSensitivity( caseSensitivity ), - m_wildcard( NoWildcard ), - m_pattern( adjustCase( pattern ) ) - { - if( startsWith( m_pattern, '*' ) ) { - m_pattern = m_pattern.substr( 1 ); - m_wildcard = WildcardAtStart; - } - if( endsWith( m_pattern, '*' ) ) { - m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); - m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); - } - } - virtual ~WildcardPattern(); - virtual bool matches( std::string const& str ) const { - switch( m_wildcard ) { - case NoWildcard: - return m_pattern == adjustCase( str ); - case WildcardAtStart: - return endsWith( adjustCase( str ), m_pattern ); - case WildcardAtEnd: - return startsWith( adjustCase( str ), m_pattern ); - case WildcardAtBothEnds: - return contains( adjustCase( str ), m_pattern ); - } - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunreachable-code" -#endif - throw std::logic_error( "Unknown enum" ); -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - } - private: - std::string adjustCase( std::string const& str ) const { - return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; - } - CaseSensitive::Choice m_caseSensitivity; - WildcardPosition m_wildcard; - std::string m_pattern; - }; -} - -#include -#include - -namespace Catch { - - class TestSpec { - struct Pattern : SharedImpl<> { - virtual ~Pattern(); - virtual bool matches( TestCaseInfo const& testCase ) const = 0; - }; - class NamePattern : public Pattern { - public: - NamePattern( std::string const& name ) - : m_wildcardPattern( toLower( name ), CaseSensitive::No ) - {} - virtual ~NamePattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { - return m_wildcardPattern.matches( toLower( testCase.name ) ); - } - private: - WildcardPattern m_wildcardPattern; - }; - - class TagPattern : public Pattern { - public: - TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} - virtual ~TagPattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { - return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); - } - private: - std::string m_tag; - }; - - class ExcludedPattern : public Pattern { - public: - ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} - virtual ~ExcludedPattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } - private: - Ptr m_underlyingPattern; - }; - - struct Filter { - std::vector > m_patterns; - - bool matches( TestCaseInfo const& testCase ) const { - // All patterns in a filter must match for the filter to be a match - for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { - if( !(*it)->matches( testCase ) ) - return false; - } - return true; - } - }; - - public: - bool hasFilters() const { - return !m_filters.empty(); - } - bool matches( TestCaseInfo const& testCase ) const { - // A TestSpec matches if any filter matches - for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) - if( it->matches( testCase ) ) - return true; - return false; - } - - private: - std::vector m_filters; - - friend class TestSpecParser; - }; -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -namespace Catch { - - class TestSpecParser { - enum Mode{ None, Name, QuotedName, Tag, EscapedName }; - Mode m_mode; - bool m_exclusion; - std::size_t m_start, m_pos; - std::string m_arg; - std::vector m_escapeChars; - TestSpec::Filter m_currentFilter; - TestSpec m_testSpec; - ITagAliasRegistry const* m_tagAliases; - - public: - TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {} - - TestSpecParser& parse( std::string const& arg ) { - m_mode = None; - m_exclusion = false; - m_start = std::string::npos; - m_arg = m_tagAliases->expandAliases( arg ); - m_escapeChars.clear(); - for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) - visitChar( m_arg[m_pos] ); - if( m_mode == Name ) - addPattern(); - return *this; - } - TestSpec testSpec() { - addFilter(); - return m_testSpec; - } - private: - void visitChar( char c ) { - if( m_mode == None ) { - switch( c ) { - case ' ': return; - case '~': m_exclusion = true; return; - case '[': return startNewMode( Tag, ++m_pos ); - case '"': return startNewMode( QuotedName, ++m_pos ); - case '\\': return escape(); - default: startNewMode( Name, m_pos ); break; - } - } - if( m_mode == Name ) { - if( c == ',' ) { - addPattern(); - addFilter(); - } - else if( c == '[' ) { - if( subString() == "exclude:" ) - m_exclusion = true; - else - addPattern(); - startNewMode( Tag, ++m_pos ); - } - else if( c == '\\' ) - escape(); - } - else if( m_mode == EscapedName ) - m_mode = Name; - else if( m_mode == QuotedName && c == '"' ) - addPattern(); - else if( m_mode == Tag && c == ']' ) - addPattern(); - } - void startNewMode( Mode mode, std::size_t start ) { - m_mode = mode; - m_start = start; - } - void escape() { - if( m_mode == None ) - m_start = m_pos; - m_mode = EscapedName; - m_escapeChars.push_back( m_pos ); - } - std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } - template - void addPattern() { - std::string token = subString(); - for( size_t i = 0; i < m_escapeChars.size(); ++i ) - token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); - m_escapeChars.clear(); - if( startsWith( token, "exclude:" ) ) { - m_exclusion = true; - token = token.substr( 8 ); - } - if( !token.empty() ) { - Ptr pattern = new T( token ); - if( m_exclusion ) - pattern = new TestSpec::ExcludedPattern( pattern ); - m_currentFilter.m_patterns.push_back( pattern ); - } - m_exclusion = false; - m_mode = None; - } - void addFilter() { - if( !m_currentFilter.m_patterns.empty() ) { - m_testSpec.m_filters.push_back( m_currentFilter ); - m_currentFilter = TestSpec::Filter(); - } - } - }; - inline TestSpec parseTestSpec( std::string const& arg ) { - return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); - } - -} // namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// #included from: catch_interfaces_config.h -#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED - -#include -#include -#include - -namespace Catch { - - struct Verbosity { enum Level { - NoOutput = 0, - Quiet, - Normal - }; }; - - struct WarnAbout { enum What { - Nothing = 0x00, - NoAssertions = 0x01 - }; }; - - struct ShowDurations { enum OrNot { - DefaultForReporter, - Always, - Never - }; }; - struct RunTests { enum InWhatOrder { - InDeclarationOrder, - InLexicographicalOrder, - InRandomOrder - }; }; - struct UseColour { enum YesOrNo { - Auto, - Yes, - No - }; }; - struct WaitForKeypress { enum When { - Never, - BeforeStart = 1, - BeforeExit = 2, - BeforeStartAndExit = BeforeStart | BeforeExit - }; }; - - class TestSpec; - - struct IConfig : IShared { - - virtual ~IConfig(); - - virtual bool allowThrows() const = 0; - virtual std::ostream& stream() const = 0; - virtual std::string name() const = 0; - virtual bool includeSuccessfulResults() const = 0; - virtual bool shouldDebugBreak() const = 0; - virtual bool warnAboutMissingAssertions() const = 0; - virtual int abortAfter() const = 0; - virtual bool showInvisibles() const = 0; - virtual ShowDurations::OrNot showDurations() const = 0; - virtual TestSpec const& testSpec() const = 0; - virtual RunTests::InWhatOrder runOrder() const = 0; - virtual unsigned int rngSeed() const = 0; - virtual UseColour::YesOrNo useColour() const = 0; - virtual std::vector const& getSectionsToRun() const = 0; - - }; -} - -// #included from: catch_stream.h -#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED - -// #included from: catch_streambuf.h -#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED - -#include - -namespace Catch { - - class StreamBufBase : public std::streambuf { - public: - virtual ~StreamBufBase() CATCH_NOEXCEPT; - }; -} - -#include -#include -#include -#include - -namespace Catch { - - std::ostream& cout(); - std::ostream& cerr(); - std::ostream& clog(); - - struct IStream { - virtual ~IStream() CATCH_NOEXCEPT; - virtual std::ostream& stream() const = 0; - }; - - class FileStream : public IStream { - mutable std::ofstream m_ofs; - public: - FileStream( std::string const& filename ); - virtual ~FileStream() CATCH_NOEXCEPT; - public: // IStream - virtual std::ostream& stream() const CATCH_OVERRIDE; - }; - - class CoutStream : public IStream { - mutable std::ostream m_os; - public: - CoutStream(); - virtual ~CoutStream() CATCH_NOEXCEPT; - - public: // IStream - virtual std::ostream& stream() const CATCH_OVERRIDE; - }; - - class DebugOutStream : public IStream { - CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf; - mutable std::ostream m_os; - public: - DebugOutStream(); - virtual ~DebugOutStream() CATCH_NOEXCEPT; - - public: // IStream - virtual std::ostream& stream() const CATCH_OVERRIDE; - }; -} - -#include -#include -#include -#include - -#ifndef CATCH_CONFIG_CONSOLE_WIDTH -#define CATCH_CONFIG_CONSOLE_WIDTH 80 -#endif - -namespace Catch { - - struct ConfigData { - - ConfigData() - : listTests( false ), - listTags( false ), - listReporters( false ), - listTestNamesOnly( false ), - listExtraInfo( false ), - showSuccessfulTests( false ), - shouldDebugBreak( false ), - noThrow( false ), - showHelp( false ), - showInvisibles( false ), - filenamesAsTags( false ), - libIdentify( false ), - abortAfter( -1 ), - rngSeed( 0 ), - verbosity( Verbosity::Normal ), - warnings( WarnAbout::Nothing ), - showDurations( ShowDurations::DefaultForReporter ), - runOrder( RunTests::InDeclarationOrder ), - useColour( UseColour::Auto ), - waitForKeypress( WaitForKeypress::Never ) - {} - - bool listTests; - bool listTags; - bool listReporters; - bool listTestNamesOnly; - bool listExtraInfo; - - bool showSuccessfulTests; - bool shouldDebugBreak; - bool noThrow; - bool showHelp; - bool showInvisibles; - bool filenamesAsTags; - bool libIdentify; - - int abortAfter; - unsigned int rngSeed; - - Verbosity::Level verbosity; - WarnAbout::What warnings; - ShowDurations::OrNot showDurations; - RunTests::InWhatOrder runOrder; - UseColour::YesOrNo useColour; - WaitForKeypress::When waitForKeypress; - - std::string outputFilename; - std::string name; - std::string processName; - - std::vector reporterNames; - std::vector testsOrTags; - std::vector sectionsToRun; - }; - - class Config : public SharedImpl { - private: - Config( Config const& other ); - Config& operator = ( Config const& other ); - virtual void dummy(); - public: - - Config() - {} - - Config( ConfigData const& data ) - : m_data( data ), - m_stream( openStream() ) - { - if( !data.testsOrTags.empty() ) { - TestSpecParser parser( ITagAliasRegistry::get() ); - for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) - parser.parse( data.testsOrTags[i] ); - m_testSpec = parser.testSpec(); - } - } - - virtual ~Config() {} - - std::string const& getFilename() const { - return m_data.outputFilename ; - } - - bool listTests() const { return m_data.listTests; } - bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } - bool listTags() const { return m_data.listTags; } - bool listReporters() const { return m_data.listReporters; } - bool listExtraInfo() const { return m_data.listExtraInfo; } - - std::string getProcessName() const { return m_data.processName; } - - std::vector const& getReporterNames() const { return m_data.reporterNames; } - std::vector const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; } - - virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; } - - bool showHelp() const { return m_data.showHelp; } - - // IConfig interface - virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; } - virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); } - virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; } - virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; } - virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; } - virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; } - virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; } - virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; } - virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; } - virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; } - virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; } - virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; } - - private: - - IStream const* openStream() { - if( m_data.outputFilename.empty() ) - return new CoutStream(); - else if( m_data.outputFilename[0] == '%' ) { - if( m_data.outputFilename == "%debug" ) - return new DebugOutStream(); - else - throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); - } - else - return new FileStream( m_data.outputFilename ); - } - ConfigData m_data; - - CATCH_AUTO_PTR( IStream const ) m_stream; - TestSpec m_testSpec; - }; - -} // end namespace Catch - -// #included from: catch_clara.h -#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED - -// Use Catch's value for console width (store Clara's off to the side, if present) -#ifdef CLARA_CONFIG_CONSOLE_WIDTH -#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH -#undef CLARA_CONFIG_CONSOLE_WIDTH -#endif -#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - -// Declare Clara inside the Catch namespace -#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { -// #included from: ../external/clara.h - -// Version 0.0.2.4 - -// Only use header guard if we are not using an outer namespace -#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) - -#ifndef STITCH_CLARA_OPEN_NAMESPACE -#define TWOBLUECUBES_CLARA_H_INCLUDED -#define STITCH_CLARA_OPEN_NAMESPACE -#define STITCH_CLARA_CLOSE_NAMESPACE -#else -#define STITCH_CLARA_CLOSE_NAMESPACE } -#endif - -#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE - -// ----------- #included from tbc_text_format.h ----------- - -// Only use header guard if we are not using an outer namespace -#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) -#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -#define TBC_TEXT_FORMAT_H_INCLUDED -#endif - -#include -#include -#include -#include -#include - -// Use optional outer namespace -#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { -#endif - -namespace Tbc { - -#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH - const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - struct TextAttributes { - TextAttributes() - : initialIndent( std::string::npos ), - indent( 0 ), - width( consoleWidth-1 ), - tabChar( '\t' ) - {} - - TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } - TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } - TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } - TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } - - std::size_t initialIndent; // indent of first line, or npos - std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos - std::size_t width; // maximum width of text, including indent. Longer text will wrap - char tabChar; // If this char is seen the indent is changed to current pos - }; - - class Text { - public: - Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) - : attr( _attr ) - { - std::string wrappableChars = " [({.,/|\\-"; - std::size_t indent = _attr.initialIndent != std::string::npos - ? _attr.initialIndent - : _attr.indent; - std::string remainder = _str; - - while( !remainder.empty() ) { - if( lines.size() >= 1000 ) { - lines.push_back( "... message truncated due to excessive size" ); - return; - } - std::size_t tabPos = std::string::npos; - std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); - std::size_t pos = remainder.find_first_of( '\n' ); - if( pos <= width ) { - width = pos; - } - pos = remainder.find_last_of( _attr.tabChar, width ); - if( pos != std::string::npos ) { - tabPos = pos; - if( remainder[width] == '\n' ) - width--; - remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); - } - - if( width == remainder.size() ) { - spliceLine( indent, remainder, width ); - } - else if( remainder[width] == '\n' ) { - spliceLine( indent, remainder, width ); - if( width <= 1 || remainder.size() != 1 ) - remainder = remainder.substr( 1 ); - indent = _attr.indent; - } - else { - pos = remainder.find_last_of( wrappableChars, width ); - if( pos != std::string::npos && pos > 0 ) { - spliceLine( indent, remainder, pos ); - if( remainder[0] == ' ' ) - remainder = remainder.substr( 1 ); - } - else { - spliceLine( indent, remainder, width-1 ); - lines.back() += "-"; - } - if( lines.size() == 1 ) - indent = _attr.indent; - if( tabPos != std::string::npos ) - indent += tabPos; - } - } - } - - void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { - lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); - _remainder = _remainder.substr( _pos ); - } - - typedef std::vector::const_iterator const_iterator; - - const_iterator begin() const { return lines.begin(); } - const_iterator end() const { return lines.end(); } - std::string const& last() const { return lines.back(); } - std::size_t size() const { return lines.size(); } - std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } - std::string toString() const { - std::ostringstream oss; - oss << *this; - return oss.str(); - } - - friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { - for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); - it != itEnd; ++it ) { - if( it != _text.begin() ) - _stream << "\n"; - _stream << *it; - } - return _stream; - } - - private: - std::string str; - TextAttributes attr; - std::vector lines; - }; - -} // end namespace Tbc - -#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -} // end outer namespace -#endif - -#endif // TBC_TEXT_FORMAT_H_INCLUDED - -// ----------- end of #include from tbc_text_format.h ----------- -// ........... back in clara.h - -#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE - -// ----------- #included from clara_compilers.h ----------- - -#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED -#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED - -// Detect a number of compiler features - mostly C++11/14 conformance - by compiler -// The following features are defined: -// -// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported? -// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported? -// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods -// CLARA_CONFIG_CPP11_OVERRIDE : is override supported? -// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) - -// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported? - -// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported? - -// In general each macro has a _NO_ form -// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature. -// Many features, at point of detection, define an _INTERNAL_ macro, so they -// can be combined, en-mass, with the _NO_ forms later. - -// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11 - -#ifdef __clang__ - -#if __has_feature(cxx_nullptr) -#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR -#endif - -#if __has_feature(cxx_noexcept) -#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT -#endif - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// GCC -#ifdef __GNUC__ - -#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) -#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR -#endif - -// - otherwise more recent versions define __cplusplus >= 201103L -// and will get picked up below - -#endif // __GNUC__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#ifdef _MSC_VER - -#if (_MSC_VER >= 1600) -#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR -#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR -#endif - -#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) -#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT -#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -#endif - -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// -// C++ language feature support - -// catch all support for C++11 -#if defined(__cplusplus) && __cplusplus >= 201103L - -#define CLARA_CPP11_OR_GREATER - -#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) -#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR -#endif - -#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT -#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT -#endif - -#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -#endif - -#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) -#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE -#endif -#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) -#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR -#endif - -#endif // __cplusplus >= 201103L - -// Now set the actual defines based on the above + anything the user has configured -#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) -#define CLARA_CONFIG_CPP11_NULLPTR -#endif -#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) -#define CLARA_CONFIG_CPP11_NOEXCEPT -#endif -#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) -#define CLARA_CONFIG_CPP11_GENERATED_METHODS -#endif -#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) -#define CLARA_CONFIG_CPP11_OVERRIDE -#endif -#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) -#define CLARA_CONFIG_CPP11_UNIQUE_PTR -#endif - -// noexcept support: -#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) -#define CLARA_NOEXCEPT noexcept -# define CLARA_NOEXCEPT_IS(x) noexcept(x) -#else -#define CLARA_NOEXCEPT throw() -# define CLARA_NOEXCEPT_IS(x) -#endif - -// nullptr support -#ifdef CLARA_CONFIG_CPP11_NULLPTR -#define CLARA_NULL nullptr -#else -#define CLARA_NULL NULL -#endif - -// override support -#ifdef CLARA_CONFIG_CPP11_OVERRIDE -#define CLARA_OVERRIDE override -#else -#define CLARA_OVERRIDE -#endif - -// unique_ptr support -#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR -# define CLARA_AUTO_PTR( T ) std::unique_ptr -#else -# define CLARA_AUTO_PTR( T ) std::auto_ptr -#endif - -#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED - -// ----------- end of #include from clara_compilers.h ----------- -// ........... back in clara.h - -#include -#include -#include - -#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) -#define CLARA_PLATFORM_WINDOWS -#endif - -// Use optional outer namespace -#ifdef STITCH_CLARA_OPEN_NAMESPACE -STITCH_CLARA_OPEN_NAMESPACE -#endif - -namespace Clara { - - struct UnpositionalTag {}; - - extern UnpositionalTag _; - -#ifdef CLARA_CONFIG_MAIN - UnpositionalTag _; -#endif - - namespace Detail { - -#ifdef CLARA_CONSOLE_WIDTH - const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - using namespace Tbc; - - inline bool startsWith( std::string const& str, std::string const& prefix ) { - return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; - } - - template struct RemoveConstRef{ typedef T type; }; - template struct RemoveConstRef{ typedef T type; }; - template struct RemoveConstRef{ typedef T type; }; - template struct RemoveConstRef{ typedef T type; }; - - template struct IsBool { static const bool value = false; }; - template<> struct IsBool { static const bool value = true; }; - - template - void convertInto( std::string const& _source, T& _dest ) { - std::stringstream ss; - ss << _source; - ss >> _dest; - if( ss.fail() ) - throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); - } - inline void convertInto( std::string const& _source, std::string& _dest ) { - _dest = _source; - } - char toLowerCh(char c) { - return static_cast( std::tolower( c ) ); - } - inline void convertInto( std::string const& _source, bool& _dest ) { - std::string sourceLC = _source; - std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh ); - if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) - _dest = true; - else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) - _dest = false; - else - throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); - } - - template - struct IArgFunction { - virtual ~IArgFunction() {} -#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS - IArgFunction() = default; - IArgFunction( IArgFunction const& ) = default; -#endif - virtual void set( ConfigT& config, std::string const& value ) const = 0; - virtual bool takesArg() const = 0; - virtual IArgFunction* clone() const = 0; - }; - - template - class BoundArgFunction { - public: - BoundArgFunction() : functionObj( CLARA_NULL ) {} - BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} - BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {} - BoundArgFunction& operator = ( BoundArgFunction const& other ) { - IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL; - delete functionObj; - functionObj = newFunctionObj; - return *this; - } - ~BoundArgFunction() { delete functionObj; } - - void set( ConfigT& config, std::string const& value ) const { - functionObj->set( config, value ); - } - bool takesArg() const { return functionObj->takesArg(); } - - bool isSet() const { - return functionObj != CLARA_NULL; - } - private: - IArgFunction* functionObj; - }; - - template - struct NullBinder : IArgFunction{ - virtual void set( C&, std::string const& ) const {} - virtual bool takesArg() const { return true; } - virtual IArgFunction* clone() const { return new NullBinder( *this ); } - }; - - template - struct BoundDataMember : IArgFunction{ - BoundDataMember( M C::* _member ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - convertInto( stringValue, p.*member ); - } - virtual bool takesArg() const { return !IsBool::value; } - virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } - M C::* member; - }; - template - struct BoundUnaryMethod : IArgFunction{ - BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - typename RemoveConstRef::type value; - convertInto( stringValue, value ); - (p.*member)( value ); - } - virtual bool takesArg() const { return !IsBool::value; } - virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } - void (C::*member)( M ); - }; - template - struct BoundNullaryMethod : IArgFunction{ - BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - bool value; - convertInto( stringValue, value ); - if( value ) - (p.*member)(); - } - virtual bool takesArg() const { return false; } - virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } - void (C::*member)(); - }; - - template - struct BoundUnaryFunction : IArgFunction{ - BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} - virtual void set( C& obj, std::string const& stringValue ) const { - bool value; - convertInto( stringValue, value ); - if( value ) - function( obj ); - } - virtual bool takesArg() const { return false; } - virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } - void (*function)( C& ); - }; - - template - struct BoundBinaryFunction : IArgFunction{ - BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} - virtual void set( C& obj, std::string const& stringValue ) const { - typename RemoveConstRef::type value; - convertInto( stringValue, value ); - function( obj, value ); - } - virtual bool takesArg() const { return !IsBool::value; } - virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } - void (*function)( C&, T ); - }; - - } // namespace Detail - - inline std::vector argsToVector( int argc, char const* const* const argv ) { - std::vector args( static_cast( argc ) ); - for( std::size_t i = 0; i < static_cast( argc ); ++i ) - args[i] = argv[i]; - - return args; - } - - class Parser { - enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional }; - Mode mode; - std::size_t from; - bool inQuotes; - public: - - struct Token { - enum Type { Positional, ShortOpt, LongOpt }; - Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} - Type type; - std::string data; - }; - - Parser() : mode( None ), from( 0 ), inQuotes( false ){} - - void parseIntoTokens( std::vector const& args, std::vector& tokens ) { - const std::string doubleDash = "--"; - for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i ) - parseIntoTokens( args[i], tokens); - } - - void parseIntoTokens( std::string const& arg, std::vector& tokens ) { - for( std::size_t i = 0; i < arg.size(); ++i ) { - char c = arg[i]; - if( c == '"' ) - inQuotes = !inQuotes; - mode = handleMode( i, c, arg, tokens ); - } - mode = handleMode( arg.size(), '\0', arg, tokens ); - } - Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { - switch( mode ) { - case None: return handleNone( i, c ); - case MaybeShortOpt: return handleMaybeShortOpt( i, c ); - case ShortOpt: - case LongOpt: - case SlashOpt: return handleOpt( i, c, arg, tokens ); - case Positional: return handlePositional( i, c, arg, tokens ); - default: throw std::logic_error( "Unknown mode" ); - } - } - - Mode handleNone( std::size_t i, char c ) { - if( inQuotes ) { - from = i; - return Positional; - } - switch( c ) { - case '-': return MaybeShortOpt; -#ifdef CLARA_PLATFORM_WINDOWS - case '/': from = i+1; return SlashOpt; -#endif - default: from = i; return Positional; - } - } - Mode handleMaybeShortOpt( std::size_t i, char c ) { - switch( c ) { - case '-': from = i+1; return LongOpt; - default: from = i; return ShortOpt; - } - } - - Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { - if( std::string( ":=\0", 3 ).find( c ) == std::string::npos ) - return mode; - - std::string optName = arg.substr( from, i-from ); - if( mode == ShortOpt ) - for( std::size_t j = 0; j < optName.size(); ++j ) - tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) ); - else if( mode == SlashOpt && optName.size() == 1 ) - tokens.push_back( Token( Token::ShortOpt, optName ) ); - else - tokens.push_back( Token( Token::LongOpt, optName ) ); - return None; - } - Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { - if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos ) - return mode; - - std::string data = arg.substr( from, i-from ); - tokens.push_back( Token( Token::Positional, data ) ); - return None; - } - }; - - template - struct CommonArgProperties { - CommonArgProperties() {} - CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} - - Detail::BoundArgFunction boundField; - std::string description; - std::string detail; - std::string placeholder; // Only value if boundField takes an arg - - bool takesArg() const { - return !placeholder.empty(); - } - void validate() const { - if( !boundField.isSet() ) - throw std::logic_error( "option not bound" ); - } - }; - struct OptionArgProperties { - std::vector shortNames; - std::string longName; - - bool hasShortName( std::string const& shortName ) const { - return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); - } - bool hasLongName( std::string const& _longName ) const { - return _longName == longName; - } - }; - struct PositionalArgProperties { - PositionalArgProperties() : position( -1 ) {} - int position; // -1 means non-positional (floating) - - bool isFixedPositional() const { - return position != -1; - } - }; - - template - class CommandLine { - - struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { - Arg() {} - Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} - - using CommonArgProperties::placeholder; // !TBD - - std::string dbgName() const { - if( !longName.empty() ) - return "--" + longName; - if( !shortNames.empty() ) - return "-" + shortNames[0]; - return "positional args"; - } - std::string commands() const { - std::ostringstream oss; - bool first = true; - std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); - for(; it != itEnd; ++it ) { - if( first ) - first = false; - else - oss << ", "; - oss << "-" << *it; - } - if( !longName.empty() ) { - if( !first ) - oss << ", "; - oss << "--" << longName; - } - if( !placeholder.empty() ) - oss << " <" << placeholder << ">"; - return oss.str(); - } - }; - - typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr; - - friend void addOptName( Arg& arg, std::string const& optName ) - { - if( optName.empty() ) - return; - if( Detail::startsWith( optName, "--" ) ) { - if( !arg.longName.empty() ) - throw std::logic_error( "Only one long opt may be specified. '" - + arg.longName - + "' already specified, now attempting to add '" - + optName + "'" ); - arg.longName = optName.substr( 2 ); - } - else if( Detail::startsWith( optName, "-" ) ) - arg.shortNames.push_back( optName.substr( 1 ) ); - else - throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); - } - friend void setPositionalArg( Arg& arg, int position ) - { - arg.position = position; - } - - class ArgBuilder { - public: - ArgBuilder( Arg* arg ) : m_arg( arg ) {} - - // Bind a non-boolean data member (requires placeholder string) - template - void bind( M C::* field, std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundDataMember( field ); - m_arg->placeholder = placeholder; - } - // Bind a boolean data member (no placeholder required) - template - void bind( bool C::* field ) { - m_arg->boundField = new Detail::BoundDataMember( field ); - } - - // Bind a method taking a single, non-boolean argument (requires a placeholder string) - template - void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); - m_arg->placeholder = placeholder; - } - - // Bind a method taking a single, boolean argument (no placeholder string required) - template - void bind( void (C::* unaryMethod)( bool ) ) { - m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); - } - - // Bind a method that takes no arguments (will be called if opt is present) - template - void bind( void (C::* nullaryMethod)() ) { - m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); - } - - // Bind a free function taking a single argument - the object to operate on (no placeholder string required) - template - void bind( void (* unaryFunction)( C& ) ) { - m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); - } - - // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) - template - void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); - m_arg->placeholder = placeholder; - } - - ArgBuilder& describe( std::string const& description ) { - m_arg->description = description; - return *this; - } - ArgBuilder& detail( std::string const& detail ) { - m_arg->detail = detail; - return *this; - } - - protected: - Arg* m_arg; - }; - - class OptBuilder : public ArgBuilder { - public: - OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} - OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} - - OptBuilder& operator[]( std::string const& optName ) { - addOptName( *ArgBuilder::m_arg, optName ); - return *this; - } - }; - - public: - - CommandLine() - : m_boundProcessName( new Detail::NullBinder() ), - m_highestSpecifiedArgPosition( 0 ), - m_throwOnUnrecognisedTokens( false ) - {} - CommandLine( CommandLine const& other ) - : m_boundProcessName( other.m_boundProcessName ), - m_options ( other.m_options ), - m_positionalArgs( other.m_positionalArgs ), - m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), - m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) - { - if( other.m_floatingArg.get() ) - m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); - } - - CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { - m_throwOnUnrecognisedTokens = shouldThrow; - return *this; - } - - OptBuilder operator[]( std::string const& optName ) { - m_options.push_back( Arg() ); - addOptName( m_options.back(), optName ); - OptBuilder builder( &m_options.back() ); - return builder; - } - - ArgBuilder operator[]( int position ) { - m_positionalArgs.insert( std::make_pair( position, Arg() ) ); - if( position > m_highestSpecifiedArgPosition ) - m_highestSpecifiedArgPosition = position; - setPositionalArg( m_positionalArgs[position], position ); - ArgBuilder builder( &m_positionalArgs[position] ); - return builder; - } - - // Invoke this with the _ instance - ArgBuilder operator[]( UnpositionalTag ) { - if( m_floatingArg.get() ) - throw std::logic_error( "Only one unpositional argument can be added" ); - m_floatingArg.reset( new Arg() ); - ArgBuilder builder( m_floatingArg.get() ); - return builder; - } - - template - void bindProcessName( M C::* field ) { - m_boundProcessName = new Detail::BoundDataMember( field ); - } - template - void bindProcessName( void (C::*_unaryMethod)( M ) ) { - m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); - } - - void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { - typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; - std::size_t maxWidth = 0; - for( it = itBegin; it != itEnd; ++it ) - maxWidth = (std::max)( maxWidth, it->commands().size() ); - - for( it = itBegin; it != itEnd; ++it ) { - Detail::Text usage( it->commands(), Detail::TextAttributes() - .setWidth( maxWidth+indent ) - .setIndent( indent ) ); - Detail::Text desc( it->description, Detail::TextAttributes() - .setWidth( width - maxWidth - 3 ) ); - - for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { - std::string usageCol = i < usage.size() ? usage[i] : ""; - os << usageCol; - - if( i < desc.size() && !desc[i].empty() ) - os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) - << desc[i]; - os << "\n"; - } - } - } - std::string optUsage() const { - std::ostringstream oss; - optUsage( oss ); - return oss.str(); - } - - void argSynopsis( std::ostream& os ) const { - for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { - if( i > 1 ) - os << " "; - typename std::map::const_iterator it = m_positionalArgs.find( i ); - if( it != m_positionalArgs.end() ) - os << "<" << it->second.placeholder << ">"; - else if( m_floatingArg.get() ) - os << "<" << m_floatingArg->placeholder << ">"; - else - throw std::logic_error( "non consecutive positional arguments with no floating args" ); - } - // !TBD No indication of mandatory args - if( m_floatingArg.get() ) { - if( m_highestSpecifiedArgPosition > 1 ) - os << " "; - os << "[<" << m_floatingArg->placeholder << "> ...]"; - } - } - std::string argSynopsis() const { - std::ostringstream oss; - argSynopsis( oss ); - return oss.str(); - } - - void usage( std::ostream& os, std::string const& procName ) const { - validate(); - os << "usage:\n " << procName << " "; - argSynopsis( os ); - if( !m_options.empty() ) { - os << " [options]\n\nwhere options are: \n"; - optUsage( os, 2 ); - } - os << "\n"; - } - std::string usage( std::string const& procName ) const { - std::ostringstream oss; - usage( oss, procName ); - return oss.str(); - } - - ConfigT parse( std::vector const& args ) const { - ConfigT config; - parseInto( args, config ); - return config; - } - - std::vector parseInto( std::vector const& args, ConfigT& config ) const { - std::string processName = args.empty() ? std::string() : args[0]; - std::size_t lastSlash = processName.find_last_of( "/\\" ); - if( lastSlash != std::string::npos ) - processName = processName.substr( lastSlash+1 ); - m_boundProcessName.set( config, processName ); - std::vector tokens; - Parser parser; - parser.parseIntoTokens( args, tokens ); - return populate( tokens, config ); - } - - std::vector populate( std::vector const& tokens, ConfigT& config ) const { - validate(); - std::vector unusedTokens = populateOptions( tokens, config ); - unusedTokens = populateFixedArgs( unusedTokens, config ); - unusedTokens = populateFloatingArgs( unusedTokens, config ); - return unusedTokens; - } - - std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { - std::vector unusedTokens; - std::vector errors; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); - for(; it != itEnd; ++it ) { - Arg const& arg = *it; - - try { - if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || - ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { - if( arg.takesArg() ) { - if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) - errors.push_back( "Expected argument to option: " + token.data ); - else - arg.boundField.set( config, tokens[++i].data ); - } - else { - arg.boundField.set( config, "true" ); - } - break; - } - } - catch( std::exception& ex ) { - errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); - } - } - if( it == itEnd ) { - if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) - unusedTokens.push_back( token ); - else if( errors.empty() && m_throwOnUnrecognisedTokens ) - errors.push_back( "unrecognised option: " + token.data ); - } - } - if( !errors.empty() ) { - std::ostringstream oss; - for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); - it != itEnd; - ++it ) { - if( it != errors.begin() ) - oss << "\n"; - oss << *it; - } - throw std::runtime_error( oss.str() ); - } - return unusedTokens; - } - std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { - std::vector unusedTokens; - int position = 1; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - typename std::map::const_iterator it = m_positionalArgs.find( position ); - if( it != m_positionalArgs.end() ) - it->second.boundField.set( config, token.data ); - else - unusedTokens.push_back( token ); - if( token.type == Parser::Token::Positional ) - position++; - } - return unusedTokens; - } - std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { - if( !m_floatingArg.get() ) - return tokens; - std::vector unusedTokens; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - if( token.type == Parser::Token::Positional ) - m_floatingArg->boundField.set( config, token.data ); - else - unusedTokens.push_back( token ); - } - return unusedTokens; - } - - void validate() const - { - if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) - throw std::logic_error( "No options or arguments specified" ); - - for( typename std::vector::const_iterator it = m_options.begin(), - itEnd = m_options.end(); - it != itEnd; ++it ) - it->validate(); - } - - private: - Detail::BoundArgFunction m_boundProcessName; - std::vector m_options; - std::map m_positionalArgs; - ArgAutoPtr m_floatingArg; - int m_highestSpecifiedArgPosition; - bool m_throwOnUnrecognisedTokens; - }; - -} // end namespace Clara - -STITCH_CLARA_CLOSE_NAMESPACE -#undef STITCH_CLARA_OPEN_NAMESPACE -#undef STITCH_CLARA_CLOSE_NAMESPACE - -#endif // TWOBLUECUBES_CLARA_H_INCLUDED -#undef STITCH_CLARA_OPEN_NAMESPACE - -// Restore Clara's value for console width, if present -#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#endif - -#include -#include - -namespace Catch { - - inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } - inline void abortAfterX( ConfigData& config, int x ) { - if( x < 1 ) - throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); - config.abortAfter = x; - } - inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } - inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); } - inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); } - - inline void addWarning( ConfigData& config, std::string const& _warning ) { - if( _warning == "NoAssertions" ) - config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); - else - throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' ); - } - inline void setOrder( ConfigData& config, std::string const& order ) { - if( startsWith( "declared", order ) ) - config.runOrder = RunTests::InDeclarationOrder; - else if( startsWith( "lexical", order ) ) - config.runOrder = RunTests::InLexicographicalOrder; - else if( startsWith( "random", order ) ) - config.runOrder = RunTests::InRandomOrder; - else - throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' ); - } - inline void setRngSeed( ConfigData& config, std::string const& seed ) { - if( seed == "time" ) { - config.rngSeed = static_cast( std::time(0) ); - } - else { - std::stringstream ss; - ss << seed; - ss >> config.rngSeed; - if( ss.fail() ) - throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" ); - } - } - inline void setVerbosity( ConfigData& config, int level ) { - // !TBD: accept strings? - config.verbosity = static_cast( level ); - } - inline void setShowDurations( ConfigData& config, bool _showDurations ) { - config.showDurations = _showDurations - ? ShowDurations::Always - : ShowDurations::Never; - } - inline void setUseColour( ConfigData& config, std::string const& value ) { - std::string mode = toLower( value ); - - if( mode == "yes" ) - config.useColour = UseColour::Yes; - else if( mode == "no" ) - config.useColour = UseColour::No; - else if( mode == "auto" ) - config.useColour = UseColour::Auto; - else - throw std::runtime_error( "colour mode must be one of: auto, yes or no" ); - } - inline void setWaitForKeypress( ConfigData& config, std::string const& keypress ) { - std::string keypressLc = toLower( keypress ); - if( keypressLc == "start" ) - config.waitForKeypress = WaitForKeypress::BeforeStart; - else if( keypressLc == "exit" ) - config.waitForKeypress = WaitForKeypress::BeforeExit; - else if( keypressLc == "both" ) - config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; - else - throw std::runtime_error( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); - }; - - inline void forceColour( ConfigData& config ) { - config.useColour = UseColour::Yes; - } - inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { - std::ifstream f( _filename.c_str() ); - if( !f.is_open() ) - throw std::domain_error( "Unable to load input file: " + _filename ); - - std::string line; - while( std::getline( f, line ) ) { - line = trim(line); - if( !line.empty() && !startsWith( line, '#' ) ) { - if( !startsWith( line, '"' ) ) - line = '"' + line + '"'; - addTestOrTags( config, line + ',' ); - } - } - } - - inline Clara::CommandLine makeCommandLineParser() { - - using namespace Clara; - CommandLine cli; - - cli.bindProcessName( &ConfigData::processName ); - - cli["-?"]["-h"]["--help"] - .describe( "display usage information" ) - .bind( &ConfigData::showHelp ); - - cli["-l"]["--list-tests"] - .describe( "list all/matching test cases" ) - .bind( &ConfigData::listTests ); - - cli["-t"]["--list-tags"] - .describe( "list all/matching tags" ) - .bind( &ConfigData::listTags ); - - cli["-s"]["--success"] - .describe( "include successful tests in output" ) - .bind( &ConfigData::showSuccessfulTests ); - - cli["-b"]["--break"] - .describe( "break into debugger on failure" ) - .bind( &ConfigData::shouldDebugBreak ); - - cli["-e"]["--nothrow"] - .describe( "skip exception tests" ) - .bind( &ConfigData::noThrow ); - - cli["-i"]["--invisibles"] - .describe( "show invisibles (tabs, newlines)" ) - .bind( &ConfigData::showInvisibles ); - - cli["-o"]["--out"] - .describe( "output filename" ) - .bind( &ConfigData::outputFilename, "filename" ); - - cli["-r"]["--reporter"] -// .placeholder( "name[:filename]" ) - .describe( "reporter to use (defaults to console)" ) - .bind( &addReporterName, "name" ); - - cli["-n"]["--name"] - .describe( "suite name" ) - .bind( &ConfigData::name, "name" ); - - cli["-a"]["--abort"] - .describe( "abort at first failure" ) - .bind( &abortAfterFirst ); - - cli["-x"]["--abortx"] - .describe( "abort after x failures" ) - .bind( &abortAfterX, "no. failures" ); - - cli["-w"]["--warn"] - .describe( "enable warnings" ) - .bind( &addWarning, "warning name" ); - -// - needs updating if reinstated -// cli.into( &setVerbosity ) -// .describe( "level of verbosity (0=no output)" ) -// .shortOpt( "v") -// .longOpt( "verbosity" ) -// .placeholder( "level" ); - - cli[_] - .describe( "which test or tests to use" ) - .bind( &addTestOrTags, "test name, pattern or tags" ); - - cli["-d"]["--durations"] - .describe( "show test durations" ) - .bind( &setShowDurations, "yes|no" ); - - cli["-f"]["--input-file"] - .describe( "load test names to run from a file" ) - .bind( &loadTestNamesFromFile, "filename" ); - - cli["-#"]["--filenames-as-tags"] - .describe( "adds a tag for the filename" ) - .bind( &ConfigData::filenamesAsTags ); - - cli["-c"]["--section"] - .describe( "specify section to run" ) - .bind( &addSectionToRun, "section name" ); - - // Less common commands which don't have a short form - cli["--list-test-names-only"] - .describe( "list all/matching test cases names only" ) - .bind( &ConfigData::listTestNamesOnly ); - - cli["--list-extra-info"] - .describe( "list all/matching test cases with more info" ) - .bind( &ConfigData::listExtraInfo ); - - cli["--list-reporters"] - .describe( "list all reporters" ) - .bind( &ConfigData::listReporters ); - - cli["--order"] - .describe( "test case order (defaults to decl)" ) - .bind( &setOrder, "decl|lex|rand" ); - - cli["--rng-seed"] - .describe( "set a specific seed for random numbers" ) - .bind( &setRngSeed, "'time'|number" ); - - cli["--force-colour"] - .describe( "force colourised output (deprecated)" ) - .bind( &forceColour ); - - cli["--use-colour"] - .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 ); - - cli["--wait-for-keypress"] - .describe( "waits for a keypress before exiting" ) - .bind( &setWaitForKeypress, "start|exit|both" ); - - return cli; - } - -} // end namespace Catch - -// #included from: internal/catch_list.hpp -#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED - -// #included from: catch_text.h -#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED - -#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - -#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch -// #included from: ../external/tbc_text_format.h -// Only use header guard if we are not using an outer namespace -#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED -# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -# endif -# else -# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED -# endif -#endif -#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -#include -#include -#include - -// Use optional outer namespace -#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { -#endif - -namespace Tbc { - -#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH - const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - struct TextAttributes { - TextAttributes() - : initialIndent( std::string::npos ), - indent( 0 ), - width( consoleWidth-1 ) - {} - - TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } - TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } - TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } - - std::size_t initialIndent; // indent of first line, or npos - std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos - std::size_t width; // maximum width of text, including indent. Longer text will wrap - }; - - class Text { - public: - Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) - : attr( _attr ) - { - const std::string wrappableBeforeChars = "[({<\t"; - const std::string wrappableAfterChars = "])}>-,./|\\"; - const std::string wrappableInsteadOfChars = " \n\r"; - std::string indent = _attr.initialIndent != std::string::npos - ? std::string( _attr.initialIndent, ' ' ) - : std::string( _attr.indent, ' ' ); - - typedef std::string::const_iterator iterator; - iterator it = _str.begin(); - const iterator strEnd = _str.end(); - - while( it != strEnd ) { - - if( lines.size() >= 1000 ) { - lines.push_back( "... message truncated due to excessive size" ); - return; - } - - std::string suffix; - std::size_t width = (std::min)( static_cast( strEnd-it ), _attr.width-static_cast( indent.size() ) ); - iterator itEnd = it+width; - iterator itNext = _str.end(); - - iterator itNewLine = std::find( it, itEnd, '\n' ); - if( itNewLine != itEnd ) - itEnd = itNewLine; - - if( itEnd != strEnd ) { - bool foundWrapPoint = false; - iterator findIt = itEnd; - do { - if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) { - itEnd = findIt+1; - itNext = findIt+1; - foundWrapPoint = true; - } - else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) { - itEnd = findIt; - itNext = findIt; - foundWrapPoint = true; - } - else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) { - itNext = findIt+1; - itEnd = findIt; - foundWrapPoint = true; - } - if( findIt == it ) - break; - else - --findIt; - } - while( !foundWrapPoint ); - - if( !foundWrapPoint ) { - // No good wrap char, so we'll break mid word and add a hyphen - --itEnd; - itNext = itEnd; - suffix = "-"; - } - else { - while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos ) - --itEnd; - } - } - lines.push_back( indent + std::string( it, itEnd ) + suffix ); - - if( indent.size() != _attr.indent ) - indent = std::string( _attr.indent, ' ' ); - it = itNext; - } - } - - typedef std::vector::const_iterator const_iterator; - - const_iterator begin() const { return lines.begin(); } - const_iterator end() const { return lines.end(); } - std::string const& last() const { return lines.back(); } - std::size_t size() const { return lines.size(); } - std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } - std::string toString() const { - std::ostringstream oss; - oss << *this; - return oss.str(); - } - - inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { - for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); - it != itEnd; ++it ) { - if( it != _text.begin() ) - _stream << "\n"; - _stream << *it; - } - return _stream; - } - - private: - std::string str; - TextAttributes attr; - std::vector lines; - }; - -} // end namespace Tbc - -#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -} // end outer namespace -#endif - -#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE - -namespace Catch { - using Tbc::Text; - using Tbc::TextAttributes; -} - -// #included from: catch_console_colour.hpp -#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED - -namespace Catch { - - struct Colour { - enum Code { - None = 0, - - White, - Red, - Green, - Blue, - Cyan, - Yellow, - Grey, - - Bright = 0x10, - - BrightRed = Bright | Red, - BrightGreen = Bright | Green, - LightGrey = Bright | Grey, - BrightWhite = Bright | White, - - // By intention - FileName = LightGrey, - Warning = Yellow, - ResultError = BrightRed, - ResultSuccess = BrightGreen, - ResultExpectedFailure = Warning, - - Error = BrightRed, - Success = Green, - - OriginalExpression = Cyan, - ReconstructedExpression = Yellow, - - SecondaryText = LightGrey, - Headers = White - }; - - // Use constructed object for RAII guard - Colour( Code _colourCode ); - Colour( Colour const& other ); - ~Colour(); - - // Use static method for one-shot changes - static void use( Code _colourCode ); - - private: - bool m_moved; - }; - - inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } - -} // end namespace Catch - -// #included from: catch_interfaces_reporter.h -#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED - -#include -#include -#include - -namespace Catch -{ - struct ReporterConfig { - explicit ReporterConfig( Ptr const& _fullConfig ) - : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} - - ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) - : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} - - std::ostream& stream() const { return *m_stream; } - Ptr fullConfig() const { return m_fullConfig; } - - private: - std::ostream* m_stream; - Ptr m_fullConfig; - }; - - struct ReporterPreferences { - ReporterPreferences() - : shouldRedirectStdOut( false ) - {} - - bool shouldRedirectStdOut; - }; - - template - struct LazyStat : Option { - LazyStat() : used( false ) {} - LazyStat& operator=( T const& _value ) { - Option::operator=( _value ); - used = false; - return *this; - } - void reset() { - Option::reset(); - used = false; - } - bool used; - }; - - struct TestRunInfo { - TestRunInfo( std::string const& _name ) : name( _name ) {} - std::string name; - }; - struct GroupInfo { - GroupInfo( std::string const& _name, - std::size_t _groupIndex, - std::size_t _groupsCount ) - : name( _name ), - groupIndex( _groupIndex ), - groupsCounts( _groupsCount ) - {} - - std::string name; - std::size_t groupIndex; - std::size_t groupsCounts; - }; - - struct AssertionStats { - AssertionStats( AssertionResult const& _assertionResult, - std::vector const& _infoMessages, - Totals const& _totals ) - : assertionResult( _assertionResult ), - infoMessages( _infoMessages ), - totals( _totals ) - { - if( assertionResult.hasMessage() ) { - // Copy message into messages list. - // !TBD This should have been done earlier, somewhere - MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); - builder << assertionResult.getMessage(); - builder.m_info.message = builder.m_stream.str(); - - infoMessages.push_back( builder.m_info ); - } - } - virtual ~AssertionStats(); - -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - AssertionStats( AssertionStats const& ) = default; - AssertionStats( AssertionStats && ) = default; - AssertionStats& operator = ( AssertionStats const& ) = default; - AssertionStats& operator = ( AssertionStats && ) = default; -# endif - - AssertionResult assertionResult; - std::vector infoMessages; - Totals totals; - }; - - struct SectionStats { - SectionStats( SectionInfo const& _sectionInfo, - Counts const& _assertions, - double _durationInSeconds, - bool _missingAssertions ) - : sectionInfo( _sectionInfo ), - assertions( _assertions ), - durationInSeconds( _durationInSeconds ), - missingAssertions( _missingAssertions ) - {} - virtual ~SectionStats(); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - SectionStats( SectionStats const& ) = default; - SectionStats( SectionStats && ) = default; - SectionStats& operator = ( SectionStats const& ) = default; - SectionStats& operator = ( SectionStats && ) = default; -# endif - - SectionInfo sectionInfo; - Counts assertions; - double durationInSeconds; - bool missingAssertions; - }; - - struct TestCaseStats { - TestCaseStats( TestCaseInfo const& _testInfo, - Totals const& _totals, - std::string const& _stdOut, - std::string const& _stdErr, - bool _aborting ) - : testInfo( _testInfo ), - totals( _totals ), - stdOut( _stdOut ), - stdErr( _stdErr ), - aborting( _aborting ) - {} - virtual ~TestCaseStats(); - -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - TestCaseStats( TestCaseStats const& ) = default; - TestCaseStats( TestCaseStats && ) = default; - TestCaseStats& operator = ( TestCaseStats const& ) = default; - TestCaseStats& operator = ( TestCaseStats && ) = default; -# endif - - TestCaseInfo testInfo; - Totals totals; - std::string stdOut; - std::string stdErr; - bool aborting; - }; - - struct TestGroupStats { - TestGroupStats( GroupInfo const& _groupInfo, - Totals const& _totals, - bool _aborting ) - : groupInfo( _groupInfo ), - totals( _totals ), - aborting( _aborting ) - {} - TestGroupStats( GroupInfo const& _groupInfo ) - : groupInfo( _groupInfo ), - aborting( false ) - {} - virtual ~TestGroupStats(); - -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - TestGroupStats( TestGroupStats const& ) = default; - TestGroupStats( TestGroupStats && ) = default; - TestGroupStats& operator = ( TestGroupStats const& ) = default; - TestGroupStats& operator = ( TestGroupStats && ) = default; -# endif - - GroupInfo groupInfo; - Totals totals; - bool aborting; - }; - - struct TestRunStats { - TestRunStats( TestRunInfo const& _runInfo, - Totals const& _totals, - bool _aborting ) - : runInfo( _runInfo ), - totals( _totals ), - aborting( _aborting ) - {} - virtual ~TestRunStats(); - -# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS - TestRunStats( TestRunStats const& _other ) - : runInfo( _other.runInfo ), - totals( _other.totals ), - aborting( _other.aborting ) - {} -# else - TestRunStats( TestRunStats const& ) = default; - TestRunStats( TestRunStats && ) = default; - TestRunStats& operator = ( TestRunStats const& ) = default; - TestRunStats& operator = ( TestRunStats && ) = default; -# endif - - TestRunInfo runInfo; - Totals totals; - bool aborting; - }; - - class MultipleReporters; - - struct IStreamingReporter : IShared { - virtual ~IStreamingReporter(); - - // Implementing class must also provide the following static method: - // static std::string getDescription(); - - virtual ReporterPreferences getPreferences() const = 0; - - virtual void noMatchingTestCases( std::string const& spec ) = 0; - - virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; - virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; - - virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; - virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; - - virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; - - // The return value indicates if the messages buffer should be cleared: - virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; - - virtual void sectionEnded( SectionStats const& sectionStats ) = 0; - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; - virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; - - virtual void skipTest( TestCaseInfo const& testInfo ) = 0; - - virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } - }; - - struct IReporterFactory : IShared { - virtual ~IReporterFactory(); - virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; - virtual std::string getDescription() const = 0; - }; - - struct IReporterRegistry { - typedef std::map > FactoryMap; - typedef std::vector > Listeners; - - virtual ~IReporterRegistry(); - virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; - virtual FactoryMap const& getFactories() const = 0; - virtual Listeners const& getListeners() const = 0; - }; - - Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ); - -} - -#include -#include - -namespace Catch { - - inline std::size_t listTests( Config const& config ) { - - TestSpec testSpec = config.testSpec(); - if( config.testSpec().hasFilters() ) - Catch::cout() << "Matching test cases:\n"; - else { - Catch::cout() << "All available test cases:\n"; - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - } - - std::size_t matchedTests = 0; - TextAttributes nameAttr, descAttr, tagsAttr; - nameAttr.setInitialIndent( 2 ).setIndent( 4 ); - descAttr.setIndent( 4 ); - tagsAttr.setIndent( 6 ); - - std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); - for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - matchedTests++; - TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); - Colour::Code colour = testCaseInfo.isHidden() - ? Colour::SecondaryText - : Colour::None; - Colour colourGuard( colour ); - - Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; - if( config.listExtraInfo() ) { - Catch::cout() << " " << testCaseInfo.lineInfo << std::endl; - std::string description = testCaseInfo.description; - if( description.empty() ) - description = "(NO DESCRIPTION)"; - Catch::cout() << Text( description, descAttr ) << std::endl; - } - if( !testCaseInfo.tags.empty() ) - Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; - } - - if( !config.testSpec().hasFilters() ) - Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl; - else - Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl; - return matchedTests; - } - - inline std::size_t listTestsNamesOnly( Config const& config ) { - TestSpec testSpec = config.testSpec(); - if( !config.testSpec().hasFilters() ) - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - std::size_t matchedTests = 0; - std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); - for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - matchedTests++; - TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); - if( startsWith( testCaseInfo.name, '#' ) ) - Catch::cout() << '"' << testCaseInfo.name << '"'; - else - Catch::cout() << testCaseInfo.name; - if ( config.listExtraInfo() ) - Catch::cout() << "\t@" << testCaseInfo.lineInfo; - Catch::cout() << std::endl; - } - return matchedTests; - } - - struct TagInfo { - TagInfo() : count ( 0 ) {} - void add( std::string const& spelling ) { - ++count; - spellings.insert( spelling ); - } - std::string all() const { - std::string out; - for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); - it != itEnd; - ++it ) - out += "[" + *it + "]"; - return out; - } - std::set spellings; - std::size_t count; - }; - - inline std::size_t listTags( Config const& config ) { - TestSpec testSpec = config.testSpec(); - if( config.testSpec().hasFilters() ) - Catch::cout() << "Tags for matching test cases:\n"; - else { - Catch::cout() << "All available tags:\n"; - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - } - - std::map tagCounts; - - std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); - for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), - tagItEnd = it->getTestCaseInfo().tags.end(); - tagIt != tagItEnd; - ++tagIt ) { - std::string tagName = *tagIt; - std::string lcaseTagName = toLower( tagName ); - std::map::iterator countIt = tagCounts.find( lcaseTagName ); - if( countIt == tagCounts.end() ) - countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; - countIt->second.add( tagName ); - } - } - - for( std::map::const_iterator countIt = tagCounts.begin(), - countItEnd = tagCounts.end(); - countIt != countItEnd; - ++countIt ) { - std::ostringstream oss; - oss << " " << std::setw(2) << countIt->second.count << " "; - Text wrapper( countIt->second.all(), TextAttributes() - .setInitialIndent( 0 ) - .setIndent( oss.str().size() ) - .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); - Catch::cout() << oss.str() << wrapper << '\n'; - } - Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; - return tagCounts.size(); - } - - inline std::size_t listReporters( Config const& /*config*/ ) { - Catch::cout() << "Available reporters:\n"; - IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); - IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; - std::size_t maxNameLen = 0; - for(it = itBegin; it != itEnd; ++it ) - maxNameLen = (std::max)( maxNameLen, it->first.size() ); - - for(it = itBegin; it != itEnd; ++it ) { - Text wrapper( it->second->getDescription(), TextAttributes() - .setInitialIndent( 0 ) - .setIndent( 7+maxNameLen ) - .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); - Catch::cout() << " " - << it->first - << ':' - << std::string( maxNameLen - it->first.size() + 2, ' ' ) - << wrapper << '\n'; - } - Catch::cout() << std::endl; - return factories.size(); - } - - inline Option list( Config const& config ) { - Option listedCount; - if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) ) - listedCount = listedCount.valueOr(0) + listTests( config ); - if( config.listTestNamesOnly() ) - listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); - if( config.listTags() ) - listedCount = listedCount.valueOr(0) + listTags( config ); - if( config.listReporters() ) - listedCount = listedCount.valueOr(0) + listReporters( config ); - return listedCount; - } - -} // end namespace Catch - -// #included from: internal/catch_run_context.hpp -#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED - -// #included from: catch_test_case_tracker.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED - -#include -#include -#include -#include -#include - -CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS - -namespace Catch { -namespace TestCaseTracking { - - struct NameAndLocation { - std::string name; - SourceLineInfo location; - - NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) - : name( _name ), - location( _location ) - {} - }; - - struct ITracker : SharedImpl<> { - virtual ~ITracker(); - - // static queries - virtual NameAndLocation const& nameAndLocation() const = 0; - - // dynamic queries - virtual bool isComplete() const = 0; // Successfully completed or failed - virtual bool isSuccessfullyCompleted() const = 0; - virtual bool isOpen() const = 0; // Started but not complete - virtual bool hasChildren() const = 0; - - virtual ITracker& parent() = 0; - - // actions - virtual void close() = 0; // Successfully complete - virtual void fail() = 0; - virtual void markAsNeedingAnotherRun() = 0; - - virtual void addChild( Ptr const& child ) = 0; - virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0; - virtual void openChild() = 0; - - // Debug/ checking - virtual bool isSectionTracker() const = 0; - virtual bool isIndexTracker() const = 0; - }; - - class TrackerContext { - - enum RunState { - NotStarted, - Executing, - CompletedCycle - }; - - Ptr m_rootTracker; - ITracker* m_currentTracker; - RunState m_runState; - - public: - - static TrackerContext& instance() { - static TrackerContext s_instance; - return s_instance; - } - - TrackerContext() - : m_currentTracker( CATCH_NULL ), - m_runState( NotStarted ) - {} - - ITracker& startRun(); - - void endRun() { - m_rootTracker.reset(); - m_currentTracker = CATCH_NULL; - m_runState = NotStarted; - } - - void startCycle() { - m_currentTracker = m_rootTracker.get(); - m_runState = Executing; - } - void completeCycle() { - m_runState = CompletedCycle; - } - - bool completedCycle() const { - return m_runState == CompletedCycle; - } - ITracker& currentTracker() { - return *m_currentTracker; - } - void setCurrentTracker( ITracker* tracker ) { - m_currentTracker = tracker; - } - }; - - class TrackerBase : public ITracker { - protected: - enum CycleState { - NotStarted, - Executing, - ExecutingChildren, - NeedsAnotherRun, - CompletedSuccessfully, - Failed - }; - class TrackerHasName { - NameAndLocation m_nameAndLocation; - public: - TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} - bool operator ()( Ptr const& tracker ) { - return - tracker->nameAndLocation().name == m_nameAndLocation.name && - tracker->nameAndLocation().location == m_nameAndLocation.location; - } - }; - typedef std::vector > Children; - NameAndLocation m_nameAndLocation; - TrackerContext& m_ctx; - ITracker* m_parent; - Children m_children; - CycleState m_runState; - public: - TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : m_nameAndLocation( nameAndLocation ), - m_ctx( ctx ), - m_parent( parent ), - m_runState( NotStarted ) - {} - virtual ~TrackerBase(); - - virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE { - return m_nameAndLocation; - } - virtual bool isComplete() const CATCH_OVERRIDE { - return m_runState == CompletedSuccessfully || m_runState == Failed; - } - virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { - return m_runState == CompletedSuccessfully; - } - virtual bool isOpen() const CATCH_OVERRIDE { - return m_runState != NotStarted && !isComplete(); - } - virtual bool hasChildren() const CATCH_OVERRIDE { - return !m_children.empty(); - } - - virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { - m_children.push_back( child ); - } - - virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE { - Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); - return( it != m_children.end() ) - ? it->get() - : CATCH_NULL; - } - virtual ITracker& parent() CATCH_OVERRIDE { - assert( m_parent ); // Should always be non-null except for root - return *m_parent; - } - - virtual void openChild() CATCH_OVERRIDE { - if( m_runState != ExecutingChildren ) { - m_runState = ExecutingChildren; - if( m_parent ) - m_parent->openChild(); - } - } - - virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } - virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } - - void open() { - m_runState = Executing; - moveToThis(); - if( m_parent ) - m_parent->openChild(); - } - - virtual void close() CATCH_OVERRIDE { - - // Close any still open children (e.g. generators) - while( &m_ctx.currentTracker() != this ) - m_ctx.currentTracker().close(); - - switch( m_runState ) { - case NotStarted: - case CompletedSuccessfully: - case Failed: - throw std::logic_error( "Illogical state" ); - - case NeedsAnotherRun: - break;; - - case Executing: - m_runState = CompletedSuccessfully; - break; - case ExecutingChildren: - if( m_children.empty() || m_children.back()->isComplete() ) - m_runState = CompletedSuccessfully; - break; - - default: - throw std::logic_error( "Unexpected state" ); - } - moveToParent(); - m_ctx.completeCycle(); - } - virtual void fail() CATCH_OVERRIDE { - m_runState = Failed; - if( m_parent ) - m_parent->markAsNeedingAnotherRun(); - moveToParent(); - m_ctx.completeCycle(); - } - virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { - m_runState = NeedsAnotherRun; - } - private: - void moveToParent() { - assert( m_parent ); - m_ctx.setCurrentTracker( m_parent ); - } - void moveToThis() { - m_ctx.setCurrentTracker( this ); - } - }; - - class SectionTracker : public TrackerBase { - std::vector m_filters; - public: - SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : TrackerBase( nameAndLocation, ctx, parent ) - { - if( parent ) { - while( !parent->isSectionTracker() ) - parent = &parent->parent(); - - SectionTracker& parentSection = static_cast( *parent ); - addNextFilters( parentSection.m_filters ); - } - } - virtual ~SectionTracker(); - - virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } - - static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { - SectionTracker* section = CATCH_NULL; - - ITracker& currentTracker = ctx.currentTracker(); - if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { - assert( childTracker ); - assert( childTracker->isSectionTracker() ); - section = static_cast( childTracker ); - } - else { - section = new SectionTracker( nameAndLocation, ctx, ¤tTracker ); - currentTracker.addChild( section ); - } - if( !ctx.completedCycle() ) - section->tryOpen(); - return *section; - } - - void tryOpen() { - if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) - open(); - } - - void addInitialFilters( std::vector const& filters ) { - if( !filters.empty() ) { - m_filters.push_back(""); // Root - should never be consulted - m_filters.push_back(""); // Test Case - not a section filter - m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); - } - } - void addNextFilters( std::vector const& filters ) { - if( filters.size() > 1 ) - m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() ); - } - }; - - class IndexTracker : public TrackerBase { - int m_size; - int m_index; - public: - IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) - : TrackerBase( nameAndLocation, ctx, parent ), - m_size( size ), - m_index( -1 ) - {} - virtual ~IndexTracker(); - - virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } - - static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { - IndexTracker* tracker = CATCH_NULL; - - ITracker& currentTracker = ctx.currentTracker(); - if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { - assert( childTracker ); - assert( childTracker->isIndexTracker() ); - tracker = static_cast( childTracker ); - } - else { - tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size ); - currentTracker.addChild( tracker ); - } - - if( !ctx.completedCycle() && !tracker->isComplete() ) { - if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) - tracker->moveNext(); - tracker->open(); - } - - return *tracker; - } - - int index() const { return m_index; } - - void moveNext() { - m_index++; - m_children.clear(); - } - - virtual void close() CATCH_OVERRIDE { - TrackerBase::close(); - if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) - m_runState = Executing; - } - }; - - inline ITracker& TrackerContext::startRun() { - m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL ); - m_currentTracker = CATCH_NULL; - m_runState = Executing; - return *m_rootTracker; - } - -} // namespace TestCaseTracking - -using TestCaseTracking::ITracker; -using TestCaseTracking::TrackerContext; -using TestCaseTracking::SectionTracker; -using TestCaseTracking::IndexTracker; - -} // namespace Catch - -CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS - -// #included from: catch_fatal_condition.hpp -#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED - -namespace Catch { - - // Report the error condition - inline void reportFatal( std::string const& message ) { - IContext& context = Catch::getCurrentContext(); - IResultCapture* resultCapture = context.getResultCapture(); - resultCapture->handleFatalErrorCondition( message ); - } - -} // namespace Catch - -#if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// -// #included from: catch_windows_h_proxy.h - -#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED - -#ifdef CATCH_DEFINES_NOMINMAX -# define NOMINMAX -#endif -#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif - -#ifdef __AFXDLL -#include -#else -#include -#endif - -#ifdef CATCH_DEFINES_NOMINMAX -# undef NOMINMAX -#endif -#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN -# undef WIN32_LEAN_AND_MEAN -#endif - - -# if !defined ( CATCH_CONFIG_WINDOWS_SEH ) - -namespace Catch { - struct FatalConditionHandler { - void reset() {} - }; -} - -# else // CATCH_CONFIG_WINDOWS_SEH is defined - -namespace Catch { - - struct SignalDefs { DWORD id; const char* name; }; - extern SignalDefs signalDefs[]; - // There is no 1-1 mapping between signals and windows exceptions. - // Windows can easily distinguish between SO and SigSegV, - // but SigInt, SigTerm, etc are handled differently. - SignalDefs signalDefs[] = { - { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, - { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, - { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, - { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, - }; - - struct FatalConditionHandler { - - static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { - for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { - if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { - reportFatal(signalDefs[i].name); - } - } - // If its not an exception we care about, pass it along. - // This stops us from eating debugger breaks etc. - return EXCEPTION_CONTINUE_SEARCH; - } - - FatalConditionHandler() { - isSet = true; - // 32k seems enough for Catch to handle stack overflow, - // but the value was found experimentally, so there is no strong guarantee - guaranteeSize = 32 * 1024; - exceptionHandlerHandle = CATCH_NULL; - // Register as first handler in current chain - exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); - // Pass in guarantee size to be filled - SetThreadStackGuarantee(&guaranteeSize); - } - - static void reset() { - if (isSet) { - // Unregister handler and restore the old guarantee - RemoveVectoredExceptionHandler(exceptionHandlerHandle); - SetThreadStackGuarantee(&guaranteeSize); - exceptionHandlerHandle = CATCH_NULL; - isSet = false; - } - } - - ~FatalConditionHandler() { - reset(); - } - private: - static bool isSet; - static ULONG guaranteeSize; - static PVOID exceptionHandlerHandle; - }; - - bool FatalConditionHandler::isSet = false; - ULONG FatalConditionHandler::guaranteeSize = 0; - PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL; - -} // namespace Catch - -# endif // CATCH_CONFIG_WINDOWS_SEH - -#else // Not Windows - assumed to be POSIX compatible ////////////////////////// - -# if !defined(CATCH_CONFIG_POSIX_SIGNALS) - -namespace Catch { - struct FatalConditionHandler { - void reset() {} - }; -} - -# else // CATCH_CONFIG_POSIX_SIGNALS is defined - -#include - -namespace Catch { - - struct SignalDefs { - int id; - const char* name; - }; - extern SignalDefs signalDefs[]; - SignalDefs signalDefs[] = { - { SIGINT, "SIGINT - Terminal interrupt signal" }, - { SIGILL, "SIGILL - Illegal instruction signal" }, - { SIGFPE, "SIGFPE - Floating point error signal" }, - { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, - { SIGTERM, "SIGTERM - Termination request signal" }, - { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } - }; - - struct FatalConditionHandler { - - static bool isSet; - static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)]; - static stack_t oldSigStack; - static char altStackMem[SIGSTKSZ]; - - static void handleSignal( int sig ) { - std::string name = ""; - for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { - SignalDefs &def = signalDefs[i]; - if (sig == def.id) { - name = def.name; - break; - } - } - reset(); - reportFatal(name); - raise( sig ); - } - - FatalConditionHandler() { - isSet = true; - stack_t sigStack; - sigStack.ss_sp = altStackMem; - sigStack.ss_size = SIGSTKSZ; - sigStack.ss_flags = 0; - sigaltstack(&sigStack, &oldSigStack); - struct sigaction sa = { 0 }; - - sa.sa_handler = handleSignal; - sa.sa_flags = SA_ONSTACK; - for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { - sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); - } - } - - ~FatalConditionHandler() { - reset(); - } - static void reset() { - if( isSet ) { - // Set signals back to previous values -- hopefully nobody overwrote them in the meantime - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { - sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL); - } - // Return the old stack - sigaltstack(&oldSigStack, CATCH_NULL); - isSet = false; - } - } - }; - - bool FatalConditionHandler::isSet = false; - struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; - stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; - -} // namespace Catch - -# endif // CATCH_CONFIG_POSIX_SIGNALS - -#endif // not Windows - -#include -#include - -namespace Catch { - - class StreamRedirect { - - public: - StreamRedirect( std::ostream& stream, std::string& targetString ) - : m_stream( stream ), - m_prevBuf( stream.rdbuf() ), - m_targetString( targetString ) - { - stream.rdbuf( m_oss.rdbuf() ); - } - - ~StreamRedirect() { - m_targetString += m_oss.str(); - m_stream.rdbuf( m_prevBuf ); - } - - private: - std::ostream& m_stream; - std::streambuf* m_prevBuf; - std::ostringstream m_oss; - std::string& m_targetString; - }; - - // StdErr has two constituent streams in C++, std::cerr and std::clog - // This means that we need to redirect 2 streams into 1 to keep proper - // order of writes and cannot use StreamRedirect on its own - class StdErrRedirect { - public: - StdErrRedirect(std::string& targetString) - :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()), - m_targetString(targetString){ - cerr().rdbuf(m_oss.rdbuf()); - clog().rdbuf(m_oss.rdbuf()); - } - ~StdErrRedirect() { - m_targetString += m_oss.str(); - cerr().rdbuf(m_cerrBuf); - clog().rdbuf(m_clogBuf); - } - private: - std::streambuf* m_cerrBuf; - std::streambuf* m_clogBuf; - std::ostringstream m_oss; - std::string& m_targetString; - }; - - /////////////////////////////////////////////////////////////////////////// - - class RunContext : public IResultCapture, public IRunner { - - RunContext( RunContext const& ); - void operator =( RunContext const& ); - - public: - - explicit RunContext( Ptr const& _config, Ptr const& reporter ) - : m_runInfo( _config->name() ), - m_context( getCurrentMutableContext() ), - m_activeTestCase( CATCH_NULL ), - m_config( _config ), - m_reporter( reporter ), - m_shouldReportUnexpected ( true ) - { - m_context.setRunner( this ); - m_context.setConfig( m_config ); - m_context.setResultCapture( this ); - m_reporter->testRunStarting( m_runInfo ); - } - - virtual ~RunContext() { - m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); - } - - void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { - m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); - } - void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { - m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); - } - - Totals runTest( TestCase const& testCase ) { - Totals prevTotals = m_totals; - - std::string redirectedCout; - std::string redirectedCerr; - - TestCaseInfo testInfo = testCase.getTestCaseInfo(); - - m_reporter->testCaseStarting( testInfo ); - - m_activeTestCase = &testCase; - - do { - ITracker& rootTracker = m_trackerContext.startRun(); - assert( rootTracker.isSectionTracker() ); - static_cast( rootTracker ).addInitialFilters( m_config->getSectionsToRun() ); - do { - m_trackerContext.startCycle(); - m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) ); - runCurrentTest( redirectedCout, redirectedCerr ); - } - while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); - } - // !TBD: deprecated - this will be replaced by indexed trackers - while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); - - Totals deltaTotals = m_totals.delta( prevTotals ); - if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) { - deltaTotals.assertions.failed++; - deltaTotals.testCases.passed--; - deltaTotals.testCases.failed++; - } - m_totals.testCases += deltaTotals.testCases; - m_reporter->testCaseEnded( TestCaseStats( testInfo, - deltaTotals, - redirectedCout, - redirectedCerr, - aborting() ) ); - - m_activeTestCase = CATCH_NULL; - m_testCaseTracker = CATCH_NULL; - - return deltaTotals; - } - - Ptr config() const { - return m_config; - } - - private: // IResultCapture - - virtual void assertionEnded( AssertionResult const& result ) { - if( result.getResultType() == ResultWas::Ok ) { - m_totals.assertions.passed++; - } - else if( !result.isOk() ) { - if( m_activeTestCase->getTestCaseInfo().okToFail() ) - m_totals.assertions.failedButOk++; - else - m_totals.assertions.failed++; - } - - // We have no use for the return value (whether messages should be cleared), because messages were made scoped - // and should be let to clear themselves out. - static_cast(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); - - // Reset working state - m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); - m_lastResult = result; - } - - virtual bool lastAssertionPassed() - { - return m_totals.assertions.passed == (m_prevPassed + 1); - } - - virtual void assertionPassed() - { - m_totals.assertions.passed++; - m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"; - m_lastAssertionInfo.macroName = ""; - } - - virtual void assertionRun() - { - m_prevPassed = m_totals.assertions.passed; - } - - virtual bool sectionStarted ( - SectionInfo const& sectionInfo, - Counts& assertions - ) - { - ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) ); - if( !sectionTracker.isOpen() ) - return false; - m_activeSections.push_back( §ionTracker ); - - m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; - - m_reporter->sectionStarting( sectionInfo ); - - assertions = m_totals.assertions; - - return true; - } - bool testForMissingAssertions( Counts& assertions ) { - if( assertions.total() != 0 ) - return false; - if( !m_config->warnAboutMissingAssertions() ) - return false; - if( m_trackerContext.currentTracker().hasChildren() ) - return false; - m_totals.assertions.failed++; - assertions.failed++; - return true; - } - - virtual void sectionEnded( SectionEndInfo const& endInfo ) { - Counts assertions = m_totals.assertions - endInfo.prevAssertions; - bool missingAssertions = testForMissingAssertions( assertions ); - - if( !m_activeSections.empty() ) { - m_activeSections.back()->close(); - m_activeSections.pop_back(); - } - - m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); - m_messages.clear(); - } - - virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { - if( m_unfinishedSections.empty() ) - m_activeSections.back()->fail(); - else - m_activeSections.back()->close(); - m_activeSections.pop_back(); - - m_unfinishedSections.push_back( endInfo ); - } - - virtual void pushScopedMessage( MessageInfo const& message ) { - m_messages.push_back( message ); - } - - virtual void popScopedMessage( MessageInfo const& message ) { - m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); - } - - virtual std::string getCurrentTestName() const { - return m_activeTestCase - ? m_activeTestCase->getTestCaseInfo().name - : std::string(); - } - - virtual const AssertionResult* getLastResult() const { - return &m_lastResult; - } - - virtual void exceptionEarlyReported() { - m_shouldReportUnexpected = false; - } - - virtual void handleFatalErrorCondition( std::string const& message ) { - // Don't rebuild the result -- the stringification itself can cause more fatal errors - // Instead, fake a result data. - AssertionResultData tempResult; - tempResult.resultType = ResultWas::FatalErrorCondition; - tempResult.message = message; - AssertionResult result(m_lastAssertionInfo, tempResult); - - getResultCapture().assertionEnded(result); - - handleUnfinishedSections(); - - // Recreate section for test case (as we will lose the one that was in scope) - TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); - - Counts assertions; - assertions.failed = 1; - SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); - m_reporter->sectionEnded( testCaseSectionStats ); - - TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); - - Totals deltaTotals; - deltaTotals.testCases.failed = 1; - deltaTotals.assertions.failed = 1; - m_reporter->testCaseEnded( TestCaseStats( testInfo, - deltaTotals, - std::string(), - std::string(), - false ) ); - m_totals.testCases.failed++; - testGroupEnded( std::string(), m_totals, 1, 1 ); - m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); - } - - public: - // !TBD We need to do this another way! - bool aborting() const { - return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); - } - - private: - - void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { - TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); - m_reporter->sectionStarting( testCaseSection ); - Counts prevAssertions = m_totals.assertions; - double duration = 0; - m_shouldReportUnexpected = true; - try { - m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); - - seedRng( *m_config ); - - Timer timer; - timer.start(); - if( m_reporter->getPreferences().shouldRedirectStdOut ) { - StreamRedirect coutRedir( Catch::cout(), redirectedCout ); - StdErrRedirect errRedir( redirectedCerr ); - invokeActiveTestCase(); - } - else { - invokeActiveTestCase(); - } - duration = timer.getElapsedSeconds(); - } - catch( TestFailureException& ) { - // This just means the test was aborted due to failure - } - catch(...) { - // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions - // are reported without translation at the point of origin. - if (m_shouldReportUnexpected) { - makeUnexpectedResultBuilder().useActiveException(); - } - } - m_testCaseTracker->close(); - handleUnfinishedSections(); - m_messages.clear(); - - Counts assertions = m_totals.assertions - prevAssertions; - bool missingAssertions = testForMissingAssertions( assertions ); - - SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); - m_reporter->sectionEnded( testCaseSectionStats ); - } - - void invokeActiveTestCase() { - FatalConditionHandler fatalConditionHandler; // Handle signals - m_activeTestCase->invoke(); - fatalConditionHandler.reset(); - } - - private: - - ResultBuilder makeUnexpectedResultBuilder() const { - return ResultBuilder( m_lastAssertionInfo.macroName, - m_lastAssertionInfo.lineInfo, - m_lastAssertionInfo.capturedExpression, - m_lastAssertionInfo.resultDisposition ); - } - - void handleUnfinishedSections() { - // If sections ended prematurely due to an exception we stored their - // infos here so we can tear them down outside the unwind process. - for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), - itEnd = m_unfinishedSections.rend(); - it != itEnd; - ++it ) - sectionEnded( *it ); - m_unfinishedSections.clear(); - } - - TestRunInfo m_runInfo; - IMutableContext& m_context; - TestCase const* m_activeTestCase; - ITracker* m_testCaseTracker; - ITracker* m_currentSectionTracker; - AssertionResult m_lastResult; - - Ptr m_config; - Totals m_totals; - Ptr m_reporter; - std::vector m_messages; - AssertionInfo m_lastAssertionInfo; - std::vector m_unfinishedSections; - std::vector m_activeSections; - TrackerContext m_trackerContext; - size_t m_prevPassed; - bool m_shouldReportUnexpected; - }; - - IResultCapture& getResultCapture() { - if( IResultCapture* capture = getCurrentContext().getResultCapture() ) - return *capture; - else - throw std::logic_error( "No result capture instance" ); - } - -} // end namespace Catch - -// #included from: internal/catch_version.h -#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED - -namespace Catch { - - // Versioning information - struct Version { - Version( unsigned int _majorVersion, - unsigned int _minorVersion, - unsigned int _patchNumber, - char const * const _branchName, - unsigned int _buildNumber ); - - unsigned int const majorVersion; - unsigned int const minorVersion; - unsigned int const patchNumber; - - // buildNumber is only used if branchName is not null - char const * const branchName; - unsigned int const buildNumber; - - friend std::ostream& operator << ( std::ostream& os, Version const& version ); - - private: - void operator=( Version const& ); - }; - - inline Version libraryVersion(); -} - -#include -#include -#include - -namespace Catch { - - Ptr createReporter( std::string const& reporterName, Ptr const& config ) { - Ptr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() ); - if( !reporter ) { - std::ostringstream oss; - oss << "No reporter registered with name: '" << reporterName << "'"; - throw std::domain_error( oss.str() ); - } - return reporter; - } - -#if !defined(CATCH_CONFIG_DEFAULT_REPORTER) -#define CATCH_CONFIG_DEFAULT_REPORTER "console" -#endif - - Ptr makeReporter( Ptr const& config ) { - std::vector reporters = config->getReporterNames(); - if( reporters.empty() ) - reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER ); - - Ptr reporter; - for( std::vector::const_iterator it = reporters.begin(), itEnd = reporters.end(); - it != itEnd; - ++it ) - reporter = addReporter( reporter, createReporter( *it, config ) ); - return reporter; - } - Ptr addListeners( Ptr const& config, Ptr reporters ) { - IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); - for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); - it != itEnd; - ++it ) - reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) ); - return reporters; - } - - Totals runTests( Ptr const& config ) { - - Ptr iconfig = config.get(); - - Ptr reporter = makeReporter( config ); - reporter = addListeners( iconfig, reporter ); - - RunContext context( iconfig, reporter ); - - Totals totals; - - context.testGroupStarting( config->name(), 1, 1 ); - - TestSpec testSpec = config->testSpec(); - if( !testSpec.hasFilters() ) - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests - - std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); - for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); - it != itEnd; - ++it ) { - if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) - totals += context.runTest( *it ); - else - reporter->skipTest( *it ); - } - - context.testGroupEnded( iconfig->name(), totals, 1, 1 ); - return totals; - } - - void applyFilenamesAsTags( IConfig const& config ) { - std::vector const& tests = getAllTestCasesSorted( config ); - for(std::size_t i = 0; i < tests.size(); ++i ) { - TestCase& test = const_cast( tests[i] ); - std::set tags = test.tags; - - std::string filename = test.lineInfo.file; - std::string::size_type lastSlash = filename.find_last_of( "\\/" ); - if( lastSlash != std::string::npos ) - filename = filename.substr( lastSlash+1 ); - - std::string::size_type lastDot = filename.find_last_of( '.' ); - if( lastDot != std::string::npos ) - filename = filename.substr( 0, lastDot ); - - tags.insert( '#' + filename ); - setTags( test, tags ); - } - } - - class Session : NonCopyable { - static bool alreadyInstantiated; - - public: - - struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; - - Session() - : m_cli( makeCommandLineParser() ) { - if( alreadyInstantiated ) { - std::string msg = "Only one instance of Catch::Session can ever be used"; - Catch::cerr() << msg << std::endl; - throw std::logic_error( msg ); - } - alreadyInstantiated = true; - } - ~Session() { - Catch::cleanUp(); - } - - void showHelp( std::string const& processName ) { - Catch::cout() << "\nCatch v" << libraryVersion() << "\n"; - - m_cli.usage( Catch::cout(), processName ); - Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; - } - void libIdentify() { - Catch::cout() - << std::left << std::setw(16) << "description: " << "A Catch test executable\n" - << std::left << std::setw(16) << "category: " << "testframework\n" - << std::left << std::setw(16) << "framework: " << "Catch Test\n" - << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; - } - - int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { - try { - m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); - m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); - if( m_configData.showHelp ) - showHelp( m_configData.processName ); - if( m_configData.libIdentify ) - libIdentify(); - m_config.reset(); - } - catch( std::exception& ex ) { - { - Colour colourGuard( Colour::Red ); - Catch::cerr() - << "\nError(s) in input:\n" - << Text( ex.what(), TextAttributes().setIndent(2) ) - << "\n\n"; - } - m_cli.usage( Catch::cout(), m_configData.processName ); - return (std::numeric_limits::max)(); - } - return 0; - } - - void useConfigData( ConfigData const& _configData ) { - m_configData = _configData; - m_config.reset(); - } - - int run( int argc, char const* const* const argv ) { - - int returnCode = applyCommandLine( argc, argv ); - if( returnCode == 0 ) - returnCode = run(); - return returnCode; - } - - #if defined(WIN32) && defined(UNICODE) - int run( int argc, wchar_t const* const* const argv ) { - - char **utf8Argv = new char *[ argc ]; - - for ( int i = 0; i < argc; ++i ) { - int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); - - utf8Argv[ i ] = new char[ bufSize ]; - - WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); - } - - int returnCode = applyCommandLine( argc, utf8Argv ); - if( returnCode == 0 ) - returnCode = run(); - - for ( int i = 0; i < argc; ++i ) - delete [] utf8Argv[ i ]; - - delete [] utf8Argv; - - return returnCode; - } - #endif - - int run() { - if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { - Catch::cout() << "...waiting for enter/ return before starting" << std::endl; - static_cast(std::getchar()); - } - int exitCode = runInternal(); - if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { - Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; - static_cast(std::getchar()); - } - return exitCode; - } - - Clara::CommandLine const& cli() const { - return m_cli; - } - std::vector const& unusedTokens() const { - return m_unusedTokens; - } - ConfigData& configData() { - return m_configData; - } - Config& config() { - if( !m_config ) - m_config = new Config( m_configData ); - return *m_config; - } - private: - - int runInternal() { - if( m_configData.showHelp || m_configData.libIdentify ) - return 0; - - try - { - config(); // Force config to be constructed - - seedRng( *m_config ); - - if( m_configData.filenamesAsTags ) - applyFilenamesAsTags( *m_config ); - - // Handle list request - if( Option listed = list( config() ) ) - return static_cast( *listed ); - - return static_cast( runTests( m_config ).assertions.failed ); - } - catch( std::exception& ex ) { - Catch::cerr() << ex.what() << std::endl; - return (std::numeric_limits::max)(); - } - } - - Clara::CommandLine m_cli; - std::vector m_unusedTokens; - ConfigData m_configData; - Ptr m_config; - }; - - bool Session::alreadyInstantiated = false; - -} // end namespace Catch - -// #included from: catch_registry_hub.hpp -#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED - -// #included from: catch_test_case_registry_impl.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED - -#include -#include -#include -#include - -namespace Catch { - - struct RandomNumberGenerator { - typedef std::ptrdiff_t 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(); } -#endif - template - static void shuffle( V& vector ) { - RandomNumberGenerator rng; -#ifdef CATCH_CONFIG_CPP11_SHUFFLE - std::shuffle( vector.begin(), vector.end(), rng ); -#else - std::random_shuffle( vector.begin(), vector.end(), rng ); -#endif - } - }; - - inline std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { - - std::vector sorted = unsortedTestCases; - - switch( config.runOrder() ) { - case RunTests::InLexicographicalOrder: - std::sort( sorted.begin(), sorted.end() ); - break; - case RunTests::InRandomOrder: - { - seedRng( config ); - RandomNumberGenerator::shuffle( sorted ); - } - break; - case RunTests::InDeclarationOrder: - // already in declaration order - break; - } - return sorted; - } - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { - return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); - } - - void enforceNoDuplicateTestCases( std::vector const& functions ) { - std::set seenFunctions; - for( std::vector::const_iterator it = functions.begin(), itEnd = functions.end(); - it != itEnd; - ++it ) { - std::pair::const_iterator, bool> prev = seenFunctions.insert( *it ); - if( !prev.second ) { - std::ostringstream ss; - - ss << Colour( Colour::Red ) - << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" - << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n' - << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; - - throw std::runtime_error(ss.str()); - } - } - } - - std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { - std::vector filtered; - filtered.reserve( testCases.size() ); - for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); - it != itEnd; - ++it ) - if( matchTest( *it, testSpec, config ) ) - filtered.push_back( *it ); - return filtered; - } - std::vector const& getAllTestCasesSorted( IConfig const& config ) { - return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); - } - - class TestRegistry : public ITestCaseRegistry { - public: - TestRegistry() - : m_currentSortOrder( RunTests::InDeclarationOrder ), - m_unnamedCount( 0 ) - {} - virtual ~TestRegistry(); - - virtual void registerTest( TestCase const& testCase ) { - std::string name = testCase.getTestCaseInfo().name; - if( name.empty() ) { - std::ostringstream oss; - oss << "Anonymous test case " << ++m_unnamedCount; - return registerTest( testCase.withName( oss.str() ) ); - } - m_functions.push_back( testCase ); - } - - virtual std::vector const& getAllTests() const { - return m_functions; - } - virtual std::vector const& getAllTestsSorted( IConfig const& config ) const { - if( m_sortedFunctions.empty() ) - enforceNoDuplicateTestCases( m_functions ); - - if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { - m_sortedFunctions = sortTests( config, m_functions ); - m_currentSortOrder = config.runOrder(); - } - return m_sortedFunctions; - } - - private: - std::vector m_functions; - mutable RunTests::InWhatOrder m_currentSortOrder; - mutable std::vector m_sortedFunctions; - size_t m_unnamedCount; - std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised - }; - - /////////////////////////////////////////////////////////////////////////// - - class FreeFunctionTestCase : public SharedImpl { - public: - - FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} - - virtual void invoke() const { - m_fun(); - } - - private: - virtual ~FreeFunctionTestCase(); - - TestFunction m_fun; - }; - - inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { - std::string className = classOrQualifiedMethodName; - if( startsWith( className, '&' ) ) - { - std::size_t lastColons = className.rfind( "::" ); - std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); - if( penultimateColons == std::string::npos ) - penultimateColons = 1; - className = className.substr( penultimateColons, lastColons-penultimateColons ); - } - return className; - } - - void registerTestCase - ( ITestCase* testCase, - char const* classOrQualifiedMethodName, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ) { - - getMutableRegistryHub().registerTest - ( makeTestCase - ( testCase, - extractClassName( classOrQualifiedMethodName ), - nameAndDesc.name, - nameAndDesc.description, - lineInfo ) ); - } - void registerTestCaseFunction - ( TestFunction function, - SourceLineInfo const& lineInfo, - NameAndDesc const& nameAndDesc ) { - registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); - } - - /////////////////////////////////////////////////////////////////////////// - - AutoReg::AutoReg - ( TestFunction function, - SourceLineInfo const& lineInfo, - NameAndDesc const& nameAndDesc ) { - registerTestCaseFunction( function, lineInfo, nameAndDesc ); - } - - AutoReg::~AutoReg() {} - -} // end namespace Catch - -// #included from: catch_reporter_registry.hpp -#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED - -#include - -namespace Catch { - - class ReporterRegistry : public IReporterRegistry { - - public: - - virtual ~ReporterRegistry() CATCH_OVERRIDE {} - - virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { - FactoryMap::const_iterator it = m_factories.find( name ); - if( it == m_factories.end() ) - return CATCH_NULL; - return it->second->create( ReporterConfig( config ) ); - } - - void registerReporter( std::string const& name, Ptr const& factory ) { - m_factories.insert( std::make_pair( name, factory ) ); - } - void registerListener( Ptr const& factory ) { - m_listeners.push_back( factory ); - } - - virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { - return m_factories; - } - virtual Listeners const& getListeners() const CATCH_OVERRIDE { - return m_listeners; - } - - private: - FactoryMap m_factories; - Listeners m_listeners; - }; -} - -// #included from: catch_exception_translator_registry.hpp -#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED - -#ifdef __OBJC__ -#import "Foundation/Foundation.h" -#endif - -namespace Catch { - - class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { - public: - ~ExceptionTranslatorRegistry() { - deleteAll( m_translators ); - } - - virtual void registerTranslator( const IExceptionTranslator* translator ) { - m_translators.push_back( translator ); - } - - virtual std::string translateActiveException() const { - try { -#ifdef __OBJC__ - // In Objective-C try objective-c exceptions first - @try { - return tryTranslators(); - } - @catch (NSException *exception) { - return Catch::toString( [exception description] ); - } -#else - return tryTranslators(); -#endif - } - catch( TestFailureException& ) { - throw; - } - catch( std::exception& ex ) { - return ex.what(); - } - catch( std::string& msg ) { - return msg; - } - catch( const char* msg ) { - return msg; - } - catch(...) { - return "Unknown exception"; - } - } - - std::string tryTranslators() const { - if( m_translators.empty() ) - throw; - else - return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); - } - - private: - std::vector m_translators; - }; -} - -// #included from: catch_tag_alias_registry.h -#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED - -#include - -namespace Catch { - - class TagAliasRegistry : public ITagAliasRegistry { - public: - virtual ~TagAliasRegistry(); - virtual Option find( std::string const& alias ) const; - virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; - void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ); - - private: - std::map m_registry; - }; - -} // end namespace Catch - -namespace Catch { - - namespace { - - class RegistryHub : public IRegistryHub, public IMutableRegistryHub { - - RegistryHub( RegistryHub const& ); - void operator=( RegistryHub const& ); - - public: // IRegistryHub - RegistryHub() { - } - virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { - return m_reporterRegistry; - } - virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { - return m_testCaseRegistry; - } - virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { - return m_exceptionTranslatorRegistry; - } - virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE { - return m_tagAliasRegistry; - } - - public: // IMutableRegistryHub - virtual void registerReporter( std::string const& name, Ptr const& factory ) CATCH_OVERRIDE { - m_reporterRegistry.registerReporter( name, factory ); - } - virtual void registerListener( Ptr const& factory ) CATCH_OVERRIDE { - m_reporterRegistry.registerListener( factory ); - } - virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { - m_testCaseRegistry.registerTest( testInfo ); - } - virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { - m_exceptionTranslatorRegistry.registerTranslator( translator ); - } - virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE { - m_tagAliasRegistry.add( alias, tag, lineInfo ); - } - - private: - TestRegistry m_testCaseRegistry; - ReporterRegistry m_reporterRegistry; - ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; - TagAliasRegistry m_tagAliasRegistry; - }; - - // Single, global, instance - inline RegistryHub*& getTheRegistryHub() { - static RegistryHub* theRegistryHub = CATCH_NULL; - if( !theRegistryHub ) - theRegistryHub = new RegistryHub(); - return theRegistryHub; - } - } - - IRegistryHub& getRegistryHub() { - return *getTheRegistryHub(); - } - IMutableRegistryHub& getMutableRegistryHub() { - return *getTheRegistryHub(); - } - void cleanUp() { - delete getTheRegistryHub(); - getTheRegistryHub() = CATCH_NULL; - cleanUpContext(); - } - std::string translateActiveException() { - return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); - } - -} // end namespace Catch - -// #included from: catch_notimplemented_exception.hpp -#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED - -#include - -namespace Catch { - - NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) - : m_lineInfo( lineInfo ) { - std::ostringstream oss; - oss << lineInfo << ": function "; - oss << "not implemented"; - m_what = oss.str(); - } - - const char* NotImplementedException::what() const CATCH_NOEXCEPT { - return m_what.c_str(); - } - -} // end namespace Catch - -// #included from: catch_context_impl.hpp -#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED - -// #included from: catch_stream.hpp -#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED - -#include -#include -#include - -namespace Catch { - - template - class StreamBufImpl : public StreamBufBase { - char data[bufferSize]; - WriterF m_writer; - - public: - StreamBufImpl() { - setp( data, data + sizeof(data) ); - } - - ~StreamBufImpl() CATCH_NOEXCEPT { - sync(); - } - - private: - int overflow( int c ) { - sync(); - - if( c != EOF ) { - if( pbase() == epptr() ) - m_writer( std::string( 1, static_cast( c ) ) ); - else - sputc( static_cast( c ) ); - } - return 0; - } - - int sync() { - if( pbase() != pptr() ) { - m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); - setp( pbase(), epptr() ); - } - return 0; - } - }; - - /////////////////////////////////////////////////////////////////////////// - - FileStream::FileStream( std::string const& filename ) { - m_ofs.open( filename.c_str() ); - if( m_ofs.fail() ) { - std::ostringstream oss; - oss << "Unable to open file: '" << filename << '\''; - throw std::domain_error( oss.str() ); - } - } - - std::ostream& FileStream::stream() const { - return m_ofs; - } - - struct OutputDebugWriter { - - void operator()( std::string const&str ) { - writeToDebugConsole( str ); - } - }; - - DebugOutStream::DebugOutStream() - : m_streamBuf( new StreamBufImpl() ), - m_os( m_streamBuf.get() ) - {} - - std::ostream& DebugOutStream::stream() const { - return m_os; - } - - // Store the streambuf from cout up-front because - // cout may get redirected when running tests - CoutStream::CoutStream() - : m_os( Catch::cout().rdbuf() ) - {} - - std::ostream& CoutStream::stream() const { - return m_os; - } - -#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions - std::ostream& cout() { - return std::cout; - } - std::ostream& cerr() { - return std::cerr; - } - std::ostream& clog() { - return std::clog; - } -#endif -} - -namespace Catch { - - class Context : public IMutableContext { - - Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} - Context( Context const& ); - void operator=( Context const& ); - - public: - virtual ~Context() { - deleteAllValues( m_generatorsByTestName ); - } - - public: // IContext - virtual IResultCapture* getResultCapture() { - return m_resultCapture; - } - virtual IRunner* getRunner() { - return m_runner; - } - virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { - return getGeneratorsForCurrentTest() - .getGeneratorInfo( fileInfo, totalSize ) - .getCurrentIndex(); - } - virtual bool advanceGeneratorsForCurrentTest() { - IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); - return generators && generators->moveNext(); - } - - virtual Ptr getConfig() const { - return m_config; - } - - public: // IMutableContext - virtual void setResultCapture( IResultCapture* resultCapture ) { - m_resultCapture = resultCapture; - } - virtual void setRunner( IRunner* runner ) { - m_runner = runner; - } - virtual void setConfig( Ptr const& config ) { - m_config = config; - } - - friend IMutableContext& getCurrentMutableContext(); - - private: - IGeneratorsForTest* findGeneratorsForCurrentTest() { - std::string testName = getResultCapture()->getCurrentTestName(); - - std::map::const_iterator it = - m_generatorsByTestName.find( testName ); - return it != m_generatorsByTestName.end() - ? it->second - : CATCH_NULL; - } - - IGeneratorsForTest& getGeneratorsForCurrentTest() { - IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); - if( !generators ) { - std::string testName = getResultCapture()->getCurrentTestName(); - generators = createGeneratorsForTest(); - m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); - } - return *generators; - } - - private: - Ptr m_config; - IRunner* m_runner; - IResultCapture* m_resultCapture; - std::map m_generatorsByTestName; - }; - - namespace { - Context* currentContext = CATCH_NULL; - } - IMutableContext& getCurrentMutableContext() { - if( !currentContext ) - currentContext = new Context(); - return *currentContext; - } - IContext& getCurrentContext() { - return getCurrentMutableContext(); - } - - void cleanUpContext() { - delete currentContext; - currentContext = CATCH_NULL; - } -} - -// #included from: catch_console_colour_impl.hpp -#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED - -// #included from: catch_errno_guard.hpp -#define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED - -#include - -namespace Catch { - - class ErrnoGuard { - public: - ErrnoGuard():m_oldErrno(errno){} - ~ErrnoGuard() { errno = m_oldErrno; } - private: - int m_oldErrno; - }; - -} - -namespace Catch { - namespace { - - struct IColourImpl { - virtual ~IColourImpl() {} - virtual void use( Colour::Code _colourCode ) = 0; - }; - - struct NoColourImpl : IColourImpl { - void use( Colour::Code ) {} - - static IColourImpl* instance() { - static NoColourImpl s_instance; - return &s_instance; - } - }; - - } // anon namespace -} // namespace Catch - -#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) -# ifdef CATCH_PLATFORM_WINDOWS -# define CATCH_CONFIG_COLOUR_WINDOWS -# else -# define CATCH_CONFIG_COLOUR_ANSI -# endif -#endif - -#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// - -namespace Catch { -namespace { - - class Win32ColourImpl : public IColourImpl { - public: - Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) - { - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); - originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); - originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); - } - - virtual void use( Colour::Code _colourCode ) { - switch( _colourCode ) { - case Colour::None: return setTextAttribute( originalForegroundAttributes ); - case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); - case Colour::Red: return setTextAttribute( FOREGROUND_RED ); - case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); - case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); - case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); - case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); - case Colour::Grey: return setTextAttribute( 0 ); - - case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); - case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); - case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); - case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); - - case Colour::Bright: throw std::logic_error( "not a colour" ); - } - } - - private: - void setTextAttribute( WORD _textAttribute ) { - SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); - } - HANDLE stdoutHandle; - WORD originalForegroundAttributes; - WORD originalBackgroundAttributes; - }; - - IColourImpl* platformColourInstance() { - static Win32ColourImpl s_instance; - - Ptr config = getCurrentContext().getConfig(); - UseColour::YesOrNo colourMode = config - ? config->useColour() - : UseColour::Auto; - if( colourMode == UseColour::Auto ) - colourMode = !isDebuggerActive() - ? UseColour::Yes - : UseColour::No; - return colourMode == UseColour::Yes - ? &s_instance - : NoColourImpl::instance(); - } - -} // end anon namespace -} // end namespace Catch - -#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// - -#include - -namespace Catch { -namespace { - - // use POSIX/ ANSI console terminal codes - // Thanks to Adam Strzelecki for original contribution - // (http://github.com/nanoant) - // https://github.com/philsquared/Catch/pull/131 - class PosixColourImpl : public IColourImpl { - public: - virtual void use( Colour::Code _colourCode ) { - switch( _colourCode ) { - case Colour::None: - case Colour::White: return setColour( "[0m" ); - case Colour::Red: return setColour( "[0;31m" ); - case Colour::Green: return setColour( "[0;32m" ); - case Colour::Blue: return setColour( "[0;34m" ); - case Colour::Cyan: return setColour( "[0;36m" ); - case Colour::Yellow: return setColour( "[0;33m" ); - case Colour::Grey: return setColour( "[1;30m" ); - - case Colour::LightGrey: return setColour( "[0;37m" ); - case Colour::BrightRed: return setColour( "[1;31m" ); - case Colour::BrightGreen: return setColour( "[1;32m" ); - case Colour::BrightWhite: return setColour( "[1;37m" ); - - case Colour::Bright: throw std::logic_error( "not a colour" ); - } - } - static IColourImpl* instance() { - static PosixColourImpl s_instance; - return &s_instance; - } - - private: - void setColour( const char* _escapeCode ) { - Catch::cout() << '\033' << _escapeCode; - } - }; - - IColourImpl* platformColourInstance() { - ErrnoGuard guard; - Ptr config = getCurrentContext().getConfig(); - UseColour::YesOrNo colourMode = config - ? config->useColour() - : UseColour::Auto; - if( colourMode == UseColour::Auto ) - colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) - ? UseColour::Yes - : UseColour::No; - return colourMode == UseColour::Yes - ? PosixColourImpl::instance() - : NoColourImpl::instance(); - } - -} // end anon namespace -} // end namespace Catch - -#else // not Windows or ANSI /////////////////////////////////////////////// - -namespace Catch { - - static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } - -} // end namespace Catch - -#endif // Windows/ ANSI/ None - -namespace Catch { - - Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } - Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } - Colour::~Colour(){ if( !m_moved ) use( None ); } - - void Colour::use( Code _colourCode ) { - static IColourImpl* impl = platformColourInstance(); - impl->use( _colourCode ); - } - -} // end namespace Catch - -// #included from: catch_generators_impl.hpp -#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED - -#include -#include -#include - -namespace Catch { - - struct GeneratorInfo : IGeneratorInfo { - - GeneratorInfo( std::size_t size ) - : m_size( size ), - m_currentIndex( 0 ) - {} - - bool moveNext() { - if( ++m_currentIndex == m_size ) { - m_currentIndex = 0; - return false; - } - return true; - } - - std::size_t getCurrentIndex() const { - return m_currentIndex; - } - - std::size_t m_size; - std::size_t m_currentIndex; - }; - - /////////////////////////////////////////////////////////////////////////// - - class GeneratorsForTest : public IGeneratorsForTest { - - public: - ~GeneratorsForTest() { - deleteAll( m_generatorsInOrder ); - } - - IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { - std::map::const_iterator it = m_generatorsByName.find( fileInfo ); - if( it == m_generatorsByName.end() ) { - IGeneratorInfo* info = new GeneratorInfo( size ); - m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); - m_generatorsInOrder.push_back( info ); - return *info; - } - return *it->second; - } - - bool moveNext() { - std::vector::const_iterator it = m_generatorsInOrder.begin(); - std::vector::const_iterator itEnd = m_generatorsInOrder.end(); - for(; it != itEnd; ++it ) { - if( (*it)->moveNext() ) - return true; - } - return false; - } - - private: - std::map m_generatorsByName; - std::vector m_generatorsInOrder; - }; - - IGeneratorsForTest* createGeneratorsForTest() - { - return new GeneratorsForTest(); - } - -} // end namespace Catch - -// #included from: catch_assertionresult.hpp -#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED - -namespace Catch { - - AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){} - - AssertionInfo::AssertionInfo( char const * _macroName, - SourceLineInfo const& _lineInfo, - char const * _capturedExpression, - ResultDisposition::Flags _resultDisposition, - char const * _secondArg) - : macroName( _macroName ), - lineInfo( _lineInfo ), - capturedExpression( _capturedExpression ), - resultDisposition( _resultDisposition ), - secondArg( _secondArg ) - {} - - AssertionResult::AssertionResult() {} - - AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) - : m_info( info ), - m_resultData( data ) - {} - - AssertionResult::~AssertionResult() {} - - // Result was a success - bool AssertionResult::succeeded() const { - return Catch::isOk( m_resultData.resultType ); - } - - // Result was a success, or failure is suppressed - bool AssertionResult::isOk() const { - return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); - } - - ResultWas::OfType AssertionResult::getResultType() const { - return m_resultData.resultType; - } - - bool AssertionResult::hasExpression() const { - return m_info.capturedExpression[0] != 0; - } - - bool AssertionResult::hasMessage() const { - return !m_resultData.message.empty(); - } - - std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) { - return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"') - ? capturedExpression - : std::string(capturedExpression) + ", " + secondArg; - } - - std::string AssertionResult::getExpression() const { - if( isFalseTest( m_info.resultDisposition ) ) - return '!' + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); - else - return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); - } - std::string AssertionResult::getExpressionInMacro() const { - if( m_info.macroName[0] == 0 ) - return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); - else - return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )"; - } - - bool AssertionResult::hasExpandedExpression() const { - return hasExpression() && getExpandedExpression() != getExpression(); - } - - std::string AssertionResult::getExpandedExpression() const { - return m_resultData.reconstructExpression(); - } - - std::string AssertionResult::getMessage() const { - return m_resultData.message; - } - SourceLineInfo AssertionResult::getSourceInfo() const { - return m_info.lineInfo; - } - - std::string AssertionResult::getTestMacroName() const { - return m_info.macroName; - } - - void AssertionResult::discardDecomposedExpression() const { - m_resultData.decomposedExpression = CATCH_NULL; - } - - void AssertionResult::expandDecomposedExpression() const { - m_resultData.reconstructExpression(); - } - -} // end namespace Catch - -// #included from: catch_test_case_info.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED - -#include - -namespace Catch { - - inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { - if( startsWith( tag, '.' ) || - tag == "hide" || - tag == "!hide" ) - return TestCaseInfo::IsHidden; - else if( tag == "!throws" ) - return TestCaseInfo::Throws; - else if( tag == "!shouldfail" ) - return TestCaseInfo::ShouldFail; - else if( tag == "!mayfail" ) - return TestCaseInfo::MayFail; - else if( tag == "!nonportable" ) - return TestCaseInfo::NonPortable; - else - return TestCaseInfo::None; - } - inline bool isReservedTag( std::string const& tag ) { - return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); - } - inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { - if( isReservedTag( tag ) ) { - std::ostringstream ss; - ss << Colour(Colour::Red) - << "Tag name [" << tag << "] not allowed.\n" - << "Tag names starting with non alpha-numeric characters are reserved\n" - << Colour(Colour::FileName) - << _lineInfo << '\n'; - throw std::runtime_error(ss.str()); - } - } - - TestCase makeTestCase( ITestCase* _testCase, - std::string const& _className, - std::string const& _name, - std::string const& _descOrTags, - SourceLineInfo const& _lineInfo ) - { - bool isHidden( startsWith( _name, "./" ) ); // Legacy support - - // Parse out tags - std::set tags; - std::string desc, tag; - bool inTag = false; - for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { - char c = _descOrTags[i]; - if( !inTag ) { - if( c == '[' ) - inTag = true; - else - desc += c; - } - else { - if( c == ']' ) { - TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); - if( prop == TestCaseInfo::IsHidden ) - isHidden = true; - else if( prop == TestCaseInfo::None ) - enforceNotReservedTag( tag, _lineInfo ); - - tags.insert( tag ); - tag.clear(); - inTag = false; - } - else - tag += c; - } - } - if( isHidden ) { - tags.insert( "hide" ); - tags.insert( "." ); - } - - TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); - return TestCase( _testCase, info ); - } - - void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ) - { - testCaseInfo.tags = tags; - testCaseInfo.lcaseTags.clear(); - - std::ostringstream oss; - for( std::set::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) { - oss << '[' << *it << ']'; - std::string lcaseTag = toLower( *it ); - testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); - testCaseInfo.lcaseTags.insert( lcaseTag ); - } - testCaseInfo.tagsAsString = oss.str(); - } - - TestCaseInfo::TestCaseInfo( std::string const& _name, - std::string const& _className, - std::string const& _description, - std::set const& _tags, - SourceLineInfo const& _lineInfo ) - : name( _name ), - className( _className ), - description( _description ), - lineInfo( _lineInfo ), - properties( None ) - { - setTags( *this, _tags ); - } - - TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) - : name( other.name ), - className( other.className ), - description( other.description ), - tags( other.tags ), - lcaseTags( other.lcaseTags ), - tagsAsString( other.tagsAsString ), - lineInfo( other.lineInfo ), - properties( other.properties ) - {} - - bool TestCaseInfo::isHidden() const { - return ( properties & IsHidden ) != 0; - } - bool TestCaseInfo::throws() const { - return ( properties & Throws ) != 0; - } - bool TestCaseInfo::okToFail() const { - return ( properties & (ShouldFail | MayFail ) ) != 0; - } - bool TestCaseInfo::expectedToFail() const { - return ( properties & (ShouldFail ) ) != 0; - } - - TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} - - TestCase::TestCase( TestCase const& other ) - : TestCaseInfo( other ), - test( other.test ) - {} - - TestCase TestCase::withName( std::string const& _newName ) const { - TestCase other( *this ); - other.name = _newName; - return other; - } - - void TestCase::swap( TestCase& other ) { - test.swap( other.test ); - name.swap( other.name ); - className.swap( other.className ); - description.swap( other.description ); - tags.swap( other.tags ); - lcaseTags.swap( other.lcaseTags ); - tagsAsString.swap( other.tagsAsString ); - std::swap( TestCaseInfo::properties, static_cast( other ).properties ); - std::swap( lineInfo, other.lineInfo ); - } - - void TestCase::invoke() const { - test->invoke(); - } - - bool TestCase::operator == ( TestCase const& other ) const { - return test.get() == other.test.get() && - name == other.name && - className == other.className; - } - - bool TestCase::operator < ( TestCase const& other ) const { - return name < other.name; - } - TestCase& TestCase::operator = ( TestCase const& other ) { - TestCase temp( other ); - swap( temp ); - return *this; - } - - TestCaseInfo const& TestCase::getTestCaseInfo() const - { - return *this; - } - -} // end namespace Catch - -// #included from: catch_version.hpp -#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED - -namespace Catch { - - Version::Version - ( unsigned int _majorVersion, - unsigned int _minorVersion, - unsigned int _patchNumber, - char const * const _branchName, - unsigned int _buildNumber ) - : majorVersion( _majorVersion ), - minorVersion( _minorVersion ), - patchNumber( _patchNumber ), - branchName( _branchName ), - buildNumber( _buildNumber ) - {} - - std::ostream& operator << ( std::ostream& os, Version const& version ) { - os << version.majorVersion << '.' - << version.minorVersion << '.' - << version.patchNumber; - // branchName is never null -> 0th char is \0 if it is empty - if (version.branchName[0]) { - os << '-' << version.branchName - << '.' << version.buildNumber; - } - return os; - } - - inline Version libraryVersion() { - static Version version( 1, 10, 0, "", 0 ); - return version; - } - -} - -// #included from: catch_message.hpp -#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED - -namespace Catch { - - MessageInfo::MessageInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ) - : macroName( _macroName ), - lineInfo( _lineInfo ), - type( _type ), - sequence( ++globalCount ) - {} - - // This may need protecting if threading support is added - unsigned int MessageInfo::globalCount = 0; - - //////////////////////////////////////////////////////////////////////////// - - ScopedMessage::ScopedMessage( MessageBuilder const& builder ) - : m_info( builder.m_info ) - { - m_info.message = builder.m_stream.str(); - getResultCapture().pushScopedMessage( m_info ); - } - ScopedMessage::ScopedMessage( ScopedMessage const& other ) - : m_info( other.m_info ) - {} - - ScopedMessage::~ScopedMessage() { - if ( !std::uncaught_exception() ){ - getResultCapture().popScopedMessage(m_info); - } - } - -} // end namespace Catch - -// #included from: catch_legacy_reporter_adapter.hpp -#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED - -// #included from: catch_legacy_reporter_adapter.h -#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED - -namespace Catch -{ - // Deprecated - struct IReporter : IShared { - virtual ~IReporter(); - - virtual bool shouldRedirectStdout() const = 0; - - virtual void StartTesting() = 0; - virtual void EndTesting( Totals const& totals ) = 0; - virtual void StartGroup( std::string const& groupName ) = 0; - virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; - virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; - virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; - virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; - virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; - virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; - virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; - virtual void Aborted() = 0; - virtual void Result( AssertionResult const& result ) = 0; - }; - - class LegacyReporterAdapter : public SharedImpl - { - public: - LegacyReporterAdapter( Ptr const& legacyReporter ); - virtual ~LegacyReporterAdapter(); - - virtual ReporterPreferences getPreferences() const; - virtual void noMatchingTestCases( std::string const& ); - virtual void testRunStarting( TestRunInfo const& ); - virtual void testGroupStarting( GroupInfo const& groupInfo ); - virtual void testCaseStarting( TestCaseInfo const& testInfo ); - virtual void sectionStarting( SectionInfo const& sectionInfo ); - virtual void assertionStarting( AssertionInfo const& ); - virtual bool assertionEnded( AssertionStats const& assertionStats ); - virtual void sectionEnded( SectionStats const& sectionStats ); - virtual void testCaseEnded( TestCaseStats const& testCaseStats ); - virtual void testGroupEnded( TestGroupStats const& testGroupStats ); - virtual void testRunEnded( TestRunStats const& testRunStats ); - virtual void skipTest( TestCaseInfo const& ); - - private: - Ptr m_legacyReporter; - }; -} - -namespace Catch -{ - LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) - : m_legacyReporter( legacyReporter ) - {} - LegacyReporterAdapter::~LegacyReporterAdapter() {} - - ReporterPreferences LegacyReporterAdapter::getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); - return prefs; - } - - void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} - void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { - m_legacyReporter->StartTesting(); - } - void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { - m_legacyReporter->StartGroup( groupInfo.name ); - } - void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { - m_legacyReporter->StartTestCase( testInfo ); - } - void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { - m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); - } - void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { - // Not on legacy interface - } - - bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { - if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { - for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); - it != itEnd; - ++it ) { - if( it->type == ResultWas::Info ) { - ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); - rb << it->message; - rb.setResultType( ResultWas::Info ); - AssertionResult result = rb.build(); - m_legacyReporter->Result( result ); - } - } - } - m_legacyReporter->Result( assertionStats.assertionResult ); - return true; - } - void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { - if( sectionStats.missingAssertions ) - m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); - m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); - } - void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { - m_legacyReporter->EndTestCase - ( testCaseStats.testInfo, - testCaseStats.totals, - testCaseStats.stdOut, - testCaseStats.stdErr ); - } - void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { - if( testGroupStats.aborting ) - m_legacyReporter->Aborted(); - m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); - } - void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { - m_legacyReporter->EndTesting( testRunStats.totals ); - } - void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { - } -} - -// #included from: catch_timer.hpp - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wc++11-long-long" -#endif - -#ifdef CATCH_PLATFORM_WINDOWS - -#else - -#include - -#endif - -namespace Catch { - - namespace { -#ifdef CATCH_PLATFORM_WINDOWS - UInt64 getCurrentTicks() { - static UInt64 hz=0, hzo=0; - if (!hz) { - QueryPerformanceFrequency( reinterpret_cast( &hz ) ); - QueryPerformanceCounter( reinterpret_cast( &hzo ) ); - } - UInt64 t; - QueryPerformanceCounter( reinterpret_cast( &t ) ); - return ((t-hzo)*1000000)/hz; - } -#else - UInt64 getCurrentTicks() { - timeval t; - gettimeofday(&t,CATCH_NULL); - return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); - } -#endif - } - - void Timer::start() { - m_ticks = getCurrentTicks(); - } - unsigned int Timer::getElapsedMicroseconds() const { - return static_cast(getCurrentTicks() - m_ticks); - } - unsigned int Timer::getElapsedMilliseconds() const { - return static_cast(getElapsedMicroseconds()/1000); - } - double Timer::getElapsedSeconds() const { - return getElapsedMicroseconds()/1000000.0; - } - -} // namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif -// #included from: catch_common.hpp -#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED - -#include -#include - -namespace Catch { - - bool startsWith( std::string const& s, std::string const& prefix ) { - return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); - } - bool startsWith( std::string const& s, char prefix ) { - return !s.empty() && s[0] == prefix; - } - bool endsWith( std::string const& s, std::string const& suffix ) { - return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); - } - bool endsWith( std::string const& s, char suffix ) { - return !s.empty() && s[s.size()-1] == suffix; - } - bool contains( std::string const& s, std::string const& infix ) { - return s.find( infix ) != std::string::npos; - } - char toLowerCh(char c) { - return static_cast( std::tolower( c ) ); - } - void toLowerInPlace( std::string& s ) { - std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); - } - std::string toLower( std::string const& s ) { - std::string lc = s; - toLowerInPlace( lc ); - return lc; - } - std::string trim( std::string const& str ) { - static char const* whitespaceChars = "\n\r\t "; - std::string::size_type start = str.find_first_not_of( whitespaceChars ); - std::string::size_type end = str.find_last_not_of( whitespaceChars ); - - return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); - } - - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { - bool replaced = false; - std::size_t i = str.find( replaceThis ); - while( i != std::string::npos ) { - replaced = true; - str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); - if( i < str.size()-withThis.size() ) - i = str.find( replaceThis, i+withThis.size() ); - else - i = std::string::npos; - } - return replaced; - } - - pluralise::pluralise( std::size_t count, std::string const& label ) - : m_count( count ), - m_label( label ) - {} - - std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { - os << pluraliser.m_count << ' ' << pluraliser.m_label; - if( pluraliser.m_count != 1 ) - os << 's'; - return os; - } - - SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){} - SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) - : file( _file ), - line( _line ) - {} - bool SourceLineInfo::empty() const { - return file[0] == '\0'; - } - bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { - return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); - } - bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { - return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); - } - - void seedRng( IConfig const& config ) { - if( config.rngSeed() != 0 ) - std::srand( config.rngSeed() ); - } - unsigned int rngSeed() { - return getCurrentContext().getConfig()->rngSeed(); - } - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { -#ifndef __GNUG__ - os << info.file << '(' << info.line << ')'; -#else - os << info.file << ':' << info.line; -#endif - return os; - } - - void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { - std::ostringstream oss; - oss << locationInfo << ": Internal Catch error: '" << message << '\''; - if( alwaysTrue() ) - throw std::logic_error( oss.str() ); - } -} - -// #included from: catch_section.hpp -#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED - -namespace Catch { - - SectionInfo::SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name, - std::string const& _description ) - : name( _name ), - description( _description ), - lineInfo( _lineInfo ) - {} - - Section::Section( SectionInfo const& info ) - : m_info( info ), - m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) - { - m_timer.start(); - } - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17 -#endif - Section::~Section() { - if( m_sectionIncluded ) { - SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); - if( std::uncaught_exception() ) - getResultCapture().sectionEndedEarly( endInfo ); - else - getResultCapture().sectionEnded( endInfo ); - } - } -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - - // This indicates whether the section should be executed or not - Section::operator bool() const { - return m_sectionIncluded; - } - -} // end namespace Catch - -// #included from: catch_debugger.hpp -#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED - -#ifdef CATCH_PLATFORM_MAC - - #include - #include - #include - #include - #include - - namespace Catch{ - - // The following function is taken directly from the following technical note: - // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html - - // Returns true if the current process is being debugged (either - // running under the debugger or has a debugger attached post facto). - bool isDebuggerActive(){ - - int mib[4]; - struct kinfo_proc info; - size_t size; - - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - - info.kp_proc.p_flag = 0; - - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - - // Call sysctl. - - size = sizeof(info); - if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { - Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; - return false; - } - - // We're being debugged if the P_TRACED flag is set. - - return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); - } - } // namespace Catch - -#elif defined(CATCH_PLATFORM_LINUX) - #include - #include - - namespace Catch{ - // The standard POSIX way of detecting a debugger is to attempt to - // ptrace() the process, but this needs to be done from a child and not - // this process itself to still allow attaching to this process later - // if wanted, so is rather heavy. Under Linux we have the PID of the - // "debugger" (which doesn't need to be gdb, of course, it could also - // be strace, for example) in /proc/$PID/status, so just get it from - // there instead. - bool isDebuggerActive(){ - // Libstdc++ has a bug, where std::ifstream sets errno to 0 - // This way our users can properly assert over errno values - ErrnoGuard guard; - std::ifstream in("/proc/self/status"); - for( std::string line; std::getline(in, line); ) { - static const int PREFIX_LEN = 11; - if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { - // We're traced if the PID is not 0 and no other PID starts - // with 0 digit, so it's enough to check for just a single - // character. - return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; - } - } - - return false; - } - } // namespace Catch -#elif defined(_MSC_VER) - extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); - namespace Catch { - bool isDebuggerActive() { - return IsDebuggerPresent() != 0; - } - } -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); - namespace Catch { - bool isDebuggerActive() { - return IsDebuggerPresent() != 0; - } - } -#else - namespace Catch { - inline bool isDebuggerActive() { return false; } - } -#endif // Platform - -#ifdef CATCH_PLATFORM_WINDOWS - - namespace Catch { - void writeToDebugConsole( std::string const& text ) { - ::OutputDebugStringA( text.c_str() ); - } - } -#else - namespace Catch { - void writeToDebugConsole( std::string const& text ) { - // !TBD: Need a version for Mac/ XCode and other IDEs - Catch::cout() << text; - } - } -#endif // Platform - -// #included from: catch_tostring.hpp -#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED - -namespace Catch { - -namespace Detail { - - const std::string unprintableString = "{?}"; - - namespace { - const int hexThreshold = 255; - - struct Endianness { - enum Arch { Big, Little }; - - static Arch which() { - union _{ - int asInt; - char asChar[sizeof (int)]; - } u; - - u.asInt = 1; - return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; - } - }; - } - - std::string rawMemoryToString( const void *object, std::size_t size ) - { - // Reverse order for little endian architectures - int i = 0, end = static_cast( size ), inc = 1; - if( Endianness::which() == Endianness::Little ) { - i = end-1; - end = inc = -1; - } - - unsigned char const *bytes = static_cast(object); - std::ostringstream os; - os << "0x" << std::setfill('0') << std::hex; - for( ; i != end; i += inc ) - os << std::setw(2) << static_cast(bytes[i]); - return os.str(); - } -} - -std::string toString( std::string const& value ) { - std::string s = value; - if( getCurrentContext().getConfig()->showInvisibles() ) { - for(size_t i = 0; i < s.size(); ++i ) { - std::string subs; - switch( s[i] ) { - case '\n': subs = "\\n"; break; - case '\t': subs = "\\t"; break; - default: break; - } - if( !subs.empty() ) { - s = s.substr( 0, i ) + subs + s.substr( i+1 ); - ++i; - } - } - } - return '"' + s + '"'; -} -std::string toString( std::wstring const& value ) { - - std::string s; - s.reserve( value.size() ); - for(size_t i = 0; i < value.size(); ++i ) - s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; - return Catch::toString( s ); -} - -std::string toString( const char* const value ) { - return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); -} - -std::string toString( char* const value ) { - return Catch::toString( static_cast( value ) ); -} - -std::string toString( const wchar_t* const value ) -{ - return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); -} - -std::string toString( wchar_t* const value ) -{ - return Catch::toString( static_cast( value ) ); -} - -std::string toString( int value ) { - std::ostringstream oss; - oss << value; - if( value > Detail::hexThreshold ) - oss << " (0x" << std::hex << value << ')'; - return oss.str(); -} - -std::string toString( unsigned long value ) { - std::ostringstream oss; - oss << value; - if( value > Detail::hexThreshold ) - oss << " (0x" << std::hex << value << ')'; - return oss.str(); -} - -std::string toString( unsigned int value ) { - return Catch::toString( static_cast( value ) ); -} - -template -std::string fpToString( T value, int precision ) { - std::ostringstream oss; - oss << std::setprecision( precision ) - << std::fixed - << value; - std::string d = oss.str(); - std::size_t i = d.find_last_not_of( '0' ); - if( i != std::string::npos && i != d.size()-1 ) { - if( d[i] == '.' ) - i++; - d = d.substr( 0, i+1 ); - } - return d; -} - -std::string toString( const double value ) { - return fpToString( value, 10 ); -} -std::string toString( const float value ) { - return fpToString( value, 5 ) + 'f'; -} - -std::string toString( bool value ) { - return value ? "true" : "false"; -} - -std::string toString( char value ) { - if ( value == '\r' ) - return "'\\r'"; - if ( value == '\f' ) - return "'\\f'"; - if ( value == '\n' ) - return "'\\n'"; - if ( value == '\t' ) - return "'\\t'"; - if ( '\0' <= value && value < ' ' ) - return toString( static_cast( value ) ); - char chstr[] = "' '"; - chstr[1] = value; - return chstr; -} - -std::string toString( signed char value ) { - return toString( static_cast( value ) ); -} - -std::string toString( unsigned char value ) { - return toString( static_cast( value ) ); -} - -#ifdef CATCH_CONFIG_CPP11_LONG_LONG -std::string toString( long long value ) { - std::ostringstream oss; - oss << value; - if( value > Detail::hexThreshold ) - oss << " (0x" << std::hex << value << ')'; - return oss.str(); -} -std::string toString( unsigned long long value ) { - std::ostringstream oss; - oss << value; - if( value > Detail::hexThreshold ) - oss << " (0x" << std::hex << value << ')'; - return oss.str(); -} -#endif - -#ifdef CATCH_CONFIG_CPP11_NULLPTR -std::string toString( std::nullptr_t ) { - return "nullptr"; -} -#endif - -#ifdef __OBJC__ - std::string toString( NSString const * const& nsstring ) { - if( !nsstring ) - return "nil"; - return "@" + toString([nsstring UTF8String]); - } - std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) { - if( !nsstring ) - return "nil"; - return "@" + toString([nsstring UTF8String]); - } - std::string toString( NSObject* const& nsObject ) { - return toString( [nsObject description] ); - } -#endif - -} // end namespace Catch - -// #included from: catch_result_builder.hpp -#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED - -namespace Catch { - - ResultBuilder::ResultBuilder( char const* macroName, - SourceLineInfo const& lineInfo, - char const* capturedExpression, - ResultDisposition::Flags resultDisposition, - char const* secondArg ) - : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ), - m_shouldDebugBreak( false ), - m_shouldThrow( false ), - m_guardException( false ), - m_usedStream( false ) - {} - - ResultBuilder::~ResultBuilder() { -#if defined(CATCH_CONFIG_FAST_COMPILE) - if ( m_guardException ) { - stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; - captureResult( ResultWas::ThrewException ); - getCurrentContext().getResultCapture()->exceptionEarlyReported(); - } -#endif - } - - ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { - m_data.resultType = result; - return *this; - } - ResultBuilder& ResultBuilder::setResultType( bool result ) { - m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; - return *this; - } - - void ResultBuilder::endExpression( DecomposedExpression const& expr ) { - // Flip bool results if FalseTest flag is set - if( isFalseTest( m_assertionInfo.resultDisposition ) ) { - m_data.negate( expr.isBinaryExpression() ); - } - - getResultCapture().assertionRun(); - - if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok) - { - AssertionResult result = build( expr ); - handleResult( result ); - } - else - getResultCapture().assertionPassed(); - } - - void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { - m_assertionInfo.resultDisposition = resultDisposition; - stream().oss << Catch::translateActiveException(); - captureResult( ResultWas::ThrewException ); - } - - void ResultBuilder::captureResult( ResultWas::OfType resultType ) { - setResultType( resultType ); - captureExpression(); - } - - void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { - if( expectedMessage.empty() ) - captureExpectedException( Matchers::Impl::MatchAllOf() ); - else - captureExpectedException( Matchers::Equals( expectedMessage ) ); - } - - void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase const& matcher ) { - - assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); - AssertionResultData data = m_data; - data.resultType = ResultWas::Ok; - data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); - - std::string actualMessage = Catch::translateActiveException(); - if( !matcher.match( actualMessage ) ) { - data.resultType = ResultWas::ExpressionFailed; - data.reconstructedExpression = actualMessage; - } - AssertionResult result( m_assertionInfo, data ); - handleResult( result ); - } - - void ResultBuilder::captureExpression() { - AssertionResult result = build(); - handleResult( result ); - } - - void ResultBuilder::handleResult( AssertionResult const& result ) - { - getResultCapture().assertionEnded( result ); - - if( !result.isOk() ) { - if( getCurrentContext().getConfig()->shouldDebugBreak() ) - m_shouldDebugBreak = true; - if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) - m_shouldThrow = true; - } - } - - void ResultBuilder::react() { -#if defined(CATCH_CONFIG_FAST_COMPILE) - if (m_shouldDebugBreak) { - /////////////////////////////////////////////////////////////////// - // To inspect the state during test, you need to go one level up the callstack - // To go back to the test and change execution, jump over the throw statement - /////////////////////////////////////////////////////////////////// - CATCH_BREAK_INTO_DEBUGGER(); - } -#endif - if( m_shouldThrow ) - throw Catch::TestFailureException(); - } - - bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } - bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } - - AssertionResult ResultBuilder::build() const - { - return build( *this ); - } - - // CAVEAT: The returned AssertionResult stores a pointer to the argument expr, - // a temporary DecomposedExpression, which in turn holds references to - // operands, possibly temporary as well. - // It should immediately be passed to handleResult; if the expression - // needs to be reported, its string expansion must be composed before - // the temporaries are destroyed. - AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const - { - assert( m_data.resultType != ResultWas::Unknown ); - AssertionResultData data = m_data; - - if(m_usedStream) - data.message = m_stream().oss.str(); - data.decomposedExpression = &expr; // for lazy reconstruction - return AssertionResult( m_assertionInfo, data ); - } - - void ResultBuilder::reconstructExpression( std::string& dest ) const { - dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); - } - - void ResultBuilder::setExceptionGuard() { - m_guardException = true; - } - void ResultBuilder::unsetExceptionGuard() { - m_guardException = false; - } - -} // end namespace Catch - -// #included from: catch_tag_alias_registry.hpp -#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED - -namespace Catch { - - TagAliasRegistry::~TagAliasRegistry() {} - - Option TagAliasRegistry::find( std::string const& alias ) const { - std::map::const_iterator it = m_registry.find( alias ); - if( it != m_registry.end() ) - return it->second; - else - return Option(); - } - - std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { - std::string expandedTestSpec = unexpandedTestSpec; - for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); - it != itEnd; - ++it ) { - std::size_t pos = expandedTestSpec.find( it->first ); - if( pos != std::string::npos ) { - expandedTestSpec = expandedTestSpec.substr( 0, pos ) + - it->second.tag + - expandedTestSpec.substr( pos + it->first.size() ); - } - } - return expandedTestSpec; - } - - void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) { - - if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) { - std::ostringstream oss; - oss << Colour( Colour::Red ) - << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" - << Colour( Colour::FileName ) - << lineInfo << '\n'; - throw std::domain_error( oss.str().c_str() ); - } - if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { - std::ostringstream oss; - oss << Colour( Colour::Red ) - << "error: tag alias, \"" << alias << "\" already registered.\n" - << "\tFirst seen at " - << Colour( Colour::Red ) << find(alias)->lineInfo << '\n' - << Colour( Colour::Red ) << "\tRedefined at " - << Colour( Colour::FileName) << lineInfo << '\n'; - throw std::domain_error( oss.str().c_str() ); - } - } - - ITagAliasRegistry::~ITagAliasRegistry() {} - - ITagAliasRegistry const& ITagAliasRegistry::get() { - return getRegistryHub().getTagAliasRegistry(); - } - - RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { - getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo ); - } - -} // end namespace Catch - -// #included from: catch_matchers_string.hpp - -namespace Catch { -namespace Matchers { - - namespace StdString { - - CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) - : m_caseSensitivity( caseSensitivity ), - m_str( adjustString( str ) ) - {} - std::string CasedString::adjustString( std::string const& str ) const { - return m_caseSensitivity == CaseSensitive::No - ? toLower( str ) - : str; - } - std::string CasedString::caseSensitivitySuffix() const { - return m_caseSensitivity == CaseSensitive::No - ? " (case insensitive)" - : std::string(); - } - - StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator ) - : m_comparator( comparator ), - m_operation( operation ) { - } - - std::string StringMatcherBase::describe() const { - std::string description; - description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + - m_comparator.caseSensitivitySuffix().size()); - description += m_operation; - description += ": \""; - description += m_comparator.m_str; - description += "\""; - description += m_comparator.caseSensitivitySuffix(); - return description; - } - - EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} - - bool EqualsMatcher::match( std::string const& source ) const { - return m_comparator.adjustString( source ) == m_comparator.m_str; - } - - ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} - - bool ContainsMatcher::match( std::string const& source ) const { - return contains( m_comparator.adjustString( source ), m_comparator.m_str ); - } - - StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} - - bool StartsWithMatcher::match( std::string const& source ) const { - return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); - } - - EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} - - bool EndsWithMatcher::match( std::string const& source ) const { - return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); - } - - } // namespace StdString - - StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { - return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); - } - StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { - return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); - } - StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { - return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); - } - StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { - return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); - } - -} // namespace Matchers -} // namespace Catch -// #included from: ../reporters/catch_reporter_multi.hpp -#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED - -namespace Catch { - -class MultipleReporters : public SharedImpl { - typedef std::vector > Reporters; - Reporters m_reporters; - -public: - void add( Ptr const& reporter ) { - m_reporters.push_back( reporter ); - } - -public: // IStreamingReporter - - virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { - return m_reporters[0]->getPreferences(); - } - - virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->noMatchingTestCases( spec ); - } - - virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->testRunStarting( testRunInfo ); - } - - virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->testGroupStarting( groupInfo ); - } - - virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->testCaseStarting( testInfo ); - } - - virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->sectionStarting( sectionInfo ); - } - - virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->assertionStarting( assertionInfo ); - } - - // The return value indicates if the messages buffer should be cleared: - virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { - bool clearBuffer = false; - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - clearBuffer |= (*it)->assertionEnded( assertionStats ); - return clearBuffer; - } - - virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->sectionEnded( sectionStats ); - } - - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->testCaseEnded( testCaseStats ); - } - - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->testGroupEnded( testGroupStats ); - } - - virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->testRunEnded( testRunStats ); - } - - virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { - for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); - it != itEnd; - ++it ) - (*it)->skipTest( testInfo ); - } - - virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE { - return this; - } - -}; - -Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ) { - Ptr resultingReporter; - - if( existingReporter ) { - MultipleReporters* multi = existingReporter->tryAsMulti(); - if( !multi ) { - multi = new MultipleReporters; - resultingReporter = Ptr( multi ); - if( existingReporter ) - multi->add( existingReporter ); - } - else - resultingReporter = existingReporter; - multi->add( additionalReporter ); - } - else - resultingReporter = additionalReporter; - - return resultingReporter; -} - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_xml.hpp -#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED - -// #included from: catch_reporter_bases.hpp -#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED - -#include -#include -#include -#include - -namespace Catch { - - namespace { - // Because formatting using c++ streams is stateful, drop down to C is required - // Alternatively we could use stringstream, but its performance is... not good. - std::string getFormattedDuration( double duration ) { - // Max exponent + 1 is required to represent the whole part - // + 1 for decimal point - // + 3 for the 3 decimal places - // + 1 for null terminator - const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; - char buffer[maxDoubleSize]; - - // Save previous errno, to prevent sprintf from overwriting it - ErrnoGuard guard; -#ifdef _MSC_VER - sprintf_s(buffer, "%.3f", duration); -#else - sprintf(buffer, "%.3f", duration); -#endif - return std::string(buffer); - } - } - - struct StreamingReporterBase : SharedImpl { - - StreamingReporterBase( ReporterConfig const& _config ) - : m_config( _config.fullConfig() ), - stream( _config.stream() ) - { - m_reporterPrefs.shouldRedirectStdOut = false; - } - - virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { - return m_reporterPrefs; - } - - virtual ~StreamingReporterBase() CATCH_OVERRIDE; - - virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {} - - virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE { - currentTestRunInfo = _testRunInfo; - } - virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE { - currentGroupInfo = _groupInfo; - } - - virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE { - currentTestCaseInfo = _testInfo; - } - virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { - m_sectionStack.push_back( _sectionInfo ); - } - - virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE { - m_sectionStack.pop_back(); - } - virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE { - currentTestCaseInfo.reset(); - } - virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE { - currentGroupInfo.reset(); - } - virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE { - currentTestCaseInfo.reset(); - currentGroupInfo.reset(); - currentTestRunInfo.reset(); - } - - virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE { - // Don't do anything with this by default. - // It can optionally be overridden in the derived class. - } - - Ptr m_config; - std::ostream& stream; - - LazyStat currentTestRunInfo; - LazyStat currentGroupInfo; - LazyStat currentTestCaseInfo; - - std::vector m_sectionStack; - ReporterPreferences m_reporterPrefs; - }; - - struct CumulativeReporterBase : SharedImpl { - template - struct Node : SharedImpl<> { - explicit Node( T const& _value ) : value( _value ) {} - virtual ~Node() {} - - typedef std::vector > ChildNodes; - T value; - ChildNodes children; - }; - struct SectionNode : SharedImpl<> { - explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} - virtual ~SectionNode(); - - bool operator == ( SectionNode const& other ) const { - return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; - } - bool operator == ( Ptr const& other ) const { - return operator==( *other ); - } - - SectionStats stats; - typedef std::vector > ChildSections; - typedef std::vector Assertions; - ChildSections childSections; - Assertions assertions; - std::string stdOut; - std::string stdErr; - }; - - struct BySectionInfo { - BySectionInfo( SectionInfo const& other ) : m_other( other ) {} - BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} - bool operator() ( Ptr const& node ) const { - return ((node->stats.sectionInfo.name == m_other.name) && - (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); - } - private: - void operator=( BySectionInfo const& ); - SectionInfo const& m_other; - }; - - typedef Node TestCaseNode; - typedef Node TestGroupNode; - typedef Node TestRunNode; - - CumulativeReporterBase( ReporterConfig const& _config ) - : m_config( _config.fullConfig() ), - stream( _config.stream() ) - { - m_reporterPrefs.shouldRedirectStdOut = false; - } - ~CumulativeReporterBase(); - - virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { - return m_reporterPrefs; - } - - virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {} - virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {} - - virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {} - - virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { - SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); - Ptr node; - if( m_sectionStack.empty() ) { - if( !m_rootSection ) - m_rootSection = new SectionNode( incompleteStats ); - node = m_rootSection; - } - else { - SectionNode& parentNode = *m_sectionStack.back(); - SectionNode::ChildSections::const_iterator it = - std::find_if( parentNode.childSections.begin(), - parentNode.childSections.end(), - BySectionInfo( sectionInfo ) ); - if( it == parentNode.childSections.end() ) { - node = new SectionNode( incompleteStats ); - parentNode.childSections.push_back( node ); - } - else - node = *it; - } - m_sectionStack.push_back( node ); - m_deepestSection = node; - } - - virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} - - virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { - assert( !m_sectionStack.empty() ); - SectionNode& sectionNode = *m_sectionStack.back(); - sectionNode.assertions.push_back( assertionStats ); - // AssertionResult holds a pointer to a temporary DecomposedExpression, - // which getExpandedExpression() calls to build the expression string. - // Our section stack copy of the assertionResult will likely outlive the - // temporary, so it must be expanded or discarded now to avoid calling - // a destroyed object later. - prepareExpandedExpression( sectionNode.assertions.back().assertionResult ); - return true; - } - virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { - assert( !m_sectionStack.empty() ); - SectionNode& node = *m_sectionStack.back(); - node.stats = sectionStats; - m_sectionStack.pop_back(); - } - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { - Ptr node = new TestCaseNode( testCaseStats ); - assert( m_sectionStack.size() == 0 ); - node->children.push_back( m_rootSection ); - m_testCases.push_back( node ); - m_rootSection.reset(); - - assert( m_deepestSection ); - m_deepestSection->stdOut = testCaseStats.stdOut; - m_deepestSection->stdErr = testCaseStats.stdErr; - } - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { - Ptr node = new TestGroupNode( testGroupStats ); - node->children.swap( m_testCases ); - m_testGroups.push_back( node ); - } - virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { - Ptr node = new TestRunNode( testRunStats ); - node->children.swap( m_testGroups ); - m_testRuns.push_back( node ); - testRunEndedCumulative(); - } - virtual void testRunEndedCumulative() = 0; - - virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} - - virtual void prepareExpandedExpression( AssertionResult& result ) const { - if( result.isOk() ) - result.discardDecomposedExpression(); - else - result.expandDecomposedExpression(); - } - - Ptr m_config; - std::ostream& stream; - std::vector m_assertions; - std::vector > > m_sections; - std::vector > m_testCases; - std::vector > m_testGroups; - - std::vector > m_testRuns; - - Ptr m_rootSection; - Ptr m_deepestSection; - std::vector > m_sectionStack; - ReporterPreferences m_reporterPrefs; - - }; - - template - char const* getLineOfChars() { - static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; - if( !*line ) { - std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); - line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; - } - return line; - } - - struct TestEventListenerBase : StreamingReporterBase { - TestEventListenerBase( ReporterConfig const& _config ) - : StreamingReporterBase( _config ) - {} - - virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} - virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE { - return false; - } - }; - -} // end namespace Catch - -// #included from: ../internal/catch_reporter_registrars.hpp -#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED - -namespace Catch { - - template - class LegacyReporterRegistrar { - - class ReporterFactory : public IReporterFactory { - virtual IStreamingReporter* create( ReporterConfig const& config ) const { - return new LegacyReporterAdapter( new T( config ) ); - } - - virtual std::string getDescription() const { - return T::getDescription(); - } - }; - - public: - - LegacyReporterRegistrar( std::string const& name ) { - getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); - } - }; - - template - class ReporterRegistrar { - - class ReporterFactory : public SharedImpl { - - // *** Please Note ***: - // - If you end up here looking at a compiler error because it's trying to register - // your custom reporter class be aware that the native reporter interface has changed - // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via - // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. - // However please consider updating to the new interface as the old one is now - // deprecated and will probably be removed quite soon! - // Please contact me via github if you have any questions at all about this. - // In fact, ideally, please contact me anyway to let me know you've hit this - as I have - // no idea who is actually using custom reporters at all (possibly no-one!). - // The new interface is designed to minimise exposure to interface changes in the future. - virtual IStreamingReporter* create( ReporterConfig const& config ) const { - return new T( config ); - } - - virtual std::string getDescription() const { - return T::getDescription(); - } - }; - - public: - - ReporterRegistrar( std::string const& name ) { - getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); - } - }; - - template - class ListenerRegistrar { - - class ListenerFactory : public SharedImpl { - - virtual IStreamingReporter* create( ReporterConfig const& config ) const { - return new T( config ); - } - virtual std::string getDescription() const { - return std::string(); - } - }; - - public: - - ListenerRegistrar() { - getMutableRegistryHub().registerListener( new ListenerFactory() ); - } - }; -} - -#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ - namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } - -#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ - namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } - -// Deprecated - use the form without INTERNAL_ -#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ - namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } - -#define CATCH_REGISTER_LISTENER( listenerType ) \ - namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } - -// #included from: ../internal/catch_xmlwriter.hpp -#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED - -#include -#include -#include -#include - -namespace Catch { - - class XmlEncode { - public: - enum ForWhat { ForTextNodes, ForAttributes }; - - XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ) - : m_str( str ), - m_forWhat( forWhat ) - {} - - void encodeTo( std::ostream& os ) const { - - // Apostrophe escaping not necessary if we always use " to write attributes - // (see: http://www.w3.org/TR/xml/#syntax) - - for( std::size_t i = 0; i < m_str.size(); ++ i ) { - char c = m_str[i]; - switch( c ) { - case '<': os << "<"; break; - case '&': os << "&"; break; - - case '>': - // See: http://www.w3.org/TR/xml/#syntax - if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' ) - os << ">"; - else - os << c; - break; - - case '\"': - if( m_forWhat == ForAttributes ) - os << """; - else - os << c; - break; - - default: - // Escape control chars - based on contribution by @espenalb in PR #465 and - // by @mrpi PR #588 - if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) { - // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 - os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) - << static_cast( c ); - } - else - os << c; - } - } - } - - friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { - xmlEncode.encodeTo( os ); - return os; - } - - private: - std::string m_str; - ForWhat m_forWhat; - }; - - class XmlWriter { - public: - - class ScopedElement { - public: - ScopedElement( XmlWriter* writer ) - : m_writer( writer ) - {} - - ScopedElement( ScopedElement const& other ) - : m_writer( other.m_writer ){ - other.m_writer = CATCH_NULL; - } - - ~ScopedElement() { - if( m_writer ) - m_writer->endElement(); - } - - ScopedElement& writeText( std::string const& text, bool indent = true ) { - m_writer->writeText( text, indent ); - return *this; - } - - template - ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { - m_writer->writeAttribute( name, attribute ); - return *this; - } - - private: - mutable XmlWriter* m_writer; - }; - - XmlWriter() - : m_tagIsOpen( false ), - m_needsNewline( false ), - m_os( Catch::cout() ) - { - writeDeclaration(); - } - - XmlWriter( std::ostream& os ) - : m_tagIsOpen( false ), - m_needsNewline( false ), - m_os( os ) - { - writeDeclaration(); - } - - ~XmlWriter() { - while( !m_tags.empty() ) - endElement(); - } - - XmlWriter& startElement( std::string const& name ) { - ensureTagClosed(); - newlineIfNecessary(); - m_os << m_indent << '<' << name; - m_tags.push_back( name ); - m_indent += " "; - m_tagIsOpen = true; - return *this; - } - - ScopedElement scopedElement( std::string const& name ) { - ScopedElement scoped( this ); - startElement( name ); - return scoped; - } - - XmlWriter& endElement() { - newlineIfNecessary(); - m_indent = m_indent.substr( 0, m_indent.size()-2 ); - if( m_tagIsOpen ) { - m_os << "/>"; - m_tagIsOpen = false; - } - else { - m_os << m_indent << ""; - } - m_os << std::endl; - m_tags.pop_back(); - return *this; - } - - XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { - if( !name.empty() && !attribute.empty() ) - m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; - return *this; - } - - XmlWriter& writeAttribute( std::string const& name, bool attribute ) { - m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; - return *this; - } - - template - XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { - std::ostringstream oss; - oss << attribute; - return writeAttribute( name, oss.str() ); - } - - XmlWriter& writeText( std::string const& text, bool indent = true ) { - if( !text.empty() ){ - bool tagWasOpen = m_tagIsOpen; - ensureTagClosed(); - if( tagWasOpen && indent ) - m_os << m_indent; - m_os << XmlEncode( text ); - m_needsNewline = true; - } - return *this; - } - - XmlWriter& writeComment( std::string const& text ) { - ensureTagClosed(); - m_os << m_indent << ""; - m_needsNewline = true; - return *this; - } - - void writeStylesheetRef( std::string const& url ) { - m_os << "\n"; - } - - XmlWriter& writeBlankLine() { - ensureTagClosed(); - m_os << '\n'; - return *this; - } - - void ensureTagClosed() { - if( m_tagIsOpen ) { - m_os << ">" << std::endl; - m_tagIsOpen = false; - } - } - - private: - XmlWriter( XmlWriter const& ); - void operator=( XmlWriter const& ); - - void writeDeclaration() { - m_os << "\n"; - } - - void newlineIfNecessary() { - if( m_needsNewline ) { - m_os << std::endl; - m_needsNewline = false; - } - } - - bool m_tagIsOpen; - bool m_needsNewline; - std::vector m_tags; - std::string m_indent; - std::ostream& m_os; - }; - -} - -namespace Catch { - class XmlReporter : public StreamingReporterBase { - public: - XmlReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ), - m_xml(_config.stream()), - m_sectionDepth( 0 ) - { - m_reporterPrefs.shouldRedirectStdOut = true; - } - - virtual ~XmlReporter() CATCH_OVERRIDE; - - static std::string getDescription() { - return "Reports test results as an XML document"; - } - - virtual std::string getStylesheetRef() const { - return std::string(); - } - - void writeSourceInfo( SourceLineInfo const& sourceInfo ) { - m_xml - .writeAttribute( "filename", sourceInfo.file ) - .writeAttribute( "line", sourceInfo.line ); - } - - public: // StreamingReporterBase - - virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE { - StreamingReporterBase::noMatchingTestCases( s ); - } - - virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE { - StreamingReporterBase::testRunStarting( testInfo ); - std::string stylesheetRef = getStylesheetRef(); - if( !stylesheetRef.empty() ) - m_xml.writeStylesheetRef( stylesheetRef ); - m_xml.startElement( "Catch" ); - if( !m_config->name().empty() ) - m_xml.writeAttribute( "name", m_config->name() ); - } - - virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { - StreamingReporterBase::testGroupStarting( groupInfo ); - m_xml.startElement( "Group" ) - .writeAttribute( "name", groupInfo.name ); - } - - virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { - StreamingReporterBase::testCaseStarting(testInfo); - m_xml.startElement( "TestCase" ) - .writeAttribute( "name", trim( testInfo.name ) ) - .writeAttribute( "description", testInfo.description ) - .writeAttribute( "tags", testInfo.tagsAsString ); - - writeSourceInfo( testInfo.lineInfo ); - - if ( m_config->showDurations() == ShowDurations::Always ) - m_testCaseTimer.start(); - m_xml.ensureTagClosed(); - } - - virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { - StreamingReporterBase::sectionStarting( sectionInfo ); - if( m_sectionDepth++ > 0 ) { - m_xml.startElement( "Section" ) - .writeAttribute( "name", trim( sectionInfo.name ) ) - .writeAttribute( "description", sectionInfo.description ); - writeSourceInfo( sectionInfo.lineInfo ); - m_xml.ensureTagClosed(); - } - } - - virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } - - virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { - - AssertionResult const& result = assertionStats.assertionResult; - - bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); - - if( includeResults ) { - // Print any info messages in tags. - for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); - it != itEnd; - ++it ) { - if( it->type == ResultWas::Info ) { - m_xml.scopedElement( "Info" ) - .writeText( it->message ); - } else if ( it->type == ResultWas::Warning ) { - m_xml.scopedElement( "Warning" ) - .writeText( it->message ); - } - } - } - - // Drop out if result was successful but we're not printing them. - if( !includeResults && result.getResultType() != ResultWas::Warning ) - return true; - - // Print the expression if there is one. - if( result.hasExpression() ) { - m_xml.startElement( "Expression" ) - .writeAttribute( "success", result.succeeded() ) - .writeAttribute( "type", result.getTestMacroName() ); - - writeSourceInfo( result.getSourceInfo() ); - - m_xml.scopedElement( "Original" ) - .writeText( result.getExpression() ); - m_xml.scopedElement( "Expanded" ) - .writeText( result.getExpandedExpression() ); - } - - // And... Print a result applicable to each result type. - switch( result.getResultType() ) { - case ResultWas::ThrewException: - m_xml.startElement( "Exception" ); - writeSourceInfo( result.getSourceInfo() ); - m_xml.writeText( result.getMessage() ); - m_xml.endElement(); - break; - case ResultWas::FatalErrorCondition: - m_xml.startElement( "FatalErrorCondition" ); - writeSourceInfo( result.getSourceInfo() ); - m_xml.writeText( result.getMessage() ); - m_xml.endElement(); - break; - case ResultWas::Info: - m_xml.scopedElement( "Info" ) - .writeText( result.getMessage() ); - break; - case ResultWas::Warning: - // Warning will already have been written - break; - case ResultWas::ExplicitFailure: - m_xml.startElement( "Failure" ); - writeSourceInfo( result.getSourceInfo() ); - m_xml.writeText( result.getMessage() ); - m_xml.endElement(); - break; - default: - break; - } - - if( result.hasExpression() ) - m_xml.endElement(); - - return true; - } - - virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { - StreamingReporterBase::sectionEnded( sectionStats ); - if( --m_sectionDepth > 0 ) { - XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); - e.writeAttribute( "successes", sectionStats.assertions.passed ); - e.writeAttribute( "failures", sectionStats.assertions.failed ); - e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); - - if ( m_config->showDurations() == ShowDurations::Always ) - e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); - - m_xml.endElement(); - } - } - - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { - StreamingReporterBase::testCaseEnded( testCaseStats ); - XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); - e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); - - if ( m_config->showDurations() == ShowDurations::Always ) - e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); - - if( !testCaseStats.stdOut.empty() ) - m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); - if( !testCaseStats.stdErr.empty() ) - m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); - - m_xml.endElement(); - } - - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { - StreamingReporterBase::testGroupEnded( testGroupStats ); - // TODO: Check testGroupStats.aborting and act accordingly. - m_xml.scopedElement( "OverallResults" ) - .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) - .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); - m_xml.endElement(); - } - - virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { - StreamingReporterBase::testRunEnded( testRunStats ); - m_xml.scopedElement( "OverallResults" ) - .writeAttribute( "successes", testRunStats.totals.assertions.passed ) - .writeAttribute( "failures", testRunStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); - m_xml.endElement(); - } - - private: - Timer m_testCaseTimer; - XmlWriter m_xml; - int m_sectionDepth; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_junit.hpp -#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED - -#include - -namespace Catch { - - namespace { - std::string getCurrentTimestamp() { - // Beware, this is not reentrant because of backward compatibility issues - // Also, UTC only, again because of backward compatibility (%z is C++11) - time_t rawtime; - std::time(&rawtime); - const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z"); - -#ifdef _MSC_VER - std::tm timeInfo = {}; - gmtime_s(&timeInfo, &rawtime); -#else - std::tm* timeInfo; - timeInfo = std::gmtime(&rawtime); -#endif - - char timeStamp[timeStampSize]; - const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; - -#ifdef _MSC_VER - std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); -#else - std::strftime(timeStamp, timeStampSize, fmt, timeInfo); -#endif - return std::string(timeStamp); - } - - } - - class JunitReporter : public CumulativeReporterBase { - public: - JunitReporter( ReporterConfig const& _config ) - : CumulativeReporterBase( _config ), - xml( _config.stream() ), - unexpectedExceptions( 0 ), - m_okToFail( false ) - { - m_reporterPrefs.shouldRedirectStdOut = true; - } - - virtual ~JunitReporter() CATCH_OVERRIDE; - - static std::string getDescription() { - return "Reports test results in an XML format that looks like Ant's junitreport target"; - } - - virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {} - - virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE { - CumulativeReporterBase::testRunStarting( runInfo ); - xml.startElement( "testsuites" ); - } - - virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { - suiteTimer.start(); - stdOutForSuite.str(""); - stdErrForSuite.str(""); - unexpectedExceptions = 0; - CumulativeReporterBase::testGroupStarting( groupInfo ); - } - - virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE { - m_okToFail = testCaseInfo.okToFail(); - } - virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { - if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail ) - unexpectedExceptions++; - return CumulativeReporterBase::assertionEnded( assertionStats ); - } - - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { - stdOutForSuite << testCaseStats.stdOut; - stdErrForSuite << testCaseStats.stdErr; - CumulativeReporterBase::testCaseEnded( testCaseStats ); - } - - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { - double suiteTime = suiteTimer.getElapsedSeconds(); - CumulativeReporterBase::testGroupEnded( testGroupStats ); - writeGroup( *m_testGroups.back(), suiteTime ); - } - - virtual void testRunEndedCumulative() CATCH_OVERRIDE { - xml.endElement(); - } - - void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { - XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); - TestGroupStats const& stats = groupNode.value; - xml.writeAttribute( "name", stats.groupInfo.name ); - xml.writeAttribute( "errors", unexpectedExceptions ); - xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); - xml.writeAttribute( "tests", stats.totals.assertions.total() ); - xml.writeAttribute( "hostname", "tbd" ); // !TBD - if( m_config->showDurations() == ShowDurations::Never ) - xml.writeAttribute( "time", "" ); - else - xml.writeAttribute( "time", suiteTime ); - xml.writeAttribute( "timestamp", getCurrentTimestamp() ); - - // Write test cases - for( TestGroupNode::ChildNodes::const_iterator - it = groupNode.children.begin(), itEnd = groupNode.children.end(); - it != itEnd; - ++it ) - writeTestCase( **it ); - - xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); - xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); - } - - void writeTestCase( TestCaseNode const& testCaseNode ) { - TestCaseStats const& stats = testCaseNode.value; - - // All test cases have exactly one section - which represents the - // test case itself. That section may have 0-n nested sections - assert( testCaseNode.children.size() == 1 ); - SectionNode const& rootSection = *testCaseNode.children.front(); - - std::string className = stats.testInfo.className; - - if( className.empty() ) { - if( rootSection.childSections.empty() ) - className = "global"; - } - writeSection( className, "", rootSection ); - } - - void writeSection( std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode ) { - std::string name = trim( sectionNode.stats.sectionInfo.name ); - if( !rootName.empty() ) - name = rootName + '/' + name; - - if( !sectionNode.assertions.empty() || - !sectionNode.stdOut.empty() || - !sectionNode.stdErr.empty() ) { - XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); - if( className.empty() ) { - xml.writeAttribute( "classname", name ); - xml.writeAttribute( "name", "root" ); - } - else { - xml.writeAttribute( "classname", className ); - xml.writeAttribute( "name", name ); - } - xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); - - writeAssertions( sectionNode ); - - if( !sectionNode.stdOut.empty() ) - xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); - if( !sectionNode.stdErr.empty() ) - xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); - } - for( SectionNode::ChildSections::const_iterator - it = sectionNode.childSections.begin(), - itEnd = sectionNode.childSections.end(); - it != itEnd; - ++it ) - if( className.empty() ) - writeSection( name, "", **it ); - else - writeSection( className, name, **it ); - } - - void writeAssertions( SectionNode const& sectionNode ) { - for( SectionNode::Assertions::const_iterator - it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); - it != itEnd; - ++it ) - writeAssertion( *it ); - } - void writeAssertion( AssertionStats const& stats ) { - AssertionResult const& result = stats.assertionResult; - if( !result.isOk() ) { - std::string elementName; - switch( result.getResultType() ) { - case ResultWas::ThrewException: - case ResultWas::FatalErrorCondition: - elementName = "error"; - break; - case ResultWas::ExplicitFailure: - elementName = "failure"; - break; - case ResultWas::ExpressionFailed: - elementName = "failure"; - break; - case ResultWas::DidntThrowException: - elementName = "failure"; - break; - - // We should never see these here: - case ResultWas::Info: - case ResultWas::Warning: - case ResultWas::Ok: - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - elementName = "internalError"; - break; - } - - XmlWriter::ScopedElement e = xml.scopedElement( elementName ); - - xml.writeAttribute( "message", result.getExpandedExpression() ); - xml.writeAttribute( "type", result.getTestMacroName() ); - - std::ostringstream oss; - if( !result.getMessage().empty() ) - oss << result.getMessage() << '\n'; - for( std::vector::const_iterator - it = stats.infoMessages.begin(), - itEnd = stats.infoMessages.end(); - it != itEnd; - ++it ) - if( it->type == ResultWas::Info ) - oss << it->message << '\n'; - - oss << "at " << result.getSourceInfo(); - xml.writeText( oss.str(), false ); - } - } - - XmlWriter xml; - Timer suiteTimer; - std::ostringstream stdOutForSuite; - std::ostringstream stdErrForSuite; - unsigned int unexpectedExceptions; - bool m_okToFail; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_console.hpp -#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED - -#include -#include - -namespace Catch { - - struct ConsoleReporter : StreamingReporterBase { - ConsoleReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ), - m_headerPrinted( false ) - {} - - virtual ~ConsoleReporter() CATCH_OVERRIDE; - static std::string getDescription() { - return "Reports test results as plain lines of text"; - } - - virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { - stream << "No test cases matched '" << spec << '\'' << std::endl; - } - - virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { - } - - virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE { - AssertionResult const& result = _assertionStats.assertionResult; - - bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); - - // Drop out if result was successful but we're not printing them. - if( !includeResults && result.getResultType() != ResultWas::Warning ) - return false; - - lazyPrint(); - - AssertionPrinter printer( stream, _assertionStats, includeResults ); - printer.print(); - stream << std::endl; - return true; - } - - virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { - m_headerPrinted = false; - StreamingReporterBase::sectionStarting( _sectionInfo ); - } - virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE { - if( _sectionStats.missingAssertions ) { - lazyPrint(); - Colour colour( Colour::ResultError ); - if( m_sectionStack.size() > 1 ) - stream << "\nNo assertions in section"; - else - stream << "\nNo assertions in test case"; - stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; - } - if( m_config->showDurations() == ShowDurations::Always ) { - stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; - } - if( m_headerPrinted ) { - m_headerPrinted = false; - } - StreamingReporterBase::sectionEnded( _sectionStats ); - } - - virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { - StreamingReporterBase::testCaseEnded( _testCaseStats ); - m_headerPrinted = false; - } - virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE { - if( currentGroupInfo.used ) { - printSummaryDivider(); - stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; - printTotals( _testGroupStats.totals ); - stream << '\n' << std::endl; - } - StreamingReporterBase::testGroupEnded( _testGroupStats ); - } - virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE { - printTotalsDivider( _testRunStats.totals ); - printTotals( _testRunStats.totals ); - stream << std::endl; - StreamingReporterBase::testRunEnded( _testRunStats ); - } - - private: - - class AssertionPrinter { - void operator= ( AssertionPrinter const& ); - public: - AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) - : stream( _stream ), - stats( _stats ), - result( _stats.assertionResult ), - colour( Colour::None ), - message( result.getMessage() ), - messages( _stats.infoMessages ), - printInfoMessages( _printInfoMessages ) - { - switch( result.getResultType() ) { - case ResultWas::Ok: - colour = Colour::Success; - passOrFail = "PASSED"; - //if( result.hasMessage() ) - if( _stats.infoMessages.size() == 1 ) - messageLabel = "with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "with messages"; - break; - case ResultWas::ExpressionFailed: - if( result.isOk() ) { - colour = Colour::Success; - passOrFail = "FAILED - but was ok"; - } - else { - colour = Colour::Error; - passOrFail = "FAILED"; - } - if( _stats.infoMessages.size() == 1 ) - messageLabel = "with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "with messages"; - break; - case ResultWas::ThrewException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to unexpected exception with "; - if (_stats.infoMessages.size() == 1) - messageLabel += "message"; - if (_stats.infoMessages.size() > 1) - messageLabel += "messages"; - break; - case ResultWas::FatalErrorCondition: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to a fatal error condition"; - break; - case ResultWas::DidntThrowException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "because no exception was thrown where one was expected"; - break; - case ResultWas::Info: - messageLabel = "info"; - break; - case ResultWas::Warning: - messageLabel = "warning"; - break; - case ResultWas::ExplicitFailure: - passOrFail = "FAILED"; - colour = Colour::Error; - if( _stats.infoMessages.size() == 1 ) - messageLabel = "explicitly with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "explicitly with messages"; - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - passOrFail = "** internal error **"; - colour = Colour::Error; - break; - } - } - - void print() const { - printSourceInfo(); - if( stats.totals.assertions.total() > 0 ) { - if( result.isOk() ) - stream << '\n'; - printResultType(); - printOriginalExpression(); - printReconstructedExpression(); - } - else { - stream << '\n'; - } - printMessage(); - } - - private: - void printResultType() const { - if( !passOrFail.empty() ) { - Colour colourGuard( colour ); - stream << passOrFail << ":\n"; - } - } - void printOriginalExpression() const { - if( result.hasExpression() ) { - Colour colourGuard( Colour::OriginalExpression ); - stream << " "; - stream << result.getExpressionInMacro(); - stream << '\n'; - } - } - void printReconstructedExpression() const { - if( result.hasExpandedExpression() ) { - stream << "with expansion:\n"; - Colour colourGuard( Colour::ReconstructedExpression ); - stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n'; - } - } - void printMessage() const { - if( !messageLabel.empty() ) - stream << messageLabel << ':' << '\n'; - for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); - it != itEnd; - ++it ) { - // If this assertion is a warning ignore any INFO messages - if( printInfoMessages || it->type != ResultWas::Info ) - stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n'; - } - } - void printSourceInfo() const { - Colour colourGuard( Colour::FileName ); - stream << result.getSourceInfo() << ": "; - } - - std::ostream& stream; - AssertionStats const& stats; - AssertionResult const& result; - Colour::Code colour; - std::string passOrFail; - std::string messageLabel; - std::string message; - std::vector messages; - bool printInfoMessages; - }; - - void lazyPrint() { - - if( !currentTestRunInfo.used ) - lazyPrintRunInfo(); - if( !currentGroupInfo.used ) - lazyPrintGroupInfo(); - - if( !m_headerPrinted ) { - printTestCaseAndSectionHeader(); - m_headerPrinted = true; - } - } - void lazyPrintRunInfo() { - stream << '\n' << getLineOfChars<'~'>() << '\n'; - Colour colour( Colour::SecondaryText ); - stream << currentTestRunInfo->name - << " is a Catch v" << libraryVersion() << " host application.\n" - << "Run with -? for options\n\n"; - - if( m_config->rngSeed() != 0 ) - stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; - - currentTestRunInfo.used = true; - } - void lazyPrintGroupInfo() { - if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { - printClosedHeader( "Group: " + currentGroupInfo->name ); - currentGroupInfo.used = true; - } - } - void printTestCaseAndSectionHeader() { - assert( !m_sectionStack.empty() ); - printOpenHeader( currentTestCaseInfo->name ); - - if( m_sectionStack.size() > 1 ) { - Colour colourGuard( Colour::Headers ); - - std::vector::const_iterator - it = m_sectionStack.begin()+1, // Skip first section (test case) - itEnd = m_sectionStack.end(); - for( ; it != itEnd; ++it ) - printHeaderString( it->name, 2 ); - } - - SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; - - if( !lineInfo.empty() ){ - stream << getLineOfChars<'-'>() << '\n'; - Colour colourGuard( Colour::FileName ); - stream << lineInfo << '\n'; - } - stream << getLineOfChars<'.'>() << '\n' << std::endl; - } - - void printClosedHeader( std::string const& _name ) { - printOpenHeader( _name ); - stream << getLineOfChars<'.'>() << '\n'; - } - void printOpenHeader( std::string const& _name ) { - stream << getLineOfChars<'-'>() << '\n'; - { - Colour colourGuard( Colour::Headers ); - printHeaderString( _name ); - } - } - - // if string has a : in first line will set indent to follow it on - // subsequent lines - void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { - std::size_t i = _string.find( ": " ); - if( i != std::string::npos ) - i+=2; - else - i = 0; - stream << Text( _string, TextAttributes() - .setIndent( indent+i) - .setInitialIndent( indent ) ) << '\n'; - } - - struct SummaryColumn { - - SummaryColumn( std::string const& _label, Colour::Code _colour ) - : label( _label ), - colour( _colour ) - {} - SummaryColumn addRow( std::size_t count ) { - std::ostringstream oss; - oss << count; - std::string row = oss.str(); - for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { - while( it->size() < row.size() ) - *it = ' ' + *it; - while( it->size() > row.size() ) - row = ' ' + row; - } - rows.push_back( row ); - return *this; - } - - std::string label; - Colour::Code colour; - std::vector rows; - - }; - - void printTotals( Totals const& totals ) { - if( totals.testCases.total() == 0 ) { - stream << Colour( Colour::Warning ) << "No tests ran\n"; - } - else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) { - stream << Colour( Colour::ResultSuccess ) << "All tests passed"; - stream << " (" - << pluralise( totals.assertions.passed, "assertion" ) << " in " - << pluralise( totals.testCases.passed, "test case" ) << ')' - << '\n'; - } - else { - - std::vector columns; - columns.push_back( SummaryColumn( "", Colour::None ) - .addRow( totals.testCases.total() ) - .addRow( totals.assertions.total() ) ); - columns.push_back( SummaryColumn( "passed", Colour::Success ) - .addRow( totals.testCases.passed ) - .addRow( totals.assertions.passed ) ); - columns.push_back( SummaryColumn( "failed", Colour::ResultError ) - .addRow( totals.testCases.failed ) - .addRow( totals.assertions.failed ) ); - columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) - .addRow( totals.testCases.failedButOk ) - .addRow( totals.assertions.failedButOk ) ); - - printSummaryRow( "test cases", columns, 0 ); - printSummaryRow( "assertions", columns, 1 ); - } - } - void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { - for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { - std::string value = it->rows[row]; - if( it->label.empty() ) { - stream << label << ": "; - if( value != "0" ) - stream << value; - else - stream << Colour( Colour::Warning ) << "- none -"; - } - else if( value != "0" ) { - stream << Colour( Colour::LightGrey ) << " | "; - stream << Colour( it->colour ) - << value << ' ' << it->label; - } - } - stream << '\n'; - } - - static std::size_t makeRatio( std::size_t number, std::size_t total ) { - std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; - return ( ratio == 0 && number > 0 ) ? 1 : ratio; - } - static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { - if( i > j && i > k ) - return i; - else if( j > k ) - return j; - else - return k; - } - - void printTotalsDivider( Totals const& totals ) { - if( totals.testCases.total() > 0 ) { - std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); - std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); - std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); - while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) - findMax( failedRatio, failedButOkRatio, passedRatio )++; - while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) - findMax( failedRatio, failedButOkRatio, passedRatio )--; - - stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); - stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); - if( totals.testCases.allPassed() ) - stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); - else - stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); - } - else { - stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); - } - stream << '\n'; - } - void printSummaryDivider() { - stream << getLineOfChars<'-'>() << '\n'; - } - - private: - bool m_headerPrinted; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_compact.hpp -#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED - -namespace Catch { - - struct CompactReporter : StreamingReporterBase { - - CompactReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ) - {} - - virtual ~CompactReporter(); - - static std::string getDescription() { - return "Reports test results on a single line, suitable for IDEs"; - } - - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = false; - return prefs; - } - - virtual void noMatchingTestCases( std::string const& spec ) { - stream << "No test cases matched '" << spec << '\'' << std::endl; - } - - virtual void assertionStarting( AssertionInfo const& ) {} - - virtual bool assertionEnded( AssertionStats const& _assertionStats ) { - AssertionResult const& result = _assertionStats.assertionResult; - - bool printInfoMessages = true; - - // Drop out if result was successful and we're not printing those - if( !m_config->includeSuccessfulResults() && result.isOk() ) { - if( result.getResultType() != ResultWas::Warning ) - return false; - printInfoMessages = false; - } - - AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); - printer.print(); - - stream << std::endl; - return true; - } - - virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE { - if (m_config->showDurations() == ShowDurations::Always) { - stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; - } - } - - virtual void testRunEnded( TestRunStats const& _testRunStats ) { - printTotals( _testRunStats.totals ); - stream << '\n' << std::endl; - StreamingReporterBase::testRunEnded( _testRunStats ); - } - - private: - class AssertionPrinter { - void operator= ( AssertionPrinter const& ); - public: - AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) - : stream( _stream ) - , stats( _stats ) - , result( _stats.assertionResult ) - , messages( _stats.infoMessages ) - , itMessage( _stats.infoMessages.begin() ) - , printInfoMessages( _printInfoMessages ) - {} - - void print() { - printSourceInfo(); - - itMessage = messages.begin(); - - switch( result.getResultType() ) { - case ResultWas::Ok: - printResultType( Colour::ResultSuccess, passedString() ); - printOriginalExpression(); - printReconstructedExpression(); - if ( ! result.hasExpression() ) - printRemainingMessages( Colour::None ); - else - printRemainingMessages(); - break; - case ResultWas::ExpressionFailed: - if( result.isOk() ) - printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); - else - printResultType( Colour::Error, failedString() ); - printOriginalExpression(); - printReconstructedExpression(); - printRemainingMessages(); - break; - case ResultWas::ThrewException: - printResultType( Colour::Error, failedString() ); - printIssue( "unexpected exception with message:" ); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::FatalErrorCondition: - printResultType( Colour::Error, failedString() ); - printIssue( "fatal error condition with message:" ); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::DidntThrowException: - printResultType( Colour::Error, failedString() ); - printIssue( "expected exception, got none" ); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::Info: - printResultType( Colour::None, "info" ); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::Warning: - printResultType( Colour::None, "warning" ); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::ExplicitFailure: - printResultType( Colour::Error, failedString() ); - printIssue( "explicitly" ); - printRemainingMessages( Colour::None ); - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - printResultType( Colour::Error, "** internal error **" ); - break; - } - } - - private: - // Colour::LightGrey - - static Colour::Code dimColour() { return Colour::FileName; } - -#ifdef CATCH_PLATFORM_MAC - static const char* failedString() { return "FAILED"; } - static const char* passedString() { return "PASSED"; } -#else - static const char* failedString() { return "failed"; } - static const char* passedString() { return "passed"; } -#endif - - void printSourceInfo() const { - Colour colourGuard( Colour::FileName ); - stream << result.getSourceInfo() << ':'; - } - - void printResultType( Colour::Code colour, std::string const& passOrFail ) const { - if( !passOrFail.empty() ) { - { - Colour colourGuard( colour ); - stream << ' ' << passOrFail; - } - stream << ':'; - } - } - - void printIssue( std::string const& issue ) const { - stream << ' ' << issue; - } - - void printExpressionWas() { - if( result.hasExpression() ) { - stream << ';'; - { - Colour colour( dimColour() ); - stream << " expression was:"; - } - printOriginalExpression(); - } - } - - void printOriginalExpression() const { - if( result.hasExpression() ) { - stream << ' ' << result.getExpression(); - } - } - - void printReconstructedExpression() const { - if( result.hasExpandedExpression() ) { - { - Colour colour( dimColour() ); - stream << " for: "; - } - stream << result.getExpandedExpression(); - } - } - - void printMessage() { - if ( itMessage != messages.end() ) { - stream << " '" << itMessage->message << '\''; - ++itMessage; - } - } - - void printRemainingMessages( Colour::Code colour = dimColour() ) { - if ( itMessage == messages.end() ) - return; - - // using messages.end() directly yields compilation error: - std::vector::const_iterator itEnd = messages.end(); - const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); - - { - Colour colourGuard( colour ); - stream << " with " << pluralise( N, "message" ) << ':'; - } - - for(; itMessage != itEnd; ) { - // If this assertion is a warning ignore any INFO messages - if( printInfoMessages || itMessage->type != ResultWas::Info ) { - stream << " '" << itMessage->message << '\''; - if ( ++itMessage != itEnd ) { - Colour colourGuard( dimColour() ); - stream << " and"; - } - } - } - } - - private: - std::ostream& stream; - AssertionStats const& stats; - AssertionResult const& result; - std::vector messages; - std::vector::const_iterator itMessage; - bool printInfoMessages; - }; - - // Colour, message variants: - // - white: No tests ran. - // - red: Failed [both/all] N test cases, failed [both/all] M assertions. - // - white: Passed [both/all] N test cases (no assertions). - // - red: Failed N tests cases, failed M assertions. - // - green: Passed [both/all] N tests cases with M assertions. - - std::string bothOrAll( std::size_t count ) const { - return count == 1 ? std::string() : count == 2 ? "both " : "all " ; - } - - void printTotals( const Totals& totals ) const { - if( totals.testCases.total() == 0 ) { - stream << "No tests ran."; - } - else if( totals.testCases.failed == totals.testCases.total() ) { - Colour colour( Colour::ResultError ); - const std::string qualify_assertions_failed = - totals.assertions.failed == totals.assertions.total() ? - bothOrAll( totals.assertions.failed ) : std::string(); - stream << - "Failed " << bothOrAll( totals.testCases.failed ) - << pluralise( totals.testCases.failed, "test case" ) << ", " - "failed " << qualify_assertions_failed << - pluralise( totals.assertions.failed, "assertion" ) << '.'; - } - else if( totals.assertions.total() == 0 ) { - stream << - "Passed " << bothOrAll( totals.testCases.total() ) - << pluralise( totals.testCases.total(), "test case" ) - << " (no assertions)."; - } - else if( totals.assertions.failed ) { - Colour colour( Colour::ResultError ); - stream << - "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " - "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.'; - } - else { - Colour colour( Colour::ResultSuccess ); - stream << - "Passed " << bothOrAll( totals.testCases.passed ) - << pluralise( totals.testCases.passed, "test case" ) << - " with " << pluralise( totals.assertions.passed, "assertion" ) << '.'; - } - } - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) - -} // end namespace Catch - -namespace Catch { - // These are all here to avoid warnings about not having any out of line - // virtual methods - NonCopyable::~NonCopyable() {} - IShared::~IShared() {} - IStream::~IStream() CATCH_NOEXCEPT {} - FileStream::~FileStream() CATCH_NOEXCEPT {} - CoutStream::~CoutStream() CATCH_NOEXCEPT {} - DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} - StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} - IContext::~IContext() {} - IResultCapture::~IResultCapture() {} - ITestCase::~ITestCase() {} - ITestCaseRegistry::~ITestCaseRegistry() {} - IRegistryHub::~IRegistryHub() {} - IMutableRegistryHub::~IMutableRegistryHub() {} - IExceptionTranslator::~IExceptionTranslator() {} - IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} - IReporter::~IReporter() {} - IReporterFactory::~IReporterFactory() {} - IReporterRegistry::~IReporterRegistry() {} - IStreamingReporter::~IStreamingReporter() {} - AssertionStats::~AssertionStats() {} - SectionStats::~SectionStats() {} - TestCaseStats::~TestCaseStats() {} - TestGroupStats::~TestGroupStats() {} - TestRunStats::~TestRunStats() {} - CumulativeReporterBase::SectionNode::~SectionNode() {} - CumulativeReporterBase::~CumulativeReporterBase() {} - - StreamingReporterBase::~StreamingReporterBase() {} - ConsoleReporter::~ConsoleReporter() {} - CompactReporter::~CompactReporter() {} - IRunner::~IRunner() {} - IMutableContext::~IMutableContext() {} - IConfig::~IConfig() {} - XmlReporter::~XmlReporter() {} - JunitReporter::~JunitReporter() {} - TestRegistry::~TestRegistry() {} - FreeFunctionTestCase::~FreeFunctionTestCase() {} - IGeneratorInfo::~IGeneratorInfo() {} - IGeneratorsForTest::~IGeneratorsForTest() {} - WildcardPattern::~WildcardPattern() {} - TestSpec::Pattern::~Pattern() {} - TestSpec::NamePattern::~NamePattern() {} - TestSpec::TagPattern::~TagPattern() {} - TestSpec::ExcludedPattern::~ExcludedPattern() {} - Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {} - - void Config::dummy() {} - - namespace TestCaseTracking { - ITracker::~ITracker() {} - TrackerBase::~TrackerBase() {} - SectionTracker::~SectionTracker() {} - IndexTracker::~IndexTracker() {} - } -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#endif - -#ifdef CATCH_CONFIG_MAIN -// #included from: internal/catch_default_main.hpp -#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED - -#ifndef __OBJC__ - -#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) -// Standard C/C++ Win32 Unicode wmain entry point -extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { -#else -// Standard C/C++ main entry point -int main (int argc, char * argv[]) { -#endif - - int result = Catch::Session().run( argc, argv ); - return ( result < 0xff ? result : 0xff ); -} - -#else // __OBJC__ - -// Objective-C entry point -int main (int argc, char * const argv[]) { -#if !CATCH_ARC_ENABLED - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; -#endif - - Catch::registerTestMethods(); - int result = Catch::Session().run( argc, (char* const*)argv ); - -#if !CATCH_ARC_ENABLED - [pool drain]; -#endif - - return ( result < 0xff ? result : 0xff ); -} - -#endif // __OBJC__ - -#endif - -#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED -# undef CLARA_CONFIG_MAIN -#endif - -////// - -// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ -#ifdef CATCH_CONFIG_PREFIX_ALL - -#if defined(CATCH_CONFIG_FAST_COMPILE) -#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) -#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) -#else -#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) -#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) -#endif - -#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) -#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) -#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) -#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) - -#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) -#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) - -#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) -#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) -#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) - -#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) - -#if defined(CATCH_CONFIG_FAST_COMPILE) -#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) -#else -#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) -#endif - -#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) -#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) -#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) -#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) -#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) - #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) - #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) - #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) - #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) - #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) - #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) - #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#else - #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) - #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) - #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) - #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) - #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) - #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) - #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) - #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) -#endif -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) - -#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) -#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) - -#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) - -// "BDD-style" convenience wrappers -#ifdef CATCH_CONFIG_VARIADIC_MACROS -#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) -#else -#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) -#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) -#endif -#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) -#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) -#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) -#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) -#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) - -// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required -#else - -#if defined(CATCH_CONFIG_FAST_COMPILE) -#define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr ) -#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) - -#else -#define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr ) -#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) -#endif - -#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) -#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) -#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) -#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) - -#define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) -#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) - -#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) -#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) -#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) -#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) - -#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) - -#if defined(CATCH_CONFIG_FAST_COMPILE) -#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) -#else -#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) -#endif - -#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) -#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) -#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) -#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) -#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) - -#ifdef CATCH_CONFIG_VARIADIC_MACROS -#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) -#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) -#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) -#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) -#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) -#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) -#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) -#else -#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) - #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) - #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) - #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) - #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) - #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) - #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) - #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) -#endif -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) - -#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) -#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) - -#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) - -#endif - -#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) - -// "BDD-style" convenience wrappers -#ifdef CATCH_CONFIG_VARIADIC_MACROS -#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) -#else -#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) -#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) -#endif -#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) -#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) -#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) -#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) -#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) - -using Catch::Detail::Approx; - -// #included from: internal/catch_reenable_warnings.h - -#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(pop) -# else -# pragma clang diagnostic pop -# endif -#elif defined __GNUC__ -# pragma GCC diagnostic pop -#endif - -#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED - diff -Nru armadillo-9.800.4+dfsg/tests/decomp_eig_gen.cpp armadillo-10.8.2+dfsg/tests/decomp_eig_gen.cpp --- armadillo-9.800.4+dfsg/tests/decomp_eig_gen.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/decomp_eig_gen.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("decomp_eig_gen_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - cx_vec eigvals1 = - { - cx_double(-0.431507827005653, +0.336567219978257), - cx_double(-0.431507827005653, -0.336567219978257), - cx_double( 0.509611570246060, +0.000000000000000), - cx_double( 0.020403541882623, +0.255686097698784), - cx_double( 0.020403541882623, -0.255686097698784) - }; - - cx_vec eigvals2 = eig_gen(A); - - cx_vec eigvals3; - bool status = eig_gen(eigvals3, A); - - cx_vec eigvals4; - cx_mat eigvecs4; - eig_gen(eigvals4, eigvecs4, A); - - cx_mat B = eigvecs4 * diagmat(eigvals4) * inv(eigvecs4); - - REQUIRE( status == true ); - REQUIRE( accu(abs(eigvals2 - eigvals1)) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs(eigvals3 - eigvals1)) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs(eigvals4 - eigvals1)) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs(A - B )) == Approx(0.0).epsilon(0.0001) ); - } - - - -TEST_CASE("decomp_eig_gen_2") - { - cx_mat A = - { - { cx_double( 0.111205, +0.074101), cx_double(-0.225872, -0.068474), cx_double(-0.192660, +0.236887), cx_double( 0.355204, -0.355735) }, - { cx_double( 0.119869, +0.217667), cx_double(-0.412722, +0.366157), cx_double( 0.069916, -0.222238), cx_double( 0.234987, -0.072355) }, - { cx_double( 0.003791, +0.183253), cx_double(-0.212887, -0.172758), cx_double( 0.168689, -0.393418), cx_double( 0.008795, -0.289654) }, - { cx_double(-0.331639, -0.166660), cx_double( 0.436969, -0.313498), cx_double(-0.431574, +0.017421), cx_double(-0.104165, +0.145246) } - }; - - cx_vec eigvals1 = - { - cx_double(-0.47418, +0.60377), - cx_double( 0.15084, -0.44209), - cx_double(-0.15790, -0.35629), - cx_double( 0.24426, +0.38670) - }; - - cx_vec eigvals2 = eig_gen(A); - - cx_vec eigvals3; - bool status = eig_gen(eigvals3, A); - - cx_vec eigvals4; - cx_mat eigvecs4; - eig_gen(eigvals4, eigvecs4, A); - - cx_mat B = eigvecs4 * diagmat(eigvals4) * inv(eigvecs4); - - REQUIRE( status == true ); - REQUIRE( accu(abs(eigvals2 - eigvals1)) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs(eigvals3 - eigvals1)) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs(eigvals4 - eigvals1)) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs(A - B )) == Approx(0.0).epsilon(0.0001) ); - } - - - -TEST_CASE("decomp_eig_gen_3") - { - mat A(5,5,fill::randu); - - cx_vec eigvals(10, fill::randu); - cx_mat eigvecs(10, 10, fill::randu); - - A(0,0) = datum::inf; - bool status = eig_gen(eigvals, eigvecs, A); - - REQUIRE( status == false ); - REQUIRE( eigvals.n_elem == uword(0) ); - REQUIRE( eigvecs.n_elem == uword(0) ); - } - - - -TEST_CASE("decomp_eig_gen_4") - { - mat A(5,6,fill::randu); - - cx_vec eigvals; - cx_mat eigvecs; - - REQUIRE_THROWS( eig_gen(eigvals, eigvecs, A) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/decomp_eig_sym.cpp armadillo-10.8.2+dfsg/tests/decomp_eig_sym.cpp --- armadillo-9.800.4+dfsg/tests/decomp_eig_sym.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/decomp_eig_sym.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("decomp_eig_sym_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - A = A*A.t(); - - vec eigvals1 = - { - 0.0044188, - 0.0697266, - 0.3364172, - 0.8192910, - 1.1872184 - }; - - vec eigvals2 = eig_sym(A); - - vec eigvals3; - bool status = eig_sym(eigvals3, A); - - vec eigvals4; - mat eigvecs4; - eig_sym(eigvals4, eigvecs4, A); - - mat B = eigvecs4 * diagmat(eigvals4) * eigvecs4.t(); - - REQUIRE( status == true ); - REQUIRE( accu(abs(eigvals2 - eigvals1)) == Approx(0.0) ); - REQUIRE( accu(abs(eigvals3 - eigvals1)) == Approx(0.0) ); - REQUIRE( accu(abs(eigvals4 - eigvals1)) == Approx(0.0) ); - REQUIRE( accu(abs(A - B )) == Approx(0.0) ); - } - - - -TEST_CASE("eig_sym_2") - { - cx_mat A = - { - { cx_double( 0.111205, +0.074101), cx_double(-0.225872, -0.068474), cx_double(-0.192660, +0.236887), cx_double( 0.355204, -0.355735) }, - { cx_double( 0.119869, +0.217667), cx_double(-0.412722, +0.366157), cx_double( 0.069916, -0.222238), cx_double( 0.234987, -0.072355) }, - { cx_double( 0.003791, +0.183253), cx_double(-0.212887, -0.172758), cx_double( 0.168689, -0.393418), cx_double( 0.008795, -0.289654) }, - { cx_double(-0.331639, -0.166660), cx_double( 0.436969, -0.313498), cx_double(-0.431574, +0.017421), cx_double(-0.104165, +0.145246) } - }; - - A = A*A.t(); - - vec eigvals1 = - { - 0.030904, - 0.253778, - 0.432459, - 1.204726 - }; - - vec eigvals2 = eig_sym(A); - - vec eigvals3; - bool status = eig_sym(eigvals3, A); - - vec eigvals4; - cx_mat eigvecs4; - eig_sym(eigvals4, eigvecs4, A); - - cx_mat B = eigvecs4 * diagmat(eigvals4) * eigvecs4.t(); - - REQUIRE( status == true ); - REQUIRE( accu(abs(eigvals2 - eigvals1)) == Approx(0.0) ); - REQUIRE( accu(abs(eigvals3 - eigvals1)) == Approx(0.0) ); - REQUIRE( accu(abs(eigvals4 - eigvals1)) == Approx(0.0) ); - REQUIRE( accu(abs(A - B )) == Approx(0.0) ); - } - - - -TEST_CASE("eig_sym_3") - { - mat A(5,6,fill::randu); - - vec eigvals; - mat eigvecs; - - REQUIRE_THROWS( eig_sym(eigvals, eigvecs, A) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/expr_elem.cpp armadillo-10.8.2+dfsg/tests/expr_elem.cpp --- armadillo-9.800.4+dfsg/tests/expr_elem.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/expr_elem.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("expr_elem_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat A_plus_2 = - "\ - 2.061198 2.201990 2.019678 1.506064 1.873255 2.051408;\ - 2.437242 2.058956 1.850638 1.954535 2.296153 2.035437;\ - 1.507526 1.968691 2.314156 2.419733 2.068317 1.545501;\ - 2.336352 2.411541 2.458476 1.606861 1.864960 2.373833;\ - 2.239585 1.571087 1.593047 1.708980 1.646232 2.258704;\ - "; - - mat A_minus_2 = - "\ - -1.938802 -1.798010 -1.980322 -2.493936 -2.126745 -1.948592;\ - -1.562758 -1.941044 -2.149362 -2.045465 -1.703847 -1.964563;\ - -2.492474 -2.031309 -1.685844 -1.580267 -1.931683 -2.454499;\ - -1.663648 -1.588459 -1.541524 -2.393139 -2.135040 -1.626167;\ - -1.760415 -2.428913 -2.406953 -2.291020 -2.353768 -1.741296;\ - "; - - mat two_minus_A = - "\ - 1.938802 1.798010 1.980322 2.493936 2.126745 1.948592;\ - 1.562758 1.941044 2.149362 2.045465 1.703847 1.964563;\ - 2.492474 2.031309 1.685844 1.580267 1.931683 2.454499;\ - 1.663648 1.588459 1.541524 2.393139 2.135040 1.626167;\ - 1.760415 2.428913 2.406953 2.291020 2.353768 1.741296;\ - "; - - mat A_times_2 = - "\ - 0.122396 0.403980 0.039356 -0.987872 -0.253490 0.102816;\ - 0.874484 0.117912 -0.298724 -0.090930 0.592306 0.070874;\ - -0.984948 -0.062618 0.628312 0.839466 0.136634 -0.908998;\ - 0.672704 0.823082 0.916952 -0.786278 -0.270080 0.747666;\ - 0.479170 -0.857826 -0.813906 -0.582040 -0.707536 0.517408;\ - "; - - mat A_elem_mul_A = - "\ - 3.74519520400000e-03 4.07999601000000e-02 3.87223684000000e-04 2.43972772096000e-01 1.60642950250000e-02 2.64278246400000e-03;\ - 1.91180566564000e-01 3.47580993600000e-03 2.23090070440000e-02 2.06706622500000e-03 8.77065994090000e-02 1.25578096900000e-03;\ - 2.42530640676000e-01 9.80253481000000e-04 9.86939923360000e-02 1.76175791289000e-01 4.66721248900000e-03 2.06569341001000e-01;\ - 1.13132667904000e-01 1.69365994681000e-01 2.10200242576000e-01 1.54558273321000e-01 1.82358016000000e-02 1.39751111889000e-01;\ - 5.74009722250000e-02 1.83966361569000e-01 1.65610744209000e-01 8.46926404000000e-02 1.25151797824000e-01 6.69277596160000e-02;\ - "; - - mat A_div_2 = - "\ - 0.03059900000000000 0.10099500000000000 0.00983900000000000 -0.24696799999999999 -0.06337250000000000 0.02570400000000000;\ - 0.21862100000000001 0.02947800000000000 -0.07468100000000000 -0.02273250000000000 0.14807650000000000 0.01771850000000000;\ - -0.24623700000000001 -0.01565450000000000 0.15707800000000000 0.20986650000000001 0.03415850000000000 -0.22724949999999999;\ - 0.16817599999999999 0.20577050000000000 0.22923800000000000 -0.19656950000000001 -0.06752000000000000 0.18691650000000001;\ - 0.11979250000000000 -0.21445649999999999 -0.20347650000000000 -0.14551000000000000 -0.17688400000000001 0.12935199999999999;\ - "; - - mat two_div_A = - "\ - 32.68080656230595 9.90148027130056 101.63634515702815 -4.04910757669010 -15.77971517614107 38.90445066915655;\ - 4.57412599887476 33.92360404369360 -13.39028668603795 -43.98988232706478 6.75326604829261 56.43818607669949;\ - -4.06112810016366 -63.87939570091667 6.36626389437095 4.76493389845449 29.27529019131402 -4.40044972596199;\ - 5.94615165065170 4.85978310787990 4.36227850530889 -5.08725921366234 -14.81042654028436 5.34998247880738;\ - 8.34776801552685 -4.66295029528133 -4.91457244448376 -6.87237990516116 -5.65342258203116 7.73084297111757;\ - "; - - REQUIRE( accu(abs(( A - A ))) == Approx(0.0) ); - REQUIRE( accu(abs((2*A - 2*A ))) == Approx(0.0) ); - REQUIRE( accu(abs((2*A - (A+A)))) == Approx(0.0) ); - - REQUIRE( accu(abs((A+0) - A )) == Approx(0.0) ); - REQUIRE( accu(abs((A-0) - A )) == Approx(0.0) ); - - REQUIRE( accu(abs((A*1) - A )) == Approx(0.0) ); - REQUIRE( accu(abs((A/1) - A )) == Approx(0.0) ); - - REQUIRE( accu(abs((A+2) - A_plus_2)) == Approx(0.0) ); - REQUIRE( accu(abs((2+A) - A_plus_2)) == Approx(0.0) ); - - REQUIRE( accu(abs((A*2) - A_times_2)) == Approx(0.0) ); - REQUIRE( accu(abs((2*A) - A_times_2)) == Approx(0.0) ); - REQUIRE( accu(abs((A+A) - A_times_2)) == Approx(0.0) ); - - REQUIRE( accu(abs((A+A+A - A) - A_times_2)) == Approx(0.0) ); - REQUIRE( accu(abs((3*A - A) - A_times_2)) == Approx(0.0) ); - - REQUIRE( accu(abs((A/2 ) - A_div_2)) == Approx(0.0) ); - REQUIRE( accu(abs((A*0.5) - A_div_2)) == Approx(0.0) ); - - REQUIRE( accu(abs((2/A ) - two_div_A)) == Approx(0.0) ); - - REQUIRE( accu(abs( (A % A) - A_elem_mul_A )) == Approx(0.0) ); - REQUIRE( accu(abs( (A % A) - square(A) )) == Approx(0.0) ); - - REQUIRE( accu(abs(( (2/A) % (A/2) ) - ones(size(A)))) == Approx(0.0) ); - - - REQUIRE( accu(abs(( A - A(span::all,span::all) ))) == Approx(0.0) ); - - REQUIRE( accu(abs((A(span::all,span::all)+2) - A_plus_2)) == Approx(0.0) ); - REQUIRE( accu(abs((2+A(span::all,span::all)) - A_plus_2)) == Approx(0.0) ); - - REQUIRE( accu(abs(((A+A+A) / (3*A)) - ones(size(A)))) == Approx(0.0) ); - - REQUIRE_THROWS( A + randu(A.n_rows+1, A.n_cols ) ); - REQUIRE_THROWS( A + randu(A.n_rows , A.n_cols+1) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/expr_misc.cpp armadillo-10.8.2+dfsg/tests/expr_misc.cpp --- armadillo-9.800.4+dfsg/tests/expr_misc.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/expr_misc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("expr_misc_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = A( span(0,min(size(A))-1), span(0,min(size(A))-1) ); - - colvec q = B.tail_cols(1); - rowvec r = B.head_rows(1); - - B = B + q*r + B + B.col(1)*B.row(2) + inv(B.t() + B); - - mat C = - "\ - -0.598176493690805 1.743720221389917 -0.464434209123318 -0.578107329514025 -0.466519088609519;\ - 2.235239222999917 0.352055300390581 0.130383508730418 0.178723856228643 0.315212838210605;\ - -1.530100759221318 0.356920033171418 0.660107612169934 1.456138259553199 -0.459039415535322;\ - 0.724145463141975 1.174109038919643 1.707140663038199 -0.861429259650926 -0.384555300447272;\ - 0.425855872233481 -1.159439708059395 -1.540488679549322 -0.747036381125272 -1.722286962209877;\ - "; - - REQUIRE( accu(abs(B - C)) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_abs.cpp armadillo-10.8.2+dfsg/tests/fn_abs.cpp --- armadillo-9.800.4+dfsg/tests/fn_abs.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_abs.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,249 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_abs_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat abs_A = - "\ - 0.061198 0.201990 0.019678 0.493936 0.126745 0.051408;\ - 0.437242 0.058956 0.149362 0.045465 0.296153 0.035437;\ - 0.492474 0.031309 0.314156 0.419733 0.068317 0.454499;\ - 0.336352 0.411541 0.458476 0.393139 0.135040 0.373833;\ - 0.239585 0.428913 0.406953 0.291020 0.353768 0.258704;\ - "; - - mat X = abs(A); - - REQUIRE( X(0,0) == Approx(0.061198) ); - REQUIRE( X(1,0) == Approx(0.437242) ); - REQUIRE( X(2,0) == Approx(0.492474) ); - REQUIRE( X(3,0) == Approx(0.336352) ); - REQUIRE( X(4,0) == Approx(0.239585) ); - - REQUIRE( X(0,1) == Approx(0.201990) ); - REQUIRE( X(1,1) == Approx(0.058956) ); - REQUIRE( X(2,1) == Approx(0.031309) ); - REQUIRE( X(3,1) == Approx(0.411541) ); - REQUIRE( X(4,1) == Approx(0.428913) ); - - REQUIRE( X(0,5) == Approx(0.051408) ); - REQUIRE( X(1,5) == Approx(0.035437) ); - REQUIRE( X(2,5) == Approx(0.454499) ); - REQUIRE( X(3,5) == Approx(0.373833) ); - REQUIRE( X(4,5) == Approx(0.258704) ); - - mat Y = abs(2*A) / 2; - - REQUIRE( Y(0,0) == Approx(0.061198) ); - REQUIRE( Y(1,0) == Approx(0.437242) ); - REQUIRE( Y(2,0) == Approx(0.492474) ); - REQUIRE( Y(3,0) == Approx(0.336352) ); - REQUIRE( Y(4,0) == Approx(0.239585) ); - - REQUIRE( Y(0,1) == Approx(0.201990) ); - REQUIRE( Y(1,1) == Approx(0.058956) ); - REQUIRE( Y(2,1) == Approx(0.031309) ); - REQUIRE( Y(3,1) == Approx(0.411541) ); - REQUIRE( Y(4,1) == Approx(0.428913) ); - - REQUIRE( Y(0,5) == Approx(0.051408) ); - REQUIRE( Y(1,5) == Approx(0.035437) ); - REQUIRE( Y(2,5) == Approx(0.454499) ); - REQUIRE( Y(3,5) == Approx(0.373833) ); - REQUIRE( Y(4,5) == Approx(0.258704) ); - - REQUIRE( accu( abs(A) - abs_A ) == Approx(0.0) ); - REQUIRE( accu( 2*abs(A) - 2*abs_A ) == Approx(0.0) ); - - REQUIRE( accu( abs(-A) - abs_A ) == Approx(0.0) ); - REQUIRE( accu( 2*abs(-A) - 2*abs_A ) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } - - - -TEST_CASE("fn_abs_2") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - cx_mat C = cx_mat(A,fliplr(A)); - - mat abs_C = - "\ - 0.079925 0.238462 0.494328 0.494328 0.238462 0.079925;\ - 0.438676 0.301964 0.156128 0.156128 0.301964 0.438676;\ - 0.670149 0.075150 0.524280 0.524280 0.075150 0.670149;\ - 0.502876 0.433130 0.603952 0.603952 0.433130 0.502876;\ - 0.352603 0.555984 0.500303 0.500303 0.555984 0.352603;\ - "; - - mat X = abs(C); - - REQUIRE( X(0,0) == Approx(0.079925) ); - REQUIRE( X(1,0) == Approx(0.438676) ); - REQUIRE( X(2,0) == Approx(0.670149) ); - REQUIRE( X(3,0) == Approx(0.502876) ); - REQUIRE( X(4,0) == Approx(0.352603) ); - - REQUIRE( X(0,1) == Approx(0.238462) ); - REQUIRE( X(1,1) == Approx(0.301964) ); - REQUIRE( X(2,1) == Approx(0.075150) ); - REQUIRE( X(3,1) == Approx(0.433130) ); - REQUIRE( X(4,1) == Approx(0.555984) ); - - REQUIRE( X(0,5) == Approx(0.079925) ); - REQUIRE( X(1,5) == Approx(0.438676) ); - REQUIRE( X(2,5) == Approx(0.670149) ); - REQUIRE( X(3,5) == Approx(0.502876) ); - REQUIRE( X(4,5) == Approx(0.352603) ); - - REQUIRE( accu( abs(C) - abs_C ) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } - - - -TEST_CASE("fn_abs_3") - { - vec re = 2*linspace(1,5,6); - vec im = -4*linspace(1,5,6); - - cx_vec a(re,im); - - vec b = - { - 4.47213595499958, - 8.04984471899924, - 11.62755348299891, - 15.20526224699857, - 18.78297101099824, - 22.36067977499790 - }; - - - vec c = abs(a); - - REQUIRE( accu(c - b) == Approx(0.0) ); - REQUIRE( accu(abs(a) - b) == Approx(0.0) ); - } - - -TEST_CASE("fn_abs_4") - { - vec a = -2*linspace(1,5,6); - vec b = +2*linspace(1,5,6); - - REQUIRE( accu(abs(a) - b) == Approx(0.0) ); - REQUIRE( accu(abs(a(span::all)) - b(span::all)) == Approx(0.0) ); - } - - - -TEST_CASE("fn_abs_5") - { - mat A = randu(5,6); - - REQUIRE( accu(abs(-2*A) - (2*A)) == Approx(0.0) ); - REQUIRE( accu(abs(-2*A(span::all,span::all)) - (2*A(span::all,span::all))) == Approx(0.0) ); - } - - - -TEST_CASE("fn_abs_sp_mat") - { - SpMat a(3, 3); - a(0, 2) = 4.3; - a(1, 1) = -5.5; - a(2, 2) = -6.3; - - SpMat b = abs(a); - - REQUIRE( (double) b(0, 0) == 0 ); - REQUIRE( (double) b(1, 0) == 0 ); - REQUIRE( (double) b(2, 0) == 0 ); - REQUIRE( (double) b(0, 1) == 0 ); - REQUIRE( (double) b(1, 1) == Approx(5.5) ); - REQUIRE( (double) b(2, 1) == 0 ); - REQUIRE( (double) b(0, 2) == Approx(4.3) ); - REQUIRE( (double) b(1, 2) == 0 ); - REQUIRE( (double) b(2, 2) == Approx(6.3) ); - - // Just test that these compile and run. - b = abs(a); - b *= abs(a); - b %= abs(a); - b /= abs(a); - } - - - -TEST_CASE("fn_abs_sp_mat_2") - { - mat x = randu(100, 100); - x -= 0.5; - - SpMat y(x); - - mat xr = abs(x); - SpMat yr = abs(y); - - for(size_t i = 0; i < xr.n_elem; ++i) - { - REQUIRE( xr[i] == Approx((double) yr[i]) ); - } - } - - - -TEST_CASE("fn_abs_sp_cx_mat") - { - cx_mat x = randu(100, 100); - x -= cx_double(0.5, 0.5); - - sp_cx_mat y(x); - - mat xr = abs(x); - SpMat yr = abs(y); - - for(size_t i = 0; i < xr.n_elem; ++i) - { - REQUIRE( xr[i] == Approx((double) yr[i]) ); - } - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_accu.cpp armadillo-10.8.2+dfsg/tests/fn_accu.cpp --- armadillo-9.800.4+dfsg/tests/fn_accu.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_accu.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_accu_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - REQUIRE( accu(A) == Approx( 0.240136) ); - REQUIRE( accu(abs(A)) == Approx( 7.845382) ); - REQUIRE( accu(A-A) == Approx( 0.0 ) ); - REQUIRE( accu(A+A) == Approx( 0.480272) ); - REQUIRE( accu(2*A) == Approx( 0.480272) ); - REQUIRE( accu( -A) == Approx(-0.240136) ); - REQUIRE( accu(2*A+3*A) == Approx( 1.200680) ); - REQUIRE( accu(fliplr(A)) == Approx( 0.240136) ); - REQUIRE( accu(flipud(A)) == Approx( 0.240136) ); - REQUIRE( accu(A.col(1)) == Approx( 0.212265) ); - REQUIRE( accu(A.row(1)) == Approx( 0.632961) ); - REQUIRE( accu(2*A.col(1)) == Approx( 0.424530) ); - REQUIRE( accu(2*A.row(1)) == Approx( 1.265922) ); - - REQUIRE( accu(A%A) == Approx(2.834218657806) ); - REQUIRE( accu(A*A.t()) == Approx(1.218704694166) ); - REQUIRE( accu(A.t()*A) == Approx(2.585464740700) ); - - REQUIRE( accu(vectorise(A)) == Approx(0.240136) ); - - REQUIRE( accu( A(span(1,3), span(1,4)) ) == Approx(1.273017) ); - REQUIRE( accu( 2*A(span(1,3), span(1,4)) ) == Approx(2.546034) ); - - REQUIRE_THROWS( accu(A*A) ); - } - - - -TEST_CASE("fn_accu_2") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - cx_mat C = cx_mat(A, 2*fliplr(A)); - cx_mat D = cx_mat(2*fliplr(A), A); - - REQUIRE( abs(accu(C) - cx_double(0.240136, +0.480272)) == Approx(0.0) ); - - REQUIRE( abs(accu(cx_double(2,3)*C) - cx_double(-0.960544000000001, +1.680951999999999)) == Approx(0.0) ); - - REQUIRE( abs(accu(C*D.t() ) - cx_double(-0.710872588088, +3.656114082498002)) == Approx(0.0) ); - REQUIRE( abs(accu(C*D.st()) - cx_double(0.0, +6.093523470830000)) == Approx(0.0) ); - - REQUIRE( abs(accu(C.t() *D) - cx_double(10.341858962800, -7.756394222100000)) == Approx(0.0) ); - REQUIRE( abs(accu(C.st()*D) - cx_double(0.0, +1.29273237035e+01)) == Approx(0.0) ); - } - - - -TEST_CASE("fn_accu_3") - { - vec a = linspace(1,5,5); - vec b = linspace(1,5,6); - vec c = -linspace(1,5,6); - - REQUIRE(accu(a) == Approx( 15.0)); - REQUIRE(accu(b) == Approx( 18.0)); - REQUIRE(accu(c) == Approx(-18.0)); - } - - - -TEST_CASE("fn_accu_4") - { - mat A(5,6); A.fill(2.0); - mat B(5,6); B.fill(4.0); - mat C(6,5); C.fill(6.0); - - REQUIRE( accu(A + B) == Approx(double((2+4)*(A.n_rows*A.n_cols))) ); - REQUIRE( accu(A(span::all,span::all) + B(span::all,span::all)) == Approx(double((2+4)*(A.n_rows*A.n_cols))) ); - - REQUIRE( accu(A % B) == Approx(double((2*4)*(A.n_rows*A.n_cols))) ); - REQUIRE( accu(A(span::all,span::all) % B(span::all,span::all)) == Approx(double((2*4)*(A.n_rows*A.n_cols))) ); - - // A and C matrices are non-conformat, so accu() will throw unless ARMA_NO_DEBUG is defined - REQUIRE_THROWS( accu(A % C) ); - REQUIRE_THROWS( accu(A(span::all,span::all) % C(span::all,span::all)) ); - } - - - -TEST_CASE("fn_accu_spmat") - { - SpMat b(4, 4); - b(0, 1) = 6; - b(1, 3) = 15; - b(3, 1) = 14; - b(2, 0) = 5; - b(3, 3) = 12; - - REQUIRE( accu(b) == 52 ); - REQUIRE( accu(b.submat(1, 1, 3, 3)) == 41 ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_all.cpp armadillo-10.8.2+dfsg/tests/fn_all.cpp --- armadillo-9.800.4+dfsg/tests/fn_all.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_all.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_all_1") - { - vec a(5, fill::zeros); - vec b(5, fill::zeros); b(0) = 1.0; - vec c(5, fill::ones ); - - REQUIRE( all(a) == false); - REQUIRE( all(b) == false); - REQUIRE( all(c) == true ); - - REQUIRE( all(a(span::all)) == false); - REQUIRE( all(b(span::all)) == false); - REQUIRE( all(c(span::all)) == true ); - - REQUIRE( all( c - c) == false); - REQUIRE( all(2*c -2*c) == false); - - REQUIRE( all(c < 0.5) == false); - REQUIRE( all(c > 0.5) == true ); - } - - - -TEST_CASE("fn_all_2") - { - mat A(5, 6, fill::zeros); - mat B(5, 6, fill::zeros); B(0,0) = 1.0; - mat C(5, 6, fill::ones ); - - REQUIRE( all(vectorise(A)) == false); - REQUIRE( all(vectorise(B)) == false); - REQUIRE( all(vectorise(C)) == true ); - - REQUIRE( all(vectorise(A(span::all,span::all))) == false); - REQUIRE( all(vectorise(B(span::all,span::all))) == false); - REQUIRE( all(vectorise(C(span::all,span::all))) == true ); - - - REQUIRE( all(vectorise( C - C)) == false); - REQUIRE( all(vectorise(2*C -2*C)) == false); - - REQUIRE( all(vectorise(C) < 0.5) == false); - REQUIRE( all(vectorise(C) > 0.5) == true ); - } - - - -TEST_CASE("fn_all_3") - { - mat A(5, 6, fill::zeros); - mat B(5, 6, fill::zeros); B(0,0) = 1.0; - mat C(5, 6, fill::ones ); - mat D(5, 6, fill::ones ); D(0,0) = 0.0; - - REQUIRE( accu( all(A) == urowvec({0, 0, 0, 0, 0, 0}) ) == 6 ); - REQUIRE( accu( all(A,0) == urowvec({0, 0, 0, 0, 0, 0}) ) == 6 ); - REQUIRE( accu( all(A,1) == uvec ({0, 0, 0, 0, 0} ) ) == 5 ); - - REQUIRE( accu( all(B) == urowvec({0, 0, 0, 0, 0, 0}) ) == 6 ); - REQUIRE( accu( all(B,0) == urowvec({0, 0, 0, 0, 0, 0}) ) == 6 ); - REQUIRE( accu( all(B,1) == uvec ({0, 0, 0, 0, 0} ) ) == 5 ); - - REQUIRE( accu( all(C) == urowvec({1, 1, 1, 1, 1, 1}) ) == 6 ); - REQUIRE( accu( all(C,0) == urowvec({1, 1, 1, 1, 1, 1}) ) == 6 ); - REQUIRE( accu( all(C,1) == uvec ({1, 1, 1, 1, 1} ) ) == 5 ); - - REQUIRE( accu( all(D) == urowvec({0, 1, 1, 1, 1, 1}) ) == 6 ); - REQUIRE( accu( all(D,0) == urowvec({0, 1, 1, 1, 1, 1}) ) == 6 ); - REQUIRE( accu( all(D,1) == uvec ({0, 1, 1, 1, 1} ) ) == 5 ); - } - - diff -Nru armadillo-9.800.4+dfsg/tests/fn_any.cpp armadillo-10.8.2+dfsg/tests/fn_any.cpp --- armadillo-9.800.4+dfsg/tests/fn_any.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_any.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_any_1") - { - vec a(5, fill::zeros); - vec b(5, fill::zeros); b(0) = 1.0; - vec c(5, fill::ones ); - - REQUIRE( any(a) == false); - REQUIRE( any(b) == true ); - REQUIRE( any(c) == true ); - - REQUIRE( any(a(span::all)) == false); - REQUIRE( any(b(span::all)) == true ); - REQUIRE( any(c(span::all)) == true ); - - REQUIRE( any( c - c) == false); - REQUIRE( any(2*c -2*c) == false); - - REQUIRE( any(c < 0.5) == false); - REQUIRE( any(c > 0.5) == true ); - } - - - -TEST_CASE("fn_any_2") - { - mat A(5, 6, fill::zeros); - mat B(5, 6, fill::zeros); B(0,0) = 1.0; - mat C(5, 6, fill::ones ); - - REQUIRE( any(vectorise(A)) == false); - REQUIRE( any(vectorise(B)) == true ); - REQUIRE( any(vectorise(C)) == true ); - - REQUIRE( any(vectorise(A(span::all,span::all))) == false); - REQUIRE( any(vectorise(B(span::all,span::all))) == true ); - REQUIRE( any(vectorise(C(span::all,span::all))) == true ); - - - REQUIRE( any(vectorise( C - C)) == false); - REQUIRE( any(vectorise(2*C -2*C)) == false); - - REQUIRE( any(vectorise(C) < 0.5) == false); - REQUIRE( any(vectorise(C) > 0.5) == true ); - } - - - -TEST_CASE("fn_any_3") - { - mat A(5, 6, fill::zeros); - mat B(5, 6, fill::zeros); B(0,0) = 1.0; - mat C(5, 6, fill::ones ); - mat D(5, 6, fill::ones ); D(0,0) = 0.0; - - REQUIRE( accu( any(A) == urowvec({0, 0, 0, 0, 0, 0}) ) == 6 ); - REQUIRE( accu( any(A,0) == urowvec({0, 0, 0, 0, 0, 0}) ) == 6 ); - REQUIRE( accu( any(A,1) == uvec ({0, 0, 0, 0, 0} ) ) == 5 ); - - REQUIRE( accu( any(B) == urowvec({1, 0, 0, 0, 0, 0}) ) == 6 ); - REQUIRE( accu( any(B,0) == urowvec({1, 0, 0, 0, 0, 0}) ) == 6 ); - REQUIRE( accu( any(B,1) == uvec ({1, 0, 0, 0, 0} ) ) == 5 ); - - REQUIRE( accu( any(C) == urowvec({1, 1, 1, 1, 1, 1}) ) == 6 ); - REQUIRE( accu( any(C,0) == urowvec({1, 1, 1, 1, 1, 1}) ) == 6 ); - REQUIRE( accu( any(C,1) == uvec ({1, 1, 1, 1, 1} ) ) == 5 ); - - REQUIRE( accu( any(D) == urowvec({1, 1, 1, 1, 1, 1}) ) == 6 ); - REQUIRE( accu( any(D,0) == urowvec({1, 1, 1, 1, 1, 1}) ) == 6 ); - REQUIRE( accu( any(D,1) == uvec ({1, 1, 1, 1, 1} ) ) == 5 ); - } - - diff -Nru armadillo-9.800.4+dfsg/tests/fn_as_scalar.cpp armadillo-10.8.2+dfsg/tests/fn_as_scalar.cpp --- armadillo-9.800.4+dfsg/tests/fn_as_scalar.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_as_scalar.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_as_scalar_1") - { - mat A(1,1); A.fill(2.0); - mat B(2,2); B.fill(2.0); - - REQUIRE( as_scalar(A) == Approx(2.0) ); - - REQUIRE( as_scalar(2+A) == Approx(4.0) ); - - REQUIRE( as_scalar(B(span(0,0), span(0,0))) == Approx(2.0) ); - - REQUIRE_THROWS( as_scalar(B) ); - } - - - -TEST_CASE("fn_as_scalar_2") - { - rowvec r = linspace(1,5,6); - colvec q = linspace(1,5,6); - mat X = 0.5*toeplitz(q); - - REQUIRE( as_scalar(r*q) == Approx(65.2) ); - - REQUIRE( as_scalar(r*X*q) == Approx(380.848) ); - - REQUIRE( as_scalar(r*diagmat(X)*q) == Approx(32.6) ); - REQUIRE( as_scalar(r*inv(diagmat(X))*q) == Approx(130.4) ); - } - - - -TEST_CASE("fn_as_scalar_3") - { - cube A(1,1,1); A.fill(2.0); - cube B(2,2,2); B.fill(2.0); - - REQUIRE( as_scalar(A) == Approx(2.0) ); - - REQUIRE( as_scalar(2+A) == Approx(4.0) ); - - REQUIRE( as_scalar(B(span(0,0), span(0,0), span(0,0))) == Approx(2.0) ); - - REQUIRE_THROWS( as_scalar(B) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_clamp.cpp armadillo-10.8.2+dfsg/tests/fn_clamp.cpp --- armadillo-9.800.4+dfsg/tests/fn_clamp.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_clamp.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_clamp_1") - { - mat A = randu(5,6); - - mat B = clamp(A, 0.2, 0.8); - REQUIRE( B.min() == Approx(0.2) ); - REQUIRE( B.max() == Approx(0.8) ); - - mat C = clamp(A, A.min(), 0.8); - REQUIRE( C.min() == A.min() ); - REQUIRE( C.max() == Approx(0.8) ); - - mat D = clamp(A, 0.2, A.max()); - REQUIRE( D.min() == Approx(0.2) ); - REQUIRE( D.max() == A.max() ); - - REQUIRE_THROWS( clamp(A, A.max(), A.min() ) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_cond.cpp armadillo-10.8.2+dfsg/tests/fn_cond.cpp --- armadillo-9.800.4+dfsg/tests/fn_cond.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_cond.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_cond_1") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - REQUIRE( cond(A) == Approx(1.7455) ); - REQUIRE( cond(A(span::all,span::all)) == Approx(1.7455) ); - } - - - -TEST_CASE("fn_cond_2") - { - mat A = zeros(5,6); - - REQUIRE( is_finite(cond(A)) == false ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_conj.cpp armadillo-10.8.2+dfsg/tests/fn_conj.cpp --- armadillo-9.800.4+dfsg/tests/fn_conj.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_conj.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_conj_1") - { - vec re = linspace(1,5,6); - vec im = 2*linspace(1,5,6); - - cx_vec a = cx_vec(re,im); - cx_vec b = conj(a); - - REQUIRE( accu(abs(real(b) - ( re))) == Approx(0.0) ); - REQUIRE( accu(abs(imag(b) - (-im))) == Approx(0.0) ); - } - - - -TEST_CASE("fn_conj2") - { - cx_mat A = randu(5,6); - - cx_mat B = conj(A); - - REQUIRE( all(vectorise(real(B) == real(A))) == true ); - REQUIRE( all(vectorise(imag(B) == -imag(A))) == true ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_conv.cpp armadillo-10.8.2+dfsg/tests/fn_conv.cpp --- armadillo-9.800.4+dfsg/tests/fn_conv.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_conv.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_conv_1") - { - vec a = linspace(1,5,6); - vec b = 2*linspace(1,6,7); - - vec c = conv(a,b); - vec d = - { - 2.00000000000000, - 7.26666666666667, - 17.13333333333333, - 32.93333333333334, - 56.00000000000000, - 87.66666666666667, - 117.66666666666666, - 134.00000000000003, - 137.73333333333335, - 127.53333333333336, - 102.06666666666668, - 60.00000000000000 - }; - - REQUIRE( accu(abs(c - d)) == Approx(0.0) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_conv_to.cpp armadillo-10.8.2+dfsg/tests/fn_conv_to.cpp --- armadillo-9.800.4+dfsg/tests/fn_conv_to.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_conv_to.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_conv_to_1") - { - typedef std::vector stdvec; - - stdvec x(3); - x[0] = 10.0; x[1] = 20.0; x[2] = 30.0; - - colvec y = conv_to< colvec >::from(x); - stdvec z = conv_to< stdvec >::from(y); - - REQUIRE( z[0] == Approx(10.0) ); - REQUIRE( z[1] == Approx(20.0) ); - REQUIRE( z[2] == Approx(30.0) ); - } - - - -TEST_CASE("fn_conv_to2") - { - mat A(5,6); A.fill(0.1); - - umat uA = conv_to::from(A); - imat iA = conv_to::from(A); - - REQUIRE( (uA.n_rows - A.n_rows) == 0 ); - REQUIRE( (iA.n_rows - A.n_rows) == 0 ); - - REQUIRE( (uA.n_cols - A.n_cols) == 0 ); - REQUIRE( (iA.n_cols - A.n_cols) == 0 ); - - REQUIRE( any(vectorise(uA)) == false); - REQUIRE( any(vectorise(iA)) == false); - } - - -TEST_CASE("fn_conv_to3") - { - mat A(5,6); A.fill(1.0); - - umat uA = conv_to::from(A); - imat iA = conv_to::from(A); - - REQUIRE( all(vectorise(uA)) == true); - REQUIRE( all(vectorise(iA)) == true); - } - - -TEST_CASE("fn_conv_to4") - { - mat A = linspace(1,5,6); - mat B = 2*linspace(1,5,6); - mat C = randu(5,6); - - REQUIRE( as_scalar( conv_to::from(A) * conv_to::from(B) ) == Approx(130.40) ); - - REQUIRE( conv_to::from(A * B) == Approx(130.40) ); - - REQUIRE_THROWS( conv_to::from(C) ); - } - - diff -Nru armadillo-9.800.4+dfsg/tests/fn_cor.cpp armadillo-10.8.2+dfsg/tests/fn_cor.cpp --- armadillo-9.800.4+dfsg/tests/fn_cor.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_cor.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_cor_1") - { - vec a = linspace(1,5,6); - vec b = 0.5*linspace(1,5,6); - vec c = flipud(b); - - REQUIRE( as_scalar(cor(a,b) - (+1.0)) == Approx(0.0) ); - REQUIRE( as_scalar(cor(a,c) - (-1.0)) == Approx(0.0) ); - } - - - -TEST_CASE("fn_cor_2") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - mat B = 0.5 * A; - - mat C = fliplr(B); - - mat AA = - "\ - 1.00000 -0.54561 -0.28838 -0.99459;\ - -0.54561 1.00000 -0.64509 0.45559;\ - -0.28838 -0.64509 1.00000 0.38630;\ - -0.99459 0.45559 0.38630 1.00000;\ - "; - - mat AB = - "\ - 1.00000 -0.54561 -0.28838 -0.99459;\ - -0.54561 1.00000 -0.64509 0.45559;\ - -0.28838 -0.64509 1.00000 0.38630;\ - -0.99459 0.45559 0.38630 1.00000;\ - "; - - mat AC = - "\ - -0.99459 -0.28838 -0.54561 1.00000;\ - 0.45559 -0.64509 1.00000 -0.54561;\ - 0.38630 1.00000 -0.64509 -0.28838;\ - 1.00000 0.38630 0.45559 -0.99459;\ - "; - - REQUIRE( accu(abs(cor(A) - AA)) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs(cor(A,B) - AA)) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs(cor(A,C) - AC)) == Approx(0.0).epsilon(0.0001) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_cov.cpp armadillo-10.8.2+dfsg/tests/fn_cov.cpp --- armadillo-9.800.4+dfsg/tests/fn_cov.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_cov.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_cov_1") - { - vec a = linspace(1,5,6); - vec b = 0.5*linspace(1,5,6); - vec c = flipud(b); - - REQUIRE( as_scalar(cov(a,b) - (+1.12)) == Approx(0.0) ); - REQUIRE( as_scalar(cov(a,c) - (-1.12)) == Approx(0.0) ); - } - - - -TEST_CASE("fn_cov_2") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - mat B = 0.5 * A; - - mat C = fliplr(B); - - mat AA = - "\ - 0.670783 -0.191509 -0.120822 -0.211274;\ - -0.191509 0.183669 -0.141426 0.050641;\ - -0.120822 -0.141426 0.261684 0.051254;\ - -0.211274 0.050641 0.051254 0.067270;\ - "; - - mat AB = - "\ - 0.335392 -0.095755 -0.060411 -0.105637;\ - -0.095755 0.091834 -0.070713 0.025320;\ - -0.060411 -0.070713 0.130842 0.025627;\ - -0.105637 0.025320 0.025627 0.033635;\ - "; - - mat AC = - "\ - -0.105637 -0.060411 -0.095755 0.335392;\ - 0.025320 -0.070713 0.091834 -0.095755;\ - 0.025627 0.130842 -0.070713 -0.060411;\ - 0.033635 0.025627 0.025320 -0.105637;\ - "; - - REQUIRE( accu(abs(cov(A) - AA)) == Approx(0.0) ); - REQUIRE( accu(abs(cov(A,B) - AB)) == Approx(0.0) ); - REQUIRE( accu(abs(cov(A,C) - AC)) == Approx(0.0) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_cross.cpp armadillo-10.8.2+dfsg/tests/fn_cross.cpp --- armadillo-9.800.4+dfsg/tests/fn_cross.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_cross.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_cross_1") - { - vec a = { 0.1, 2.3, 4.5 }; - vec b = { 6.7, 8.9, 10.0 }; - - vec c = {-17.050, 29.150, -14.520 }; - - REQUIRE( accu(abs(cross(a,b) - c)) == Approx(0.0) ); - - vec x; - - REQUIRE_THROWS( x = cross(randu(4), randu(4)) ); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/fn_cumprod.cpp armadillo-10.8.2+dfsg/tests/fn_cumprod.cpp --- armadillo-9.800.4+dfsg/tests/fn_cumprod.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_cumprod.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_cumprod_1") - { - colvec a = linspace(1,5,6); - rowvec b = linspace(1,5,6); - - colvec c = { 1.0000, 1.8000, 4.6800, 15.9120, 66.8304, 334.1520 }; - - REQUIRE( accu(abs(cumprod(a) - c )) == Approx(0.0) ); - REQUIRE( accu(abs(cumprod(b) - c.t())) == Approx(0.0) ); - - REQUIRE_THROWS( b = cumprod(a) ); - } - - - -TEST_CASE("fn_cumprod_2") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - mat B = - { - { -0.788380, 0.692980, 0.410840, 0.901420 }, - { -0.389026, -0.083296, 0.324510, 0.478870 }, - { -0.286218, -0.043401, -0.072246, 0.192329 } - - }; - - mat C = - { - { -0.788380, -0.546332, -0.224455, -0.202328 }, - { 0.493450, -0.059313, -0.046849, -0.024888 }, - { 0.735730, 0.383345, -0.085344, -0.034277 } - }; - - REQUIRE( accu(abs(cumprod(A) - B)) == Approx(0.0) ); - REQUIRE( accu(abs(cumprod(A,0) - B)) == Approx(0.0) ); - REQUIRE( accu(abs(cumprod(A,1) - C)) == Approx(0.0) ); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/fn_cumsum.cpp armadillo-10.8.2+dfsg/tests/fn_cumsum.cpp --- armadillo-9.800.4+dfsg/tests/fn_cumsum.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_cumsum.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_cumsum_1") - { - colvec a = linspace(1,5,6); - rowvec b = linspace(1,5,6); - - colvec c = { 1.0000, 2.8000, 5.4000, 8.8000, 13.0000, 18.0000 }; - - REQUIRE( accu(abs(cumsum(a) - c )) == Approx(0.0) ); - REQUIRE( accu(abs(cumsum(b) - c.t())) == Approx(0.0) ); - - REQUIRE_THROWS( b = cumsum(a) ); - } - - - -TEST_CASE("fn_cumsum_2") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - mat B = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { -0.29493, 0.57278, 1.20071, 1.43266 }, - { 0.44080, 1.09382, 0.97808, 1.83429 } - }; - - mat C = - { - {-0.78838, -0.09540, 0.31544, 1.21686 }, - { 0.49345, 0.37325, 1.16312, 1.69436 }, - { 0.73573, 1.25677, 1.03414, 1.43577 } - }; - - REQUIRE( accu(abs(cumsum(A) - B)) == Approx(0.0) ); - REQUIRE( accu(abs(cumsum(A,0) - B)) == Approx(0.0) ); - REQUIRE( accu(abs(cumsum(A,1) - C)) == Approx(0.0) ); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/fn_det.cpp armadillo-10.8.2+dfsg/tests/fn_det.cpp --- armadillo-9.800.4+dfsg/tests/fn_det.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_det.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_det_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - REQUIRE( det(A(0,0,size(0,0))) == Approx(+1.0 ) ); - REQUIRE( det(A(0,0,size(1,1))) == Approx(+0.0611980000000000) ); - REQUIRE( det(A(0,0,size(2,2))) == Approx(-0.0847105222920000) ); - REQUIRE( det(A(0,0,size(3,3))) == Approx(-0.0117387923199772) ); - REQUIRE( det(A(0,0,size(4,4))) == Approx(+0.0126070917169865) ); - REQUIRE( det(A(0,0,size(5,5))) == Approx(+0.0100409091117668) ); - - REQUIRE_THROWS( det(A) ); - } - - - -TEST_CASE("fn_det_2") - { - mat A = toeplitz(linspace(1,5,6)); - - REQUIRE( det(A) == Approx(-31.45728) ); - - - mat B(6, 6, fill::zeros); B.diag() = linspace(1,5,6); - - REQUIRE( det(B) == Approx(334.152) ); - - REQUIRE( det(diagmat(B)) == Approx(334.152) ); - - - mat C(5,6, fill::randu); - - REQUIRE_THROWS( det(C) ); - - REQUIRE_THROWS( det(diagmat(C)) ); - } - - -TEST_CASE("fn_det_3") - { - mat A = toeplitz(linspace(1,5,6)); - - double val; - double sign; - - log_det(val, sign, A); - - REQUIRE( val == Approx(3.44863) ); - REQUIRE( sign == Approx(-1.0) ); - - REQUIRE( (std::exp(val)*sign) == Approx( det(A) ) ); - - mat B(5,6, fill::randu); - - REQUIRE_THROWS( log_det(val, sign, B) ); - } - diff -Nru armadillo-9.800.4+dfsg/tests/fn_diagmat.cpp armadillo-10.8.2+dfsg/tests/fn_diagmat.cpp --- armadillo-9.800.4+dfsg/tests/fn_diagmat.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_diagmat.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,141 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_diagmat_1") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - mat Ap1 = - { - { -0.0 , 0.69298, 0.0 , 0.0 }, - { 0.0 , 0.0 , 0.78987, 0.0 }, - { 0.0 , 0.0 , 0.0 , 0.40163 } - }; - - mat Amain = - { - { -0.78838, 0.0 , 0.0 , 0.0 }, - { 0.0 , -0.12020, 0.0 , 0.0 }, - { 0.0 , 0.0 , -0.22263, 0.0 } - }; - - mat Am1 = - { - { 0.0 , 0.0 , 0.0 , 0.0 }, - { 0.49345, 0.0 , 0.0 , 0.0 }, - { 0.0 , 0.52104, 0.0 , 0.0 } - }; - - - REQUIRE( accu(abs(diagmat(A ) - Amain)) == Approx(0.0 ) ); - REQUIRE( accu(abs(diagmat(A, 0) - Amain)) == Approx(0.0 ) ); - - REQUIRE( accu(abs(diagmat(A, 1) - Ap1 )) == Approx(0.0 ) ); - REQUIRE( accu(abs(diagmat(A,-1) - Am1 )) == Approx(0.0 ) ); - } - - - -TEST_CASE("fn_diagmat_2") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - vec dp1 = { 0.69298, 0.78987, 0.40163 }; - vec dmain = { -0.78838, -0.12020, -0.22263 }; - vec dm1 = { 0.49345, 0.52104 }; - - mat Ap1 (size(A),fill::zeros); Ap1.diag( 1) = dp1; - mat Amain(size(A),fill::zeros); Amain.diag( ) = dmain; - mat Am1 (size(A),fill::zeros); Am1.diag(-1) = dm1; - - REQUIRE( accu(abs(diagmat(A ) - Amain)) == Approx(0.0) ); - REQUIRE( accu(abs(diagmat(A, 0) - Amain)) == Approx(0.0) ); - - REQUIRE( accu(abs(diagmat(A, 1) - Ap1)) == Approx(0.0) ); - REQUIRE( accu(abs(diagmat(A,-1) - Am1)) == Approx(0.0) ); - } - - - -TEST_CASE("fn_diagmat_3") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - mat B = - "\ - 0.171180 0.106848 0.490557 -0.079866;\ - 0.073839 -0.428277 -0.049842 0.398193;\ - -0.030523 0.366160 0.260348 -0.412238;\ - "; - - mat Asub = A(span::all,span(0,2)); - mat At = A.t(); - - mat Bsub = B(span::all,span(0,2)); - mat Bt = B.t(); - - mat Asubdiagmat_times_Bsubdiagmat = - "\ - -0.13495488840 0.00000000000 0.00000000000;\ - 0.00000000000 0.05147889540 0.00000000000;\ - 0.00000000000 0.00000000000 -0.05796127524;\ - "; - - mat Bsub_times_Adiagmat = - "\ - -0.13495488840 -0.01284312960 -0.10921270491 0.00000000000;\ - -0.05821319082 0.05147889540 0.01109632446 0.00000000000;\ - 0.02406372274 -0.04401243200 -0.05796127524 0.00000000000;\ - "; - - mat Adiagmat_times_Bt = - "\ - -0.134955 -0.058213 0.024064;\ - -0.012843 0.051479 -0.044012;\ - -0.109213 0.011096 -0.057961;\ - "; - - REQUIRE( accu(abs((diagmat(Asub) * diagmat(Bsub)) - Asubdiagmat_times_Bsubdiagmat)) == Approx(0.0) ); - - REQUIRE( accu(abs((Bsub * diagmat(A)) - Bsub_times_Adiagmat)) == Approx(0.0) ); - REQUIRE( accu(abs((B(span::all, span(0,2)) * diagmat(A)) - Bsub_times_Adiagmat)) == Approx(0.0) ); - - REQUIRE( accu(abs((diagmat(A) * Bt ) - Adiagmat_times_Bt )) == Approx(0.0) ); - REQUIRE( accu(abs((diagmat(A) * B.t() ) - Adiagmat_times_Bt )) == Approx(0.0) ); - - // TODO: Asub and At - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_diagvec.cpp armadillo-10.8.2+dfsg/tests/fn_diagvec.cpp --- armadillo-9.800.4+dfsg/tests/fn_diagvec.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_diagvec.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_diagvec_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - vec A_main1 = diagvec(A); - vec A_main2 = diagvec(A,0); - - vec A_p1 = diagvec(A, 1); - vec A_m1 = diagvec(A,-1); - - vec a = - { - 0.061198, - 0.058956, - 0.314156, - -0.393139, - -0.353768 - }; - - vec b = - { - 0.20199, - -0.14936, - 0.41973, - -0.13504 - }; - - vec c = - { - 0.437242, - -0.031309, - 0.458476, - -0.291020 - }; - - REQUIRE( accu(abs(A_main1 - a)) == Approx(0.0) ); - REQUIRE( accu(abs(A_main2 - a)) == Approx(0.0) ); - - REQUIRE( accu(abs(A_p1 - b)) == Approx(0.0) ); - REQUIRE( accu(abs(A_m1 - c)) == Approx(0.0) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_diff.cpp armadillo-10.8.2+dfsg/tests/fn_diff.cpp --- armadillo-9.800.4+dfsg/tests/fn_diff.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_diff.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_diff_1") - { - colvec a = square( linspace(1,5,6) ); - rowvec b = square( linspace(1,5,5) ); - - colvec a_diff_1 = { 2.2400, 3.5200, 4.8000, 6.0800, 7.3600 }; - colvec a_diff_2 = { 1.2800, 1.2800, 1.2800, 1.2800 }; - colvec a_diff_9; - - rowvec b_diff_1 = { 3, 5, 7, 9 }; - rowvec b_diff_2 = { 2, 2, 2 }; - rowvec b_diff_9; - - REQUIRE( accu(abs(diff(a,0) - a )) == Approx(0.0) ); - REQUIRE( accu(abs(diff(a ) - a_diff_1)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(a,1) - a_diff_1)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(a,2) - a_diff_2)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(a,9) - a_diff_9)) == Approx(0.0) ); - - REQUIRE( accu(abs(diff(b,0) - b )) == Approx(0.0) ); - REQUIRE( accu(abs(diff(b ) - b_diff_1)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(b,1) - b_diff_1)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(b,2) - b_diff_2)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(b,9) - b_diff_9)) == Approx(0.0) ); - } - - - -TEST_CASE("fn_diff_2") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - mat A_diff1_0 = - "\ - 0.376044 -0.143034 -0.169040 0.448471 0.422898;\ - -0.929716 -0.090265 0.463518 0.465198 -0.227836;\ - 0.828826 0.442850 0.144320 -0.812872 -0.203357;\ - -0.096767 -0.840454 -0.865429 0.102119 -0.218728;\ - "; - - mat A_diff2_0 = - "\ - -1.305760 0.052769 0.632558 0.016727 -0.650734;\ - 1.758542 0.533115 -0.319198 -1.278070 0.024479;\ - -0.925593 -1.283304 -1.009749 0.914991 -0.015371;\ - "; - - mat A_diff3_0 = - "\ - 3.064302 0.480346 -0.951756 -1.294797 0.675213;\ - -2.684135 -1.816419 -0.690551 2.193061 -0.039850;\ - "; - - mat A_diff1_1 = - "\ - 0.140792 -0.182312 -0.513614 0.367191;\ - -0.378286 -0.208318 0.103897 0.341618;\ - 0.461165 0.345465 0.105577 -0.351416;\ - 0.075189 0.046935 -0.851615 0.258099;\ - -0.668498 0.021960 0.115933 -0.062748;\ - "; - - mat A_diff2_1 = - "\ - -0.323104 -0.331302 0.880805;\ - 0.169968 0.312215 0.237721;\ - -0.115700 -0.239888 -0.456993;\ - -0.028254 -0.898550 1.109714;\ - 0.690458 0.093973 -0.178681;\ - "; - - mat A_diff3_1 = - "\ - -0.0081980 1.2121070;\ - 0.1422470 -0.0744940;\ - -0.1241880 -0.2171050;\ - -0.8702960 2.0082640;\ - -0.5964850 -0.2726540;\ - "; - - REQUIRE( accu(abs(diff(A,0) - A )) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A ) - A_diff1_0)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,1) - A_diff1_0)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,2) - A_diff2_0)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,3) - A_diff3_0)) == Approx(0.0) ); - - REQUIRE( accu(abs(diff(A,0,0) - A )) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,1,0) - A_diff1_0)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,2,0) - A_diff2_0)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,3,0) - A_diff3_0)) == Approx(0.0) ); - - REQUIRE( accu(abs(diff(A,0,1) - A )) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,1,1) - A_diff1_1)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,2,1) - A_diff2_1)) == Approx(0.0) ); - REQUIRE( accu(abs(diff(A,3,1) - A_diff3_1)) == Approx(0.0) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_dot.cpp armadillo-10.8.2+dfsg/tests/fn_dot.cpp --- armadillo-9.800.4+dfsg/tests/fn_dot.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_dot.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_dot_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - vec a = A.head_cols(1); - vec b = A.tail_cols(1); - - rowvec c = A.head_rows(1); - rowvec d = A.tail_rows(1); - - REQUIRE( dot( a, b) == Approx(-0.04208883710200) ); - REQUIRE( dot(2*a,2+b) == Approx( 2.24343432579600) ); - - REQUIRE( dot( c, d) == Approx( 0.108601544706000) ); - REQUIRE( dot(0.5*c,2-d) == Approx(-0.392115772353000) ); - - REQUIRE( dot(a,b) == Approx( dot(A.head_cols(1), A.tail_cols(1)) ) ); - REQUIRE( dot(c,d) == Approx( dot(A.head_rows(1), A.tail_rows(1)) ) ); - } - - - -TEST_CASE("fn_dot_2") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - cx_vec a = cx_vec(A.col(0), A.col(1)); - cx_vec b = cx_vec(A.col(2), A.col(3)); - - cx_rowvec c = cx_rowvec(A.row(0), A.row(1)); - cx_rowvec d = cx_rowvec(A.row(2), A.row(3)); - - REQUIRE( abs( dot(a,b) - cx_double(-0.009544718641000, -0.110209641379000)) == Approx(0.0) ); - REQUIRE( abs( dot(c,d) - cx_double(-0.326993347830000, +0.061084261990000)) == Approx(0.0) ); - - REQUIRE( abs(cdot(a,b) - cx_double(-0.314669805873000, -0.807333974477000)) == Approx(0.0) ); - REQUIRE( abs(cdot(c,d) - cx_double(-0.165527940664000, +0.586984291846000)) == Approx(0.0) ); - } - - - -TEST_CASE("fn_dot_sp_mat_mat") - { - // Make matrices. - SpMat a("3.0 0.0 0.0; 1.0 2.0 2.0; 0.0 0.0 1.0"); - Mat b("1.0 2.0 1.0; 1.0 2.0 2.0; 3.0 4.0 5.0"); - - REQUIRE( dot(a, b) == Approx(17.0) ); - REQUIRE( dot(b, a) == Approx(17.0) ); - } - - - -TEST_CASE("fn_dot_sp_col_col") - { - SpCol a("3; 4; 0; 0; 0; 2; 0; 0"); - Col b("1 6 1 2 3 7 1 2"); - - REQUIRE( dot(a, b) == 41 ); - REQUIRE( dot(b, a) == 41 ); - } - - - -TEST_CASE("fn_dot_sp_mat_sp_mat") - { - SpMat a("3.0 0.0 0.0; 1.0 2.0 2.0; 0.0 0.0 1.0"); - SpMat b("3.0 0.0 0.0; 1.0 2.0 2.0; 0.0 0.0 1.0"); - - REQUIRE( dot(a, b) == Approx(19.0) ); - REQUIRE( dot(b, a) == Approx(19.0) ); - } - - - -TEST_CASE("fn_dot_sp_col_sp_col") - { - SpCol a("3; 4; 0; 0; 0; 2; 0; 0"); - SpCol b("0; 8; 0; 1; 1; 0; 0; 0"); - - REQUIRE( dot(a, b) == 32 ); - REQUIRE( dot(b, a) == 32 ); - } - - - -// TODO: norm_dot diff -Nru armadillo-9.800.4+dfsg/tests/fn_eigs_gen.cpp armadillo-10.8.2+dfsg/tests/fn_eigs_gen.cpp --- armadillo-9.800.4+dfsg/tests/fn_eigs_gen.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_eigs_gen.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,453 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("fn_eigs_gen_odd_test") - { - const uword n_rows = 10; - const uword n_eigval = 5; - for (size_t trial = 0; trial < 10; ++trial) - { - sp_mat m; - m.sprandu(n_rows, n_rows, 0.3); - mat d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col< std::complex > sp_eigval; - Mat< std::complex > sp_eigvec; - eigs_gen(sp_eigval, sp_eigvec, m, n_eigval); - - // Do the same for the dense case. - Col< std::complex > eigval; - Mat< std::complex > eigvec; - eig_gen(eigval, eigvec, d); - - uvec used(n_rows); - used.fill(0); - - for (size_t i = 0; i < n_eigval; ++i) - { - // Sorting these is a super bitch. - // Find which one is the likely dense eigenvalue. - uword dense_eval = n_rows + 1; - for (uword k = 0; k < n_rows; ++k) - { - if ((std::abs(std::complex(sp_eigval[i]).real() - eigval[k].real()) < 1e-4) && - (std::abs(std::complex(sp_eigval[i]).imag() - eigval[k].imag()) < 1e-4) && - (used[k] == 0)) - { - dense_eval = k; - used[k] = 1; - break; - } - } - - REQUIRE( dense_eval != n_rows + 1 ); - - REQUIRE( std::abs(sp_eigval[i]) == Approx(std::abs(eigval[dense_eval])).epsilon(0.1) ); - for (uword j = 0; j < n_rows; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == Approx(std::abs(eigvec(j, dense_eval))).epsilon(0.1) ); - } - } - } - } - - - -TEST_CASE("fn_eigs_gen_even_test") - { - const uword n_rows = 10; - const uword n_eigval = 4; - for (size_t trial = 0; trial < 10; ++trial) - { - sp_mat m; - m.sprandu(n_rows, n_rows, 0.3); - sp_mat z(5, 5); - z.sprandu(5, 5, 0.5); - m.submat(2, 2, 6, 6) += 5 * z; - mat d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col< std::complex > sp_eigval; - Mat< std::complex > sp_eigvec; - eigs_gen(sp_eigval, sp_eigvec, m, n_eigval); - - // Do the same for the dense case. - Col< std::complex > eigval; - Mat< std::complex > eigvec; - eig_gen(eigval, eigvec, d); - - uvec used(n_rows); - used.fill(0); - - for (size_t i = 0; i < n_eigval; ++i) - { - // Sorting these is a super bitch. - // Find which one is the likely dense eigenvalue. - uword dense_eval = n_rows + 1; - for (uword k = 0; k < n_rows; ++k) - { - if ((std::abs(std::complex(sp_eigval[i]).real() - eigval[k].real()) < 1e-4) && - (std::abs(std::complex(sp_eigval[i]).imag() - eigval[k].imag()) < 1e-4) && - (used[k] == 0)) - { - dense_eval = k; - used[k] = 1; - break; - } - } - - REQUIRE( dense_eval != n_rows + 1 ); - - REQUIRE( std::abs(sp_eigval[i]) == Approx(std::abs(eigval[dense_eval])).epsilon(0.01) ); - for (uword j = 0; j < n_rows; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == Approx(std::abs(eigvec(j, dense_eval))).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_eigs_gen_odd_float_test") - { - const uword n_rows = 10; - const uword n_eigval = 5; - for (size_t trial = 0; trial < 10; ++trial) - { - SpMat m; - m.sprandu(n_rows, n_rows, 0.3); - for (uword i = 0; i < n_rows; ++i) - { - m(i, i) += 5 * double(i) / double(n_rows); - } - Mat d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col< std::complex > sp_eigval; - Mat< std::complex > sp_eigvec; - eigs_gen(sp_eigval, sp_eigvec, m, n_eigval); - - // Do the same for the dense case. - Col< std::complex > eigval; - Mat< std::complex > eigvec; - eig_gen(eigval, eigvec, d); - - uvec used(n_rows); - used.fill(0); - - for (size_t i = 0; i < n_eigval; ++i) - { - // Sorting these is a super bitch. - // Find which one is the likely dense eigenvalue. - uword dense_eval = n_rows + 1; - for (uword k = 0; k < n_rows; ++k) - { - if ((std::abs(std::complex(sp_eigval[i]).real() - eigval[k].real()) < 0.001) && - (std::abs(std::complex(sp_eigval[i]).imag() - eigval[k].imag()) < 0.001) && - (used[k] == 0)) - { - dense_eval = k; - used[k] = 1; - break; - } - } - - REQUIRE( dense_eval != n_rows + 1 ); - - REQUIRE( std::abs(sp_eigval[i]) == Approx(std::abs(eigval[dense_eval])).epsilon(0.001) ); - for (uword j = 0; j < n_rows; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == Approx(std::abs(eigvec(j, dense_eval))).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_eigs_gen_even_float_test") - { - const uword n_rows = 12; - const uword n_eigval = 8; - for (size_t trial = 0; trial < 10; ++trial) - { - SpMat m; - m.sprandu(n_rows, n_rows, 0.3); - for (uword i = 0; i < n_rows; ++i) - { - m(i, i) += 5 * double(i) / double(n_rows); - } - Mat d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col< std::complex > sp_eigval; - Mat< std::complex > sp_eigvec; - eigs_gen(sp_eigval, sp_eigvec, m, n_eigval); - - // Do the same for the dense case. - Col< std::complex > eigval; - Mat< std::complex > eigvec; - eig_gen(eigval, eigvec, d); - - uvec used(n_rows); - used.fill(0); - - for (size_t i = 0; i < n_eigval; ++i) - { - // Sorting these is a super bitch. - // Find which one is the likely dense eigenvalue. - uword dense_eval = n_rows + 1; - for (uword k = 0; k < n_rows; ++k) - { - if ((std::abs(std::complex(sp_eigval[i]).real() - eigval[k].real()) < 0.001) && - (std::abs(std::complex(sp_eigval[i]).imag() - eigval[k].imag()) < 0.001) && - (used[k] == 0)) - { - dense_eval = k; - used[k] = 1; - break; - } - } - - REQUIRE( dense_eval != n_rows + 1 ); - - REQUIRE( std::abs(sp_eigval[i]) == Approx(std::abs(eigval[dense_eval])).epsilon(0.01) ); - for (uword j = 0; j < n_rows; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == Approx(std::abs(eigvec(j, dense_eval))).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_eigs_gen_odd_complex_float_test") - { - const uword n_rows = 10; - const uword n_eigval = 5; - for (size_t trial = 0; trial < 10; ++trial) - { - SpMat< std::complex > m; - m.sprandu(n_rows, n_rows, 0.3); - Mat< std::complex > d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col< std::complex > sp_eigval; - Mat< std::complex > sp_eigvec; - eigs_gen(sp_eigval, sp_eigvec, m, n_eigval); - - // Do the same for the dense case. - Col< std::complex > eigval; - Mat< std::complex > eigvec; - eig_gen(eigval, eigvec, d); - - uvec used(n_rows); - used.fill(0); - - for (size_t i = 0; i < n_eigval; ++i) - { - // Sorting these is a super bitch. - // Find which one is the likely dense eigenvalue. - uword dense_eval = n_rows + 1; - for (uword k = 0; k < n_rows; ++k) - { - if ((std::abs(std::complex(sp_eigval[i]).real() - eigval[k].real()) < 0.001) && - (std::abs(std::complex(sp_eigval[i]).imag() - eigval[k].imag()) < 0.001) && - (used[k] == 0)) - { - dense_eval = k; - used[k] = 1; - break; - } - } - - REQUIRE( dense_eval != n_rows + 1 ); - - REQUIRE( std::abs(sp_eigval[i]) == Approx(std::abs(eigval[dense_eval])).epsilon(0.01) ); - for (uword j = 0; j < n_rows; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == Approx(std::abs(eigvec(j, dense_eval))).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_eigs_gen_even_complex_float_test") - { - const uword n_rows = 12; - const uword n_eigval = 8; - for (size_t trial = 0; trial < 10; ++trial) - { - SpMat< std::complex > m; - m.sprandu(n_rows, n_rows, 0.3); - Mat< std::complex > d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col< std::complex > sp_eigval; - Mat< std::complex > sp_eigvec; - eigs_gen(sp_eigval, sp_eigvec, m, n_eigval); - - // Do the same for the dense case. - Col< std::complex > eigval; - Mat< std::complex > eigvec; - eig_gen(eigval, eigvec, d); - - uvec used(n_rows); - used.fill(0); - - for (size_t i = 0; i < n_eigval; ++i) - { - // Sorting these is a super bitch. - // Find which one is the likely dense eigenvalue. - uword dense_eval = n_rows + 1; - for (uword k = 0; k < n_rows; ++k) - { - if ((std::abs(std::complex(sp_eigval[i]).real() - eigval[k].real()) < 0.001) && - (std::abs(std::complex(sp_eigval[i]).imag() - eigval[k].imag()) < 0.001) && - (used[k] == 0)) - { - dense_eval = k; - used[k] = 1; - break; - } - } - - REQUIRE( dense_eval != n_rows + 1 ); - - REQUIRE( std::abs(sp_eigval[i]) == Approx(std::abs(eigval[dense_eval])).epsilon(0.01) ); - for (uword j = 0; j < n_rows; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == Approx(std::abs(eigvec(j, dense_eval))).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("eigs_gen_odd_complex_test") - { - const uword n_rows = 10; - const uword n_eigval = 5; - for (size_t trial = 0; trial < 10; ++trial) - { - SpMat< std::complex > m; - m.sprandu(n_rows, n_rows, 0.3); - Mat< std::complex > d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col< std::complex > sp_eigval; - Mat< std::complex > sp_eigvec; - eigs_gen(sp_eigval, sp_eigvec, m, n_eigval); - - // Do the same for the dense case. - Col< std::complex > eigval; - Mat< std::complex > eigvec; - eig_gen(eigval, eigvec, d); - - uvec used(n_rows); - used.fill(0); - - for (size_t i = 0; i < n_eigval; ++i) - { - // Sorting these is a super bitch. - // Find which one is the likely dense eigenvalue. - uword dense_eval = n_rows + 1; - for (uword k = 0; k < n_rows; ++k) - { - if ((std::abs(std::complex(sp_eigval[i]).real() - eigval[k].real()) < 1e-10) && - (std::abs(std::complex(sp_eigval[i]).imag() - eigval[k].imag()) < 1e-10) && - (used[k] == 0)) - { - dense_eval = k; - used[k] = 1; - break; - } - } - - REQUIRE( dense_eval != n_rows + 1 ); - - REQUIRE( std::abs(sp_eigval[i]) == Approx(std::abs(eigval[dense_eval])).epsilon(0.01) ); - for (size_t j = 0; j < n_rows; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == Approx(std::abs(eigvec(j, dense_eval))).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_eigs_gen_even_complex_test") - { - const uword n_rows = 15; - const uword n_eigval = 6; - for (size_t trial = 0; trial < 10; ++trial) - { - SpMat< std::complex > m; - m.sprandu(n_rows, n_rows, 0.3); - Mat< std::complex > d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col< std::complex > sp_eigval; - Mat< std::complex > sp_eigvec; - eigs_gen(sp_eigval, sp_eigvec, m, n_eigval); - - // Do the same for the dense case. - Col< std::complex > eigval; - Mat< std::complex > eigvec; - eig_gen(eigval, eigvec, d); - - uvec used(n_rows); - used.fill(0); - - for (size_t i = 0; i < n_eigval; ++i) - { - // Sorting these is a super bitch. - // Find which one is the likely dense eigenvalue. - uword dense_eval = n_rows + 1; - for (uword k = 0; k < n_rows; ++k) - { - if ((std::abs(std::complex(sp_eigval[i]).real() - eigval[k].real()) < 1e-10) && - (std::abs(std::complex(sp_eigval[i]).imag() - eigval[k].imag()) < 1e-10) && - (used[k] == 0)) - { - dense_eval = k; - used[k] = 1; - break; - } - } - - REQUIRE( dense_eval != n_rows + 1 ); - - REQUIRE( std::abs(sp_eigval[i]) == Approx(std::abs(eigval[dense_eval])).epsilon(0.01) ); - for (uword j = 0; j < n_rows; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == Approx(std::abs(eigvec(j, dense_eval))).epsilon(0.01) ); - } - } - } - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_eigs_sym.cpp armadillo-10.8.2+dfsg/tests/fn_eigs_sym.cpp --- armadillo-9.800.4+dfsg/tests/fn_eigs_sym.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_eigs_sym.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("fn_eigs_test") - { - for (size_t trial = 0; trial < 10; ++trial) - { - // Test ARPACK decomposition of sparse matrices. - sp_mat m(1000, 1000); - sp_vec dd; - for (size_t i = 0; i < 10; ++i) - { - dd.sprandu(1000, 1, 0.15); - double eig = rand(); - m += eig * dd * dd.t(); - } - mat d(m); - - // Eigendecompose, getting first 5 eigenvectors. - vec sp_eigval; - mat sp_eigvec; - eigs_sym(sp_eigval, sp_eigvec, m, 5); - - // Do the same for the dense case. - vec eigval; - mat eigvec; - eig_sym(eigval, eigvec, d); - - for (uword i = 0; i < 5; ++i) - { - // It may be pointed the wrong direction. - REQUIRE( sp_eigval[i] == Approx(eigval[i + 995]).epsilon(0.01) ); - - for (uword j = 0; j < 1000; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == - Approx(std::abs(eigvec(j, i + 995))).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_eigs_float_test") - { - for (size_t trial = 0; trial < 10; ++trial) - { - // Test ARPACK decomposition of sparse matrices. - SpMat m(100, 100); - SpCol dd; - for (size_t i = 0; i < 10; ++i) - { - dd.sprandu(100, 1, 0.15); - float eig = rand(); - m += 0.000001 * eig * dd * dd.t(); - } - Mat d(m); - - // Eigendecompose, getting first 5 eigenvectors. - Col sp_eigval; - Mat sp_eigvec; - eigs_sym(sp_eigval, sp_eigvec, m, 5); - - // Do the same for the dense case. - Col eigval; - Mat eigvec; - eig_sym(eigval, eigvec, d); - - for (uword i = 0; i < 5; ++i) - { - // It may be pointed the wrong direction. - REQUIRE( sp_eigval[i] == Approx(eigval[i + 95]).epsilon(0.01) ); - - for (uword j = 0; j < 100; ++j) - { - REQUIRE(std::abs(sp_eigvec(j, i)) == - Approx(std::abs(eigvec(j, i + 95))).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_eigs_sm_test") - { - for (size_t trial = 0; trial < 10; ++trial) - { - // Test ARPACK decomposition of sparse matrices. - sp_mat m(100, 100); - sp_vec dd; - for (uword i = 0; i < 100; ++i) - { - m(i, i) = i + 10; - } - mat d(m); - - // Eigendecompose, getting first 5 eigenvectors. - vec sp_eigval; - mat sp_eigvec; - eigs_sym(sp_eigval, sp_eigvec, m, 5, "sm"); - - // Do the same for the dense case. - vec eigval; - mat eigvec; - eig_sym(eigval, eigvec, d); - - for (size_t i = 0; i < 5; ++i) - { - // It may be pointed the wrong direction. - REQUIRE( sp_eigval[i] == Approx(eigval[i]).epsilon(0.01) ); - - for (size_t j = 0; j < 100; ++j) - { - REQUIRE( std::abs(sp_eigvec(j, i)) == - Approx(std::abs(eigvec(j, i))).epsilon(0.01) ); - } - } - } - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_eps.cpp armadillo-10.8.2+dfsg/tests/fn_eps.cpp --- armadillo-9.800.4+dfsg/tests/fn_eps.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_eps.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_eps_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - // NOTE: this may not be portable, - // due to minor differences in representations of floating numbers between architectures - - mat B = - "\ - 6.93889390390723e-18 2.77555756156289e-17 3.46944695195361e-18 5.55111512312578e-17 2.77555756156289e-17;\ - 5.55111512312578e-17 6.93889390390723e-18 2.77555756156289e-17 6.93889390390723e-18 5.55111512312578e-17;\ - 5.55111512312578e-17 6.93889390390723e-18 5.55111512312578e-17 5.55111512312578e-17 1.38777878078145e-17;\ - 5.55111512312578e-17 5.55111512312578e-17 5.55111512312578e-17 5.55111512312578e-17 2.77555756156289e-17;\ - 2.77555756156289e-17 5.55111512312578e-17 5.55111512312578e-17 5.55111512312578e-17 5.55111512312578e-17;\ - "; - - REQUIRE( accu(abs(eps(A) - B)) == Approx(0.0) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_expmat.cpp armadillo-10.8.2+dfsg/tests/fn_expmat.cpp --- armadillo-9.800.4+dfsg/tests/fn_expmat.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_expmat.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_expmat_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - mat B = - "\ - 1.02538869823674172 0.13790240598460396 -0.08367367160987488 -0.41792875395466716 -0.06290741731634941;\ - 0.51916795070543009 1.02637747615061659 -0.27092263726001209 -0.22015456965211999 0.22949488377909516;\ - -0.52324535450897358 -0.00364605079279409 1.47390226507168753 0.52746339141825938 0.06773886386884656;\ - 0.25814904446999026 0.39201997396696092 0.44019950493687843 0.69739553609450822 -0.04345234429697794;\ - 0.16726671762680370 -0.40082334719624046 -0.43832065342010318 -0.30675328534305307 0.64261934864584291;\ - "; - - REQUIRE( accu(abs(expmat(A) - B)) == Approx(0.0) ); - - mat X; - - REQUIRE_THROWS( X = expmat(A(span(0,3),span::all)) ); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/fn_find.cpp armadillo-10.8.2+dfsg/tests/fn_find.cpp --- armadillo-9.800.4+dfsg/tests/fn_find.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_find.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_find_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - A(2,2) = 0.0; - - uvec indices_nonzero = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }; - - uvec indices_zero = { 12 }; - - uvec indices_greaterthan_00 = { 0, 1, 3, 4, 5, 6, 8, 10, 13, 17, 21, 22, 25, 26, 28, 29 }; - - uvec indices_lessthan_00 = { 2, 7, 9, 11, 14, 15, 16, 18, 19, 20, 23, 24, 27 }; - - uvec indices_greaterthan_04 = { 1, 8, 13, 17 }; - - uvec indices_lessthan_neg04 = { 2, 9, 14, 15, 27 }; - - REQUIRE( accu(abs( conv_to::from(find(A )) - conv_to::from(indices_nonzero ) )) == Approx(0.0) ); - - REQUIRE( accu(abs( conv_to::from(find(A == 0.0)) - conv_to::from(indices_zero ) )) == Approx(0.0) ); - - REQUIRE( accu(abs( conv_to::from(find(A > 0.0)) - conv_to::from(indices_greaterthan_00) )) == Approx(0.0) ); - - REQUIRE( accu(abs( conv_to::from(find(A < 0.0)) - conv_to::from(indices_lessthan_00 ) )) == Approx(0.0) ); - - REQUIRE( accu(abs( conv_to::from(find(A > 0.4)) - conv_to::from(indices_greaterthan_04) )) == Approx(0.0) ); - - REQUIRE( accu(abs( conv_to::from(find(A < -0.4)) - conv_to::from(indices_lessthan_neg04) )) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_find_finite.cpp armadillo-10.8.2+dfsg/tests/fn_find_finite.cpp --- armadillo-9.800.4+dfsg/tests/fn_find_finite.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_find_finite.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_find_finite_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = A; - - B( 6) = datum::nan; - B( 8) = datum::inf; - B(10) = -datum::inf; - - REQUIRE( accu(A.elem(find_finite(A))) == Approx(+0.240136) ); - REQUIRE( accu(B.elem(find_finite(B))) == Approx(-0.250039) ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_find_nonfinite.cpp armadillo-10.8.2+dfsg/tests/fn_find_nonfinite.cpp --- armadillo-9.800.4+dfsg/tests/fn_find_nonfinite.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_find_nonfinite.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_find_nonfinite_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = A; - - B( 6) = datum::nan; - B( 8) = datum::inf; - B(10) = -datum::inf; - - uvec indices1 = find_nonfinite(A); - uvec indices2 = find_nonfinite(B); - - REQUIRE( indices1.n_elem == 0 ); - REQUIRE( indices2.n_elem == 3 ); - - REQUIRE( accu(indices2 - uvec({6,8,10})) == 0 ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_find_unique.cpp armadillo-10.8.2+dfsg/tests/fn_find_unique.cpp --- armadillo-9.800.4+dfsg/tests/fn_find_unique.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_find_unique.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_find_unique_1") - { - mat A = - { - { 1, 3, 5, 6, 7 }, - { 2, 4, 5, 7, 8 }, - { 3, 5, 5, 6, 9 }, - }; - - uvec indices = find_unique(A); - - uvec indices2 = { 0, 1, 2, 4, 5, 9, 10, 13, 14 }; - - REQUIRE( indices.n_elem == indices2.n_elem ); - - bool same = true; - - for(uword i=0; i < indices.n_elem; ++i) - { - if(indices(i) != indices2(i)) { same = false; break; } - } - - REQUIRE( same == true ); - - vec unique_elem = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - - REQUIRE( accu(abs( A.elem(indices) - unique_elem )) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } - - - -TEST_CASE("fn_find_unique_2") - { - cx_mat A = - { - { cx_double(1,-1), cx_double(3, 2), cx_double(5, 2), cx_double(6, 1), cx_double(7,-1) }, - { cx_double(2, 1), cx_double(4, 4), cx_double(5, 2), cx_double(7,-1), cx_double(8, 1) }, - { cx_double(3, 2), cx_double(5, 1), cx_double(5, 3), cx_double(6, 1), cx_double(9,-9) } - }; - - uvec indices = find_unique(A); - - uvec indices2 = { 0, 1, 2, 4, 5, 6, 8, 9, 10, 13, 14 }; - - REQUIRE( indices.n_elem == indices2.n_elem ); - - bool same = true; - - for(uword i=0; i < indices.n_elem; ++i) - { - if(indices(i) != indices2(i)) { same = false; break; } - } - - REQUIRE( same == true ); - - cx_vec unique_elem = - { - cx_double(1,-1), - cx_double(2, 1), - cx_double(3, 2), - cx_double(4, 4), - cx_double(5, 1), - cx_double(5, 2), - cx_double(5, 3), - cx_double(6, 1), - cx_double(7,-1), - cx_double(8, 1), - cx_double(9,-9) - }; - - REQUIRE( accu(abs( A.elem(indices) - unique_elem )) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_flip.cpp armadillo-10.8.2+dfsg/tests/fn_flip.cpp --- armadillo-9.800.4+dfsg/tests/fn_flip.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_flip.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_flip_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat A_fliplr = - "\ - 0.051408 -0.126745 -0.493936 0.019678 0.201990 0.061198;\ - 0.035437 0.296153 -0.045465 -0.149362 0.058956 0.437242;\ - -0.454499 0.068317 0.419733 0.314156 -0.031309 -0.492474;\ - 0.373833 -0.135040 -0.393139 0.458476 0.411541 0.336352;\ - 0.258704 -0.353768 -0.291020 -0.406953 -0.428913 0.239585;\ - "; - - mat A_flipud = - "\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - "; - - - mat two_times_A_fliplr = - "\ - 0.102816 -0.253490 -0.987872 0.039356 0.403980 0.122396;\ - 0.070874 0.592306 -0.090930 -0.298724 0.117912 0.874484;\ - -0.908998 0.136634 0.839466 0.628312 -0.062618 -0.984948;\ - 0.747666 -0.270080 -0.786278 0.916952 0.823082 0.672704;\ - 0.517408 -0.707536 -0.582040 -0.813906 -0.857826 0.479170;\ - "; - - mat two_times_A_flipud = - "\ - 0.479170 -0.857826 -0.813906 -0.582040 -0.707536 0.517408;\ - 0.672704 0.823082 0.916952 -0.786278 -0.270080 0.747666;\ - -0.984948 -0.062618 0.628312 0.839466 0.136634 -0.908998;\ - 0.874484 0.117912 -0.298724 -0.090930 0.592306 0.070874;\ - 0.122396 0.403980 0.039356 -0.987872 -0.253490 0.102816;\ - "; - - REQUIRE( accu(abs( fliplr(A) - A_fliplr )) == Approx(0.0) ); - REQUIRE( accu(abs( flipud(A) - A_flipud )) == Approx(0.0) ); - - REQUIRE( accu(abs( (-fliplr(A)) + A_fliplr )) == Approx(0.0) ); - REQUIRE( accu(abs( (-flipud(A)) + A_flipud )) == Approx(0.0) ); - - REQUIRE( accu(abs( fliplr(-A) + A_fliplr )) == Approx(0.0) ); - REQUIRE( accu(abs( flipud(-A) + A_flipud )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*fliplr(A) - two_times_A_fliplr )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*flipud(A) - two_times_A_flipud )) == Approx(0.0) ); - - REQUIRE( accu(abs( fliplr(2*A) - two_times_A_fliplr )) == Approx(0.0) ); - REQUIRE( accu(abs( flipud(2*A) - two_times_A_flipud )) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_hess.cpp armadillo-10.8.2+dfsg/tests/fn_hess.cpp --- armadillo-9.800.4+dfsg/tests/fn_hess.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_hess.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,644 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include -#include "catch.hpp" - -using namespace arma; -using namespace std; - - - -TEST_CASE("fn_hess_non_square") - { - mat A(5, 6, fill::ones); - mat U, H; - REQUIRE_THROWS( hess(U, H, A) ); - } - - -/***************** tests for real matrix ****************/ - -TEST_CASE("fn_hess_empty") - { - mat A(1, 1); - A.reset(); - mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U.is_empty() == true ); - REQUIRE( H.is_empty() == true ); - REQUIRE( H1.is_empty() == true ); - REQUIRE( H2.is_empty() == true ); - } - - - -TEST_CASE("fn_hess_1") - { - mat A(1, 1); - A(0, 0) = 0.061198; - mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U(0, 0) == Approx(1.0) ); - REQUIRE( H(0, 0) == Approx(0.061198) ); - REQUIRE( H1(0, 0) == Approx(0.061198) ); - REQUIRE( H2(0, 0) == Approx(0.061198) ); - } - - - -TEST_CASE("fn_hess_2") - { - mat A = - "\ - 0.061198 0.201990;\ - 0.437242 0.058956;\ - "; - mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U(0, 0) == Approx(1.0) ); - REQUIRE( U(0, 1) == Approx(0.0) ); - REQUIRE( U(1, 0) == Approx(0.0) ); - REQUIRE( U(1, 1) == Approx(1.0) ); - - REQUIRE( H(0, 0) == Approx(0.061198) ); - REQUIRE( H(0, 1) == Approx(0.201990) ); - REQUIRE( H(1, 0) == Approx(0.437242) ); - REQUIRE( H(1, 1) == Approx(0.058956) ); - - REQUIRE( H1(0, 0) == Approx(0.061198) ); - REQUIRE( H1(0, 1) == Approx(0.201990) ); - REQUIRE( H1(1, 0) == Approx(0.437242) ); - REQUIRE( H1(1, 1) == Approx(0.058956) ); - - REQUIRE( H2(0, 0) == Approx(0.061198) ); - REQUIRE( H2(0, 1) == Approx(0.201990) ); - REQUIRE( H2(1, 0) == Approx(0.437242) ); - REQUIRE( H2(1, 1) == Approx(0.058956) ); - } - - - -TEST_CASE("fn_hess_3") - { - mat A = - "\ - 0.061198 0.201990 0.019678;\ - 0.437242 0.058956 -0.149362;\ - -0.492474 -0.031309 0.314156;\ - "; - mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U(0, 0) == Approx(1.0) ); - REQUIRE( U(0, 1) == Approx(0.0) ); - REQUIRE( U(0, 2) == Approx(0.0) ); - - REQUIRE( U(1, 0) == Approx( 0.0) ); - REQUIRE( U(1, 1) == Approx(-0.663928864062532) ); - REQUIRE( U(1, 2) == Approx( 0.747795736457915) ); - - REQUIRE( U(2, 0) == Approx( 0.0) ); - REQUIRE( U(2, 1) == Approx( 0.747795736457915) ); - REQUIRE( U(2, 2) == Approx( 0.663928864062532) ); - - - REQUIRE( H(0, 0) == Approx( 0.061198000000000) ); - REQUIRE( H(0, 1) == Approx(-0.119391866749972) ); - REQUIRE( H(0, 2) == Approx( 0.164112052994157) ); - - REQUIRE( H(1, 0) == Approx(-0.658567541896805) ); - REQUIRE( H(1, 1) == Approx( 0.291363559380149) ); - REQUIRE( H(1, 2) == Approx( 0.175033560375766) ); - - REQUIRE( H(2, 0) == Approx( 0.0) ); - REQUIRE( H(2, 1) == Approx( 0.056980560375766) ); - REQUIRE( H(2, 2) == Approx( 0.081748440619851) ); - - - REQUIRE( H1(0, 0) == Approx( 0.061198000000000) ); - REQUIRE( H1(0, 1) == Approx(-0.119391866749972) ); - REQUIRE( H1(0, 2) == Approx( 0.164112052994157) ); - - REQUIRE( H1(1, 0) == Approx(-0.658567541896805) ); - REQUIRE( H1(1, 1) == Approx( 0.291363559380149) ); - REQUIRE( H1(1, 2) == Approx( 0.175033560375766) ); - - REQUIRE( H1(2, 0) == Approx( 0.0) ); - REQUIRE( H1(2, 1) == Approx( 0.056980560375766) ); - REQUIRE( H1(2, 2) == Approx( 0.081748440619851) ); - - - REQUIRE( H2(0, 0) == Approx( 0.061198000000000) ); - REQUIRE( H2(0, 1) == Approx(-0.119391866749972) ); - REQUIRE( H2(0, 2) == Approx( 0.164112052994157) ); - - REQUIRE( H2(1, 0) == Approx(-0.658567541896805) ); - REQUIRE( H2(1, 1) == Approx( 0.291363559380149) ); - REQUIRE( H2(1, 2) == Approx( 0.175033560375766) ); - - REQUIRE( H2(2, 0) == Approx( 0.0) ); - REQUIRE( H2(2, 1) == Approx( 0.056980560375766) ); - REQUIRE( H2(2, 2) == Approx( 0.081748440619851) ); - } - - - - -TEST_CASE("fn_hess_4") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936;\ - 0.437242 0.058956 -0.149362 -0.045465;\ - -0.492474 -0.031309 0.314156 0.419733;\ - 0.336352 0.411541 0.458476 -0.393139;\ - "; - mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U(0, 0) == Approx(1.0) ); - REQUIRE( U(0, 1) == Approx(0.0) ); - REQUIRE( U(0, 2) == Approx(0.0) ); - REQUIRE( U(0, 3) == Approx(0.0) ); - - REQUIRE( U(1, 0) == Approx( 0.0) ); - REQUIRE( U(1, 1) == Approx(-0.591275924818639) ); - REQUIRE( U(1, 2) == Approx(-0.462981984254642) ); - REQUIRE( U(1, 3) == Approx( 0.660333599770220) ); - - REQUIRE( U(2, 0) == Approx( 0.0) ); - REQUIRE( U(2, 1) == Approx( 0.665965345962041) ); - REQUIRE( U(2, 2) == Approx( 0.181491258046004) ); - REQUIRE( U(2, 3) == Approx( 0.723568297557693) ); - - REQUIRE( U(3, 0) == Approx( 0.0) ); - REQUIRE( U(3, 1) == Approx(-0.454843861899358) ); - REQUIRE( U(3, 2) == Approx( 0.867587808529208) ); - REQUIRE( U(3, 3) == Approx( 0.201018545870685) ); - - - REQUIRE( H(0, 0) == Approx( 0.061198000000000) ); - REQUIRE( H(0, 1) == Approx( 0.118336799794845) ); - REQUIRE( H(0, 2) == Approx(-0.518479197817449) ); - REQUIRE( H(0, 3) == Approx( 0.048328864303744) ); - - REQUIRE( H(1, 0) == Approx(-0.739488928344434) ); - REQUIRE( H(1, 1) == Approx(-0.017815019577445) ); - REQUIRE( H(1, 2) == Approx( 0.549585804168668) ); - REQUIRE( H(1, 3) == Approx( 0.001541438669749) ); - - REQUIRE( H(2, 0) == Approx( 0.0) ); - REQUIRE( H(2, 1) == Approx( 0.268224897826587) ); - REQUIRE( H(2, 2) == Approx(-0.266514530817371) ); - REQUIRE( H(2, 3) == Approx( 0.544078897369960) ); - - REQUIRE( H(3, 0) == Approx( 0.0) ); - REQUIRE( H(3, 1) == Approx( 0.0) ); - REQUIRE( H(3, 2) == Approx( 0.163125252889179) ); - REQUIRE( H(3, 3) == Approx( 0.264302550394816) ); - - - REQUIRE( H1(0, 0) == Approx( 0.061198000000000) ); - REQUIRE( H1(0, 1) == Approx( 0.118336799794845) ); - REQUIRE( H1(0, 2) == Approx(-0.518479197817449) ); - REQUIRE( H1(0, 3) == Approx( 0.048328864303744) ); - - REQUIRE( H1(1, 0) == Approx(-0.739488928344434) ); - REQUIRE( H1(1, 1) == Approx(-0.017815019577445) ); - REQUIRE( H1(1, 2) == Approx( 0.549585804168668) ); - REQUIRE( H1(1, 3) == Approx( 0.001541438669749) ); - - REQUIRE( H1(2, 0) == Approx( 0.0) ); - REQUIRE( H1(2, 1) == Approx( 0.268224897826587) ); - REQUIRE( H1(2, 2) == Approx(-0.266514530817371) ); - REQUIRE( H1(2, 3) == Approx( 0.544078897369960) ); - - REQUIRE( H1(3, 0) == Approx( 0.0) ); - REQUIRE( H1(3, 1) == Approx( 0.0) ); - REQUIRE( H1(3, 2) == Approx( 0.163125252889179) ); - REQUIRE( H1(3, 3) == Approx( 0.264302550394816) ); - - - REQUIRE( H2(0, 0) == Approx( 0.061198000000000) ); - REQUIRE( H2(0, 1) == Approx( 0.118336799794845) ); - REQUIRE( H2(0, 2) == Approx(-0.518479197817449) ); - REQUIRE( H2(0, 3) == Approx( 0.048328864303744) ); - - REQUIRE( H2(1, 0) == Approx(-0.739488928344434) ); - REQUIRE( H2(1, 1) == Approx(-0.017815019577445) ); - REQUIRE( H2(1, 2) == Approx( 0.549585804168668) ); - REQUIRE( H2(1, 3) == Approx( 0.001541438669749) ); - - REQUIRE( H2(2, 0) == Approx( 0.0) ); - REQUIRE( H2(2, 1) == Approx( 0.268224897826587) ); - REQUIRE( H2(2, 2) == Approx(-0.266514530817371) ); - REQUIRE( H2(2, 3) == Approx( 0.544078897369960) ); - - REQUIRE( H2(3, 0) == Approx( 0.0) ); - REQUIRE( H2(3, 1) == Approx( 0.0) ); - REQUIRE( H2(3, 2) == Approx( 0.163125252889179) ); - REQUIRE( H2(3, 3) == Approx( 0.264302550394816) ); - } - - - -/***************** tests for complex matrix ****************/ - -TEST_CASE("fn_hess_cx_empty") - { - cx_mat A(1, 1); - A.reset(); - cx_mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U.is_empty() == true ); - REQUIRE( H.is_empty() == true ); - REQUIRE( H1.is_empty() == true ); - REQUIRE( H2.is_empty() == true ); - } - - - -TEST_CASE("fn_hess_cx_1") - { - cx_mat A(1, 1); - A(0, 0) = complex(0.061198, 1.012234); - cx_mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U(0, 0).real() == Approx(1.0) ); - REQUIRE( U(0, 0).imag() == Approx(0.0) ); - - REQUIRE( H(0, 0).real() == Approx(0.061198) ); - REQUIRE( H(0, 0).imag() == Approx(1.012234) ); - - REQUIRE( H1(0, 0).real() == Approx(0.061198) ); - REQUIRE( H1(0, 0).imag() == Approx(1.012234) ); - - REQUIRE( H2(0, 0).real() == Approx(0.061198) ); - REQUIRE( H2(0, 0).imag() == Approx(1.012234) ); - } - - - -TEST_CASE("fn_hess_cx_2") - { - mat B = - "\ - 0.061198 0.201990;\ - 0.437242 0.058956;\ - "; - cx_mat A(B, B*B); - cx_mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U(0, 0).real() == Approx(1.0) ); - REQUIRE( U(0, 0).imag() == Approx(0.0) ); - REQUIRE( U(0, 1).real() == Approx(0.0) ); - REQUIRE( U(0, 1).imag() == Approx(0.0) ); - REQUIRE( U(1, 0).real() == Approx(0.0) ); - REQUIRE( U(1, 0).imag() == Approx(0.0) ); - REQUIRE( U(1, 1).real() == Approx(1.0) ); - REQUIRE( U(1, 1).imag() == Approx(0.0) ); - - REQUIRE( H(0, 0).real() == Approx( 0.061198000000000) ); - REQUIRE( H(0, 0).imag() == Approx( 0.092063706784000) ); - REQUIRE( H(0, 1).real() == Approx( 0.201990000000000) ); - REQUIRE( H(0, 1).imag() == Approx( 0.024269906460000) ); - REQUIRE( H(1, 0).real() == Approx( 0.437242000000000) ); - REQUIRE( H(1, 0).imag() == Approx( 0.052536375268000) ); - REQUIRE( H(1, 1).real() == Approx( 0.058956000000000) ); - REQUIRE( H(1, 1).imag() == Approx( 0.091794321516000) ); - - REQUIRE( H1(0, 0).real() == Approx( 0.061198000000000) ); - REQUIRE( H1(0, 0).imag() == Approx( 0.092063706784000) ); - REQUIRE( H1(0, 1).real() == Approx( 0.201990000000000) ); - REQUIRE( H1(0, 1).imag() == Approx( 0.024269906460000) ); - REQUIRE( H1(1, 0).real() == Approx( 0.437242000000000) ); - REQUIRE( H1(1, 0).imag() == Approx( 0.052536375268000) ); - REQUIRE( H1(1, 1).real() == Approx( 0.058956000000000) ); - REQUIRE( H1(1, 1).imag() == Approx( 0.091794321516000) ); - - REQUIRE( H2(0, 0).real() == Approx( 0.061198000000000) ); - REQUIRE( H2(0, 0).imag() == Approx( 0.092063706784000) ); - REQUIRE( H2(0, 1).real() == Approx( 0.201990000000000) ); - REQUIRE( H2(0, 1).imag() == Approx( 0.024269906460000) ); - REQUIRE( H2(1, 0).real() == Approx( 0.437242000000000) ); - REQUIRE( H2(1, 0).imag() == Approx( 0.052536375268000) ); - REQUIRE( H2(1, 1).real() == Approx( 0.058956000000000) ); - REQUIRE( H2(1, 1).imag() == Approx( 0.091794321516000) ); - } - - - -TEST_CASE("fn_hess_cx_3") - { - mat B = - "\ - 0.061198 0.201990 0.019678;\ - 0.437242 0.058956 -0.149362;\ - -0.492474 -0.031309 0.314156;\ - "; - cx_mat A(B, B*B); - cx_mat U, H, H1, H2; - - hess(U, H, A); - H1 = hess(A); - hess(H2, A); - - REQUIRE( U(0, 0).real() == Approx(1.0) ); - REQUIRE( U(0, 0).imag() == Approx(0.0) ); - REQUIRE( U(0, 1).real() == Approx(0.0) ); - REQUIRE( U(0, 1).imag() == Approx(0.0) ); - REQUIRE( U(0, 2).real() == Approx(0.0) ); - REQUIRE( U(0, 2).imag() == Approx(0.0) ); - - REQUIRE( U(1, 0).real() == Approx( 0.0) ); - REQUIRE( U(1, 0).imag() == Approx( 0.0) ); - REQUIRE( U(1, 1).real() == Approx(-0.625250908290361) ); - REQUIRE( U(1, 1).imag() == Approx(-0.180311900237219) ); - REQUIRE( U(1, 2).real() == Approx(-0.694923841863332) ); - REQUIRE( U(1, 2).imag() == Approx(-0.305989827159056) ); - - REQUIRE( U(2, 0).real() == Approx( 0.0) ); - REQUIRE( U(2, 0).imag() == Approx( 0.0) ); - REQUIRE( U(2, 1).real() == Approx( 0.704232017531224) ); - REQUIRE( U(2, 1).imag() == Approx( 0.283912285396078) ); - REQUIRE( U(2, 2).real() == Approx(-0.565610163671470) ); - REQUIRE( U(2, 2).imag() == Approx(-0.321770449912063) ); - - - REQUIRE( H(0, 0).real() == Approx( 0.061198000000000) ); - REQUIRE( H(0, 0).imag() == Approx( 0.082372803412000) ); - REQUIRE( H(0, 1).real() == Approx(-0.101702999021493) ); - REQUIRE( H(0, 1).imag() == Approx(-0.061668749553784) ); - REQUIRE( H(0, 2).real() == Approx(-0.151590948501704) ); - REQUIRE( H(0, 2).imag() == Approx(-0.071689748472419) ); - - REQUIRE( H(1, 0).real() == Approx(-0.699306461138236) ); - REQUIRE( H(1, 0).imag() == Approx( 0.0) ); - REQUIRE( H(1, 1).real() == Approx( 0.298129546829246) ); - REQUIRE( H(1, 1).imag() == Approx( 0.178624769103627) ); - REQUIRE( H(1, 2).real() == Approx(-0.165941859233838) ); - REQUIRE( H(1, 2).imag() == Approx( 0.014927427092653) ); - - REQUIRE( H(2, 0).real() == Approx( 0.0) ); - REQUIRE( H(2, 0).imag() == Approx( 0.0) ); - REQUIRE( H(2, 1).real() == Approx(-0.061767777059231) ); - REQUIRE( H(2, 1).imag() == Approx( 0.0) ); - REQUIRE( H(2, 2).real() == Approx( 0.074982453170754) ); - REQUIRE( H(2, 2).imag() == Approx( 0.011525391092373) ); - - - REQUIRE( H1(0, 0).real() == Approx( 0.061198000000000) ); - REQUIRE( H1(0, 0).imag() == Approx( 0.082372803412000) ); - REQUIRE( H1(0, 1).real() == Approx(-0.101702999021493) ); - REQUIRE( H1(0, 1).imag() == Approx(-0.061668749553784) ); - REQUIRE( H1(0, 2).real() == Approx(-0.151590948501704) ); - REQUIRE( H1(0, 2).imag() == Approx(-0.071689748472419) ); - - REQUIRE( H1(1, 0).real() == Approx(-0.699306461138236) ); - REQUIRE( H1(1, 0).imag() == Approx( 0.0) ); - REQUIRE( H1(1, 1).real() == Approx( 0.298129546829246) ); - REQUIRE( H1(1, 1).imag() == Approx( 0.178624769103627) ); - REQUIRE( H1(1, 2).real() == Approx(-0.165941859233838) ); - REQUIRE( H1(1, 2).imag() == Approx( 0.014927427092653) ); - - REQUIRE( H1(2, 0).real() == Approx( 0.0) ); - REQUIRE( H1(2, 0).imag() == Approx( 0.0) ); - REQUIRE( H1(2, 1).real() == Approx(-0.061767777059231) ); - REQUIRE( H1(2, 1).imag() == Approx( 0.0) ); - REQUIRE( H1(2, 2).real() == Approx( 0.074982453170754) ); - REQUIRE( H1(2, 2).imag() == Approx( 0.011525391092373) ); - - - REQUIRE( H2(0, 0).real() == Approx( 0.061198000000000) ); - REQUIRE( H2(0, 0).imag() == Approx( 0.082372803412000) ); - REQUIRE( H2(0, 1).real() == Approx(-0.101702999021493) ); - REQUIRE( H2(0, 1).imag() == Approx(-0.061668749553784) ); - REQUIRE( H2(0, 2).real() == Approx(-0.151590948501704) ); - REQUIRE( H2(0, 2).imag() == Approx(-0.071689748472419) ); - - REQUIRE( H2(1, 0).real() == Approx(-0.699306461138236) ); - REQUIRE( H2(1, 0).imag() == Approx( 0.0) ); - REQUIRE( H2(1, 1).real() == Approx( 0.298129546829246) ); - REQUIRE( H2(1, 1).imag() == Approx( 0.178624769103627) ); - REQUIRE( H2(1, 2).real() == Approx(-0.165941859233838) ); - REQUIRE( H2(1, 2).imag() == Approx( 0.014927427092653) ); - - REQUIRE( H2(2, 0).real() == Approx( 0.0) ); - REQUIRE( H2(2, 0).imag() == Approx( 0.0) ); - REQUIRE( H2(2, 1).real() == Approx(-0.061767777059231) ); - REQUIRE( H2(2, 1).imag() == Approx( 0.0) ); - REQUIRE( H2(2, 2).real() == Approx( 0.074982453170754) ); - REQUIRE( H2(2, 2).imag() == Approx( 0.011525391092373) ); - } - - - - -TEST_CASE("fn_hess_cx_4") - { - mat B = - "\ - 0.061198 0.201990 0.019678 -0.493936;\ - 0.437242 0.058956 -0.149362 -0.045465;\ - -0.492474 -0.031309 0.314156 0.419733;\ - 0.336352 0.411541 0.458476 -0.393139;\ - "; - cx_mat A(B, B*B); - cx_mat U, H, H1, H2; - - hess(U, H, A*A); - H1 = hess(A*A); - hess(H2, A*A); - - REQUIRE( U(0, 0).real() == Approx(1.0) ); - REQUIRE( U(0, 0).imag() == Approx(0.0) ); - REQUIRE( U(0, 1).real() == Approx(0.0) ); - REQUIRE( U(0, 1).imag() == Approx(0.0) ); - REQUIRE( U(0, 2).real() == Approx(0.0) ); - REQUIRE( U(0, 2).imag() == Approx(0.0) ); - REQUIRE( U(0, 3).real() == Approx(0.0) ); - REQUIRE( U(0, 3).imag() == Approx(0.0) ); - - REQUIRE( U(1, 0).real() == Approx( 0.0) ); - REQUIRE( U(1, 0).imag() == Approx( 0.0) ); - REQUIRE( U(1, 1).real() == Approx(-0.310409361344421) ); - REQUIRE( U(1, 1).imag() == Approx( 0.134965522927510) ); - REQUIRE( U(1, 2).real() == Approx( 0.368370931495079) ); - REQUIRE( U(1, 2).imag() == Approx( 0.620286967761253) ); - REQUIRE( U(1, 3).real() == Approx(-0.461565151978241) ); - REQUIRE( U(1, 3).imag() == Approx( 0.389788251419862) ); - - REQUIRE( U(2, 0).real() == Approx( 0.0) ); - REQUIRE( U(2, 0).imag() == Approx( 0.0) ); - REQUIRE( U(2, 1).real() == Approx( 0.090510343531288) ); - REQUIRE( U(2, 1).imag() == Approx( 0.435448214446087) ); - REQUIRE( U(2, 2).real() == Approx(-0.629572243863963) ); - REQUIRE( U(2, 2).imag() == Approx( 0.277252591049466) ); - REQUIRE( U(2, 3).real() == Approx( 0.331725833624923) ); - REQUIRE( U(2, 3).imag() == Approx( 0.467889401534022) ); - - REQUIRE( U(3, 0).real() == Approx( 0.0) ); - REQUIRE( U(3, 0).imag() == Approx( 0.0) ); - REQUIRE( U(3, 1).real() == Approx( 0.662749913792672) ); - REQUIRE( U(3, 1).imag() == Approx(-0.498383003349854) ); - REQUIRE( U(3, 2).real() == Approx(-0.073218600583049) ); - REQUIRE( U(3, 2).imag() == Approx(-0.030915392543373) ); - REQUIRE( U(3, 3).real() == Approx(-0.297561059397637) ); - REQUIRE( U(3, 3).imag() == Approx( 0.466387847936125) ); - - - REQUIRE( H(0, 0).real() == Approx(-0.059498334460944) ); - REQUIRE( H(0, 0).imag() == Approx( 0.187834910202221) ); - REQUIRE( H(0, 1).real() == Approx(-0.017930467829804) ); - REQUIRE( H(0, 1).imag() == Approx(-0.366928547670200) ); - REQUIRE( H(0, 2).real() == Approx(-0.021913405453089) ); - REQUIRE( H(0, 2).imag() == Approx(-0.128142818524165) ); - REQUIRE( H(0, 3).real() == Approx( 0.012590549436907) ); - REQUIRE( H(0, 3).imag() == Approx(-0.036787529849029) ); - - REQUIRE( H(1, 0).real() == Approx(-0.212856818153491) ); - REQUIRE( H(1, 0).imag() == Approx( 0.0) ); - REQUIRE( H(1, 1).real() == Approx( 0.173480548915683) ); - REQUIRE( H(1, 1).imag() == Approx(-0.119570582029397) ); - REQUIRE( H(1, 2).real() == Approx(-0.098222486822866) ); - REQUIRE( H(1, 2).imag() == Approx(-0.073492477972392) ); - REQUIRE( H(1, 3).real() == Approx(-0.088126641335837) ); - REQUIRE( H(1, 3).imag() == Approx( 0.107905518898551) ); - - REQUIRE( H(2, 0).real() == Approx( 0.0) ); - REQUIRE( H(2, 0).imag() == Approx( 0.0) ); - REQUIRE( H(2, 1).real() == Approx( 0.125544511009417) ); - REQUIRE( H(2, 1).imag() == Approx( 0.0) ); - REQUIRE( H(2, 2).real() == Approx( 0.374057080595739) ); - REQUIRE( H(2, 2).imag() == Approx( 0.061223114296791) ); - REQUIRE( H(2, 3).real() == Approx( 0.231175819260595) ); - REQUIRE( H(2, 3).imag() == Approx(-0.224564151240434) ); - - REQUIRE( H(3, 0).real() == Approx( 0.0) ); - REQUIRE( H(3, 0).imag() == Approx( 0.0) ); - REQUIRE( H(3, 1).real() == Approx( 0.0) ); - REQUIRE( H(3, 1).imag() == Approx( 0.0) ); - REQUIRE( H(3, 2).real() == Approx(-0.238973358869022) ); - REQUIRE( H(3, 2).imag() == Approx( 0.0) ); - REQUIRE( H(3, 3).real() == Approx(-0.101771291133878) ); - REQUIRE( H(3, 3).imag() == Approx( 0.212030655387598) ); - - - REQUIRE( H1(0, 0).real() == Approx(-0.059498334460944) ); - REQUIRE( H1(0, 0).imag() == Approx( 0.187834910202221) ); - REQUIRE( H1(0, 1).real() == Approx(-0.017930467829804) ); - REQUIRE( H1(0, 1).imag() == Approx(-0.366928547670200) ); - REQUIRE( H1(0, 2).real() == Approx(-0.021913405453089) ); - REQUIRE( H1(0, 2).imag() == Approx(-0.128142818524165) ); - REQUIRE( H1(0, 3).real() == Approx( 0.012590549436907) ); - REQUIRE( H1(0, 3).imag() == Approx(-0.036787529849029) ); - - REQUIRE( H1(1, 0).real() == Approx(-0.212856818153491) ); - REQUIRE( H1(1, 0).imag() == Approx( 0.0) ); - REQUIRE( H1(1, 1).real() == Approx( 0.173480548915683) ); - REQUIRE( H1(1, 1).imag() == Approx(-0.119570582029397) ); - REQUIRE( H1(1, 2).real() == Approx(-0.098222486822866) ); - REQUIRE( H1(1, 2).imag() == Approx(-0.073492477972392) ); - REQUIRE( H1(1, 3).real() == Approx(-0.088126641335837) ); - REQUIRE( H1(1, 3).imag() == Approx( 0.107905518898551) ); - - REQUIRE( H1(2, 0).real() == Approx( 0.0) ); - REQUIRE( H1(2, 0).imag() == Approx( 0.0) ); - REQUIRE( H1(2, 1).real() == Approx( 0.125544511009417) ); - REQUIRE( H1(2, 1).imag() == Approx( 0.0) ); - REQUIRE( H1(2, 2).real() == Approx( 0.374057080595739) ); - REQUIRE( H1(2, 2).imag() == Approx( 0.061223114296791) ); - REQUIRE( H1(2, 3).real() == Approx( 0.231175819260595) ); - REQUIRE( H1(2, 3).imag() == Approx(-0.224564151240434) ); - - REQUIRE( H1(3, 0).real() == Approx( 0.0) ); - REQUIRE( H1(3, 0).imag() == Approx( 0.0) ); - REQUIRE( H1(3, 1).real() == Approx( 0.0) ); - REQUIRE( H1(3, 1).imag() == Approx( 0.0) ); - REQUIRE( H1(3, 2).real() == Approx(-0.238973358869022) ); - REQUIRE( H1(3, 2).imag() == Approx( 0.0) ); - REQUIRE( H1(3, 3).real() == Approx(-0.101771291133878) ); - REQUIRE( H1(3, 3).imag() == Approx( 0.212030655387598) ); - - - REQUIRE( H2(0, 0).real() == Approx(-0.059498334460944) ); - REQUIRE( H2(0, 0).imag() == Approx( 0.187834910202221) ); - REQUIRE( H2(0, 1).real() == Approx(-0.017930467829804) ); - REQUIRE( H2(0, 1).imag() == Approx(-0.366928547670200) ); - REQUIRE( H2(0, 2).real() == Approx(-0.021913405453089) ); - REQUIRE( H2(0, 2).imag() == Approx(-0.128142818524165) ); - REQUIRE( H2(0, 3).real() == Approx( 0.012590549436907) ); - REQUIRE( H2(0, 3).imag() == Approx(-0.036787529849029) ); - - REQUIRE( H2(1, 0).real() == Approx(-0.212856818153491) ); - REQUIRE( H2(1, 0).imag() == Approx( 0.0) ); - REQUIRE( H2(1, 1).real() == Approx( 0.173480548915683) ); - REQUIRE( H2(1, 1).imag() == Approx(-0.119570582029397) ); - REQUIRE( H2(1, 2).real() == Approx(-0.098222486822866) ); - REQUIRE( H2(1, 2).imag() == Approx(-0.073492477972392) ); - REQUIRE( H2(1, 3).real() == Approx(-0.088126641335837) ); - REQUIRE( H2(1, 3).imag() == Approx( 0.107905518898551) ); - - REQUIRE( H2(2, 0).real() == Approx( 0.0) ); - REQUIRE( H2(2, 0).imag() == Approx( 0.0) ); - REQUIRE( H2(2, 1).real() == Approx( 0.125544511009417) ); - REQUIRE( H2(2, 1).imag() == Approx( 0.0) ); - REQUIRE( H2(2, 2).real() == Approx( 0.374057080595739) ); - REQUIRE( H2(2, 2).imag() == Approx( 0.061223114296791) ); - REQUIRE( H2(2, 3).real() == Approx( 0.231175819260595) ); - REQUIRE( H2(2, 3).imag() == Approx(-0.224564151240434) ); - - REQUIRE( H2(3, 0).real() == Approx( 0.0) ); - REQUIRE( H2(3, 0).imag() == Approx( 0.0) ); - REQUIRE( H2(3, 1).real() == Approx( 0.0) ); - REQUIRE( H2(3, 1).imag() == Approx( 0.0) ); - REQUIRE( H2(3, 2).real() == Approx(-0.238973358869022) ); - REQUIRE( H2(3, 2).imag() == Approx( 0.0) ); - REQUIRE( H2(3, 3).real() == Approx(-0.101771291133878) ); - REQUIRE( H2(3, 3).imag() == Approx( 0.212030655387598) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_interp1.cpp armadillo-10.8.2+dfsg/tests/fn_interp1.cpp --- armadillo-9.800.4+dfsg/tests/fn_interp1.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_interp1.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_interp1_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - vec x = vectorise(A(0,0,size(5,3))); - vec y = vectorise(A(0,3,size(5,3))); - - vec xi_a = linspace( x.min(), x.max(), 10 ); - vec xi_b = flipud( linspace( x.min(), x.max(), 11 ) ); - - vec yi_a; - vec yi_b; - - interp1(x, y, xi_a, yi_a); - interp1(x, y, xi_b, yi_b); - - vec yi_a_gt = { 0.419733, 0.241248, 0.149666, 0.058084, 0.057588, 0.152062, -0.284524, -0.307613, -0.336627, 0.373833 }; - vec yi_b_gt = { 0.373833, -0.300357, -0.353940, -0.201854, -0.449865, 0.063571, 0.045817, 0.085559, 0.167982, 0.250406, 0.419733 }; - - REQUIRE( accu(abs( yi_a - yi_a_gt )) == Approx(0.0) ); - REQUIRE( accu(abs( yi_b - yi_b_gt )) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_intersect.cpp armadillo-10.8.2+dfsg/tests/fn_intersect.cpp --- armadillo-9.800.4+dfsg/tests/fn_intersect.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_intersect.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_intersect_1") - { - ivec A = regspace(5, 1); // 5, 4, 3, 2, 1 - ivec B = regspace(3, 7); // 3, 4, 5, 6, 7 - - ivec C = intersect(A,B); // 3, 4, 5 - - REQUIRE( C(0) == 3 ); - REQUIRE( C(1) == 4 ); - REQUIRE( C(2) == 5 ); - - REQUIRE( accu(C) == 12 ); - - ivec CC; - uvec iA; - uvec iB; - - intersect(CC, iA, iB, A, B); - - REQUIRE( accu(abs(C-CC)) == 0 ); - - REQUIRE( iA(0) == 2 ); - REQUIRE( iA(1) == 1 ); - REQUIRE( iA(2) == 0 ); - - REQUIRE( accu(iA) == 3 ); - - REQUIRE( iB(0) == 0 ); - REQUIRE( iB(1) == 1 ); - REQUIRE( iB(2) == 2 ); - - REQUIRE( accu(iB) == 3 ); - } - - -TEST_CASE("fn_intersect_2") - { - irowvec A = regspace(5, 1); // 5, 4, 3, 2, 1 - irowvec B = regspace(3, 7); // 3, 4, 5, 6, 7 - - irowvec C = intersect(A,B); // 3, 4, 5 - - REQUIRE( C(0) == 3 ); - REQUIRE( C(1) == 4 ); - REQUIRE( C(2) == 5 ); - - REQUIRE( accu(C) == 12 ); - - irowvec CC; - uvec iA; - uvec iB; - - intersect(CC, iA, iB, A, B); - - REQUIRE( accu(abs(C-CC)) == 0 ); - - REQUIRE( iA(0) == 2 ); - REQUIRE( iA(1) == 1 ); - REQUIRE( iA(2) == 0 ); - - REQUIRE( accu(iA) == 3 ); - - REQUIRE( iB(0) == 0 ); - REQUIRE( iB(1) == 1 ); - REQUIRE( iB(2) == 2 ); - - REQUIRE( accu(iB) == 3 ); - } - - -TEST_CASE("fn_intersect_3") - { - irowvec A = regspace(5, 1); - irowvec B = regspace(3, 7); - - ivec C; - - REQUIRE_THROWS( C = intersect(A,B) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_is_finite.cpp armadillo-10.8.2+dfsg/tests/fn_is_finite.cpp --- armadillo-9.800.4+dfsg/tests/fn_is_finite.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_is_finite.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_is_finite_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = A; B(1,1) = datum::inf; - - mat C = A; C(2,4) = datum::nan; - - REQUIRE( is_finite(A) == true ); - REQUIRE( is_finite(B) == false ); - REQUIRE( is_finite(C) == false ); - - REQUIRE( is_finite(A+A) == true ); - REQUIRE( is_finite(B+B) == false ); - REQUIRE( is_finite(C+C) == false ); - - REQUIRE( is_finite(2*A) == true ); - REQUIRE( is_finite(2*B) == false ); - REQUIRE( is_finite(2*C) == false ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_max.cpp armadillo-10.8.2+dfsg/tests/fn_max.cpp --- armadillo-9.800.4+dfsg/tests/fn_max.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_max.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,736 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("fn_max_subview_test") - { - // We will assume subview.at() works and returns points within the bounds of - // the matrix, so we just have to ensure the results are the same as - // Mat.max()... - for (size_t r = 50; r < 150; ++r) - { - mat x; - x.randu(r, r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - uword x_subview_max3; - - const double mval = x.max(x_max); - const double mval1 = x.submat(0, 0, r - 1, r - 1).max(x_subview_max1); - const double mval2 = x.cols(0, r - 1).max(x_subview_max2); - const double mval3 = x.rows(0, r - 1).max(x_subview_max3); - - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - REQUIRE( x_max == x_subview_max3 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - REQUIRE( mval == Approx(mval3) ); - } - } - - - -TEST_CASE("fn_max_subview_col_test") - { - for (size_t r = 10; r < 50; ++r) - { - vec x; - x.randu(r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const double mval = x.max(x_max); - const double mval1 = x.submat(0, 0, r - 1, 0).max(x_subview_max1); - const double mval2 = x.rows(0, r - 1).max(x_subview_max2); - - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - - - -TEST_CASE("fn_max_subview_row_test") - { - for (size_t r = 10; r < 50; ++r) - { - rowvec x; - x.randu(r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const double mval = x.max(x_max); - const double mval1 = x.submat(0, 0, 0, r - 1).max(x_subview_max1); - const double mval2 = x.cols(0, r - 1).max(x_subview_max2); - - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - - - -TEST_CASE("fn_max_incomplete_subview_test") - { - for (size_t r = 50; r < 150; ++r) - { - mat x; - x.randu(r, r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - uword x_subview_max3; - - const double mval = x.max(x_max); - const double mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1); - const double mval2 = x.cols(1, r - 2).max(x_subview_max2); - const double mval3 = x.rows(1, r - 2).max(x_subview_max3); - - uword row, col; - x.max(row, col); - - if (row != 0 && row != r - 1 && col != 0 && col != r - 1) - { - uword srow, scol; - - srow = x_subview_max1 % (r - 2); - scol = x_subview_max1 / (r - 2); - REQUIRE( x_max == (srow + 1) + r * (scol + 1) ); - REQUIRE( x_max == x_subview_max2 + r ); - - srow = x_subview_max3 % (r - 2); - scol = x_subview_max3 / (r - 2); - REQUIRE( x_max == (srow + 1) + r * scol ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - REQUIRE( mval == Approx(mval3) ); - } - } - } - - - -TEST_CASE("fn_max_incomplete_subview_col_test") - { - for (size_t r = 10; r < 50; ++r) - { - vec x; - x.randu(r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const double mval = x.max(x_max); - const double mval1 = x.submat(1, 0, r - 2, 0).max(x_subview_max1); - const double mval2 = x.rows(1, r - 2).max(x_subview_max2); - - if (x_max != 0 && x_max != r - 1) - { - REQUIRE( x_max == x_subview_max1 + 1 ); - REQUIRE( x_max == x_subview_max2 + 1 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_max_cx_subview_row_test") - { - for (size_t r = 10; r < 50; ++r) - { - cx_rowvec x; - x.randu(r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(0, 0, 0, r - 1).max(x_subview_max1); - const std::complex mval2 = x.cols(0, r - 1).max(x_subview_max2); - - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - - - -TEST_CASE("fn_max_cx_incomplete_subview_test") - { - for (size_t r = 50; r < 150; ++r) - { - cx_mat x; - x.randu(r, r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - uword x_subview_max3; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1); - const std::complex mval2 = x.cols(1, r - 2).max(x_subview_max2); - const std::complex mval3 = x.rows(1, r - 2).max(x_subview_max3); - - uword row, col; - x.max(row, col); - - if (row != 0 && row != r - 1 && col != 0 && col != r - 1) - { - uword srow, scol; - - srow = x_subview_max1 % (r - 2); - scol = x_subview_max1 / (r - 2); - REQUIRE( x_max == (srow + 1) + r * (scol + 1) ); - REQUIRE( x_max == x_subview_max2 + r ); - - srow = x_subview_max3 % (r - 2); - scol = x_subview_max3 / (r - 2); - REQUIRE( x_max == (srow + 1) + r * scol ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - REQUIRE( mval.real() == Approx(mval3.real()) ); - REQUIRE( mval.imag() == Approx(mval3.imag()) ); - } - } - } - - - -TEST_CASE("fn_max_cx_incomplete_subview_col_test") - { - for (size_t r = 10; r < 50; ++r) - { - cx_vec x; - x.randu(r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(1, 0, r - 2, 0).max(x_subview_max1); - const std::complex mval2 = x.rows(1, r - 2).max(x_subview_max2); - - if (x_max != 0 && x_max != r - 1) - { - REQUIRE( x_max == x_subview_max1 + 1 ); - REQUIRE( x_max == x_subview_max2 + 1 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } - - - -TEST_CASE("fn_max_cx_incomplete_subview_row_test") - { - for (size_t r = 10; r < 50; ++r) - { - cx_rowvec x; - x.randu(r); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(0, 1, 0, r - 2).max(x_subview_max1); - const std::complex mval2 = x.cols(1, r - 2).max(x_subview_max2); - - if (x_max != 0 && x_max != r - 1) - { - REQUIRE( x_max == x_subview_max1 + 1 ); - REQUIRE( x_max == x_subview_max2 + 1 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } - - - -TEST_CASE("fn_max_weird_operation_test") - { - mat a(10, 10); - mat b(25, 10); - a.randn(); - b.randn(); - - mat output = a * b.t(); - - uword real_max; - uword operation_max; - - const double mval = output.max(real_max); - const double other_mval = (a * b.t()).max(operation_max); - - REQUIRE( real_max == operation_max ); - REQUIRE( mval == Approx(other_mval) ); - } - - - -TEST_CASE("fn_max_weird_sparse_operation_test") - { - sp_mat a(10, 10); - sp_mat b(25, 10); - a.sprandn(10, 10, 0.3); - b.sprandn(25, 10, 0.3); - - sp_mat output = a * b.t(); - - uword real_max; - uword operation_max; - - const double mval = output.max(real_max); - const double other_mval = (a * b.t()).max(operation_max); - - REQUIRE( real_max == operation_max ); - REQUIRE( mval == Approx(other_mval) ); - } - - - -TEST_CASE("fn_max_spsubview_test") - { - // We will assume subview.at() works and returns points within the bounds of - // the matrix, so we just have to ensure the results are the same as - // Mat.max()... - for (size_t r = 50; r < 150; ++r) - { - sp_mat x; - x.sprandn(r, r, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - uword x_subview_max3; - - const double mval = x.max(x_max); - const double mval1 = x.submat(0, 0, r - 1, r - 1).max(x_subview_max1); - const double mval2 = x.cols(0, r - 1).max(x_subview_max2); - const double mval3 = x.rows(0, r - 1).max(x_subview_max3); - - if (mval != 0.0) - { - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - REQUIRE( x_max == x_subview_max3 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - REQUIRE( mval == Approx(mval3) ); - } - } - } - - - -TEST_CASE("fn_max_spsubview_col_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_vec x; - x.sprandn(r, 1, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const double mval = x.max(x_max); - const double mval1 = x.submat(0, 0, r - 1, 0).max(x_subview_max1); - const double mval2 = x.rows(0, r - 1).max(x_subview_max2); - - if (mval != 0.0) - { - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_max_spsubview_row_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_rowvec x; - x.sprandn(1, r, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const double mval = x.max(x_max); - const double mval1 = x.submat(0, 0, 0, r - 1).max(x_subview_max1); - const double mval2 = x.cols(0, r - 1).max(x_subview_max2); - - if (mval != 0.0) - { - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_max_spincompletesubview_test") - { - for (size_t r = 50; r < 150; ++r) - { - sp_mat x; - x.sprandn(r, r, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - uword x_subview_max3; - - const double mval = x.max(x_max); - const double mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1); - const double mval2 = x.cols(1, r - 2).max(x_subview_max2); - const double mval3 = x.rows(1, r - 2).max(x_subview_max3); - - uword row, col; - x.max(row, col); - - if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != 0.0) - { - uword srow, scol; - - srow = x_subview_max1 % (r - 2); - scol = x_subview_max1 / (r - 2); - REQUIRE( x_max == (srow + 1) + r * (scol + 1) ); - REQUIRE( x_max == x_subview_max2 + r ); - - srow = x_subview_max3 % (r - 2); - scol = x_subview_max3 / (r - 2); - REQUIRE( x_max == (srow + 1) + r * scol ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - REQUIRE( mval == Approx(mval3) ); - } - } - } - - - -TEST_CASE("fn_max_spincompletesubview_col_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_vec x; - x.sprandu(r, 1, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const double mval = x.max(x_max); - const double mval1 = x.submat(1, 0, r - 2, 0).max(x_subview_max1); - const double mval2 = x.rows(1, r - 2).max(x_subview_max2); - - if (x_max != 0 && x_max != r - 1 && mval != 0.0) - { - REQUIRE( x_max == x_subview_max1 + 1 ); - REQUIRE( x_max == x_subview_max2 + 1 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_max_spincompletesubview_row_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_rowvec x; - x.sprandn(1, r, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const double mval = x.max(x_max); - const double mval1 = x.submat(0, 1, 0, r - 2).max(x_subview_max1); - const double mval2 = x.cols(1, r - 2).max(x_subview_max2); - - if (mval != 0.0 && x_max != 0 && x_max != r - 1) - { - REQUIRE( x_max == x_subview_max1 + 1 ); - REQUIRE( x_max == x_subview_max2 + 1 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_max_cx_spsubview_test") - { - // We will assume subview.at() works and returns points within the bounds of - // the matrix, so we just have to ensure the results are the same as - // Mat.max()... - for (size_t r = 50; r < 150; ++r) - { - sp_cx_mat x; - x.sprandn(r, r, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - uword x_subview_max3; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(0, 0, r - 1, r - 1).max(x_subview_max1); - const std::complex mval2 = x.cols(0, r - 1).max(x_subview_max2); - const std::complex mval3 = x.rows(0, r - 1).max(x_subview_max3); - - if (mval != std::complex(0.0)) - { - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - REQUIRE( x_max == x_subview_max3 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - REQUIRE( mval.real() == Approx(mval3.real()) ); - REQUIRE( mval.imag() == Approx(mval3.imag()) ); - } - } - } - - - -TEST_CASE("fn_max_cx_spsubview_col_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_cx_vec x; - x.sprandn(r, 1, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(0, 0, r - 1, 0).max(x_subview_max1); - const std::complex mval2 = x.rows(0, r - 1).max(x_subview_max2); - - if (mval != std::complex(0.0)) - { - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } - - - -TEST_CASE("fn_max_cx_spsubview_row_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_cx_rowvec x; - x.sprandn(1, r, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(0, 0, 0, r - 1).max(x_subview_max1); - const std::complex mval2 = x.cols(0, r - 1).max(x_subview_max2); - - if (mval != std::complex(0.0)) - { - REQUIRE( x_max == x_subview_max1 ); - REQUIRE( x_max == x_subview_max2 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } - - - -TEST_CASE("fn_max_cx_spincompletesubview_test") - { - for (size_t r = 50; r < 150; ++r) - { - sp_cx_mat x; - x.sprandn(r, r, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - uword x_subview_max3; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1); - const std::complex mval2 = x.cols(1, r - 2).max(x_subview_max2); - const std::complex mval3 = x.rows(1, r - 2).max(x_subview_max3); - - uword row, col; - x.max(row, col); - - if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != std::complex(0.0)) - { - uword srow, scol; - - srow = x_subview_max1 % (r - 2); - scol = x_subview_max1 / (r - 2); - REQUIRE( x_max == (srow + 1) + r * (scol + 1) ); - REQUIRE( x_max == x_subview_max2 + r ); - - srow = x_subview_max3 % (r - 2); - scol = x_subview_max3 / (r - 2); - REQUIRE( x_max == (srow + 1) + r * scol ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - REQUIRE( mval.real() == Approx(mval3.real()) ); - REQUIRE( mval.imag() == Approx(mval3.imag()) ); - } - } - } - - - -TEST_CASE("fn_max_cx_spincompletesubview_col_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_cx_vec x; - x.sprandn(r, 1, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(1, 0, r - 2, 0).max(x_subview_max1); - const std::complex mval2 = x.rows(1, r - 2).max(x_subview_max2); - - if (x_max != 0 && x_max != r - 1 && mval != std::complex(0.0)) - { - REQUIRE( x_max == x_subview_max1 + 1 ); - REQUIRE( x_max == x_subview_max2 + 1 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } - - - -TEST_CASE("fn_max_cx_spincompletesubview_row_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_cx_rowvec x; - x.sprandn(1, r, 0.3); - - uword x_max; - uword x_subview_max1; - uword x_subview_max2; - - const std::complex mval = x.max(x_max); - const std::complex mval1 = x.submat(0, 1, 0, r - 2).max(x_subview_max1); - const std::complex mval2 = x.cols(1, r - 2).max(x_subview_max2); - - if (x_max != 0 && x_max != r - 1 && mval != std::complex(0.0)) - { - REQUIRE( x_max == x_subview_max1 + 1 ); - REQUIRE( x_max == x_subview_max2 + 1 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_mean.cpp armadillo-10.8.2+dfsg/tests/fn_mean.cpp --- armadillo-9.800.4+dfsg/tests/fn_mean.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_mean.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,948 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("fn_mean_spmat_empty_test") - { - SpMat m(20, 25); - - SpRow result = mean(m, 0); - REQUIRE( result.n_nonzero == 0 ); - REQUIRE( result.n_rows == 1 ); - REQUIRE( result.n_cols == 25 ); - - SpCol result2 = mean(m, 1); - REQUIRE( result2.n_nonzero == 0 ); - REQUIRE( result2.n_rows == 20 ); - REQUIRE( result2.n_cols == 1 ); - - double r = mean(mean(m)); - REQUIRE( r == Approx(0.0) ); - - // Now the same with subviews. - result = mean(m.submat(2, 2, 11, 16)); - REQUIRE( result.n_nonzero == 0 ); - REQUIRE( result.n_rows == 1 ); - REQUIRE( result.n_cols == 15 ); - - result2 = mean(m.submat(2, 2, 11, 16), 1); - REQUIRE( result2.n_nonzero == 0 ); - REQUIRE( result2.n_rows == 10 ); - REQUIRE( result2.n_cols == 1 ); - - r = mean(mean(m.submat(2, 2, 11, 16))); - REQUIRE( r == Approx(0.0) ); - - // And with an operation. - result = mean(trans(m)); - REQUIRE( result.n_nonzero == 0 ); - REQUIRE( result.n_rows == 1 ); - REQUIRE( result.n_cols == 20 ); - - result2 = mean(trans(m), 1); - REQUIRE( result2.n_nonzero == 0 ); - REQUIRE( result2.n_rows == 25 ); - REQUIRE( result2.n_cols == 1 ); - - r = mean(mean(trans(m))); - REQUIRE( r == Approx(0.0) ); - } - - - -TEST_CASE("fn_mean_spcxmat_empty_test") - { - // Now with complex numbers. - SpMat > m(20, 25); - SpRow > result = mean(m, 0); - - REQUIRE( result.n_nonzero == 0 ); - REQUIRE( result.n_rows == 1 ); - REQUIRE( result.n_cols == 25 ); - - SpCol > result2 = mean(m, 1); - - REQUIRE( result2.n_nonzero == 0 ); - REQUIRE( result2.n_rows == 20 ); - REQUIRE( result2.n_cols == 1 ); - - std::complex r = mean(mean(m)); - - REQUIRE( real(r) == Approx(0.0) ); - REQUIRE( imag(r) == Approx(0.0) ); - - // Now the same with subviews. - result = mean(m.submat(2, 2, 11, 16)); - REQUIRE( result.n_nonzero == 0 ); - REQUIRE( result.n_rows == 1 ); - REQUIRE( result.n_cols == 15 ); - - result2 = mean(m.submat(2, 2, 11, 16), 1); - REQUIRE( result2.n_nonzero == 0 ); - REQUIRE( result2.n_rows == 10 ); - REQUIRE( result2.n_cols == 1 ); - - r = mean(mean(m.submat(2, 2, 11, 16))); - REQUIRE( real(r) == Approx(0.0) ); - REQUIRE( imag(r) == Approx(0.0) ); - - // And with an operation. - result = mean(trans(m)); - REQUIRE( result.n_nonzero == 0 ); - REQUIRE( result.n_rows == 1 ); - REQUIRE( result.n_cols == 20 ); - - result2 = mean(trans(m), 1); - REQUIRE( result2.n_nonzero == 0 ); - REQUIRE( result2.n_rows == 25 ); - REQUIRE( result2.n_cols == 1 ); - - r = mean(mean(trans(m))); - REQUIRE( real(r) == Approx(0.0) ); - REQUIRE( imag(r) == Approx(0.0) ); - } - - - -TEST_CASE("fn_mean_spmat_test") - { - // Create a random matrix and do mean testing on it, with varying levels of - // nonzero (eventually this becomes a fully dense matrix). - for (int i = 0; i < 10; ++i) - { - SpMat x; - x.sprandu(50, 75, ((double) (i + 1)) / 10); - mat d(x); - - SpRow rr = mean(x); - rowvec drr = mean(d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - REQUIRE( drr[j] == Approx((double) rr[j]) ); - - SpCol cr = mean(x, 1); - vec dcr = mean(d, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - - double dr = mean(mean(x)); - double ddr = mean(mean(d)); - - REQUIRE( dr == Approx(ddr) ); - - // Now on a subview. - rr = mean(x.submat(11, 11, 30, 45), 0); - drr = mean(d.submat(11, 11, 30, 45), 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 35 ); - for (uword j = 0; j < 35; ++j) - REQUIRE( drr[j] == Approx((double) rr[j]) ); - - cr = mean(x.submat(11, 11, 30, 45), 1); - dcr = mean(d.submat(11, 11, 30, 45), 1); - - REQUIRE( cr.n_rows == 20 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 20; ++j) - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - - dr = mean(mean(x.submat(11, 11, 30, 45))); - ddr = mean(mean(d.submat(11, 11, 30, 45))); - - REQUIRE( dr == Approx(ddr) ); - - // Now on an SpOp (spop_scalar_times) - rr = mean(3.0 * x); - drr = mean(3.0 * d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - REQUIRE( drr[j] == Approx((double) rr[j]) ); - - cr = mean(4.5 * x, 1); - dcr = mean(4.5 * d, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - - dr = mean(mean(1.2 * x)); - ddr = mean(mean(1.2 * d)); - - REQUIRE( dr == Approx(ddr) ); - - // Now on an SpGlue! - SpMat y; - y.sprandu(50, 75, 0.3); - mat e(y); - - rr = mean(x + y); - drr = mean(d + e); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - REQUIRE( drr[j] == Approx((double) rr[j]) ); - - cr = mean(x + y, 1); - dcr = mean(d + e, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - - dr = mean(mean(x + y)); - ddr = mean(mean(d + e)); - - REQUIRE( dr == Approx(ddr) ); - } - } - - - -TEST_CASE("fn_mean_spcxmat_test") - { - // Create a random matrix and do mean testing on it, with varying levels of - // nonzero (eventually this becomes a fully dense matrix). - for (int i = 0; i < 10; ++i) - { - SpMat > x; - x.sprandu(50, 75, ((double) (i + 1)) / 10); - cx_mat d(x); - - SpRow > rr = mean(x); - cx_rowvec drr = mean(d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( real(drr[j]) == Approx(real((std::complex) rr[j])) ); - REQUIRE( imag(drr[j]) == Approx(imag((std::complex) rr[j])) ); - } - - SpCol > cr = mean(x, 1); - cx_vec dcr = mean(d, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( real(dcr[j]) == Approx(real((std::complex) cr[j])) ); - REQUIRE( imag(dcr[j]) == Approx(imag((std::complex) cr[j])) ); - } - - std::complex dr = mean(mean(x)); - std::complex ddr = mean(mean(d)); - - REQUIRE( real(dr) == Approx(real(ddr)) ); - REQUIRE( imag(dr) == Approx(imag(ddr)) ); - - // Now on a subview. - rr = mean(x.submat(11, 11, 30, 45), 0); - drr = mean(d.submat(11, 11, 30, 45), 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 35 ); - for (uword j = 0; j < 35; ++j) - { - REQUIRE( real(drr[j]) == Approx(real((std::complex) rr[j])) ); - REQUIRE( imag(drr[j]) == Approx(imag((std::complex) rr[j])) ); - } - - cr = mean(x.submat(11, 11, 30, 45), 1); - dcr = mean(d.submat(11, 11, 30, 45), 1); - - REQUIRE( cr.n_rows == 20 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 20; ++j) - { - REQUIRE( real(dcr[j]) == Approx(real((std::complex) cr[j])) ); - REQUIRE( imag(dcr[j]) == Approx(imag((std::complex) cr[j])) ); - } - - dr = mean(mean(x.submat(11, 11, 30, 45))); - ddr = mean(mean(d.submat(11, 11, 30, 45))); - - REQUIRE( real(dr) == Approx(real(ddr)) ); - REQUIRE( imag(dr) == Approx(imag(ddr)) ); - - // Now on an SpOp (spop_scalar_times) - rr = mean(3.0 * x); - drr = mean(3.0 * d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( real(drr[j]) == Approx(real((std::complex) rr[j])) ); - REQUIRE( imag(drr[j]) == Approx(imag((std::complex) rr[j])) ); - } - - cr = mean(4.5 * x, 1); - dcr = mean(4.5 * d, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( real(dcr[j]) == Approx(real((std::complex) cr[j])) ); - REQUIRE( imag(dcr[j]) == Approx(imag((std::complex) cr[j])) ); - } - - dr = mean(mean(1.2 * x)); - ddr = mean(mean(1.2 * d)); - - REQUIRE( real(dr) == Approx(real(ddr)) ); - REQUIRE( imag(dr) == Approx(imag(ddr)) ); - - // Now on an SpGlue! - SpMat > y; - y.sprandu(50, 75, 0.3); - cx_mat e(y); - - rr = mean(x + y); - drr = mean(d + e); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( real(drr[j]) == Approx(real((std::complex) rr[j])) ); - REQUIRE( imag(drr[j]) == Approx(imag((std::complex) rr[j])) ); - } - - cr = mean(x + y, 1); - dcr = mean(d + e, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( real(dcr[j]) == Approx(real((std::complex) cr[j])) ); - REQUIRE( imag(dcr[j]) == Approx(imag((std::complex) cr[j])) ); - } - - dr = mean(mean(x + y)); - ddr = mean(mean(d + e)); - - REQUIRE( real(dr) == Approx(real(ddr)) ); - REQUIRE( imag(dr) == Approx(imag(ddr)) ); - } - } - - -TEST_CASE("fn_mean_sp_vector_test") - { - // Test mean() on vectors. - SpCol c(1000); - - SpCol cr = mean(c, 0); - REQUIRE( cr.n_rows == 1 ); - REQUIRE( cr.n_cols == 1 ); - REQUIRE( (double) cr[0] == Approx(0.0) ); - - cr = mean(c, 1); - REQUIRE( cr.n_rows == 1000 ); - REQUIRE( cr.n_cols == 1 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( (double) cr[i] == Approx(0.0) ); - } - - double ddcr = mean(c); - REQUIRE( ddcr == Approx(0.0) ); - - c.sprandu(1000, 1, 0.3); - vec dc(c); - - cr = mean(c, 0); - vec dcr = mean(dc, 0); - - REQUIRE( cr.n_rows == 1 ); - REQUIRE( cr.n_cols == 1 ); - REQUIRE( (double) cr[0] == Approx(dcr[0]) ); - - cr = mean(c, 1); - dcr = mean(dc, 1); - - REQUIRE( cr.n_rows == 1000 ); - REQUIRE( cr.n_cols == 1 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( (double) cr[i] == Approx(dcr[i]) ); - } - - ddcr = mean(c); - double dddr = mean(dc); - - REQUIRE( ddcr == Approx(dddr) ); - - SpRow r; - r.sprandu(1, 1000, 0.3); - rowvec dr(r); - - SpRow rr = mean(r, 0); - rowvec drr = mean(dr, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 1000 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( (double) rr[i] == Approx(drr[i]) ); - } - - rr = mean(r, 1); - drr = mean(dr, 1); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 1 ); - REQUIRE( (double) rr[0] == Approx(drr[0]) ); - - ddcr = mean(r); - dddr = mean(dr); - - REQUIRE( ddcr == Approx(dddr) ); - } - - - -TEST_CASE("fn_mean_sp_cx_vector_test") - { - // Test mean() on vectors. - SpCol > c(1000); - - SpCol > cr = mean(c, 0); - REQUIRE( cr.n_rows == 1 ); - REQUIRE( cr.n_cols == 1 ); - REQUIRE( real((std::complex) cr[0]) == Approx(0.0) ); - REQUIRE( imag((std::complex) cr[0]) == Approx(0.0) ); - - cr = mean(c, 1); - REQUIRE( cr.n_rows == 1000 ); - REQUIRE( cr.n_cols == 1 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( real((std::complex) cr[i]) == Approx(0.0) ); - REQUIRE( imag((std::complex) cr[i]) == Approx(0.0) ); - } - - std::complex ddcr = mean(c); - REQUIRE( real(ddcr) == Approx(0.0) ); - REQUIRE( imag(ddcr) == Approx(0.0) ); - - c.sprandu(1000, 1, 0.3); - cx_vec dc(c); - - cr = mean(c, 0); - cx_vec dcr = mean(dc, 0); - - REQUIRE( cr.n_rows == 1 ); - REQUIRE( cr.n_cols == 1 ); - REQUIRE( real((std::complex) cr[0]) == Approx(real(dcr[0])) ); - REQUIRE( imag((std::complex) cr[0]) == Approx(imag(dcr[0])) ); - - cr = mean(c, 1); - dcr = mean(dc, 1); - - REQUIRE( cr.n_rows == 1000 ); - REQUIRE( cr.n_cols == 1 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( real((std::complex) cr[i]) == Approx(real(dcr[i])) ); - REQUIRE( imag((std::complex) cr[i]) == Approx(imag(dcr[i])) ); - } - - ddcr = mean(c); - std::complex dddr = mean(dc); - - REQUIRE( real(ddcr) == Approx(real(dddr)) ); - REQUIRE( imag(ddcr) == Approx(imag(dddr)) ); - - SpRow > r; - r.sprandu(1, 1000, 0.3); - cx_rowvec dr(r); - - SpRow > rr = mean(r, 0); - cx_rowvec drr = mean(dr, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 1000 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( real((std::complex) rr[i]) == Approx(real(drr[i])) ); - REQUIRE( imag((std::complex) rr[i]) == Approx(imag(drr[i])) ); - } - - rr = mean(r, 1); - drr = mean(dr, 1); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 1 ); - REQUIRE( real((std::complex) rr[0]) == Approx(real(drr[0])) ); - REQUIRE( imag((std::complex) rr[0]) == Approx(imag(drr[0])) ); - - ddcr = mean(r); - dddr = mean(dr); - - REQUIRE( real(ddcr) == Approx(real(dddr)) ); - REQUIRE( imag(ddcr) == Approx(imag(dddr)) ); - } - - - -TEST_CASE("fn_mean_robust_sparse_test") - { - // Create a sparse matrix with values that will overflow. - SpMat x; - x.sprandu(50, 75, 0.1); - for (SpMat::iterator i = x.begin(); i != x.end(); ++i) - { - (*i) *= std::numeric_limits::max(); - } - mat d(x); - - SpRow rr = mean(x); - rowvec drr = mean(d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - SpCol cr = mean(x, 1); - vec dcr = mean(d, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - double dr = mean(mean(x)); - double ddr = mean(mean(d)); - - REQUIRE( dr == Approx(ddr) ); - - // Now on a subview. - rr = mean(x.submat(11, 11, 30, 45), 0); - drr = mean(d.submat(11, 11, 30, 45), 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 35 ); - for (uword j = 0; j < 35; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = mean(x.submat(11, 11, 30, 45), 1); - dcr = mean(d.submat(11, 11, 30, 45), 1); - - REQUIRE( cr.n_rows == 20 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 20; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - dr = mean(mean(x.submat(11, 11, 30, 45))); - ddr = mean(mean(d.submat(11, 11, 30, 45))); - - REQUIRE( dr == Approx(ddr) ); - - // Now on an SpOp (spop_scalar_times) - rr = mean(0.4 * x); - drr = mean(0.4 * d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = mean(0.1 * x, 1); - dcr = mean(0.1 * d, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - dr = mean(mean(0.7 * x)); - ddr = mean(mean(0.7 * d)); - - REQUIRE( dr == Approx(ddr) ); - - // Now on an SpGlue! - SpMat y; - y.sprandu(50, 75, 0.3); - for (SpMat::iterator i = y.begin(); i != y.end(); ++i) - { - (*i) *= std::numeric_limits::max(); - } - mat e(y); - - rr = mean(0.5 * x + 0.5 * y); - drr = mean(0.5 * d + 0.5 * e); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = mean(0.5 * x + 0.5 * y, 1); - dcr = mean(0.5 * d + 0.5 * e, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - dr = mean(mean(0.5 * x + 0.5 * y)); - ddr = mean(mean(0.5 * d + 0.5 * e)); - - REQUIRE( dr == Approx(ddr) ); - } - - - -TEST_CASE("fn_mean_robust_cx_sparse_test") - { - SpMat > x; - x.sprandu(50, 75, 0.3); - for (SpMat >::iterator i = x.begin(); i != x.end(); ++i) - { - (*i) *= std::numeric_limits::max(); - } - cx_mat d(x); - - SpRow > rr = mean(x); - cx_rowvec drr = mean(d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( real(drr[j]) == Approx(real((std::complex) rr[j])) ); - REQUIRE( imag(drr[j]) == Approx(imag((std::complex) rr[j])) ); - } - - SpCol > cr = mean(x, 1); - cx_vec dcr = mean(d, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( real(dcr[j]) == Approx(real((std::complex) cr[j])) ); - REQUIRE( imag(dcr[j]) == Approx(imag((std::complex) cr[j])) ); - } - - std::complex dr = mean(mean(x)); - std::complex ddr = mean(mean(d)); - - REQUIRE( real(dr) == Approx(real(ddr)) ); - REQUIRE( imag(dr) == Approx(imag(ddr)) ); - - // Now on a subview. - rr = mean(x.submat(11, 11, 30, 45), 0); - drr = mean(d.submat(11, 11, 30, 45), 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 35 ); - for (uword j = 0; j < 35; ++j) - { - REQUIRE( real(drr[j]) == Approx(real((std::complex) rr[j])) ); - REQUIRE( imag(drr[j]) == Approx(imag((std::complex) rr[j])) ); - } - - cr = mean(x.submat(11, 11, 30, 45), 1); - dcr = mean(d.submat(11, 11, 30, 45), 1); - - REQUIRE( cr.n_rows == 20 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 20; ++j) - { - REQUIRE( real(dcr[j]) == Approx(real((std::complex) cr[j])) ); - REQUIRE( imag(dcr[j]) == Approx(imag((std::complex) cr[j])) ); - } - - dr = mean(mean(x.submat(11, 11, 30, 45))); - ddr = mean(mean(d.submat(11, 11, 30, 45))); - - REQUIRE( real(dr) == Approx(real(ddr)) ); - REQUIRE( imag(dr) == Approx(imag(ddr)) ); - - // Now on an SpOp (spop_scalar_times) - rr = mean(0.5 * x); - drr = mean(0.5 * d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( real(drr[j]) == Approx(real((std::complex) rr[j])) ); - REQUIRE( imag(drr[j]) == Approx(imag((std::complex) rr[j])) ); - } - - cr = mean(0.7 * x, 1); - dcr = mean(0.7 * d, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( real(dcr[j]) == Approx(real((std::complex) cr[j])) ); - REQUIRE( imag(dcr[j]) == Approx(imag((std::complex) cr[j])) ); - } - - dr = mean(mean(0.6 * x)); - ddr = mean(mean(0.6 * d)); - - REQUIRE( real(dr) == Approx(real(ddr)) ); - REQUIRE( imag(dr) == Approx(imag(ddr)) ); - - // Now on an SpGlue! - SpMat > y; - y.sprandu(50, 75, 0.3); - for (SpMat >::iterator i = y.begin(); i != y.end(); ++i) - { - (*i) *= std::numeric_limits::max(); - } - cx_mat e(y); - - rr = mean(0.5 * x + 0.5 * y); - drr = mean(0.5 * d + 0.5 * e); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( real(drr[j]) == Approx(real((std::complex) rr[j])) ); - REQUIRE( imag(drr[j]) == Approx(imag((std::complex) rr[j])) ); - } - - cr = mean(0.5 * x + 0.5 * y, 1); - dcr = mean(0.5 * d + 0.5 * e, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( real(dcr[j]) == Approx(real((std::complex) cr[j])) ); - REQUIRE( imag(dcr[j]) == Approx(imag((std::complex) cr[j])) ); - } - - dr = mean(mean(0.5 * x + 0.5 * y)); - ddr = mean(mean(0.5 * d + 0.5 * e)); - - REQUIRE( real(dr) == Approx(real(ddr)) ); - REQUIRE( imag(dr) == Approx(imag(ddr)) ); - } - - - -TEST_CASE("fn_mean_robust_sparse_vector_test") - { - // Test mean() on vectors. - SpCol c(1000); - - SpCol cr; - double ddcr; - - c.sprandu(1000, 1, 0.3); - for (SpCol::iterator i = c.begin(); i != c.end(); ++i) - { - (*i) *= (std::numeric_limits::max()); - } - vec dc(c); - - cr = mean(c, 0); - vec dcr = mean(dc, 0); - - REQUIRE( cr.n_rows == 1 ); - REQUIRE( cr.n_cols == 1 ); - REQUIRE( (double) cr[0] == Approx(dcr[0]) ); - - cr = mean(c, 1); - dcr = mean(dc, 1); - - REQUIRE( cr.n_rows == 1000 ); - REQUIRE( cr.n_cols == 1 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( (double) cr[i] == Approx(dcr[i]) ); - } - - ddcr = mean(c); - double dddr = mean(dc); - - REQUIRE( ddcr == Approx(dddr) ); - - SpRow r; - r.sprandu(1, 1000, 0.3); - for (SpRow::iterator i = r.begin(); i != r.end(); ++i) - { - (*i) *= (std::numeric_limits::max()); - } - rowvec dr(r); - - SpRow rr = mean(r, 0); - rowvec drr = mean(dr, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 1000 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( (double) rr[i] == Approx(drr[i]) ); - } - - rr = mean(r, 1); - drr = mean(dr, 1); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 1 ); - REQUIRE( (double) rr[0] == Approx(drr[0]) ); - - ddcr = mean(r); - dddr = mean(dr); - - REQUIRE( ddcr == Approx(dddr) ); - } - - - -TEST_CASE("fn_mean_robust_cx_sparse_vector_test") - { - // Test mean() on vectors. - SpCol > c(1000); - - SpCol > cr; - std::complex ddcr; - - c.sprandu(1000, 1, 0.3); - for (SpCol >::iterator i = c.begin(); i != c.end(); ++i) - { - (*i) *= (std::numeric_limits::max()); - } - cx_vec dc(c); - - cr = mean(c, 0); - cx_vec dcr = mean(dc, 0); - - REQUIRE( cr.n_rows == 1 ); - REQUIRE( cr.n_cols == 1 ); - REQUIRE( real((std::complex) cr[0]) == Approx(real(dcr[0])) ); - REQUIRE( imag((std::complex) cr[0]) == Approx(imag(dcr[0])) ); - - cr = mean(c, 1); - dcr = mean(dc, 1); - - REQUIRE( cr.n_rows == 1000 ); - REQUIRE( cr.n_cols == 1 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( real((std::complex) cr[i]) == Approx(real(dcr[i])) ); - REQUIRE( imag((std::complex) cr[i]) == Approx(imag(dcr[i])) ); - } - - ddcr = mean(c); - std::complex dddr = mean(dc); - - REQUIRE( real(ddcr) == Approx(real(dddr)) ); - REQUIRE( imag(ddcr) == Approx(imag(dddr)) ); - - SpRow > r; - r.sprandu(1, 1000, 0.3); - cx_rowvec dr(r); - - SpRow > rr = mean(r, 0); - cx_rowvec drr = mean(dr, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 1000 ); - for (uword i = 0; i < 1000; ++i) - { - REQUIRE( real((std::complex) rr[i]) == Approx(real(drr[i])) ); - REQUIRE( imag((std::complex) rr[i]) == Approx(imag(drr[i])) ); - } - - rr = mean(r, 1); - drr = mean(dr, 1); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 1 ); - REQUIRE( real((std::complex) rr[0]) == Approx(real(drr[0])) ); - REQUIRE( imag((std::complex) rr[0]) == Approx(imag(drr[0])) ); - - ddcr = mean(r); - dddr = mean(dr); - - REQUIRE( real(ddcr) == Approx(real(dddr)) ); - REQUIRE( imag(ddcr) == Approx(imag(dddr)) ); - } - - - -TEST_CASE("fn_mean_sparse_alias_test") - { - sp_mat s; - s.sprandu(70, 70, 0.3); - mat d(s); - - s = mean(s); - d = mean(d); - - REQUIRE( d.n_rows == s.n_rows ); - REQUIRE( d.n_cols == s.n_cols ); - for (uword i = 0; i < d.n_elem; ++i) - { - REQUIRE( d[i] == Approx((double) s[i]) ); - } - - s.sprandu(70, 70, 0.3); - d = s; - - s = mean(s, 1); - d = mean(d, 1); - for (uword i = 0; i < d.n_elem; ++i) - { - REQUIRE( d[i] == Approx((double) s[i]) ); - } - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_min.cpp armadillo-10.8.2+dfsg/tests/fn_min.cpp --- armadillo-9.800.4+dfsg/tests/fn_min.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_min.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,452 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("fn_min_weird_operation") - { - mat a(10, 10); - mat b(25, 10); - a.randn(); - b.randn(); - - mat output = a * b.t(); - - uword real_min; - uword operation_min; - - const double mval = output.min(real_min); - const double other_mval = (a * b.t()).min(operation_min); - - REQUIRE( real_min == operation_min ); - REQUIRE( mval == Approx(other_mval) ); - } - - - -TEST_CASE("fn_min_weird_sparse_operation") - { - sp_mat a(10, 10); - sp_mat b(25, 10); - a.sprandn(10, 10, 0.3); - b.sprandn(25, 10, 0.3); - - sp_mat output = a * b.t(); - - uword real_min; - uword operation_min; - - const double mval = output.min(real_min); - const double other_mval = (a * b.t()).min(operation_min); - - REQUIRE( real_min == operation_min ); - REQUIRE( mval == Approx(other_mval) ); - } - - - -TEST_CASE("fn_min_sp_subview_test") - { - // We will assume subview.at() works and returns points within the bounds of - // the matrix, so we just have to ensure the results are the same as - // Mat.min()... - for (size_t r = 50; r < 150; ++r) - { - sp_mat x; - x.sprandn(r, r, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - uword x_subview_min3; - - const double mval = x.min(x_min); - const double mval1 = x.submat(0, 0, r - 1, r - 1).min(x_subview_min1); - const double mval2 = x.cols(0, r - 1).min(x_subview_min2); - const double mval3 = x.rows(0, r - 1).min(x_subview_min3); - - if (mval != 0.0) - { - REQUIRE( x_min == x_subview_min1 ); - REQUIRE( x_min == x_subview_min2 ); - REQUIRE( x_min == x_subview_min3 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - REQUIRE( mval == Approx(mval3) ); - } - } - } - - - -TEST_CASE("fn_min_spsubview_col_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_vec x; - x.sprandn(r, 1, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - - const double mval = x.min(x_min); - const double mval1 = x.submat(0, 0, r - 1, 0).min(x_subview_min1); - const double mval2 = x.rows(0, r - 1).min(x_subview_min2); - - if (mval != 0.0) - { - REQUIRE( x_min == x_subview_min1 ); - REQUIRE( x_min == x_subview_min2 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_min_spsubview_row_min_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_rowvec x; - x.sprandn(1, r, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - - const double mval = x.min(x_min); - const double mval1 = x.submat(0, 0, 0, r - 1).min(x_subview_min1); - const double mval2 = x.cols(0, r - 1).min(x_subview_min2); - - if (mval != 0.0) - { - REQUIRE( x_min == x_subview_min1 ); - REQUIRE( x_min == x_subview_min2 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_min_spincompletesubview_min_test") - { - for (size_t r = 50; r < 150; ++r) - { - sp_mat x; - x.sprandn(r, r, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - uword x_subview_min3; - - const double mval = x.min(x_min); - const double mval1 = x.submat(1, 1, r - 2, r - 2).min(x_subview_min1); - const double mval2 = x.cols(1, r - 2).min(x_subview_min2); - const double mval3 = x.rows(1, r - 2).min(x_subview_min3); - - uword row, col; - x.min(row, col); - - if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != 0.0) - { - uword srow, scol; - - srow = x_subview_min1 % (r - 2); - scol = x_subview_min1 / (r - 2); - REQUIRE( x_min == (srow + 1) + r * (scol + 1) ); - REQUIRE( x_min == x_subview_min2 + r ); - - srow = x_subview_min3 % (r - 2); - scol = x_subview_min3 / (r - 2); - REQUIRE( x_min == (srow + 1) + r * scol ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - REQUIRE( mval == Approx(mval3) ); - } - } - } - - - -TEST_CASE("fn_min_spincompletesubview_col_min_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_vec x; - x.sprandu(r, 1, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - - const double mval = x.min(x_min); - const double mval1 = x.submat(1, 0, r - 2, 0).min(x_subview_min1); - const double mval2 = x.rows(1, r - 2).min(x_subview_min2); - - if (x_min != 0 && x_min != r - 1 && mval != 0.0) - { - REQUIRE( x_min == x_subview_min1 + 1 ); - REQUIRE( x_min == x_subview_min2 + 1 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_min_spincompletesubview_row_min_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_rowvec x; - x.sprandn(1, r, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - - const double mval = x.min(x_min); - const double mval1 = x.submat(0, 1, 0, r - 2).min(x_subview_min1); - const double mval2 = x.cols(1, r - 2).min(x_subview_min2); - - if (mval != 0.0 && x_min != 0 && x_min != r - 1) - { - REQUIRE( x_min == x_subview_min1 + 1 ); - REQUIRE( x_min == x_subview_min2 + 1 ); - - REQUIRE( mval == Approx(mval1) ); - REQUIRE( mval == Approx(mval2) ); - } - } - } - - - -TEST_CASE("fn_min_sp_cx_subview_min_test") - { - // We will assume subview.at() works and returns points within the bounds of - // the matrix, so we just have to ensure the results are the same as - // Mat.min()... - for (size_t r = 50; r < 150; ++r) - { - sp_cx_mat x; - x.sprandn(r, r, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - uword x_subview_min3; - - const std::complex mval = x.min(x_min); - const std::complex mval1 = x.submat(0, 0, r - 1, r - 1).min(x_subview_min1); - const std::complex mval2 = x.cols(0, r - 1).min(x_subview_min2); - const std::complex mval3 = x.rows(0, r - 1).min(x_subview_min3); - - if (mval != std::complex(0.0)) - { - REQUIRE( x_min == x_subview_min1 ); - REQUIRE( x_min == x_subview_min2 ); - REQUIRE( x_min == x_subview_min3 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - REQUIRE( mval.real() == Approx(mval3.real()) ); - REQUIRE( mval.imag() == Approx(mval3.imag()) ); - } - } - } - - - -TEST_CASE("fn_min_sp_cx_subview_col_min_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_cx_vec x; - x.sprandn(r, 1, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - - const std::complex mval = x.min(x_min); - const std::complex mval1 = x.submat(0, 0, r - 1, 0).min(x_subview_min1); - const std::complex mval2 = x.rows(0, r - 1).min(x_subview_min2); - - if (mval != std::complex(0.0)) - { - REQUIRE( x_min == x_subview_min1 ); - REQUIRE( x_min == x_subview_min2 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } - - - -TEST_CASE("fn_min_sp_cx_subview_row_min_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_cx_rowvec x; - x.sprandn(1, r, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - - const std::complex mval = x.min(x_min); - const std::complex mval1 = x.submat(0, 0, 0, r - 1).min(x_subview_min1); - const std::complex mval2 = x.cols(0, r - 1).min(x_subview_min2); - - if (mval != std::complex(0.0)) - { - REQUIRE( x_min == x_subview_min1 ); - REQUIRE( x_min == x_subview_min2 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } - - - -TEST_CASE("fn_min_sp_cx_incomplete_subview_min_test") - { - for (size_t r = 50; r < 150; ++r) - { - sp_cx_mat x; - x.sprandn(r, r, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - uword x_subview_min3; - - const std::complex mval = x.min(x_min); - const std::complex mval1 = x.submat(1, 1, r - 2, r - 2).min(x_subview_min1); - const std::complex mval2 = x.cols(1, r - 2).min(x_subview_min2); - const std::complex mval3 = x.rows(1, r - 2).min(x_subview_min3); - - uword row, col; - x.min(row, col); - - if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != std::complex(0.0)) - { - uword srow, scol; - - srow = x_subview_min1 % (r - 2); - scol = x_subview_min1 / (r - 2); - REQUIRE( x_min == (srow + 1) + r * (scol + 1) ); - REQUIRE( x_min == x_subview_min2 + r ); - - srow = x_subview_min3 % (r - 2); - scol = x_subview_min3 / (r - 2); - REQUIRE( x_min == (srow + 1) + r * scol ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - REQUIRE( mval.real() == Approx(mval3.real()) ); - REQUIRE( mval.imag() == Approx(mval3.imag()) ); - } - } - } - - - -TEST_CASE("fn_min_sp_cx_incomplete_subview_col_min_test") - { - for (size_t r = 10; r < 50; ++r) - { - arma::sp_cx_vec x; - x.sprandn(r, 1, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - - const std::complex mval = x.min(x_min); - const std::complex mval1 = x.submat(1, 0, r - 2, 0).min(x_subview_min1); - const std::complex mval2 = x.rows(1, r - 2).min(x_subview_min2); - - if (x_min != 0 && x_min != r - 1 && mval != std::complex(0.0)) - { - REQUIRE( x_min == x_subview_min1 + 1 ); - REQUIRE( x_min == x_subview_min2 + 1 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } - - - -TEST_CASE("fn_min_sp_cx_incomplete_subview_row_min_test") - { - for (size_t r = 10; r < 50; ++r) - { - sp_cx_rowvec x; - x.sprandn(1, r, 0.3); - - uword x_min; - uword x_subview_min1; - uword x_subview_min2; - - const std::complex mval = x.min(x_min); - const std::complex mval1 = x.submat(0, 1, 0, r - 2).min(x_subview_min1); - const std::complex mval2 = x.cols(1, r - 2).min(x_subview_min2); - - if (x_min != 0 && x_min != r - 1 && mval != std::complex(0.0)) - { - REQUIRE( x_min == x_subview_min1 + 1 ); - REQUIRE( x_min == x_subview_min2 + 1 ); - - REQUIRE( mval.real() == Approx(mval1.real()) ); - REQUIRE( mval.imag() == Approx(mval1.imag()) ); - REQUIRE( mval.real() == Approx(mval2.real()) ); - REQUIRE( mval.imag() == Approx(mval2.imag()) ); - } - } - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_princomp.cpp armadillo-10.8.2+dfsg/tests/fn_princomp.cpp --- armadillo-9.800.4+dfsg/tests/fn_princomp.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_princomp.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -#include -#include "catch.hpp" - -using namespace arma; - -namespace - { - void - initMatrix(mat& m) - { - for(uword ii = 0; ii < m.n_rows; ++ii) - for(uword jj = 0; jj < m.n_cols; ++jj) - { - const int i = int(ii); - const int j = int(jj); - - m(ii, jj) = 5 * (i % 17) + (i + j) % 13 - 7 * ((j + 2) % 5) + double(i)/double(m.n_rows); - } - } - - void checkEigenvectors(const mat& coeff) - { - // sign of the eigenvectors can be flipped - REQUIRE(std::abs(coeff(0,0)) == Approx(2.2366412109e-01)); - REQUIRE(std::abs(coeff(0,1)) == Approx(3.1197826828e-01)); - REQUIRE(std::abs(coeff(0,2)) == Approx(5.1847537613e-02)); - REQUIRE(std::abs(coeff(1,0)) == Approx(2.2419616512e-01)); - REQUIRE(std::abs(coeff(1,1)) == Approx(2.7564301912e-01)); - REQUIRE(std::abs(coeff(1,2)) == Approx(1.0953921221e-01)); - REQUIRE(std::abs(coeff(2,0)) == Approx(2.2427613980e-01)); - REQUIRE(std::abs(coeff(2,1)) == Approx(1.6088934501e-01)); - REQUIRE(std::abs(coeff(2,2)) == Approx(2.3660988967e-01)); - } - - void checkScore(const mat& score) - { - REQUIRE(score(0,0) == Approx(-1.8538115696e+02)); - REQUIRE(score(0,1) == Approx(4.6671842099e+00)); - REQUIRE(score(0,2) == Approx(1.1026881736e+01)); - REQUIRE(score(1,0) == Approx(-1.6144314244e+02)); - REQUIRE(score(1,1) == Approx(8.0636602200e+00)); - REQUIRE(score(1,2) == Approx(8.5129014856e+00)); - REQUIRE(score(2,0) == Approx(-1.3750123749e+02)); - REQUIRE(score(2,1) == Approx(1.0312494525e+01)); - REQUIRE(score(2,2) == Approx(4.5214633042e+00)); - } - - void checkEigenvalues(const vec& latent) - { - REQUIRE(latent(0) == Approx(1.1989436021e+04)); - REQUIRE(latent(1) == Approx(9.2136913098e+01)); - REQUIRE(latent(2) == Approx(7.8335565832e+01)); - REQUIRE(latent(3) == Approx(2.4204644513e+01)); - REQUIRE(latent(4) == Approx(2.1302619671e+01)); - REQUIRE(latent(5) == Approx(1.1615198930e+01)); - REQUIRE(latent(6) == Approx(1.1040034957e+01)); - REQUIRE(latent(7) == Approx(7.7918177707e+00)); - REQUIRE(latent(8) == Approx(7.2862524567e+00)); - REQUIRE(latent(9) == Approx(6.5039856845e+00)); - } - - void checkHotteling(const vec& tsquared) - { - REQUIRE(tsquared(0) == Approx(7.1983631370e+02)); - REQUIRE(tsquared(1) == Approx(6.5616053343e+02)); - REQUIRE(tsquared(2) == Approx(5.6308987454e+02)); - REQUIRE(tsquared(3) == Approx(3.6908398978e+02)); - REQUIRE(tsquared(4) == Approx(2.4632493795e+02)); - REQUIRE(tsquared(5) == Approx(1.3213013367e+02)); - REQUIRE(tsquared(6) == Approx(5.7414718234e+01)); - REQUIRE(tsquared(7) == Approx(1.5157746233e+01)); - REQUIRE(tsquared(8) == Approx(1.7316032365e+01)); - REQUIRE(tsquared(9) == Approx(2.9290529527e+01)); - REQUIRE(tsquared(20) == Approx(2.6159738840e+02)); - } - } - -TEST_CASE("fn_princomp_1") - { - mat m(1000, 20); - initMatrix(m); - mat coeff = princomp(m); - checkEigenvectors(coeff); - } - -TEST_CASE("fn_princomp_2") - { - mat m(1000, 20); - initMatrix(m); - mat coeff; - princomp(coeff, m); - checkEigenvectors(coeff); - } - -TEST_CASE("fn_princomp_3") - { - mat m(1000, 20); - initMatrix(m); - mat coeff; - mat score; - princomp(coeff, score, m); - checkScore(score); - checkEigenvectors(coeff); - } - -TEST_CASE("fn_princomp_4") - { - mat m(1000, 20); - initMatrix(m); - mat coeff; - mat score; - vec latent; - princomp(coeff, score, latent, m); - checkEigenvectors(coeff); - checkScore(score); - checkEigenvalues(latent); - } - -TEST_CASE("fn_princomp_5") - { - mat m(1000, 20); - initMatrix(m); - mat coeff; - mat score; - vec latent; - vec tsquared; - princomp(coeff, score, latent, tsquared, m); - checkEigenvectors(coeff); - checkScore(score); - checkEigenvalues(latent); - // checkHotteling(tsquared); // TODO - } - -TEST_CASE("fn_princomp_6") - { - mat m(5, 20); - initMatrix(m); - mat coeff = princomp(m); - REQUIRE(std::abs(coeff(0,0)) == Approx(2.4288979933e-01)); - REQUIRE(std::abs(coeff(0,1)) == Approx(3.9409505019e-16)); - REQUIRE(std::abs(coeff(0,2)) == Approx(1.2516285718e-02)); - REQUIRE(std::abs(coeff(1,0)) == Approx(2.4288979933e-01)); - REQUIRE(std::abs(coeff(1,1)) == Approx(2.9190770799e-16)); - REQUIRE(std::abs(coeff(1,2)) == Approx(1.2516285718e-02)); - REQUIRE(std::abs(coeff(2,0)) == Approx(2.4288979933e-01)); - REQUIRE(std::abs(coeff(2,1)) == Approx(3.4719806003e-17)); - REQUIRE(std::abs(coeff(2,2)) == Approx(1.2516285718e-02)); - REQUIRE(std::abs(coeff(19,19)) == Approx(9.5528446175e-01).epsilon(0.01)); - } - diff -Nru armadillo-9.800.4+dfsg/tests/fn_spsolve.cpp armadillo-10.8.2+dfsg/tests/fn_spsolve.cpp --- armadillo-9.800.4+dfsg/tests/fn_spsolve.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_spsolve.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,900 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -#if defined(ARMA_USE_SUPERLU) - -TEST_CASE("fn_spsolve_sparse_test") - { - // We want to spsolve a system of equations, AX = B, where we want to recover - // X and we have A and B, and A is sparse. - for (size_t t = 0; t < 10; ++t) - { - const uword size = 5 * (t + 1); - - mat rX; - rX.randu(size, size); - - sp_mat A; - A.sprandu(size, size, 0.25); - for (uword i = 0; i < size; ++i) - { - A(i, i) += rand(); - } - - mat B = A * rX; - - mat X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - // Dense solver. - mat dA(A); - mat dX = solve(dA, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (uword i = 0; i < dX.n_cols; ++i) - { - for (uword j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (double) X(j, i) == Approx((double) dX(j, i)) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_sparse_nonsymmetric_test") - { - for (size_t t = 0; t < 10; ++t) - { - const uword r_size = 5 * (t + 1); - const uword c_size = 3 * (t + 4); - - mat rX; - rX.randu(r_size, c_size); - - sp_mat A; - A.sprandu(r_size, r_size, 0.25); - for (uword i = 0; i < r_size; ++i) - { - A(i, i) += rand(); - } - - mat B = A * rX; - - mat X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - // Dense solver. - mat dA(A); - mat dX = solve(dA, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (uword i = 0; i < dX.n_cols; ++i) - { - for (uword j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (double) X(j, i) == Approx((double) dX(j, i)) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_sparse_float_test") - { - // We want to spsolve a system of equations, AX = B, where we want to recover - // X and we have A and B, and A is sparse. - for (size_t t = 0; t < 10; ++t) - { - const uword size = 5 * (t + 1); - - fmat rX; - rX.randu(size, size); - - SpMat A; - A.sprandu(size, size, 0.25); - for (uword i = 0; i < size; ++i) - { - A(i, i) += rand(); - } - - fmat B = A * rX; - - fmat X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - // Dense solver. - fmat dA(A); - fmat dX = solve(dA, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (size_t i = 0; i < dX.n_cols; ++i) - { - for (size_t j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (float) X(j, i) == Approx((float) dX(j, i)) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_sparse_nonsymmetric_float_test") - { - for (size_t t = 0; t < 10; ++t) - { - const uword r_size = 5 * (t + 1); - const uword c_size = 3 * (t + 4); - - fmat rX; - rX.randu(r_size, c_size); - - SpMat A; - A.sprandu(r_size, r_size, 0.25); - for (uword i = 0; i < r_size; ++i) - { - A(i, i) += rand(); - } - - fmat B = A * rX; - - fmat X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - // Dense solver. - fmat dA(A); - fmat dX = solve(dA, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (uword i = 0; i < dX.n_cols; ++i) - { - for (uword j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (float) X(j, i) == Approx((float) dX(j, i)) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_sparse_complex_float_test") - { - // We want to spsolve a system of equations, AX = B, where we want to recover - // X and we have A and B, and A is sparse. - for (size_t t = 0; t < 10; ++t) - { - const uword size = 5 * (t + 1); - - Mat > rX; - rX.randu(size, size); - - SpMat > A; - A.sprandu(size, size, 0.25); - for(uword i = 0; i < size; ++i) - { - A(i, i) += rand(); - } - - Mat > B = A * rX; - - Mat > X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - // Dense solver. - Mat > dA(A); - Mat > dX = solve(dA, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (uword i = 0; i < dX.n_cols; ++i) - { - for (uword j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (float) std::abs((std::complex) X(j, i)) == - Approx((float) std::abs((std::complex) dX(j, i))) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_sparse_nonsymmetric_complex_float_test") - { - for (size_t t = 0; t < 10; ++t) - { - const uword r_size = 5 * (t + 1); - const uword c_size = 3 * (t + 4); - - Mat > rX; - rX.randu(r_size, c_size); - - SpMat > A; - A.sprandu(r_size, r_size, 0.25); - for (uword i = 0; i < r_size; ++i) - { - A(i, i) += rand(); - } - - Mat > B = A * rX; - - Mat > X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - // Dense solver. - Mat > dA(A); - Mat > dX = solve(dA, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (uword i = 0; i < dX.n_cols; ++i) - { - for (uword j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (float) std::abs((std::complex) X(j, i)) == - Approx((float) std::abs((std::complex) dX(j, i))) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_sparse_complex_test") - { - // We want to spsolve a system of equations, AX = B, where we want to recover - // X and we have A and B, and A is sparse. - for (size_t t = 0; t < 10; ++t) - { - const uword size = 5 * (t + 1); - - Mat > rX; - rX.randu(size, size); - - SpMat > A; - A.sprandu(size, size, 0.25); - for (uword i = 0; i < size; ++i) - { - A(i, i) += rand(); - } - - Mat > B = A * rX; - - Mat > X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - // Dense solver. - Mat > dA(A); - Mat > dX = solve(dA, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (uword i = 0; i < dX.n_cols; ++i) - { - for (uword j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (double) std::abs((std::complex) X(j, i)) == - Approx((double) std::abs((std::complex) dX(j, i))) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_sparse_nonsymmetric_complex_test") - { - for (size_t t = 0; t < 10; ++t) - { - const uword r_size = 5 * (t + 1); - const uword c_size = 3 * (t + 4); - - Mat > rX; - rX.randu(r_size, c_size); - - SpMat > A; - A.sprandu(r_size, r_size, 0.25); - for (uword i = 0; i < r_size; ++i) - { - A(i, i) += rand(); - } - - Mat > B = A * rX; - - Mat > X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - // Dense solver. - Mat > dA(A); - Mat > dX = solve(dA, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (uword i = 0; i < dX.n_cols; ++i) - { - for (uword j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (double) std::abs((std::complex) X(j, i)) == - Approx((double) std::abs((std::complex) dX(j, i))) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_delayed_sparse_test") - { - const uword size = 10; - - mat rX; - rX.randu(size, size); - - sp_mat A; - A.sprandu(size, size, 0.25); - for (uword i = 0; i < size; ++i) - { - A(i, i) += rand(); - } - - mat B = A * rX; - - mat X; - bool result = spsolve(X, A, B); - REQUIRE( result ); - - mat dX = spsolve(A, B); - - REQUIRE( X.n_cols == dX.n_cols ); - REQUIRE( X.n_rows == dX.n_rows ); - - for (uword i = 0; i < dX.n_cols; ++i) - { - for (uword j = 0; j < dX.n_rows; ++j) - { - REQUIRE( (double) X(j, i) == Approx((double) dX(j, i)) ); - } - } - } - - - -TEST_CASE("fn_spsolve_superlu_solve_test") - { - // Solve this matrix, as in the examples: - // [[19 0 21 21 0] - // [12 21 0 0 0] - // [ 0 12 16 0 0] - // [ 0 0 0 5 21] - // [12 12 0 0 18]] - sp_mat b(5, 5); - b(0, 0) = 19; - b(0, 2) = 21; - b(0, 3) = 21; - b(1, 0) = 12; - b(1, 1) = 21; - b(2, 1) = 12; - b(2, 2) = 16; - b(3, 3) = 5; - b(3, 4) = 21; - b(4, 0) = 12; - b(4, 1) = 12; - b(4, 4) = 18; - - mat db(b); - - sp_mat a; - a.eye(5, 5); - mat da(a); - - mat x; - spsolve(x, a, db); - - mat dx = solve(da, db); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - REQUIRE( (double) x(j, i) == Approx(dx(j, i)) ); - } - } - } - - - -TEST_CASE("fn_spsolve_random_superlu_solve_test") - { - // Try to solve some random systems. - const size_t iterations = 10; - for (size_t it = 0; it < iterations; ++it) - { - sp_mat a; - a.sprandu(50, 50, 0.3); - sp_mat trueX; - trueX.sprandu(50, 50, 0.3); - - sp_mat b = a * trueX; - - // Get things into the right format. - mat db(b); - - mat x; - - spsolve(x, a, db); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - REQUIRE( x(j, i) == Approx((double) trueX(j, i)) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_float_superlu_solve_test") - { - // Solve this matrix, as in the examples: - // [[19 0 21 21 0] - // [12 21 0 0 0] - // [ 0 12 16 0 0] - // [ 0 0 0 5 21] - // [12 12 0 0 18]] - sp_fmat b(5, 5); - b(0, 0) = 19; - b(0, 2) = 21; - b(0, 3) = 21; - b(1, 0) = 12; - b(1, 1) = 21; - b(2, 1) = 12; - b(2, 2) = 16; - b(3, 3) = 5; - b(3, 4) = 21; - b(4, 0) = 12; - b(4, 1) = 12; - b(4, 4) = 18; - - fmat db(b); - - sp_fmat a; - a.eye(5, 5); - fmat da(a); - - fmat x; - spsolve(x, a, db); - - fmat dx = solve(da, db); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - REQUIRE( (float) x(j, i) == Approx(dx(j, i)) ); - } - } - } - - - -TEST_CASE("fn_spsolve_float_random_superlu_solve_test") - { - // Try to solve some random systems. - const size_t iterations = 10; - for (size_t it = 0; it < iterations; ++it) - { - sp_fmat a; - a.sprandu(50, 50, 0.3); - sp_fmat trueX; - trueX.sprandu(50, 50, 0.3); - - sp_fmat b = a * trueX; - - // Get things into the right format. - fmat db(b); - - fmat x; - - spsolve(x, a, db); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - if (std::abs(trueX(j, i)) < 0.001) - REQUIRE( std::abs(x(j, i)) < 0.005 ); - else - REQUIRE( trueX(j, i) == Approx((float) x(j, i)).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_cx_float_superlu_solve_test") - { - // Solve this matrix, as in the examples: - // [[19 0 21 21 0] - // [12 21 0 0 0] - // [ 0 12 16 0 0] - // [ 0 0 0 5 21] - // [12 12 0 0 18]] (imaginary part is the same) - SpMat > b(5, 5); - b(0, 0) = std::complex(19, 19); - b(0, 2) = std::complex(21, 21); - b(0, 3) = std::complex(21, 21); - b(1, 0) = std::complex(12, 12); - b(1, 1) = std::complex(21, 21); - b(2, 1) = std::complex(12, 12); - b(2, 2) = std::complex(16, 16); - b(3, 3) = std::complex(5, 5); - b(3, 4) = std::complex(21, 21); - b(4, 0) = std::complex(12, 12); - b(4, 1) = std::complex(12, 12); - b(4, 4) = std::complex(18, 18); - - Mat > db(b); - - SpMat > a; - a.eye(5, 5); - Mat > da(a); - - Mat > x; - spsolve(x, a, db); - - Mat > dx = solve(da, db); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - if (std::abs(x(j, i)) < 0.001 ) - { - REQUIRE( std::abs(dx(j, i)) < 0.005 ); - } - else - { - REQUIRE( ((std::complex) x(j, i)).real() == - Approx(dx(j, i).real()).epsilon(0.01) ); - REQUIRE( ((std::complex) x(j, i)).imag() == - Approx(dx(j, i).imag()).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_cx_float_random_superlu_solve_test") - { - // Try to solve some random systems. - const size_t iterations = 10; - for (size_t it = 0; it < iterations; ++it) - { - SpMat > a; - a.sprandu(50, 50, 0.3); - SpMat > trueX; - trueX.sprandu(50, 50, 0.3); - - SpMat > b = a * trueX; - - // Get things into the right format. - Mat > db(b); - - Mat > x; - - spsolve(x, a, db); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - if (std::abs((std::complex) trueX(j, i)) < 0.001 ) - { - REQUIRE( std::abs(x(j, i)) < 0.001 ); - } - else - { - REQUIRE( ((std::complex) trueX(j, i)).real() == - Approx(x(j, i).real()).epsilon(0.01) ); - REQUIRE( ((std::complex) trueX(j, i)).imag() == - Approx(x(j, i).imag()).epsilon(0.01) ); - } - } - } - } - } - - - -TEST_CASE("fn_spsolve_cx_superlu_solve_test") - { - // Solve this matrix, as in the examples: - // [[19 0 21 21 0] - // [12 21 0 0 0] - // [ 0 12 16 0 0] - // [ 0 0 0 5 21] - // [12 12 0 0 18]] (imaginary part is the same) - SpMat > b(5, 5); - b(0, 0) = std::complex(19, 19); - b(0, 2) = std::complex(21, 21); - b(0, 3) = std::complex(21, 21); - b(1, 0) = std::complex(12, 12); - b(1, 1) = std::complex(21, 21); - b(2, 1) = std::complex(12, 12); - b(2, 2) = std::complex(16, 16); - b(3, 3) = std::complex(5, 5); - b(3, 4) = std::complex(21, 21); - b(4, 0) = std::complex(12, 12); - b(4, 1) = std::complex(12, 12); - b(4, 4) = std::complex(18, 18); - - cx_mat db(b); - - sp_cx_mat a; - a.eye(5, 5); - cx_mat da(a); - - cx_mat x; - spsolve(x, a, db); - - cx_mat dx = solve(da, db); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - if (std::abs(x(j, i)) < 0.001) - { - REQUIRE( std::abs(dx(j, i)) < 0.005 ); - } - else - { - REQUIRE( ((std::complex) x(j, i)).real() == - Approx(dx(j, i).real()).epsilon(0.01) ); - REQUIRE( ((std::complex) x(j, i)).imag() == - Approx(dx(j, i).imag()).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_cx_random_superlu_solve_test") - { - // Try to solve some random systems. - const size_t iterations = 10; - for (size_t it = 0; it < iterations; ++it) - { - sp_cx_mat a; - a.sprandu(50, 50, 0.3); - sp_cx_mat trueX; - trueX.sprandu(50, 50, 0.3); - - sp_cx_mat b = a * trueX; - - // Get things into the right format. - cx_mat db(b); - - cx_mat x; - - spsolve(x, a, db); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - if (std::abs((std::complex) trueX(j, i)) < 0.001) - { - REQUIRE( std::abs(x(j, i)) < 0.005 ); - } - else - { - REQUIRE( ((std::complex) trueX(j, i)).real() == - Approx(x(j, i).real()).epsilon(0.01) ); - REQUIRE( ((std::complex) trueX(j, i)).imag() == - Approx(x(j, i).imag()).epsilon(0.01) ); - } - } - } - } - } - - - -TEST_CASE("fn_spsolve_function_test") - { - sp_mat a; - a.sprandu(50, 50, 0.3); - sp_mat trueX; - trueX.sprandu(50, 50, 0.3); - - sp_mat b = a * trueX; - - // Get things into the right format. - mat db(b); - - mat x; - - // Mostly these are compilation tests. - spsolve(x, a, db); - x = spsolve(a, db); // Test another overload. - x = spsolve(a, db + 0.0); - spsolve(x, a, db + 0.0); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - REQUIRE( (double) trueX(j, i) == Approx(x(j, i)) ); - } - } - } - - - -TEST_CASE("fn_spsolve_float_function_test") - { - sp_fmat a; - a.sprandu(50, 50, 0.3); - sp_fmat trueX; - trueX.sprandu(50, 50, 0.3); - - sp_fmat b = a * trueX; - - // Get things into the right format. - fmat db(b); - - fmat x; - - // Mostly these are compilation tests. - spsolve(x, a, db); - x = spsolve(a, db); // Test another overload. - x = spsolve(a, db + 0.0); - spsolve(x, a, db + 0.0); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - if (std::abs(trueX(j, i)) < 0.001) - { - REQUIRE( std::abs(x(j, i)) < 0.001 ); - } - else - { - REQUIRE( (float) trueX(j, i) == Approx(x(j, i)).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_cx_function_test") - { - sp_cx_mat a; - a.sprandu(50, 50, 0.3); - sp_cx_mat trueX; - trueX.sprandu(50, 50, 0.3); - - sp_cx_mat b = a * trueX; - - // Get things into the right format. - cx_mat db(b); - - cx_mat x; - - // Mostly these are compilation tests. - spsolve(x, a, db); - x = spsolve(a, db); // Test another overload. - x = spsolve(a, db + std::complex(0.0)); - spsolve(x, a, db + std::complex(0.0)); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - if (std::abs((std::complex) trueX(j, i)) < 0.001) - { - REQUIRE( std::abs(x(j, i)) < 0.005 ); - } - else - { - REQUIRE( ((std::complex) trueX(j, i)).real() == - Approx(x(j, i).real()).epsilon(0.01) ); - REQUIRE( ((std::complex) trueX(j, i)).imag() == - Approx(x(j, i).imag()).epsilon(0.01) ); - } - } - } - } - - - -TEST_CASE("fn_spsolve_cx_float_function_test") - { - sp_cx_fmat a; - a.sprandu(50, 50, 0.3); - sp_cx_fmat trueX; - trueX.sprandu(50, 50, 0.3); - - sp_cx_fmat b = a * trueX; - - // Get things into the right format. - cx_fmat db(b); - - cx_fmat x; - - // Mostly these are compilation tests. - spsolve(x, a, db); - x = spsolve(a, db); // Test another overload. - x = spsolve(a, db + std::complex(0.0)); - spsolve(x, a, db + std::complex(0.0)); - - for (uword i = 0; i < x.n_cols; ++i) - { - for (uword j = 0; j < x.n_rows; ++j) - { - if (std::abs((std::complex) trueX(j, i)) < 0.001 ) - { - REQUIRE( std::abs(x(j, i)) < 0.005 ); - } - else - { - REQUIRE( ((std::complex) trueX(j, i)).real() == - Approx(x(j, i).real()).epsilon(0.01) ); - REQUIRE( ((std::complex) trueX(j, i)).imag() == - Approx(x(j, i).imag()).epsilon(0.01) ); - } - } - } - } - -#endif diff -Nru armadillo-9.800.4+dfsg/tests/fn_sum.cpp armadillo-10.8.2+dfsg/tests/fn_sum.cpp --- armadillo-9.800.4+dfsg/tests/fn_sum.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_sum.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_sum_1") - { - vec a = linspace(1,5,5); - vec b = linspace(1,5,6); - - REQUIRE(sum(a) == Approx(15.0)); - REQUIRE(sum(b) == Approx(18.0)); - } - - - -TEST_CASE("sum2") - { - mat A = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - rowvec colsums = { 0.44080, 1.09382, 0.97808, 1.83429 }; - - colvec rowsums = - { - 1.21686, - 1.69436, - 1.43577 - }; - - REQUIRE( accu(abs(colsums - sum(A ))) == Approx(0.0) ); - REQUIRE( accu(abs(colsums - sum(A,0))) == Approx(0.0) ); - REQUIRE( accu(abs(rowsums - sum(A,1))) == Approx(0.0) ); - } - - -TEST_CASE("sum3") - { - mat AA = - { - { -0.78838, 0.69298, 0.41084, 0.90142 }, - { 0.49345, -0.12020, 0.78987, 0.53124 }, - { 0.73573, 0.52104, -0.22263, 0.40163 } - }; - - cx_mat A = cx_mat(AA, 0.5*AA); - - rowvec re_colsums = { 0.44080, 1.09382, 0.97808, 1.83429 }; - - cx_rowvec cx_colsums = cx_rowvec(re_colsums, 0.5*re_colsums); - - colvec re_rowsums = - { - 1.21686, - 1.69436, - 1.43577 - }; - - cx_colvec cx_rowsums = cx_colvec(re_rowsums, 0.5*re_rowsums); - - REQUIRE( accu(abs(cx_colsums - sum(A ))) == Approx(0.0) ); - REQUIRE( accu(abs(cx_colsums - sum(A,0))) == Approx(0.0) ); - REQUIRE( accu(abs(cx_rowsums - sum(A,1))) == Approx(0.0) ); - } - - -TEST_CASE("sum4") - { - mat X(100,101, fill::randu); - - REQUIRE( (sum(sum(X))/X.n_elem) == Approx(0.5).epsilon(0.02) ); - REQUIRE( (sum(sum(X(span::all,span::all)))/X.n_elem) == Approx(0.5).epsilon(0.02) ); - } - - - -TEST_CASE("sum_spmat") - { - SpCol a(5); - a(0) = 3.0; - a(2) = 1.5; - a(3) = 1.0; - - double res = sum(a); - REQUIRE( res == Approx(5.5) ); - - SpRow b(5); - b(1) = 1.3; - b(2) = 4.4; - b(4) = 1.0; - - res = sum(b); - REQUIRE( res == Approx(6.7) ); - - SpMat c(8, 8); - c(0, 0) = 3.0; - c(1, 0) = 2.5; - c(6, 0) = 2.1; - c(4, 1) = 3.2; - c(5, 1) = 1.1; - c(1, 2) = 1.3; - c(2, 3) = 4.1; - c(5, 5) = 2.3; - c(6, 5) = 3.1; - c(7, 5) = 1.2; - c(7, 7) = 3.4; - - SpMat result = sum(c, 0); - - REQUIRE( result.n_rows == 1 ); - REQUIRE( result.n_cols == 8 ); - REQUIRE( result.n_nonzero == 6 ); - REQUIRE( (double) result(0, 0) == Approx(7.6) ); - REQUIRE( (double) result(0, 1) == Approx(4.3) ); - REQUIRE( (double) result(0, 2) == Approx(1.3) ); - REQUIRE( (double) result(0, 3) == Approx(4.1) ); - REQUIRE( (double) result(0, 4) == Approx(0.0) ); - REQUIRE( (double) result(0, 5) == Approx(6.6) ); - REQUIRE( (double) result(0, 6) == Approx(0.0) ); - REQUIRE( (double) result(0, 7) == Approx(3.4) ); - - result = sum(c, 1); - - REQUIRE( result.n_rows == 8 ); - REQUIRE( result.n_cols == 1 ); - REQUIRE( result.n_nonzero == 7 ); - REQUIRE( (double) result(0, 0) == Approx(3.0) ); - REQUIRE( (double) result(1, 0) == Approx(3.8) ); - REQUIRE( (double) result(2, 0) == Approx(4.1) ); - REQUIRE( (double) result(3, 0) == Approx(0.0) ); - REQUIRE( (double) result(4, 0) == Approx(3.2) ); - REQUIRE( (double) result(5, 0) == Approx(3.4) ); - REQUIRE( (double) result(6, 0) == Approx(5.2) ); - REQUIRE( (double) result(7, 0) == Approx(4.6) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_symmat.cpp armadillo-10.8.2+dfsg/tests/fn_symmat.cpp --- armadillo-9.800.4+dfsg/tests/fn_symmat.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_symmat.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_symmat_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = symmatu( A(0,0,size(5,5)) ); - mat C = symmatl( A(0,0,size(5,5)) ); - - mat BB = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745;\ - 0.201990 0.058956 -0.149362 -0.045465 0.296153;\ - 0.019678 -0.149362 0.314156 0.419733 0.068317;\ - -0.493936 -0.045465 0.419733 -0.393139 -0.135040;\ - -0.126745 0.296153 0.068317 -0.135040 -0.353768;\ - "; - - mat CC = - "\ - 0.061198 0.437242 -0.492474 0.336352 0.239585;\ - 0.437242 0.058956 -0.031309 0.411541 -0.428913;\ - -0.492474 -0.031309 0.314156 0.458476 -0.406953;\ - 0.336352 0.411541 0.458476 -0.393139 -0.291020;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768;\ - "; - - REQUIRE( accu(abs( B - BB )) == Approx(0.0) ); - REQUIRE( accu(abs( C - CC )) == Approx(0.0) ); - - mat X; - REQUIRE_THROWS( X = symmatu(A) ); // symmatu() and symmatl() currently handle only square matrices - } - - - -TEST_CASE("fn_symmat_2") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - cx_mat B1 = symmatu( cx_mat( A(0,0,size(3,3)), A(0,3,size(3,3)) ) ); - cx_mat C1 = symmatl( cx_mat( A(0,0,size(3,3)), A(0,3,size(3,3)) ) ); - - cx_mat B2 = symmatu( cx_mat( A(0,0,size(3,3)), A(0,3,size(3,3)) ), true ); - cx_mat C2 = symmatl( cx_mat( A(0,0,size(3,3)), A(0,3,size(3,3)) ), true ); - - cx_mat D = symmatu( cx_mat( A(0,0,size(3,3)), A(0,3,size(3,3)) ), false ); - cx_mat E = symmatl( cx_mat( A(0,0,size(3,3)), A(0,3,size(3,3)) ), false ); - - cx_mat BB = - { - { cx_double( 0.06120, -0.49394), cx_double( 0.20199, -0.12674), cx_double( 0.01968, +0.05141) }, - { cx_double( 0.20199, +0.12674), cx_double( 0.05896, +0.29615), cx_double(-0.14936, +0.03544) }, - { cx_double( 0.01968, -0.05141), cx_double(-0.14936, -0.03544), cx_double( 0.31416, -0.45450) } - }; - - cx_mat CC = - { - { cx_double( 0.06120, -0.49394), cx_double( 0.43724, +0.04546), cx_double(-0.49247, -0.41973) }, - { cx_double( 0.43724, -0.04546), cx_double( 0.05896, +0.29615), cx_double(-0.03131, -0.06832) }, - { cx_double(-0.49247, +0.41973), cx_double(-0.03131, +0.06832), cx_double( 0.31416, -0.45450) } - }; - - cx_mat DD = - { - { cx_double( 0.06120, -0.49394), cx_double( 0.20199, -0.12674), cx_double( 0.01968, +0.05141) }, - { cx_double( 0.20199, -0.12674), cx_double( 0.05896, +0.29615), cx_double(-0.14936, +0.03544) }, - { cx_double( 0.01968, +0.05141), cx_double(-0.14936, +0.03544), cx_double( 0.31416, -0.45450) } - }; - - cx_mat EE = - { - { cx_double( 0.06120, -0.49394), cx_double( 0.43724, -0.04546), cx_double(-0.49247, +0.41973) }, - { cx_double( 0.43724, -0.04546), cx_double( 0.05896, +0.29615), cx_double(-0.03131, +0.06832) }, - { cx_double(-0.49247, +0.41973), cx_double(-0.03131, +0.06832), cx_double( 0.31416, -0.45450) } - }; - - REQUIRE( accu(abs( B1 - BB )) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs( C1 - CC )) == Approx(0.0).epsilon(0.0001) ); - - REQUIRE( accu(abs( B2 - BB )) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs( C2 - CC )) == Approx(0.0).epsilon(0.0001) ); - - REQUIRE( accu(abs( D - DD )) == Approx(0.0).epsilon(0.0001) ); - REQUIRE( accu(abs( E - EE )) == Approx(0.0).epsilon(0.0001) ); - - cx_mat X; - REQUIRE_THROWS( X = symmatu( cx_mat(A(0,0,size(2,3)), A(0,3,size(2,3))) ) ); // symmatu() and symmatl() currently handle only square matrices - } - - diff -Nru armadillo-9.800.4+dfsg/tests/fn_trace.cpp armadillo-10.8.2+dfsg/tests/fn_trace.cpp --- armadillo-9.800.4+dfsg/tests/fn_trace.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_trace.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_trace_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - vec diagonal = { 0.061198, 0.058956, 0.314156, -0.393139, -0.353768 }; - - REQUIRE( accu( trace(A) - accu(diagonal) ) == Approx(0.0) ); - - REQUIRE( accu( trace(2*A) - accu(2*diagonal) ) == Approx(0.0) ); - - REQUIRE( accu( trace(A+A) - accu(diagonal+diagonal) ) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } - - - -TEST_CASE("fn_trace_spmat") - { - SpMat a(6, 6); - a(0, 0) = 3.0; - a(2, 1) = 4.4; - a(4, 1) = 1.2; - a(0, 2) = 3.1; - a(1, 2) = 3.2; - a(2, 2) = 3.3; - a(3, 3) = 4.0; - a(5, 3) = 6.0; - a(5, 4) = 5.9; - a(5, 5) = 1.2; - - REQUIRE( trace(a) == Approx(11.5) ); - - REQUIRE( trace(a.submat(2, 2, 4, 4)) == Approx(7.3) ); - } - - - -TEST_CASE("fn_trace_spmat_mul") - { - // Test trace(SpMat * SpMat) and ensure the result is the same as if we - // pre-multiplied the matrices. - sp_mat a; - a.sprandu(20, 20, 0.1); - sp_mat b; - b.sprandu(20, 20, 0.1); - - sp_mat c = a * b; - - const double trc = trace(c); - const double trab = trace(a * b); - - REQUIRE( trc == Approx(trab) ); - } - - - -TEST_CASE("fn_trace_spmat_t_mul") - { - // Test trace(SpMat.t() * SpMat) and ensure the result is the same as if we - // pre-multiplied the matrices. - sp_mat a; - a.sprandu(20, 20, 0.1); - sp_mat b; - b.sprandu(20, 20, 0.1); - - sp_mat c = a.t() * b; - - const double trc = trace(c); - const double trab = trace(a.t() * b); - - REQUIRE( trc == Approx(trab) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_trans.cpp armadillo-10.8.2+dfsg/tests/fn_trans.cpp --- armadillo-9.800.4+dfsg/tests/fn_trans.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_trans.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,621 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_trans_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat At = - "\ - 0.061198 0.437242 -0.492474 0.336352 0.239585;\ - 0.201990 0.058956 -0.031309 0.411541 -0.428913;\ - 0.019678 -0.149362 0.314156 0.458476 -0.406953;\ - -0.493936 -0.045465 0.419733 -0.393139 -0.291020;\ - -0.126745 0.296153 0.068317 -0.135040 -0.353768;\ - 0.051408 0.035437 -0.454499 0.373833 0.258704;\ - "; - - rowvec At_sum0 = { -0.28641, 0.63296, -0.17608, 1.05202, -0.98237 }; - - colvec At_sum1 = - { - 0.58190, - 0.21227, - 0.23599, - -0.80383, - -0.25108, - 0.26488 - }; - - - rowvec A_col1_t = { 0.201990, 0.058956, -0.031309, 0.411541, -0.428913 }; - - colvec A_row1_t = - { - 0.437242, - 0.058956, - -0.149362, - -0.045465, - 0.296153, - 0.035437 - }; - - - double accu_A_col1_t = 0.21227; - double accu_A_row1_t = 0.63296; - - REQUIRE( accu(abs(mat(A.t().t()) - A)) == Approx(0.0) ); - REQUIRE( accu(abs( A.t().t() - A)) == Approx(0.0) ); - - REQUIRE( accu(abs(mat(A.t() ) - At)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(A.st() ) - At)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(A.ht() ) - At)) == Approx(0.0) ); - REQUIRE( accu(abs(mat( trans(A)) - At)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(strans(A)) - At)) == Approx(0.0) ); - - REQUIRE( accu(abs(A.t() - At)) == Approx(0.0) ); - REQUIRE( accu(abs(A.st() - At)) == Approx(0.0) ); - REQUIRE( accu(abs(A.ht() - At)) == Approx(0.0) ); - REQUIRE( accu(abs( trans(A) - At)) == Approx(0.0) ); - REQUIRE( accu(abs(strans(A) - At)) == Approx(0.0) ); - - REQUIRE( accu(abs(mat(At.t() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(At.st() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(At.ht() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(mat( trans(At)) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(strans(At)) - A)) == Approx(0.0) ); - - REQUIRE( accu(abs(At.t() - A)) == Approx(0.0) ); - REQUIRE( accu(abs(At.st() - A)) == Approx(0.0) ); - REQUIRE( accu(abs(At.ht() - A)) == Approx(0.0) ); - REQUIRE( accu(abs( trans(At) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(strans(At) - A)) == Approx(0.0) ); - - REQUIRE( accu(abs((0 + At.t() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs((0 + At.st() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs((0 + At.ht() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs((0 + trans(At)) - A)) == Approx(0.0) ); - REQUIRE( accu(abs((0 + strans(At)) - A)) == Approx(0.0) ); - - REQUIRE( accu(abs(mat(0 + At.t() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(0 + At.st() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(0 + At.ht() ) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(0 + trans(At)) - A)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(0 + strans(At)) - A)) == Approx(0.0) ); - - - REQUIRE( accu(abs(2*A.t() - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(2*trans(A) - 2*At)) == Approx(0.0) ); - - REQUIRE( accu(abs((2*A).t() - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(trans(2*A) - 2*At)) == Approx(0.0) ); - - REQUIRE( accu(abs((A+A).t() - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(trans(A+A) - 2*At)) == Approx(0.0) ); - - REQUIRE( accu(abs((A.t() + At) - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs((trans(A) + At) - 2*At)) == Approx(0.0) ); - - - REQUIRE( accu(abs(mat(2*A.t()) - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(2*trans(A)) - 2*At)) == Approx(0.0) ); - - REQUIRE( accu(abs(mat((2*A).t()) - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(trans(2*A)) - 2*At)) == Approx(0.0) ); - - REQUIRE( accu(abs(mat((A+A).t()) - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(trans(A+A)) - 2*At)) == Approx(0.0) ); - - REQUIRE( accu(abs(mat(A.t() + At) - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(mat(trans(A) + At) - 2*At)) == Approx(0.0) ); - - - REQUIRE( accu(abs(rowvec(A.col(1).t()) - A_col1_t)) == Approx(0.0) ); - REQUIRE( accu(abs(colvec(A.row(1).t()) - A_row1_t)) == Approx(0.0) ); - - REQUIRE( accu(abs(A.col(1).t() - A_col1_t)) == Approx(0.0) ); - REQUIRE( accu(abs(A.row(1).t() - A_row1_t)) == Approx(0.0) ); - - REQUIRE( accu(abs(2*A.col(1).t() - 2*A_col1_t)) == Approx(0.0) ); - REQUIRE( accu(abs(2*A.row(1).t() - 2*A_row1_t)) == Approx(0.0) ); - - REQUIRE( accu(abs( (A.col(1).t() + A_col1_t) - 2*A_col1_t)) == Approx(0.0) ); - REQUIRE( accu(abs( (A.row(1).t() + A_row1_t) - 2*A_row1_t)) == Approx(0.0) ); - - - REQUIRE( abs( accu(A.col(1).t()) - accu_A_col1_t ) == Approx(0.0) ); - REQUIRE( abs( accu(A.row(1).t()) - accu_A_row1_t ) == Approx(0.0) ); - - REQUIRE( abs( accu(A.col(1).t()) - accu(A.col(1)) ) == Approx(0.0) ); - REQUIRE( abs( accu(A.row(1).t()) - accu(A.row(1)) ) == Approx(0.0) ); - - REQUIRE( abs( sum(A.col(1).t()) - accu_A_col1_t ) == Approx(0.0) ); - REQUIRE( abs( sum(A.row(1).t()) - accu_A_row1_t ) == Approx(0.0) ); - - REQUIRE_THROWS( A + A.t() ); - } - - - -TEST_CASE("fn_trans_2") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - cx_mat C = cx_mat(A,fliplr(A)); - - cx_mat Ct = - { - { cx_double( 0.061198, -0.051408), cx_double( 0.437242, -0.035437), cx_double(-0.492474, +0.454499), cx_double( 0.336352, -0.373833), cx_double( 0.239585, -0.258704) }, - { cx_double( 0.201990, +0.126745), cx_double( 0.058956, -0.296153), cx_double(-0.031309, -0.068317), cx_double( 0.411541, +0.135040), cx_double(-0.428913, +0.353768) }, - { cx_double( 0.019678, +0.493936), cx_double(-0.149362, +0.045465), cx_double( 0.314156, -0.419733), cx_double( 0.458476, +0.393139), cx_double(-0.406953, +0.291020) }, - { cx_double(-0.493936, -0.019678), cx_double(-0.045465, +0.149362), cx_double( 0.419733, -0.314156), cx_double(-0.393139, -0.458476), cx_double(-0.291020, +0.406953) }, - { cx_double(-0.126745, -0.201990), cx_double( 0.296153, -0.058956), cx_double( 0.068317, +0.031309), cx_double(-0.135040, -0.411541), cx_double(-0.353768, +0.428913) }, - { cx_double( 0.051408, -0.061198), cx_double( 0.035437, -0.437242), cx_double(-0.454499, +0.492474), cx_double( 0.373833, -0.336352), cx_double( 0.258704, -0.239585) } - }; - - cx_rowvec C_col1_t = { cx_double(0.201990, +0.126745), cx_double(0.058956, -0.296153), cx_double(-0.031309, -0.068317), cx_double(0.411541, +0.135040), cx_double(-0.428913, +0.353768) }; - - cx_colvec C_row1_t = - { - cx_double( 0.437242, -0.035437), - cx_double( 0.058956, -0.296153), - cx_double(-0.149362, +0.045465), - cx_double(-0.045465, +0.149362), - cx_double( 0.296153, -0.058956), - cx_double( 0.035437, -0.437242) - }; - - - REQUIRE( accu(abs(C.t().t() - C)) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_mat(C.t() ) - Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(C.ht() ) - Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(trans(C)) - Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs(C.t() - Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(C.ht() - Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(trans(C) - Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_mat(Ct.t() ) - C)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(Ct.ht() ) - C)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(trans(Ct)) - C)) == Approx(0.0) ); - - REQUIRE( accu(abs(Ct.t() - C)) == Approx(0.0) ); - REQUIRE( accu(abs(Ct.ht() - C)) == Approx(0.0) ); - REQUIRE( accu(abs(trans(Ct) - C)) == Approx(0.0) ); - - REQUIRE( accu(abs(2*C.t() - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(2*trans(C) - 2*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs((2*C).t() - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(trans(2*C) - 2*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs((C+C).t() - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(trans(C+C) - 2*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_double(2,3)*C.t() - cx_double(2,3)*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_double(2,3)*trans(C) - cx_double(2,3)*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_mat(2*C.t()) - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(2*trans(C)) - 2*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_mat((2*C).t()) - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(trans(2*C)) - 2*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_mat((C+C).t()) - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(trans(C+C)) - 2*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_mat(cx_double(2,3)*C.t()) - cx_double(2,3)*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(cx_double(2,3)*trans(C)) - cx_double(2,3)*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs((C.t() + Ct) - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs((trans(C) + Ct) - 2*Ct)) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_rowvec(C.col(1).t()) - C_col1_t)) == Approx(0.0) ); - REQUIRE( accu(abs(cx_colvec(C.row(1).t()) - C_row1_t)) == Approx(0.0) ); - - REQUIRE( accu(abs(C.col(1).t() - C_col1_t)) == Approx(0.0) ); - REQUIRE( accu(abs(C.row(1).t() - C_row1_t)) == Approx(0.0) ); - - REQUIRE( accu(abs(2*C.col(1).t() - 2*C_col1_t)) == Approx(0.0) ); - REQUIRE( accu(abs(2*C.row(1).t() - 2*C_row1_t)) == Approx(0.0) ); - - REQUIRE( accu(abs( (C.col(1).t() + C_col1_t) - 2*C_col1_t)) == Approx(0.0) ); - REQUIRE( accu(abs( (C.row(1).t() + C_row1_t) - 2*C_row1_t)) == Approx(0.0) ); - - // - - REQUIRE( accu(abs(cx_mat(C.st()) - conj(Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(cx_mat(strans(C)) - conj(Ct))) == Approx(0.0) ); - - REQUIRE( accu(abs(C.st() - conj(Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(strans(C) - conj(Ct))) == Approx(0.0) ); - - REQUIRE( accu(abs(2*C.st() - conj(2*Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(2*strans(C) - conj(2*Ct))) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_double(2,3)*C.st() - cx_double(2,3)*conj(Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(cx_double(2,3)*strans(C) - cx_double(2,3)*conj(Ct))) == Approx(0.0) ); - - REQUIRE( accu(abs((C.st() + C.st()) - conj(2*Ct))) == Approx(0.0) ); - REQUIRE( accu(abs((strans(C) + C.st()) - conj(2*Ct))) == Approx(0.0) ); - - REQUIRE( accu(abs(cx_rowvec(C.col(1).st()) - conj(C_col1_t))) == Approx(0.0) ); - REQUIRE( accu(abs(cx_colvec(C.row(1).st()) - conj(C_row1_t))) == Approx(0.0) ); - - REQUIRE( accu(abs(C.col(1).st() - conj(C_col1_t))) == Approx(0.0) ); - REQUIRE( accu(abs(C.row(1).st() - conj(C_row1_t))) == Approx(0.0) ); - - REQUIRE( accu(abs(2*C.col(1).st() - conj(2*C_col1_t))) == Approx(0.0) ); - REQUIRE( accu(abs(2*C.row(1).st() - conj(2*C_row1_t))) == Approx(0.0) ); - - REQUIRE( accu(abs( (C.col(1).st() + conj(C_col1_t)) - conj(2*C_col1_t))) == Approx(0.0) ); - REQUIRE( accu(abs( (C.row(1).st() + conj(C_row1_t)) - conj(2*C_row1_t))) == Approx(0.0) ); - - // - - REQUIRE_THROWS( C + C.t() ); - } - - - -TEST_CASE("fn_trans_3") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat At = - "\ - 0.061198 0.437242 -0.492474 0.336352 0.239585;\ - 0.201990 0.058956 -0.031309 0.411541 -0.428913;\ - 0.019678 -0.149362 0.314156 0.458476 -0.406953;\ - -0.493936 -0.045465 0.419733 -0.393139 -0.291020;\ - -0.126745 0.296153 0.068317 -0.135040 -0.353768;\ - 0.051408 0.035437 -0.454499 0.373833 0.258704;\ - "; - - mat B = A.head_cols(5); - - mat Bt = At.head_rows(5); - - mat X; - mat Y; - - X = A; X = X.t(); - Y = B; Y = Y.t(); - - REQUIRE( accu(abs(X - At)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - Bt)) == Approx(0.0) ); - - X = A; X = 0 + X.t(); - Y = B; Y = 0 + Y.t(); - - REQUIRE( accu(abs(X - At)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - Bt)) == Approx(0.0) ); - - X = A; X = 2*X.t(); - Y = B; Y = 2*Y.t(); - - REQUIRE( accu(abs(X - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*Bt)) == Approx(0.0) ); - - X = A; X = 0 + 2*X.t(); - Y = B; Y = 0 + 2*Y.t(); - - REQUIRE( accu(abs(X - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*Bt)) == Approx(0.0) ); - - X = A; X = (2*X).t(); - Y = B; Y = (2*Y).t(); - - REQUIRE( accu(abs(X - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*Bt)) == Approx(0.0) ); - - X = A; X = (X+X).t(); - Y = B; Y = (Y+Y).t(); - - REQUIRE( accu(abs(X - 2*At)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*Bt)) == Approx(0.0) ); - - colvec q = A.col(1); - rowvec r = A.row(1); - - REQUIRE_THROWS( q = q.t() ); - REQUIRE_THROWS( r = r.t() ); - } - - - -TEST_CASE("fn_trans_4") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - cx_mat C = cx_mat(A,fliplr(A)); - - cx_mat Ct = - { - { cx_double( 0.061198, -0.051408), cx_double( 0.437242, -0.035437), cx_double(-0.492474, +0.454499), cx_double( 0.336352, -0.373833), cx_double( 0.239585, -0.258704) }, - { cx_double( 0.201990, +0.126745), cx_double( 0.058956, -0.296153), cx_double(-0.031309, -0.068317), cx_double( 0.411541, +0.135040), cx_double(-0.428913, +0.353768) }, - { cx_double( 0.019678, +0.493936), cx_double(-0.149362, +0.045465), cx_double( 0.314156, -0.419733), cx_double( 0.458476, +0.393139), cx_double(-0.406953, +0.291020) }, - { cx_double(-0.493936, -0.019678), cx_double(-0.045465, +0.149362), cx_double( 0.419733, -0.314156), cx_double(-0.393139, -0.458476), cx_double(-0.291020, +0.406953) }, - { cx_double(-0.126745, -0.201990), cx_double( 0.296153, -0.058956), cx_double( 0.068317, +0.031309), cx_double(-0.135040, -0.411541), cx_double(-0.353768, +0.428913) }, - { cx_double( 0.051408, -0.061198), cx_double( 0.035437, -0.437242), cx_double(-0.454499, +0.492474), cx_double( 0.373833, -0.336352), cx_double( 0.258704, -0.239585) } - }; - - cx_mat D = C.head_cols(5); - - cx_mat Dt = Ct.head_rows(5); - - cx_mat X; - cx_mat Y; - - // - - X = C; X = X.t(); - Y = D; Y = Y.t(); - - REQUIRE( accu(abs(X - Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - Dt)) == Approx(0.0) ); - - X = C; X = 0 + X.t(); - Y = D; Y = 0 + Y.t(); - - REQUIRE( accu(abs(X - Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - Dt)) == Approx(0.0) ); - - X = C; X = 2*X.t(); - Y = D; Y = 2*Y.t(); - - REQUIRE( accu(abs(X - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*Dt)) == Approx(0.0) ); - - X = C; X = 0 + 2*X.t(); - Y = D; Y = 0 + 2*Y.t(); - - REQUIRE( accu(abs(X - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*Dt)) == Approx(0.0) ); - - X = C; X = (2*X).t(); - Y = D; Y = (2*Y).t(); - - REQUIRE( accu(abs(X - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*Dt)) == Approx(0.0) ); - - X = C; X = (X+X).t(); - Y = D; Y = (Y+Y).t(); - - REQUIRE( accu(abs(X - 2*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*Dt)) == Approx(0.0) ); - - X = C; X = cx_double(2,3)*X.t(); - Y = D; Y = cx_double(2,3)*Y.t(); - - REQUIRE( accu(abs(X - cx_double(2,3)*Ct)) == Approx(0.0) ); - REQUIRE( accu(abs(Y - cx_double(2,3)*Dt)) == Approx(0.0) ); - - // - - X = C; X = X.st(); - Y = D; Y = Y.st(); - - REQUIRE( accu(abs(X - conj(Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(Y - conj(Dt))) == Approx(0.0) ); - - X = C; X = 0 + X.st(); - Y = D; Y = 0 + Y.st(); - - REQUIRE( accu(abs(X - conj(Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(Y - conj(Dt))) == Approx(0.0) ); - - X = C; X = 2*X.st(); - Y = D; Y = 2*Y.st(); - - REQUIRE( accu(abs(X - 2*conj(Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*conj(Dt))) == Approx(0.0) ); - - X = C; X = 0 + 2*X.st(); - Y = D; Y = 0 + 2*Y.st(); - - REQUIRE( accu(abs(X - 2*conj(Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(Y - 2*conj(Dt))) == Approx(0.0) ); - - X = C; X = (2*X).st(); - Y = D; Y = (2*Y).st(); - - REQUIRE( accu(abs(X - conj(2*Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(Y - conj(2*Dt))) == Approx(0.0) ); - - X = C; X = (X+X).st(); - Y = D; Y = (Y+Y).st(); - - REQUIRE( accu(abs(X - conj(2*Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(Y - conj(2*Dt))) == Approx(0.0) ); - - X = C; X = cx_double(2,3)*X.st(); - Y = D; Y = cx_double(2,3)*Y.st(); - - REQUIRE( accu(abs(X - cx_double(2,3)*conj(Ct))) == Approx(0.0) ); - REQUIRE( accu(abs(Y - cx_double(2,3)*conj(Dt))) == Approx(0.0) ); - } - - - -TEST_CASE("op_trans_sp_mat") - { - SpMat a(4, 4); - a(1, 0) = 5; - a(2, 2) = 3; - a(3, 3) = 4; - a(1, 3) = 6; - a(3, 1) = 8; - - SpMat b = trans(a); - - REQUIRE( (unsigned int) b(0, 0) == 0 ); - REQUIRE( (unsigned int) b(1, 0) == 0 ); - REQUIRE( (unsigned int) b(2, 0) == 0 ); - REQUIRE( (unsigned int) b(3, 0) == 0 ); - REQUIRE( (unsigned int) b(0, 1) == 5 ); - REQUIRE( (unsigned int) b(1, 1) == 0 ); - REQUIRE( (unsigned int) b(2, 1) == 0 ); - REQUIRE( (unsigned int) b(3, 1) == 6 ); - REQUIRE( (unsigned int) b(0, 2) == 0 ); - REQUIRE( (unsigned int) b(1, 2) == 0 ); - REQUIRE( (unsigned int) b(2, 2) == 3 ); - REQUIRE( (unsigned int) b(3, 2) == 0 ); - REQUIRE( (unsigned int) b(0, 3) == 0 ); - REQUIRE( (unsigned int) b(1, 3) == 8 ); - REQUIRE( (unsigned int) b(2, 3) == 0 ); - REQUIRE( (unsigned int) b(3, 3) == 4 ); - - b = trans(b); // inplace - - REQUIRE( (unsigned int) b(0, 0) == 0 ); - REQUIRE( (unsigned int) b(1, 0) == 5 ); - REQUIRE( (unsigned int) b(2, 0) == 0 ); - REQUIRE( (unsigned int) b(3, 0) == 0 ); - REQUIRE( (unsigned int) b(0, 1) == 0 ); - REQUIRE( (unsigned int) b(1, 1) == 0 ); - REQUIRE( (unsigned int) b(2, 1) == 0 ); - REQUIRE( (unsigned int) b(3, 1) == 8 ); - REQUIRE( (unsigned int) b(0, 2) == 0 ); - REQUIRE( (unsigned int) b(1, 2) == 0 ); - REQUIRE( (unsigned int) b(2, 2) == 3 ); - REQUIRE( (unsigned int) b(3, 2) == 0 ); - REQUIRE( (unsigned int) b(0, 3) == 0 ); - REQUIRE( (unsigned int) b(1, 3) == 6 ); - REQUIRE( (unsigned int) b(2, 3) == 0 ); - REQUIRE( (unsigned int) b(3, 3) == 4 ); - - b = trans(a + a); // on an op - - REQUIRE( (unsigned int) b(0, 0) == 0 ); - REQUIRE( (unsigned int) b(1, 0) == 0 ); - REQUIRE( (unsigned int) b(2, 0) == 0 ); - REQUIRE( (unsigned int) b(3, 0) == 0 ); - REQUIRE( (unsigned int) b(0, 1) == 10 ); - REQUIRE( (unsigned int) b(1, 1) == 0 ); - REQUIRE( (unsigned int) b(2, 1) == 0 ); - REQUIRE( (unsigned int) b(3, 1) == 12 ); - REQUIRE( (unsigned int) b(0, 2) == 0 ); - REQUIRE( (unsigned int) b(1, 2) == 0 ); - REQUIRE( (unsigned int) b(2, 2) == 6 ); - REQUIRE( (unsigned int) b(3, 2) == 0 ); - REQUIRE( (unsigned int) b(0, 3) == 0 ); - REQUIRE( (unsigned int) b(1, 3) == 16 ); - REQUIRE( (unsigned int) b(2, 3) == 0 ); - REQUIRE( (unsigned int) b(3, 3) == 8 ); - - b = trans(trans(a)); // on another trans - - REQUIRE( (unsigned int) b(0, 0) == 0 ); - REQUIRE( (unsigned int) b(1, 0) == 5 ); - REQUIRE( (unsigned int) b(2, 0) == 0 ); - REQUIRE( (unsigned int) b(3, 0) == 0 ); - REQUIRE( (unsigned int) b(0, 1) == 0 ); - REQUIRE( (unsigned int) b(1, 1) == 0 ); - REQUIRE( (unsigned int) b(2, 1) == 0 ); - REQUIRE( (unsigned int) b(3, 1) == 8 ); - REQUIRE( (unsigned int) b(0, 2) == 0 ); - REQUIRE( (unsigned int) b(1, 2) == 0 ); - REQUIRE( (unsigned int) b(2, 2) == 3 ); - REQUIRE( (unsigned int) b(3, 2) == 0 ); - REQUIRE( (unsigned int) b(0, 3) == 0 ); - REQUIRE( (unsigned int) b(1, 3) == 6 ); - REQUIRE( (unsigned int) b(2, 3) == 0 ); - REQUIRE( (unsigned int) b(3, 3) == 4 ); - } - - -TEST_CASE("op_trans_sp_cxmat") - { - SpMat > a(10, 10); - for (uword c = 0; c < 7; ++c) - { - a(c, c) = std::complex(1.3, 2.4); - a(c + 1, c) = std::complex(0.0, -1.3); - a(c + 2, c) = std::complex(2.1, 0.0); - } - - SpMat > b = trans(a); - - REQUIRE( b.n_nonzero == a.n_nonzero ); - - for (uword r = 0; r < 10; ++r) - { - for (uword c = 0; c < 10; ++c) - { - double lr = real(std::complex(a(r, c))); - double rr = real(std::complex(b(c, r))); - double li = imag(std::complex(a(r, c))); - double ri = imag(std::complex(b(c, r))); - - REQUIRE( lr == Approx(rr) ); - REQUIRE( li == Approx(-ri) ); - } - } - - b = trans(a.submat(3, 3, 7, 7)); - - REQUIRE( b.n_nonzero == a.submat(3, 3, 7, 7).n_nonzero ); - - for (uword r = 0; r < 5; ++r) - { - for (uword c = 0; c < 5; ++c) - { - double lr = real(std::complex(a(r + 3, c + 3))); - double rr = real(std::complex(b(c, r))); - double li = imag(std::complex(a(r + 3, c + 3))); - double ri = imag(std::complex(b(c, r))); - - REQUIRE( lr == Approx(rr) ); - REQUIRE( li == Approx(-ri) ); - } - } - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_var.cpp armadillo-10.8.2+dfsg/tests/fn_var.cpp --- armadillo-9.800.4+dfsg/tests/fn_var.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_var.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,549 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("fn_var_empty_sparse_test") - { - SpMat m(100, 100); - - SpRow result = var(m); - - REQUIRE( result.n_cols == 100 ); - REQUIRE( result.n_rows == 1 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) result[i] == Approx(0.0) ); - } - - result = var(m, 0, 0); - - REQUIRE( result.n_cols == 100 ); - REQUIRE( result.n_rows == 1 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) result[i] == Approx(0.0) ); - } - - result = var(m, 1, 0); - - REQUIRE( result.n_cols == 100 ); - REQUIRE( result.n_rows == 1 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) result[i] == Approx(0.0) ); - } - - result = var(m, 1); - - REQUIRE( result.n_cols == 100 ); - REQUIRE( result.n_rows == 1 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) result[i] == Approx(0.0) ); - } - - SpCol colres = var(m, 1, 1); - - REQUIRE( colres.n_cols == 1 ); - REQUIRE( colres.n_rows == 100 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) colres[i] == Approx(0.0) ); - } - - colres = var(m, 0, 1); - - REQUIRE( colres.n_cols == 1 ); - REQUIRE( colres.n_rows == 100 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) colres[i] == Approx(0.0) ); - } - } - - - -TEST_CASE("fn_var_empty_cx_sparse_test") - { - SpMat > m(100, 100); - - SpRow result = var(m); - - REQUIRE( result.n_cols == 100 ); - REQUIRE( result.n_rows == 1 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) result[i] == Approx(0.0) ); - } - - result = var(m, 0, 0); - - REQUIRE( result.n_cols == 100 ); - REQUIRE( result.n_rows == 1 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) result[i] == Approx(0.0) ); - } - - result = var(m, 1, 0); - - REQUIRE( result.n_cols == 100 ); - REQUIRE( result.n_rows == 1 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) result[i] == Approx(0.0) ); - } - - result = var(m, 1); - - REQUIRE( result.n_cols == 100 ); - REQUIRE( result.n_rows == 1 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) result[i] == Approx(0.0) ); - } - - SpCol colres = var(m, 1, 1); - - REQUIRE( colres.n_cols == 1 ); - REQUIRE( colres.n_rows == 100 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) colres[i] == Approx(0.0) ); - } - - colres = var(m, 0, 1); - - REQUIRE( colres.n_cols == 1 ); - REQUIRE( colres.n_rows == 100 ); - for (uword i = 0; i < 100; ++i) - { - REQUIRE( (double) colres[i] == Approx(0.0) ); - } - } - - - -TEST_CASE("fn_var_sparse_test") - { - // Create a random matrix and do variance testing on it, with varying levels - // of nonzero (eventually this becomes a fully dense matrix). - for (int i = 0; i < 10; ++i) - { - SpMat x; - x.sprandu(50, 75, ((double) (i + 1)) / 10); - mat d(x); - - SpRow rr = var(x); - rowvec drr = var(d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(x, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(x, 1, 0); - drr = var(d, 1, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - SpCol cr = var(x, 0, 1); - vec dcr = var(d, 0, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - cr = var(x, 1, 1); - dcr = var(d, 1, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - // Now on a subview. - rr = var(x.submat(11, 11, 30, 45), 0, 0); - drr = var(d.submat(11, 11, 30, 45), 0, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 35 ); - for (uword j = 0; j < 35; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(x.submat(11, 11, 30, 45), 1, 0); - drr = var(d.submat(11, 11, 30, 45), 1, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 35 ); - for (uword j = 0; j < 35; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = var(x.submat(11, 11, 30, 45), 0, 1); - dcr = var(d.submat(11, 11, 30, 45), 0, 1); - - REQUIRE( cr.n_rows == 20 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 20; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - cr = var(x.submat(11, 11, 30, 45), 1, 1); - dcr = var(d.submat(11, 11, 30, 45), 1, 1); - - REQUIRE( cr.n_rows == 20 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 20; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - // Now on an SpOp (spop_scalar_times) - rr = var(3.0 * x, 0, 0); - drr = var(3.0 * d, 0, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(3.0 * x, 1, 0); - drr = var(3.0 * d, 1, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = var(4.5 * x, 0, 1); - dcr = var(4.5 * d, 0, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - cr = var(4.5 * x, 1, 1); - dcr = var(4.5 * d, 1, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - // Now on an SpGlue! - SpMat y; - y.sprandu(50, 75, 0.3); - mat e(y); - - rr = var(x + y); - drr = var(d + e); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(x + y, 1); - drr = var(d + e, 1); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = var(x + y, 0, 1); - dcr = var(d + e, 0, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - cr = var(x + y, 1, 1); - dcr = var(d + e, 1, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - } - } - - - -TEST_CASE("fn_var_sparse_cx_test") - { - // Create a random matrix and do variance testing on it, with varying levels - // of nonzero (eventually this becomes a fully dense matrix). - for (int i = 0; i < 10; ++i) - { - SpMat > x; - x.sprandu(50, 75, ((double) (i + 1)) / 10); - cx_mat d(x); - - SpRow rr = var(x); - rowvec drr = var(d); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(x, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(x, 1, 0); - drr = var(d, 1, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - SpCol cr = var(x, 0, 1); - vec dcr = var(d, 0, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - cr = var(x, 1, 1); - dcr = var(d, 1, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - // Now on a subview. - rr = var(x.submat(11, 11, 30, 45), 0, 0); - drr = var(d.submat(11, 11, 30, 45), 0, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 35 ); - for (uword j = 0; j < 35; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(x.submat(11, 11, 30, 45), 1, 0); - drr = var(d.submat(11, 11, 30, 45), 1, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 35 ); - for (uword j = 0; j < 35; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = var(x.submat(11, 11, 30, 45), 0, 1); - dcr = var(d.submat(11, 11, 30, 45), 0, 1); - - REQUIRE( cr.n_rows == 20 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 20; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - cr = var(x.submat(11, 11, 30, 45), 1, 1); - dcr = var(d.submat(11, 11, 30, 45), 1, 1); - - REQUIRE( cr.n_rows == 20 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 20; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - // Now on an SpOp (spop_scalar_times) - rr = var(3.0 * x, 0, 0); - drr = var(3.0 * d, 0, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(3.0 * x, 1, 0); - drr = var(3.0 * d, 1, 0); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = var(4.5 * x, 0, 1); - dcr = var(4.5 * d, 0, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - cr = var(4.5 * x, 1, 1); - dcr = var(4.5 * d, 1, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - // Now on an SpGlue! - SpMat > y; - y.sprandu(50, 75, 0.3); - cx_mat e(y); - - rr = var(x + y); - drr = var(d + e); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - rr = var(x + y, 1); - drr = var(d + e, 1); - - REQUIRE( rr.n_rows == 1 ); - REQUIRE( rr.n_cols == 75 ); - for (uword j = 0; j < 75; ++j) - { - REQUIRE( drr[j] == Approx((double) rr[j]) ); - } - - cr = var(x + y, 0, 1); - dcr = var(d + e, 0, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - - cr = var(x + y, 1, 1); - dcr = var(d + e, 1, 1); - - REQUIRE( cr.n_rows == 50 ); - REQUIRE( cr.n_cols == 1 ); - for (uword j = 0; j < 50; ++j) - { - REQUIRE( dcr[j] == Approx((double) cr[j]) ); - } - } - } - - - -TEST_CASE("fn_var_sparse_alias_test") - { - sp_mat s; - s.sprandu(70, 70, 0.3); - mat d(s); - - s = var(s); - d = var(d); - - REQUIRE( d.n_rows == s.n_rows ); - REQUIRE( d.n_cols == s.n_cols ); - for (uword i = 0; i < d.n_elem; ++i) - { - REQUIRE(d[i] == Approx((double) s[i]) ); - } - - s.sprandu(70, 70, 0.3); - d = s; - - s = var(s, 1); - d = var(d, 1); - for (uword i = 0; i < d.n_elem; ++i) - { - REQUIRE( d[i] == Approx((double) s[i]) ); - } - } diff -Nru armadillo-9.800.4+dfsg/tests/fn_vectorise.cpp armadillo-10.8.2+dfsg/tests/fn_vectorise.cpp --- armadillo-9.800.4+dfsg/tests/fn_vectorise.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/fn_vectorise.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("fn_vectorise_1") - { - mat A = - "\ - 0.061198 0.201990;\ - 0.437242 0.058956;\ - -0.492474 -0.031309;\ - 0.336352 0.411541;\ - "; - - vec a = - { - 0.061198, - 0.437242, - -0.492474, - 0.336352, - 0.201990, - 0.058956, - -0.031309, - 0.411541, - }; - - rowvec b = { 0.061198, 0.201990, 0.437242, 0.058956, -0.492474, -0.031309, 0.336352, 0.411541 }; - - REQUIRE( accu(abs(a - vectorise(A ))) == Approx(0.0) ); - REQUIRE( accu(abs(a - vectorise(A,0))) == Approx(0.0) ); - REQUIRE( accu(abs(b - vectorise(A,1))) == Approx(0.0) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/gen_linspace.cpp armadillo-10.8.2+dfsg/tests/gen_linspace.cpp --- armadillo-9.800.4+dfsg/tests/gen_linspace.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/gen_linspace.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("gen_linspace_1") - { - vec a = linspace(1,5,5); - - REQUIRE(a(0) == Approx(1.0)); - REQUIRE(a(1) == Approx(2.0)); - REQUIRE(a(2) == Approx(3.0)); - REQUIRE(a(3) == Approx(4.0)); - REQUIRE(a(4) == Approx(5.0)); - - vec b = linspace(1,5,6); - - REQUIRE(b(0) == Approx(1.0)); - REQUIRE(b(1) == Approx(1.8)); - REQUIRE(b(2) == Approx(2.6)); - REQUIRE(b(3) == Approx(3.4)); - REQUIRE(b(4) == Approx(4.2)); - REQUIRE(b(5) == Approx(5.0)); - - rowvec c = linspace(1,5,6); - - REQUIRE(c(0) == Approx(1.0)); - REQUIRE(c(1) == Approx(1.8)); - REQUIRE(c(2) == Approx(2.6)); - REQUIRE(c(3) == Approx(3.4)); - REQUIRE(c(4) == Approx(4.2)); - REQUIRE(c(5) == Approx(5.0)); - - mat X = linspace(1,5,6); - - REQUIRE(X.n_rows == 6); - REQUIRE(X.n_cols == 1); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/gen_ones.cpp armadillo-10.8.2+dfsg/tests/gen_ones.cpp --- armadillo-9.800.4+dfsg/tests/gen_ones.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/gen_ones.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("gen_ones_1") - { - mat A(5,6,fill::ones); - - REQUIRE( accu(A) == Approx(double(5*6)) ); - REQUIRE( A.n_rows == 5 ); - REQUIRE( A.n_cols == 6 ); - - mat B(5,6,fill::randu); - - B.ones(); - - REQUIRE( accu(B) == Approx(double(5*6)) ); - REQUIRE( B.n_rows == 5 ); - REQUIRE( B.n_cols == 6 ); - - mat C = ones(5,6); - - REQUIRE( accu(C) == Approx(double(5*6)) ); - REQUIRE( C.n_rows == 5 ); - REQUIRE( C.n_cols == 6 ); - - mat D; D = ones(5,6); - - REQUIRE( accu(D) == Approx(double(5*6)) ); - REQUIRE( D.n_rows == 5 ); - REQUIRE( D.n_cols == 6 ); - - mat E; E = 2*ones(5,6); - - REQUIRE( accu(E) == Approx(double(2*5*6)) ); - REQUIRE( E.n_rows == 5 ); - REQUIRE( E.n_cols == 6 ); - } - - - -TEST_CASE("gen_ones_2") - { - mat A(5,6,fill::zeros); - - A.col(1).ones(); - - REQUIRE( accu(A.col(0)) == Approx(0.0) ); - REQUIRE( accu(A.col(1)) == Approx(double(A.n_rows)) ); - REQUIRE( accu(A.col(2)) == Approx(0.0) ); - - mat B(5,6,fill::zeros); - - B.row(1).ones(); - - REQUIRE( accu(B.row(0)) == Approx(0.0) ); - REQUIRE( accu(B.row(1)) == Approx(double(B.n_cols)) ); - REQUIRE( accu(B.row(2)) == Approx(0.0) ); - - mat C(5,6,fill::zeros); - - C(span(1,3),span(1,4)).ones(); - - REQUIRE( accu(C.head_cols(1)) == Approx(0.0) ); - REQUIRE( accu(C.head_rows(1)) == Approx(0.0) ); - - REQUIRE( accu(C.tail_cols(1)) == Approx(0.0) ); - REQUIRE( accu(C.tail_rows(1)) == Approx(0.0) ); - - REQUIRE( accu(C(span(1,3),span(1,4))) == Approx(double(3*4)) ); - - mat D(5,6,fill::zeros); - - D.diag().ones(); - - REQUIRE( accu(D.diag()) == Approx(double(5)) ); - } - - - -TEST_CASE("gen_ones_3") - { - mat A(5,6,fill::zeros); - - uvec indices = { 2, 4, 6 }; - - A(indices).ones(); - - REQUIRE( accu(A) == Approx(double(3)) ); - - REQUIRE( A(0) == Approx(0.0) ); - REQUIRE( A(A.n_elem-1) == Approx(0.0) ); - - REQUIRE( A(indices(0)) == Approx(1.0) ); - REQUIRE( A(indices(1)) == Approx(1.0) ); - REQUIRE( A(indices(2)) == Approx(1.0) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/gen_randu.cpp armadillo-10.8.2+dfsg/tests/gen_randu.cpp --- armadillo-9.800.4+dfsg/tests/gen_randu.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/gen_randu.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("gen_randu_1") - { - const uword n_rows = 100; - const uword n_cols = 101; - - mat A(n_rows,n_cols, fill::randu); - - mat B(n_rows,n_cols); B.randu(); - - mat C; C.randu(n_rows,n_cols); - - REQUIRE( (accu(A)/A.n_elem) == Approx(0.5).epsilon(0.02) ); - REQUIRE( (accu(B)/A.n_elem) == Approx(0.5).epsilon(0.02) ); - REQUIRE( (accu(C)/A.n_elem) == Approx(0.5).epsilon(0.02) ); - - REQUIRE( (mean(vectorise(A))) == Approx(0.5).epsilon(0.02) ); - } - - - -TEST_CASE("gen_randu_2") - { - mat A(50,60,fill::zeros); - - A(span(1,48),span(1,58)).randu(); - - REQUIRE( accu(A.head_cols(1)) == Approx(0.0) ); - REQUIRE( accu(A.head_rows(1)) == Approx(0.0) ); - - REQUIRE( accu(A.tail_cols(1)) == Approx(0.0) ); - REQUIRE( accu(A.tail_rows(1)) == Approx(0.0) ); - - REQUIRE( mean(vectorise(A(span(1,48),span(1,58)))) == Approx(double(0.5)).epsilon(0.02) ); - } - diff -Nru armadillo-9.800.4+dfsg/tests/gen_zeros.cpp armadillo-10.8.2+dfsg/tests/gen_zeros.cpp --- armadillo-9.800.4+dfsg/tests/gen_zeros.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/gen_zeros.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("gen_zeros_1") - { - mat A(5,6,fill::zeros); - - REQUIRE( accu(A) == Approx(0.0) ); - REQUIRE( A.n_rows == 5 ); - REQUIRE( A.n_cols == 6 ); - - mat B(5,6,fill::randu); - - B.zeros(); - - REQUIRE( accu(B) == Approx(0.0) ); - REQUIRE( B.n_rows == 5 ); - REQUIRE( B.n_cols == 6 ); - - mat C = zeros(5,6); - - REQUIRE( accu(C) == Approx(0.0) ); - REQUIRE( C.n_rows == 5 ); - REQUIRE( C.n_cols == 6 ); - - mat D; D = zeros(5,6); - - REQUIRE( accu(D) == Approx(0.0) ); - REQUIRE( D.n_rows == 5 ); - REQUIRE( D.n_cols == 6 ); - - mat E; E = 2*zeros(5,6); - - REQUIRE( accu(E) == Approx(0.0) ); - REQUIRE( E.n_rows == 5 ); - REQUIRE( E.n_cols == 6 ); - } - - - -TEST_CASE("gen_zeros_2") - { - mat A(5,6,fill::ones); - - A.col(1).zeros(); - - REQUIRE( accu(A.col(0)) == Approx(double(A.n_rows)) ); - REQUIRE( accu(A.col(1)) == Approx(0.0) ); - REQUIRE( accu(A.col(2)) == Approx(double(A.n_rows)) ); - - mat B(5,6,fill::ones); - - B.row(1).zeros(); - - REQUIRE( accu(B.row(0)) == Approx(double(B.n_cols)) ); - REQUIRE( accu(B.row(1)) == Approx(0.0) ); - REQUIRE( accu(B.row(2)) == Approx(double(B.n_cols)) ); - - mat C(5,6,fill::ones); - - C(span(1,3),span(1,4)).zeros(); - - REQUIRE( accu(C.head_cols(1)) == Approx(double(5)) ); - REQUIRE( accu(C.head_rows(1)) == Approx(double(6)) ); - - REQUIRE( accu(C.tail_cols(1)) == Approx(double(5)) ); - REQUIRE( accu(C.tail_rows(1)) == Approx(double(6)) ); - - REQUIRE( accu(C(span(1,3),span(1,4))) == Approx(0.0) ); - - mat D(5,6,fill::ones); - - D.diag().zeros(); - - REQUIRE( accu(D.diag()) == Approx(0.0) ); - } - - - -TEST_CASE("gen_zeros_3") - { - mat A(5,6,fill::ones); - - uvec indices = { 2, 4, 6 }; - - A(indices).zeros(); - - REQUIRE( accu(A) == Approx(double(5*6-3)) ); - - REQUIRE( A(0) == Approx(1.0) ); - REQUIRE( A(A.n_elem-1) == Approx(1.0) ); - - REQUIRE( A(indices(0)) == Approx(0.0) ); - REQUIRE( A(indices(1)) == Approx(0.0) ); - REQUIRE( A(indices(2)) == Approx(0.0) ); - } - - - -TEST_CASE("gen_zeros_sp_mat") - { - SpMat e(2, 2); - - e(0, 0) = 3.1; - e(1, 1) = 2.2; - - e *= zeros >(2, 2); - - REQUIRE( e.n_nonzero == 0 ); - REQUIRE( (unsigned int) e(0, 0) == 0 ); - REQUIRE( (unsigned int) e(1, 0) == 0 ); - REQUIRE( (unsigned int) e(0, 1) == 0 ); - REQUIRE( (unsigned int) e(1, 1) == 0 ); - - // Just test compilation here. - e = zeros >(5, 5); - e *= zeros >(5, 5); - e %= zeros >(5, 5); - } diff -Nru armadillo-9.800.4+dfsg/tests/gmm.cpp armadillo-10.8.2+dfsg/tests/gmm.cpp --- armadillo-9.800.4+dfsg/tests/gmm.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/gmm.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ -#include -#include -#include "catch.hpp" - -using namespace std; -using namespace arma; - -/** - * Make sure that gmm_full can fit manually constructed Gaussians. - */ -TEST_CASE("gmm_full_1") - { - // Higher dimensionality gives us a greater chance of having separated Gaussians. - const uword dims = 8; - const uword gaussians = 3; - const uword maxTrials = 3; - - // Generate dataset. - mat data(dims, 500, fill::zeros); - - vector means(gaussians); - vector covars(gaussians); - - vec weights(gaussians); - uvec counts(gaussians); - - bool success = true; - - for(uword trial = 0; trial < maxTrials; ++trial) - { - // Preset weights. - weights[0] = 0.25; - weights[1] = 0.325; - weights[2] = 0.425; - - for(size_t i = 0; i < gaussians; i++) - { - counts[i] = data.n_cols * weights[i]; - } - - // Account for rounding errors (possibly necessary). - counts[gaussians - 1] += (data.n_cols - accu(counts)); - - // Build each Gaussian individually. - size_t point = 0; - for(size_t i = 0; i < gaussians; i++) - { - mat gaussian; - gaussian.randn(dims, counts[i]); - - // Randomly generate mean and covariance. - means[i].randu(dims); - means[i] -= 0.5; - means[i] *= (5 * i); - - // We need to make sure the covariance is positive definite. - // We will take a random matrix C and then set our covariance to C * C', - // which will be positive semidefinite. - covars[i].randu(dims, dims); - covars[i] += 0.5 * eye(dims, dims); - covars[i] *= trans(covars[i]); - - data.cols(point, point + counts[i] - 1) = (covars[i] * gaussian + means[i] * ones(counts[i])); - - // Calculate the actual means and covariances - // because they will probably be different. - means[i] = mean(data.cols(point, point + counts[i] - 1), 1); - covars[i] = cov(data.cols(point, point + counts[i] - 1).t(), 1 /* biased */); - - point += counts[i]; - } - - // Calculate actual weights. - for(size_t i = 0; i < gaussians; i++) - { - weights[i] = (double) counts[i] / data.n_cols; - } - - gmm_full gmm; - gmm.learn(data, gaussians, eucl_dist, random_subset, 10, 500, 1e-10, false); - - uvec sortRef = sort_index(weights); - uvec sortTry = sort_index(gmm.hefts); - - // Check the model to see that it is correct. - success = ( gmm.hefts.n_elem == gaussians ); - for(size_t i = 0; i < gaussians; i++) - { - // Check weight. - success &= ( weights[sortRef[i]] == Approx(gmm.hefts[sortTry[i]]).epsilon(0.1) ); - - for(uword j = 0; j < gmm.means.n_rows; ++j) - { - success &= ( means[sortRef[i]][j] == Approx(gmm.means(j, sortTry[i])).epsilon(0.1) ); - } - - for(uword j = 0; j < gmm.fcovs.n_rows * gmm.fcovs.n_cols; ++j) - { - success &= ( covars[sortRef[i]][j] == Approx(gmm.fcovs.slice(sortTry[i])[j]).epsilon(0.1) ); - } - - if(success == false) { continue; } - } - - if(success) { break; } - } - - REQUIRE( success == true ); - } - - - -TEST_CASE("gmm_diag_1") - { - // Higher dimensionality gives us a greater chance of having separated Gaussians. - const uword dims = 4; - const uword gaussians = 3; - const uword maxTrials = 8; // Needs more trials... - - // Generate dataset. - mat data(dims, 500, fill::zeros); - - vector means(gaussians); - vector covars(gaussians); - - vec weights(gaussians); - uvec counts(gaussians); - - bool success = true; - for(uword trial = 0; trial < maxTrials; ++trial) - { - // Preset weights. - weights[0] = 0.25; - weights[1] = 0.325; - weights[2] = 0.425; - - for(size_t i = 0; i < gaussians; i++) - { - counts[i] = data.n_cols * weights[i]; - } - - // Account for rounding errors (possibly necessary). - counts[gaussians - 1] += (data.n_cols - accu(counts)); - - // Build each Gaussian individually. - size_t point = 0; - for(size_t i = 0; i < gaussians; i++) - { - mat gaussian; - gaussian.randn(dims, counts[i]); - - // Randomly generate mean and covariance. - means[i].randu(dims); - means[i] -= 0.5; - means[i] *= (3 * (i + 1)); - - // Use a diagonal covariance matrix. - covars[i].zeros(dims, dims); - covars[i].diag() = 0.5 * randu(dims) + 0.5; - - data.cols(point, point + counts[i] - 1) = (covars[i] * gaussian + means[i] * ones(counts[i])); - - // Calculate the actual means and covariances - // because they will probably be different. - means[i] = mean(data.cols(point, point + counts[i] - 1), 1); - covars[i] = cov(data.cols(point, point + counts[i] - 1).t(), 1 /* biased */); - - point += counts[i]; - } - - // Calculate actual weights. - for(size_t i = 0; i < gaussians; i++) - { - weights[i] = (double) counts[i] / data.n_cols; - } - - gmm_diag gmm; - gmm.learn(data, gaussians, eucl_dist, random_subset, 50, 500, 1e-10, false); - - uvec sortRef = sort_index(weights); - uvec sortTry = sort_index(gmm.hefts); - - // Check the model to see that it is correct. - success = ( gmm.hefts.n_elem == gaussians ); - for(size_t i = 0; i < gaussians; i++) - { - // Check weight. - success &= ( weights[sortRef[i]] == Approx(gmm.hefts[sortTry[i]]).epsilon(0.1) ); - - for(uword j = 0; j < gmm.means.n_rows; ++j) - { - success &= ( means[sortRef[i]][j] == Approx(gmm.means(j, sortTry[i])).epsilon(0.1) ); - } - - for(uword j = 0; j < gmm.dcovs.n_rows; ++j) - { - success &= ( covars[sortRef[i]](j, j) == Approx(gmm.dcovs.col(sortTry[i])[j]).epsilon(0.1) ); - } - - if(success == false) { continue; } - } - - if(success) { break; } - } - - REQUIRE( success == true ); - } diff -Nru armadillo-9.800.4+dfsg/tests/hdf5.cpp armadillo-10.8.2+dfsg/tests/hdf5.cpp --- armadillo-9.800.4+dfsg/tests/hdf5.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/hdf5.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,847 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include -#include - -#include "catch.hpp" - -using namespace arma; - -#if defined(ARMA_USE_HDF5) - -TEST_CASE("hdf5_u8_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_u16_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_u32_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -#ifdef ARMA_USE_U64S64 -TEST_CASE("hdf5_u64_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } -#endif - - - -TEST_CASE("hdf5_s8_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_s16_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_s32_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -#ifdef ARMA_USE_U64S64 -TEST_CASE("hdf5_s64_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } -#endif - - - -TEST_CASE("hdf5_char_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_int_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_uint_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_short_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_ushort_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_long_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_ulong_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -#ifdef ARMA_USE_U64S64 -TEST_CASE("hdf5_llong_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_ullong_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } -#endif - - - -TEST_CASE("hdf5_float_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_double_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_complex_float_test") - { - arma::Mat > a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat > b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == b[i] ); - } - - // Now autoload. - arma::Mat > c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_complex_double_test") - { - arma::Mat > a; - a.randu(20, 20); - - // Save first. - a.save("file.h5", hdf5_binary); - - // Load as different matrix. - arma::Mat > b; - b.load("file.h5", hdf5_binary); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - REQUIRE( a[i] == b[i] ); - - // Now autoload. - arma::Mat > c; - c.load("file.h5"); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_dataset_append_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first dataset. - a.save( hdf5_name("file.h5", "dataset1") ); - - arma::Mat b; - b.randu(10, 10); - - // Save second dataset. - b.save( hdf5_name("file.h5", "dataset2", hdf5_opts::append) ); - - // Load first dataset as different matrix. - arma::Mat c; - c.load( hdf5_name("file.h5", "dataset1") ); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - // Load second dataset as different matrix. - arma::Mat d; - d.load( hdf5_name("file.h5", "dataset2") ); - - // Check that they are the same. - for (uword i = 0; i < b.n_elem; ++i) - { - REQUIRE( b[i] == d[i] ); - } - - std::remove("file.h5"); - } - -TEST_CASE("hdf5_cube_dataset_append_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first dataset. - a.save( hdf5_name("file.h5", "dataset1") ); - - arma::Cube b; - b.randu(10, 10, 10); - - // Save second dataset. - b.save( hdf5_name("file.h5", "dataset2", hdf5_opts::append) ); - - // Load first dataset as different matrix. - arma::Mat c; - c.load( hdf5_name("file.h5", "dataset1") ); - - // Check that they are the same. - for (uword i = 0; i < a.n_elem; ++i) - { - REQUIRE( a[i] == c[i] ); - } - - // Load second dataset as different matrix. - arma::Cube d; - d.load( hdf5_name("file.h5", "dataset2") ); - - // Check that they are the same. - for (uword i = 0; i < b.n_elem; ++i) - { - REQUIRE( b[i] == d[i] ); - } - - std::remove("file.h5"); - } - - -TEST_CASE("hdf5_dataset_append-overwrite-test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first dataset. - a.save( hdf5_name("file.h5", "dataset1") ); - - arma::Mat b; - b.randu(10, 10); - - // Save second dataset. - b.save( hdf5_name("file.h5", "dataset2") ); - - // Load first dataset as different matrix and check that first dataset has been overwritten. - arma::Mat c; - REQUIRE_FALSE( c.load( hdf5_name("file.h5", "dataset1") ) ); - - // Load second dataset as different matrix. - arma::Mat d; - d.load( hdf5_name("file.h5", "dataset2") ); - - // Check that they are the same. - for (uword i = 0; i < b.n_elem; ++i) - { - REQUIRE( b[i] == d[i] ); - } - - std::remove("file.h5"); - } - - - -TEST_CASE("hdf5_dataset_same_dataset_twice_test") - { - arma::Mat a; - a.randu(20, 20); - - // Save first dataset. - a.save(hdf5_name("file.h5", "dataset1"), hdf5_binary); - - arma::Mat b; - b.randu(10, 10); - - // Append second dataset with same name, causing failure. - REQUIRE_FALSE( b.save(hdf5_name("file.h5", "dataset1", hdf5_opts::append) ) ); - - std::remove("file.h5"); - } - -#endif diff -Nru armadillo-9.800.4+dfsg/tests/init_auxmem.cpp armadillo-10.8.2+dfsg/tests/init_auxmem.cpp --- armadillo-9.800.4+dfsg/tests/init_auxmem.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/init_auxmem.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("init_auxmem_1") - { - double data[] = { 1, 2, 3, 4, 5, 6 }; - - mat A(data, 2, 3); - mat B(data, 2, 3, false); - mat C(data, 2, 3, false, true); - - REQUIRE( A(0,0) == double(1) ); - REQUIRE( A(1,0) == double(2) ); - - REQUIRE( A(0,1) == double(3) ); - REQUIRE( A(1,1) == double(4) ); - - REQUIRE( A(0,2) == double(5) ); - REQUIRE( A(1,2) == double(6) ); - - A(0,0) = 123.0; REQUIRE( data[0] == 1 ); - - B(0,0) = 123.0; REQUIRE( data[0] == 123.0 ); - - REQUIRE_THROWS( C.set_size(5,6) ); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/init_fill.cpp armadillo-10.8.2+dfsg/tests/init_fill.cpp --- armadillo-9.800.4+dfsg/tests/init_fill.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/init_fill.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("init_fill_1") - { - mat Z( 5, 6, fill::zeros); - mat O( 5, 6, fill::ones); - mat I( 5, 6, fill::eye); - mat U(50, 60, fill::randu); - mat N(50, 60, fill::randn); - - - REQUIRE( accu(Z != 0) == 0 ); - REQUIRE( accu(O != 0) == 5*6 ); - REQUIRE( accu(I != 0) == 5 ); - - REQUIRE( mean(vectorise(U)) == Approx(0.500).epsilon(0.05) ); - REQUIRE( stddev(vectorise(U)) == Approx(0.288).epsilon(0.05) ); - - REQUIRE( mean(vectorise(N)) == Approx(0.0).epsilon(0.05) ); - REQUIRE( stddev(vectorise(N)) == Approx(1.0).epsilon(0.05) ); - - mat X(5, 6, fill::none); // only to test instantiation - } - - - -TEST_CASE("init_fill_2") - { - cube Z( 5, 6, 2, fill::zeros); - cube O( 5, 6, 2, fill::ones); - cube U(50, 60, 2, fill::randu); - cube N(50, 60, 2, fill::randn); - - REQUIRE( accu(Z != 0) == 0 ); - REQUIRE( accu(O != 0) == 5*6*2 ); - - REQUIRE( mean(vectorise(U)) == Approx(0.500).epsilon(0.05) ); - REQUIRE( stddev(vectorise(U)) == Approx(0.288).epsilon(0.05) ); - - REQUIRE( mean(vectorise(N)) == Approx(0.0).epsilon(0.05) ); - REQUIRE( stddev(vectorise(N)) == Approx(1.0).epsilon(0.05) ); - - cube X(5, 6, 2, fill::none); // only to test instantiation - - cube I; REQUIRE_THROWS( I = cube(5, 6, 2, fill::eye) ); - } diff -Nru armadillo-9.800.4+dfsg/tests/init_misc.cpp armadillo-10.8.2+dfsg/tests/init_misc.cpp --- armadillo-9.800.4+dfsg/tests/init_misc.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/init_misc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,186 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("init_misc_1") - { - const uword n_rows = 5; - const uword n_cols = 6; - - mat A(5,6, fill::zeros); - - for(uword row=0; row -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("instantiation_mat_1") - { - const uword n_rows = 5; - const uword n_cols = 6; - - mat A(n_rows,n_cols); - fmat B(n_rows,n_cols); - umat C(n_rows,n_cols); - imat D(n_rows,n_cols); - - cx_mat E(n_rows,n_cols); - cx_fmat F(n_rows,n_cols); - - mat::fixed<5,6> G; - } - - -// TODO: colvec_instantiation -// TODO: rowvec_instantiation - - -TEST_CASE("instantiation_cube_1") - { - const uword n_rows = 5; - const uword n_cols = 6; - const uword n_slices = 2; - - cube A(n_rows,n_cols,n_slices); - fcube B(n_rows,n_cols,n_slices); - ucube C(n_rows,n_cols,n_slices); - icube D(n_rows,n_cols,n_slices); - - cx_cube E(n_rows,n_cols,n_slices); - cx_fcube F(n_rows,n_cols,n_slices); - - cube::fixed<5,6,2> G; - } - - -// TODO: field_instantiation 1D 2D 3D -// TODO: spmat_instantiation - - diff -Nru armadillo-9.800.4+dfsg/tests/main.cpp armadillo-10.8.2+dfsg/tests/main.cpp --- armadillo-9.800.4+dfsg/tests/main.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include - -//#define CATCH_CONFIG_MAIN // catch.hpp will define main() -#define CATCH_CONFIG_RUNNER // we will define main() -#include "catch.hpp" - - -int -main(int argc, char** argv) - { - std::cout << "Armadillo version: " << arma::arma_version::as_string() << '\n'; - - return Catch::Session().run(argc, argv); - } - diff -Nru armadillo-9.800.4+dfsg/tests/Makefile armadillo-10.8.2+dfsg/tests/Makefile --- armadillo-9.800.4+dfsg/tests/Makefile 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ - -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 diff -Nru armadillo-9.800.4+dfsg/tests/mat_minus.cpp armadillo-10.8.2+dfsg/tests/mat_minus.cpp --- armadillo-9.800.4+dfsg/tests/mat_minus.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/mat_minus.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("mat_minus_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = fliplr(A); - - mat A_minus_B = - "\ - 0.0097900 0.3287350 0.5136140 -0.5136140 -0.3287350 -0.0097900;\ - 0.4018050 -0.2371970 -0.1038970 0.1038970 0.2371970 -0.4018050;\ - -0.0379750 -0.0996260 -0.1055770 0.1055770 0.0996260 0.0379750;\ - -0.0374810 0.5465810 0.8516150 -0.8516150 -0.5465810 0.0374810;\ - -0.0191190 -0.0751450 -0.1159330 0.1159330 0.0751450 0.0191190;\ - "; - - mat neg_of_A_minus_B = - "\ - -0.0097900 -0.3287350 -0.5136140 +0.5136140 +0.3287350 +0.0097900;\ - -0.4018050 +0.2371970 +0.1038970 -0.1038970 -0.2371970 +0.4018050;\ - +0.0379750 +0.0996260 +0.1055770 -0.1055770 -0.0996260 -0.0379750;\ - +0.0374810 -0.5465810 -0.8516150 +0.8516150 +0.5465810 -0.0374810;\ - +0.0191190 +0.0751450 +0.1159330 -0.1159330 -0.0751450 -0.0191190;\ - "; - - mat X = A - B; - - REQUIRE( X(0,0) == Approx( 0.0097900) ); - REQUIRE( X(1,0) == Approx( 0.4018050) ); - REQUIRE( X(2,0) == Approx(-0.0379750) ); - REQUIRE( X(3,0) == Approx(-0.0374810) ); - REQUIRE( X(4,0) == Approx(-0.0191190) ); - - REQUIRE( X(0,1) == Approx( 0.3287350) ); - REQUIRE( X(1,1) == Approx(-0.2371970) ); - REQUIRE( X(2,1) == Approx(-0.0996260) ); - REQUIRE( X(3,1) == Approx( 0.5465810) ); - REQUIRE( X(4,1) == Approx(-0.0751450) ); - - REQUIRE( X(0,5) == Approx(-0.0097900) ); - REQUIRE( X(1,5) == Approx(-0.4018050) ); - REQUIRE( X(2,5) == Approx( 0.0379750) ); - REQUIRE( X(3,5) == Approx( 0.0374810) ); - REQUIRE( X(4,5) == Approx( 0.0191190) ); - - - mat Y = (2*A - 2*B) / 2; - - REQUIRE( Y(0,0) == Approx( 0.0097900) ); - REQUIRE( Y(1,0) == Approx( 0.4018050) ); - REQUIRE( Y(2,0) == Approx(-0.0379750) ); - REQUIRE( Y(3,0) == Approx(-0.0374810) ); - REQUIRE( Y(4,0) == Approx(-0.0191190) ); - - REQUIRE( Y(0,1) == Approx( 0.3287350) ); - REQUIRE( Y(1,1) == Approx(-0.2371970) ); - REQUIRE( Y(2,1) == Approx(-0.0996260) ); - REQUIRE( Y(3,1) == Approx( 0.5465810) ); - REQUIRE( Y(4,1) == Approx(-0.0751450) ); - - REQUIRE( Y(0,5) == Approx(-0.0097900) ); - REQUIRE( Y(1,5) == Approx(-0.4018050) ); - REQUIRE( Y(2,5) == Approx( 0.0379750) ); - REQUIRE( Y(3,5) == Approx( 0.0374810) ); - REQUIRE( Y(4,5) == Approx( 0.0191190) ); - - - REQUIRE( accu(mat(A-B) + (neg_of_A_minus_B)) == Approx(0.0) ); - REQUIRE( accu( (A-B) + (neg_of_A_minus_B)) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*(A-B) + 2*neg_of_A_minus_B )) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/mat_mul_cx.cpp armadillo-10.8.2+dfsg/tests/mat_mul_cx.cpp --- armadillo-9.800.4+dfsg/tests/mat_mul_cx.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/mat_mul_cx.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,291 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("mat_mul_cx_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - cx_mat C = cx_mat(A,fliplr(A)); - - cx_mat D = cx_mat(flipud(A),-fliplr(A)); - - double re = 2.0; - cx_double cx = cx_double(2.0,-3.0); - - - cx_mat C_times_D_t = - "\ - (-0.185711,0.141986) (0.320782,-0.123588) (-6.93889e-18,-0.364555) (-0.320782,-0.123588) (0.185711,0.141986);\ - (0.0354121,0.18557) (-0.214015,0.406658) (-3.46945e-18,-0.596795) (0.214015,0.406658) (-0.0354121,0.18557);\ - (-0.226682,-0.699037) (-0.0995861,-0.534099) (2.77556e-17,1.41421) (0.0995861,-0.534099) (0.226682,-0.699037);\ - (-0.366865,-0.157988) (0.711264,0.107008) (0,-0.471402) (-0.711264,0.107008) (0.366865,-0.157988);\ - (0.561849,0.870633) (-0.0814947,0.151169) (-1.38778e-17,-1.03352) (0.0814947,0.151169) (-0.561849,0.870633);\ - "; - - cx_mat C_t_times_D = - "\ - (0.148843,-0.857543) (0.406412,-0.0389706) (0.415351,0.656975) (-0.449094,0.526547) (-0.114683,-0.11312) (-0.00283814,-0.867653);\ - (0.406412,-0.0244952) (-0.375592,-0.180565) (-0.368772,-0.0694664) (0.041254,-0.478571) (0.00880269,-0.412947) (0.123148,-0.11312);\ - (0.415351,0.610998) (-0.368772,-0.154831) (-0.715746,-0.432138) (0.2979,-0.996616) (0.374591,-0.478571) (0.260569,0.526547);\ - (-0.449094,0.464705) (0.041254,-0.0989421) (0.2979,-0.607187) (0.00221322,-0.432138) (-0.218553,-0.0694664) (-0.202333,0.656975);\ - (-0.114683,-0.0682625) (0.00880269,-0.128059) (0.374591,-0.0989421) (-0.218553,-0.154831) (-0.38423,-0.180565) (-0.0653194,-0.0389706);\ - (-0.00283814,-0.983136) (0.123148,-0.0682625) (0.260569,0.464705) (-0.202333,0.610998) (-0.0653194,-0.0244952) (-0.348327,-0.857543);\ - "; - - // - - cx_mat re_times_C_times_D_t = - "\ - (-0.371422,0.283972) (0.641564,-0.247176) (-1.38778e-17,-0.72911) (-0.641564,-0.247176) (0.371422,0.283972);\ - (0.0708241,0.37114) (-0.428029,0.813317) (-6.93889e-18,-1.19359) (0.428029,0.813317) (-0.0708241,0.37114);\ - (-0.453363,-1.39807) (-0.199172,-1.0682) (5.55112e-17,2.82841) (0.199172,-1.0682) (0.453363,-1.39807);\ - (-0.733729,-0.315977) (1.42253,0.214017) (0,-0.942804) (-1.42253,0.214017) (0.733729,-0.315977);\ - (1.1237,1.74127) (-0.162989,0.302339) (-2.77556e-17,-2.06704) (0.162989,0.302339) (-1.1237,1.74127);\ - "; - - cx_mat re_times_C_t_times_D = - "\ - (0.297685,-1.71509) (0.812823,-0.0779412) (0.830702,1.31395) (-0.898189,1.05309) (-0.229366,-0.22624) (-0.00567628,-1.73531);\ - (0.812823,-0.0489904) (-0.751184,-0.36113) (-0.737545,-0.138933) (0.0825079,-0.957143) (0.0176054,-0.825894) (0.246297,-0.22624);\ - (0.830702,1.222) (-0.737545,-0.309662) (-1.43149,-0.864277) (0.595799,-1.99323) (0.749183,-0.957143) (0.521138,1.05309);\ - (-0.898189,0.92941) (0.0825079,-0.197884) (0.595799,-1.21437) (0.00442644,-0.864277) (-0.437106,-0.138933) (-0.404666,1.31395);\ - (-0.229366,-0.136525) (0.0176054,-0.256119) (0.749183,-0.197884) (-0.437106,-0.309662) (-0.768459,-0.36113) (-0.130639,-0.0779412);\ - (-0.00567628,-1.96627) (0.246297,-0.136525) (0.521138,0.92941) (-0.404666,1.222) (-0.130639,-0.0489904) (-0.696654,-1.71509);\ - "; - - // - - cx_mat C_times_re_times_D_t = - "\ - (-0.371422,0.283972) (0.641564,-0.247176) (-1.38778e-17,-0.72911) (-0.641564,-0.247176) (0.371422,0.283972);\ - (0.0708241,0.37114) (-0.428029,0.813317) (-6.93889e-18,-1.19359) (0.428029,0.813317) (-0.0708241,0.37114);\ - (-0.453363,-1.39807) (-0.199172,-1.0682) (5.55112e-17,2.82841) (0.199172,-1.0682) (0.453363,-1.39807);\ - (-0.733729,-0.315977) (1.42253,0.214017) (0,-0.942804) (-1.42253,0.214017) (0.733729,-0.315977);\ - (1.1237,1.74127) (-0.162989,0.302339) (-2.77556e-17,-2.06704) (0.162989,0.302339) (-1.1237,1.74127);\ - "; - - cx_mat C_t_times_re_times_D = - "\ - (0.297685,-1.71509) (0.812823,-0.0779412) (0.830702,1.31395) (-0.898189,1.05309) (-0.229366,-0.22624) (-0.00567628,-1.73531);\ - (0.812823,-0.0489904) (-0.751184,-0.36113) (-0.737545,-0.138933) (0.0825079,-0.957143) (0.0176054,-0.825894) (0.246297,-0.22624);\ - (0.830702,1.222) (-0.737545,-0.309662) (-1.43149,-0.864277) (0.595799,-1.99323) (0.749183,-0.957143) (0.521138,1.05309);\ - (-0.898189,0.92941) (0.0825079,-0.197884) (0.595799,-1.21437) (0.00442644,-0.864277) (-0.437106,-0.138933) (-0.404666,1.31395);\ - (-0.229366,-0.136525) (0.0176054,-0.256119) (0.749183,-0.197884) (-0.437106,-0.309662) (-0.768459,-0.36113) (-0.130639,-0.0779412);\ - (-0.00567628,-1.96627) (0.246297,-0.136525) (0.521138,0.92941) (-0.404666,1.222) (-0.130639,-0.0489904) (-0.696654,-1.71509);\ - "; - - // - - cx_mat re_times_C_times_re_times_D_t = - "\ - (-0.742845,0.567944) (1.28313,-0.494352) (-2.77556e-17,-1.45822) (-1.28313,-0.494352) (0.742845,0.567944);\ - (0.141648,0.742279) (-0.856058,1.62663) (-1.38778e-17,-2.38718) (0.856058,1.62663) (-0.141648,0.742279);\ - (-0.906726,-2.79615) (-0.398345,-2.13639) (1.11022e-16,5.65683) (0.398345,-2.13639) (0.906726,-2.79615);\ - (-1.46746,-0.631953) (2.84506,0.428033) (0,-1.88561) (-2.84506,0.428033) (1.46746,-0.631953);\ - (2.2474,3.48253) (-0.325979,0.604678) (-5.55112e-17,-4.13407) (0.325979,0.604678) (-2.2474,3.48253);\ - "; - - cx_mat re_times_C_t_times_re_times_D = - "\ - (0.59537,-3.43017) (1.62565,-0.155882) (1.6614,2.6279) (-1.79638,2.10619) (-0.458732,-0.452481) (-0.0113526,-3.47061);\ - (1.62565,-0.0979807) (-1.50237,-0.722259) (-1.47509,-0.277865) (0.165016,-1.91429) (0.0352108,-1.65179) (0.492593,-0.452481);\ - (1.6614,2.44399) (-1.47509,-0.619323) (-2.86299,-1.72855) (1.1916,-3.98646) (1.49837,-1.91429) (1.04228,2.10619);\ - (-1.79638,1.85882) (0.165016,-0.395768) (1.1916,-2.42875) (0.00885288,-1.72855) (-0.874212,-0.277865) (-0.809332,2.6279);\ - (-0.458732,-0.27305) (0.0352108,-0.512237) (1.49837,-0.395768) (-0.874212,-0.619323) (-1.53692,-0.722259) (-0.261278,-0.155882);\ - (-0.0113526,-3.93254) (0.492593,-0.27305) (1.04228,1.85882) (-0.809332,2.44399) (-0.261278,-0.0979807) (-1.39331,-3.43017);\ - "; - - // - - cx_mat cx_times_C_times_D_t = - "\ - (0.0545359,0.841106) (0.2708,-1.20952) (-1.09366,-0.72911) (-1.01233,0.71517) (0.797381,-0.273161);\ - (0.627534,0.264904) (0.791946,1.45536) (-1.79039,-1.19359) (1.648,0.171273) (0.485885,0.477376);\ - (-2.55047,-0.718029) (-1.80147,-0.769439) (4.24262,2.82841) (-1.40312,-1.36696) (-1.64375,-2.07812);\ - (-1.20769,0.784617) (1.74355,-1.91978) (-1.41421,-0.942804) (-1.1015,2.34781) (0.259764,-1.41657);\ - (3.7356,0.0557187) (0.290519,0.546823) (-3.10056,-2.06704) (0.616498,0.0578546) (1.4882,3.42681);\ - "; - - cx_mat cx_times_C_t_times_D = - "\ - (-2.27494,-2.16161) (0.695911,-1.29718) (2.80163,0.0678966) (0.681454,2.40038) (-0.568727,0.117809) (-2.60864,-1.72679);\ - (0.739338,-1.26823) (-1.29288,0.765647) (-0.945944,0.967385) (-1.35321,-1.0809) (-1.22124,-0.852303) (-0.0930641,-0.595685);\ - (2.6637,-0.0240567) (-1.20204,0.796656) (-2.72791,1.28296) (-2.39405,-2.88693) (-0.686531,-2.08092) (2.10078,0.271388);\ - (0.495926,2.27669) (-0.214318,-0.321646) (-1.22576,-2.10807) (-1.29199,-0.870917) (-0.645505,0.516726) (1.56626,1.92095);\ - (-0.434154,0.207524) (-0.366573,-0.282527) (0.452357,-1.32166) (-0.901598,0.345997) (-1.31015,0.791559) (-0.247551,0.118017);\ - (-2.95508,-1.95776) (0.0415092,-0.50597) (1.91525,0.147703) (1.42833,1.82899) (-0.204124,0.146968) (-3.26928,-0.670106);\ - "; - - // - - cx_mat C_times_cx_times_D_t = - "\ - (0.0545359,0.841106) (0.2708,-1.20952) (-1.09366,-0.72911) (-1.01233,0.71517) (0.797381,-0.273161);\ - (0.627534,0.264904) (0.791946,1.45536) (-1.79039,-1.19359) (1.648,0.171273) (0.485885,0.477376);\ - (-2.55047,-0.718029) (-1.80147,-0.769439) (4.24262,2.82841) (-1.40312,-1.36696) (-1.64375,-2.07812);\ - (-1.20769,0.784617) (1.74355,-1.91978) (-1.41421,-0.942804) (-1.1015,2.34781) (0.259764,-1.41657);\ - (3.7356,0.0557187) (0.290519,0.546823) (-3.10056,-2.06704) (0.616498,0.0578546) (1.4882,3.42681);\ - "; - - cx_mat C_t_times_cx_times_D = - "\ - (-2.27494,-2.16161) (0.695911,-1.29718) (2.80163,0.0678966) (0.681454,2.40038) (-0.568727,0.117809) (-2.60864,-1.72679);\ - (0.739338,-1.26823) (-1.29288,0.765647) (-0.945944,0.967385) (-1.35321,-1.0809) (-1.22124,-0.852303) (-0.0930641,-0.595685);\ - (2.6637,-0.0240567) (-1.20204,0.796656) (-2.72791,1.28296) (-2.39405,-2.88693) (-0.686531,-2.08092) (2.10078,0.271388);\ - (0.495926,2.27669) (-0.214318,-0.321646) (-1.22576,-2.10807) (-1.29199,-0.870917) (-0.645505,0.516726) (1.56626,1.92095);\ - (-0.434154,0.207524) (-0.366573,-0.282527) (0.452357,-1.32166) (-0.901598,0.345997) (-1.31015,0.791559) (-0.247551,0.118017);\ - (-2.95508,-1.95776) (0.0415092,-0.50597) (1.91525,0.147703) (1.42833,1.82899) (-0.204124,0.146968) (-3.26928,-0.670106);\ - "; - - // - - cx_mat cx_times_C_times_cx_times_D_t = - "\ - (2.63239,1.5186) (-3.08696,-3.23144) (-4.37466,1.82277) (0.120855,4.46732) (0.775277,-2.93847);\ - (2.04978,-1.35279) (5.94997,0.534883) (-7.16154,2.98398) (3.80983,-4.60147) (2.4039,-0.502904);\ - (-7.25503,6.21536) (-5.91125,3.86553) (16.9705,-7.07103) (-6.90711,1.47546) (-9.52185,0.775005);\ - (-0.0615364,5.19232) (-2.27222,-9.07021) (-5.65682,2.35701) (4.84042,8.00013) (-3.73018,-3.61243);\ - (7.63835,-11.0954) (2.22151,0.22209) (-12.4022,5.16759) (1.40656,-1.73378) (13.2568,2.38902);\ - "; - - cx_mat cx_times_C_t_times_cx_times_D = - "\ - (-11.0347,2.5016) (-2.49971,-4.68209) (5.80694,-8.26908) (8.56404,2.7564) (-0.784027,1.9418) (-10.3976,4.37232);\ - (-2.326,-4.75446) (-0.288817,5.40993) (1.01027,4.7726) (-5.94913,1.89781) (-4.99938,1.9591) (-1.97318,-0.912178);\ - (5.25522,-8.0392) (-0.0141081,5.19942) (-1.60693,10.7496) (-13.4489,1.40828) (-7.61581,-2.10224) (5.01572,-5.75956);\ - (7.82193,3.06561) (-1.39358,-0.000336933) (-8.77574,-0.538863) (-5.19673,2.13413) (0.259168,2.96997) (8.89536,-0.856878);\ - (-0.245734,1.71751) (-1.58073,0.534664) (-3.06026,-4.00039) (-0.765206,3.39679) (-0.24563,5.51358) (-0.14105,0.978686);\ - (-11.7834,4.94974) (-1.43489,-1.13647) (4.27362,-5.45035) (8.34364,-0.626995) (0.0326548,0.906309) (-8.54888,8.46764);\ - "; - - - - REQUIRE( accu(abs( C*D.t() - C_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( C.t()*D - C_t_times_D )) == Approx(0.0).epsilon(0.00005) ); - - // - - REQUIRE( accu(abs( re*C*D.t() - re_times_C_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( re*C.t()*D - re_times_C_t_times_D )) == Approx(0.0).epsilon(0.00005) ); - - REQUIRE( accu(abs( C*re*D.t() - C_times_re_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( C.t()*re*D - C_t_times_re_times_D )) == Approx(0.0).epsilon(0.00005) ); - - REQUIRE( accu(abs( re*C*re*D.t() - re_times_C_times_re_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( re*C.t()*re*D - re_times_C_t_times_re_times_D )) == Approx(0.0).epsilon(0.00010) ); - - // - - REQUIRE( accu(abs( (re*C)*D.t() - re_times_C_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( (re*C.t())*D - re_times_C_t_times_D )) == Approx(0.0).epsilon(0.00005) ); - - REQUIRE( accu(abs( C*(re*D.t()) - C_times_re_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( C.t()*(re*D) - C_t_times_re_times_D )) == Approx(0.0).epsilon(0.00005) ); - - REQUIRE( accu(abs( (re*C)*(re*D.t()) - re_times_C_times_re_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( (re*C.t())*(re*D) - re_times_C_t_times_re_times_D )) == Approx(0.0).epsilon(0.00010) ); - - - REQUIRE( accu(abs( C*D.t().eval() - C_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( C.t().eval()*D - C_t_times_D )) == Approx(0.0).epsilon(0.00005) ); - - // - - REQUIRE( accu(abs( re*C*D.t().eval() - re_times_C_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( re*C.t().eval()*D - re_times_C_t_times_D )) == Approx(0.0).epsilon(0.00005) ); - - REQUIRE( accu(abs( C*re*D.t().eval() - C_times_re_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( C.t().eval()*re*D - C_t_times_re_times_D )) == Approx(0.0).epsilon(0.00005) ); - - REQUIRE( accu(abs( re*C*re*D.t().eval() - re_times_C_times_re_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( re*C.t().eval()*re*D - re_times_C_t_times_re_times_D )) == Approx(0.0).epsilon(0.00010) ); - - // - - REQUIRE( accu(abs( (re*C)*(D.t().eval()) - re_times_C_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( (re*C.t()).eval()*D - re_times_C_t_times_D )) == Approx(0.0).epsilon(0.00005) ); - - REQUIRE( accu(abs( C*(re*D.t()).eval() - C_times_re_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( C.t().eval()*(re*D) - C_t_times_re_times_D )) == Approx(0.0).epsilon(0.00005) ); - - REQUIRE( accu(abs( (re*C)*(re*D.t()).eval() - re_times_C_times_re_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( (re*C.t()).eval()*(re*D) - re_times_C_t_times_re_times_D )) == Approx(0.0).epsilon(0.00010) ); - - - // - - REQUIRE( accu(abs( cx*C*D.t() - cx_times_C_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( cx*C.t()*D - cx_times_C_t_times_D )) == Approx(0.0).epsilon(0.00010) ); - - REQUIRE( accu(abs( C*cx*D.t() - C_times_cx_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( C.t()*cx*D - C_t_times_cx_times_D )) == Approx(0.0).epsilon(0.00010) ); - - REQUIRE( accu(abs( cx*C*cx*D.t() - cx_times_C_times_cx_times_D_t )) == Approx(0.0).epsilon(0.00030) ); - REQUIRE( accu(abs( cx*C.t()*cx*D - cx_times_C_t_times_cx_times_D )) == Approx(0.0).epsilon(0.00030) ); - - // - - REQUIRE( accu(abs( (cx*C)*D.t() - cx_times_C_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( (cx*C.t())*D - cx_times_C_t_times_D )) == Approx(0.0).epsilon(0.00010) ); - - REQUIRE( accu(abs( C*(cx*D.t()) - C_times_cx_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( C.t()*(cx*D) - C_t_times_cx_times_D )) == Approx(0.0).epsilon(0.00010) ); - - REQUIRE( accu(abs( (cx*C)*(cx*D.t()) - cx_times_C_times_cx_times_D_t )) == Approx(0.0).epsilon(0.00030) ); - REQUIRE( accu(abs( (cx*C.t())*(cx*D) - cx_times_C_t_times_cx_times_D )) == Approx(0.0).epsilon(0.00030) ); - - - REQUIRE( accu(abs( C*D.t().eval() - C_times_D_t )) == Approx(0.0).epsilon(0.00005) ); - REQUIRE( accu(abs( C.t().eval()*D - C_t_times_D )) == Approx(0.0).epsilon(0.00005) ); - - // - - REQUIRE( accu(abs( cx*C*D.t().eval() - cx_times_C_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( cx*C.t().eval()*D - cx_times_C_t_times_D )) == Approx(0.0).epsilon(0.00010) ); - - REQUIRE( accu(abs( C*cx*D.t().eval() - C_times_cx_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( C.t().eval()*cx*D - C_t_times_cx_times_D )) == Approx(0.0).epsilon(0.00010) ); - - REQUIRE( accu(abs( cx*C*cx*D.t().eval() - cx_times_C_times_cx_times_D_t )) == Approx(0.0).epsilon(0.00030) ); - REQUIRE( accu(abs( cx*C.t().eval()*cx*D - cx_times_C_t_times_cx_times_D )) == Approx(0.0).epsilon(0.00030) ); - - // - - REQUIRE( accu(abs( (cx*C)*(D.t().eval()) - cx_times_C_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( (cx*C.t()).eval()*D - cx_times_C_t_times_D )) == Approx(0.0).epsilon(0.00010) ); - - REQUIRE( accu(abs( C*(cx*D.t()).eval() - C_times_cx_times_D_t )) == Approx(0.0).epsilon(0.00010) ); - REQUIRE( accu(abs( C.t().eval()*(cx*D) - C_t_times_cx_times_D )) == Approx(0.0).epsilon(0.00010) ); - - REQUIRE( accu(abs( (cx*C)*(cx*D.t()).eval() - cx_times_C_times_cx_times_D_t )) == Approx(0.0).epsilon(0.00030) ); - REQUIRE( accu(abs( (cx*C.t()).eval()*(cx*D) - cx_times_C_t_times_cx_times_D )) == Approx(0.0).epsilon(0.00030) ); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/mat_mul_real.cpp armadillo-10.8.2+dfsg/tests/mat_mul_real.cpp --- armadillo-9.800.4+dfsg/tests/mat_mul_real.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/mat_mul_real.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,927 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("mat_mul_real_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat A00 = A( 0,0, size(0,0) ); - mat A11 = A( 0,0, size(1,1) ); - mat A22 = A( 0,0, size(2,2) ); - mat A33 = A( 0,0, size(3,3) ); - mat A44 = A( 0,0, size(4,4) ); - mat A55 = A( 0,0, size(5,5) ); - - mat B = fliplr(A); - - mat B00 = B( 0,0, size(0,0) ); - mat B11 = B( 0,0, size(1,1) ); - mat B22 = B( 0,0, size(2,2) ); - mat B33 = B( 0,0, size(3,3) ); - mat B44 = B( 0,0, size(4,4) ); - mat B55 = B( 0,0, size(5,5) ); - - mat A00_times_B00(0,0); - - mat A11_times_B11 = - "\ - 0.003146066784;\ - "; - - mat A22_times_B22 = - "\ - 0.010304 0.052063;\ - 0.024567 -0.037958;\ - "; - - mat A33_times_B33 = - "\ - 0.0013604 0.0534077 -0.0311519;\ - 0.0924518 -0.0481622 -0.2813422;\ - -0.1692102 0.0746086 0.3765357;\ - "; - - mat A44_times_B44 = - "\ - -0.183289 0.120109 0.163034 -0.249241;\ - 0.075456 -0.042023 -0.263468 -0.067969;\ - -0.012300 0.017928 0.211522 0.286117;\ - -0.323470 0.163659 0.162149 -0.091062;\ - "; - - mat A55_times_B55 = - "\ - -0.2160787 0.1649472 0.1999190 -0.1976620 -0.1252585;\ - 0.1520715 -0.1467921 -0.3496545 -0.1884897 -0.0492639;\ - 0.0053737 -0.0062406 0.1916407 0.2583152 0.0322787;\ - -0.3584056 0.2114322 0.2014480 -0.0361067 -0.0260243;\ - -0.0182371 -0.0207407 -0.0522859 -0.0485276 0.0678171;\ - "; - - REQUIRE( accu(abs( (A00*B00) - A00_times_B00 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A11*B11) - A11_times_B11 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A22*B22) - A22_times_B22 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A33*B33) - A33_times_B33 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A44*B44) - A44_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A55*B55) - A55_times_B55 )) == Approx(0.0) ); - - mat X; - REQUIRE_THROWS( X = A22*B44 ); - } - - - -TEST_CASE("mat_mul_real_2") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat A00 = A( 0,0, size(0,0) ); - mat A11 = A( 0,0, size(1,1) ); - mat A22 = A( 0,0, size(2,2) ); - mat A33 = A( 0,0, size(3,3) ); - mat A44 = A( 0,0, size(4,4) ); - mat A55 = A( 0,0, size(5,5) ); - - mat B = fliplr(A); - - mat B00 = B( 0,0, size(0,0) ); - mat B11 = B( 0,0, size(1,1) ); - mat B22 = B( 0,0, size(2,2) ); - mat B33 = B( 0,0, size(3,3) ); - mat B44 = B( 0,0, size(4,4) ); - mat B55 = B( 0,0, size(5,5) ); - - colvec q0( uword(0) ); - colvec q1 = B11.col(0); - colvec q2 = B22.col(0); - colvec q3 = B33.col(0); - colvec q4 = B44.col(0); - colvec q5 = B55.col(0); - - rowvec r0( uword(0) ); - rowvec r1 = B11.row(0); - rowvec r2 = B22.row(0); - rowvec r3 = B33.row(0); - rowvec r4 = B44.row(0); - rowvec r5 = B55.row(0); - - mat A00_times_q0(0,1); - - mat A11_times_q1 = - "\ - 0.0031461;\ - "; - - mat A22_times_q2 = - "\ - 0.010304;\ - 0.024567;\ - "; - - mat A33_times_q3 = - "\ - 0.0013604;\ - 0.0924518;\ - -0.1692102;\ - "; - - mat A44_times_q4 = - "\ - -0.183289;\ - 0.075456;\ - -0.012300;\ - -0.323470;\ - "; - - mat A55_times_q5 = - "\ - -0.2160787;\ - 0.1520715;\ - 0.0053737;\ - -0.3584056;\ - -0.0182371;\ - "; - - mat r0_times_A00(1,0); - - mat r1_times_A11 = - "\ - 0.0031461;\ - "; - - mat r2_times_A22 = - "\ - -0.0522722 0.0029115;\ - "; - - mat r3_times_A33 = - "\ - 0.190978 0.018376 -0.135230;\ - "; - - mat r4_times_A44 = - "\ - 0.197597 0.026474 -0.126209 -0.234687;\ - "; - - mat r5_times_A55 = - "\ - 0.245991 -0.060162 -0.208409 -0.293470 -0.151911;\ - "; - - REQUIRE( accu(abs( (A00*q0) - A00_times_q0 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A11*q1) - A11_times_q1 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A22*q2) - A22_times_q2 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A33*q3) - A33_times_q3 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A44*q4) - A44_times_q4 )) == Approx(0.0) ); - REQUIRE( accu(abs( (A55*q5) - A55_times_q5 )) == Approx(0.0) ); - - REQUIRE( accu(abs( (r0*A00) - r0_times_A00 )) == Approx(0.0) ); - REQUIRE( accu(abs( (r1*A11) - r1_times_A11 )) == Approx(0.0) ); - REQUIRE( accu(abs( (r2*A22) - r2_times_A22 )) == Approx(0.0) ); - REQUIRE( accu(abs( (r3*A33) - r3_times_A33 )) == Approx(0.0) ); - REQUIRE( accu(abs( (r4*A44) - r4_times_A44 )) == Approx(0.0) ); - REQUIRE( accu(abs( (r5*A55) - r5_times_A55 )) == Approx(0.0) ); - - mat X; - REQUIRE_THROWS( X = A22*q4 ); - } - - - -TEST_CASE("mat_mul_real_3") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat A00 = A( 0,0, size(0,0) ); - mat A11 = A( 0,0, size(1,1) ); - mat A22 = A( 0,0, size(2,2) ); - mat A33 = A( 0,0, size(3,3) ); - mat A44 = A( 0,0, size(4,4) ); - mat A55 = A( 0,0, size(5,5) ); - - mat B = fliplr(A); - - mat B00 = B( 0,0, size(0,0) ); - mat B11 = B( 0,0, size(1,1) ); - mat B22 = B( 0,0, size(2,2) ); - mat B33 = B( 0,0, size(3,3) ); - mat B44 = B( 0,0, size(4,4) ); - mat B55 = B( 0,0, size(5,5) ); - - colvec q0( uword(0) ); - colvec q1 = B11.col(0); - colvec q2 = B22.col(0); - colvec q3 = B33.col(0); - colvec q4 = B44.col(0); - colvec q5 = B55.col(0); - - rowvec r0( uword(0) ); - rowvec r1 = B11.row(0); - rowvec r2 = B22.row(0); - rowvec r3 = B33.row(0); - rowvec r4 = B44.row(0); - rowvec r5 = B55.row(0); - - mat q0_t_times_A00(1,0); - - mat q1_t_times_A11 = - "\ - 0.0031461;\ - "; - - mat q2_t_times_A22 = - "\ - 0.018641 0.012473;\ - "; - - mat q3_t_times_A33 = - "\ - 0.242470 0.026703 -0.147065;\ - "; - - mat q4_t_times_A44 = - "\ - 0.368209 0.180551 0.024329 -0.364740;\ - "; - - mat q5_t_times_A55 = - "\ - 0.430191 0.069589 -0.080952 -0.440028 -0.169075;\ - "; - - mat A00_times_r0_t(0,1); - - mat A11_times_r1_t = - "\ - 0.0031461;\ - "; - - mat A22_times_r2_t = - "\ - -0.022455;\ - 0.015005;\ - "; - - mat A33_times_r3_t = - "\ - -0.032175;\ - 0.088781;\ - -0.176522;\ - "; - - mat A44_times_r4_t = - "\ - -0.041895;\ - 0.087886;\ - -0.168262;\ - -0.269064;\ - "; - - mat A55_times_r5_t = - "\ - -0.067496;\ - 0.147706;\ - -0.154463;\ - -0.296340;\ - 0.190504;\ - "; - - REQUIRE( accu(abs( (q0.t()*A00) - q0_t_times_A00 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q1.t()*A11) - q1_t_times_A11 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q2.t()*A22) - q2_t_times_A22 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q3.t()*A33) - q3_t_times_A33 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q4.t()*A44) - q4_t_times_A44 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q5.t()*A55) - q5_t_times_A55 )) == Approx(0.0) ); - - REQUIRE( accu(abs( (A00*r0.t()) - A00_times_r0_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A11*r1.t()) - A11_times_r1_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A22*r2.t()) - A22_times_r2_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A33*r3.t()) - A33_times_r3_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A44*r4.t()) - A44_times_r4_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A55*r5.t()) - A55_times_r5_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( (q0.t().eval()*A00) - q0_t_times_A00 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q1.t().eval()*A11) - q1_t_times_A11 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q2.t().eval()*A22) - q2_t_times_A22 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q3.t().eval()*A33) - q3_t_times_A33 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q4.t().eval()*A44) - q4_t_times_A44 )) == Approx(0.0) ); - REQUIRE( accu(abs( (q5.t().eval()*A55) - q5_t_times_A55 )) == Approx(0.0) ); - - REQUIRE( accu(abs( (A00*r0.t().eval()) - A00_times_r0_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A11*r1.t().eval()) - A11_times_r1_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A22*r2.t().eval()) - A22_times_r2_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A33*r3.t().eval()) - A33_times_r3_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A44*r4.t().eval()) - A44_times_r4_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (A55*r5.t().eval()) - A55_times_r5_t )) == Approx(0.0) ); - - mat X; - REQUIRE_THROWS( X = A22*r4.t() ); - } - - - -TEST_CASE("mat_mul_real_4") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat A44 = A( 0,0, size(4,4) ); - - mat B = fliplr(A); - - mat B44 = B( 0,0, size(4,4) ); - - // - - mat A44_times_B44 = - "\ - -0.183289 0.120109 0.163034 -0.249241;\ - 0.075456 -0.042023 -0.263468 -0.067969;\ - -0.012300 0.017928 0.211522 0.286117;\ - -0.323470 0.163659 0.162149 -0.091062;\ - "; - - mat A44_t_times_B44 = - "\ - 0.368209 0.042669 -0.389048 -0.064607;\ - 0.180551 -0.065855 -0.277385 0.174015;\ - 0.024329 -0.087178 -0.051312 0.331590;\ - -0.364740 0.130904 0.576774 -0.051312;\ - "; - - mat A44_times_B44_t = - "\ - -0.041895 0.134869 -0.160929 -0.238593;\ - 0.087886 0.046536 -0.271674 0.193369;\ - -0.168262 -0.103699 0.485413 -0.110945;\ - -0.269064 0.171674 -0.055826 -0.290325;\ - "; - - mat A44_t_times_B44_t = - "\ - 0.1975972 0.1038113 -0.0989840 0.3116527;\ - 0.0264745 -0.0354272 0.0283701 0.2685396;\ - -0.1262086 -0.1262987 0.2567470 0.1142194;\ - -0.2346872 0.0086687 0.2740562 -0.5237682;\ - "; - - // - - mat two_times_A44_times_B44 = - "\ - -0.366578 0.240218 0.326067 -0.498482;\ - 0.150911 -0.084045 -0.526936 -0.135939;\ - -0.024600 0.035856 0.423045 0.572234;\ - -0.646941 0.327319 0.324297 -0.182123;\ - "; - - mat two_times_A44_t_times_B44 = - "\ - 0.736418 0.085337 -0.778096 -0.129215;\ - 0.361101 -0.131709 -0.554770 0.348029;\ - 0.048657 -0.174357 -0.102624 0.663181;\ - -0.729480 0.261807 1.153548 -0.102624;\ - "; - - mat two_times_A44_times_B44_t = - "\ - -0.083789 0.269738 -0.321857 -0.477186;\ - 0.175772 0.093072 -0.543347 0.386739;\ - -0.336525 -0.207399 0.970827 -0.221889;\ - -0.538127 0.343348 -0.111652 -0.580649;\ - "; - - mat two_times_A44_t_times_B44_t = - "\ - 0.395194 0.207623 -0.197968 0.623305;\ - 0.052949 -0.070854 0.056740 0.537079;\ - -0.252417 -0.252597 0.513494 0.228439;\ - -0.469374 0.017337 0.548112 -1.047536;\ - "; - - // - - mat A44_times_two_times_B44 = - "\ - -0.366578 0.240218 0.326067 -0.498482;\ - 0.150911 -0.084045 -0.526936 -0.135939;\ - -0.024600 0.035856 0.423045 0.572234;\ - -0.646941 0.327319 0.324297 -0.182123;\ - "; - - mat A44_t_times_two_times_B44 = - "\ - 0.736418 0.085337 -0.778096 -0.129215;\ - 0.361101 -0.131709 -0.554770 0.348029;\ - 0.048657 -0.174357 -0.102624 0.663181;\ - -0.729480 0.261807 1.153548 -0.102624;\ - "; - - mat A44_times_two_times_B44_t = - "\ - -0.083789 0.269738 -0.321857 -0.477186;\ - 0.175772 0.093072 -0.543347 0.386739;\ - -0.336525 -0.207399 0.970827 -0.221889;\ - -0.538127 0.343348 -0.111652 -0.580649;\ - "; - - mat A44_t_times_two_times_B44_t = - "\ - 0.395194 0.207623 -0.197968 0.623305;\ - 0.052949 -0.070854 0.056740 0.537079;\ - -0.252417 -0.252597 0.513494 0.228439;\ - -0.469374 0.017337 0.548112 -1.047536;\ - "; - - // - - mat two_times_A44_times_two_times_B44 = - "\ - -0.733157 0.480435 0.652135 -0.996965;\ - 0.301822 -0.168090 -1.053872 -0.271877;\ - -0.049201 0.071711 0.846089 1.144468;\ - -1.293881 0.654637 0.648595 -0.364247;\ - "; - - mat two_times_A44_t_times_two_times_B44 = - "\ - 1.472836 0.170675 -1.556191 -0.258430;\ - 0.722203 -0.263419 -1.109539 0.696059;\ - 0.097314 -0.348714 -0.205248 1.326362;\ - -1.458960 0.523615 2.307096 -0.205248;\ - "; - - mat two_times_A44_times_two_times_B44_t = - "\ - -0.167578003928 0.539476906232 -0.643714124056 -0.95437155377;\ - 0.351543868312 0.186144110728 -1.086694470368 0.77347794529;\ - -0.673049184916 -0.414797273204 1.941653137076 -0.44377813703;\ - -1.076254284828 0.686695294300 -0.223303479708 -1.16129844700;\ - "; - - mat two_times_A44_t_times_two_times_B44_t = - "\ - 0.790389 0.415245 -0.395936 1.246611;\ - 0.105898 -0.141709 0.113480 1.074158;\ - -0.504834 -0.505195 1.026988 0.456878;\ - -0.938749 0.034675 1.096225 -2.095073;\ - "; - - // - - REQUIRE( accu(abs( A44 * B44 - A44_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( A44.t() * B44 - A44_t_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( A44 * B44.t() - A44_times_B44_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A44.t() * B44.t() - A44_t_times_B44_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A44 * B44 - two_times_A44_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A44.t() * B44 - two_times_A44_t_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A44 * B44.t() - two_times_A44_times_B44_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A44.t() * B44.t() - two_times_A44_t_times_B44_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( A44 * 2 * B44 - A44_times_two_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( A44.t() * 2 * B44 - A44_t_times_two_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( A44 * 2 * B44.t() - A44_times_two_times_B44_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A44.t() * 2 * B44.t() - A44_t_times_two_times_B44_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A44 * 2*B44 - two_times_A44_times_two_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A44.t() * 2*B44 - two_times_A44_t_times_two_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A44 * 2*B44.t() - two_times_A44_times_two_times_B44_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A44.t() * 2*B44.t() - two_times_A44_t_times_two_times_B44_t )) == Approx(0.0) ); - - - REQUIRE( accu(abs( A44 * B44 - A44_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( A44.t().eval() * B44 - A44_t_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( A44 * B44.t().eval() - A44_times_B44_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A44.t() * B44.t().eval() - A44_t_times_B44_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( (2*A44).eval() * B44 - two_times_A44_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A44.t()).eval() * B44 - two_times_A44_t_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A44).eval() * B44.t().eval() - two_times_A44_times_B44_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A44.t()).eval() * B44.t().eval() - two_times_A44_t_times_B44_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( A44 * (2 * B44).eval() - A44_times_two_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( A44.t().eval() * (2 * B44).eval() - A44_t_times_two_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( A44 * (2 * B44.t()).eval() - A44_times_two_times_B44_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A44.t().eval() * (2 * B44.t()).eval() - A44_t_times_two_times_B44_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( (2*A44).eval() * (2*B44).eval() - two_times_A44_times_two_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A44.t()).eval() * (2*B44).eval() - two_times_A44_t_times_two_times_B44 )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A44).eval() * (2*B44.t()).eval() - two_times_A44_times_two_times_B44_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A44.t()).eval() * (2*B44.t()).eval() - two_times_A44_t_times_two_times_B44_t )) == Approx(0.0) ); - - } - - - -TEST_CASE("mat_mul_real_5") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = fliplr(A); - - mat A55 = A( 0,0, size(5,5) ); - mat B55 = B( 0,0, size(5,5) ); - - mat A55_times_B55 = - "\ - -0.2160787 0.1649472 0.1999190 -0.1976620 -0.1252585;\ - 0.1520715 -0.1467921 -0.3496545 -0.1884897 -0.0492639;\ - 0.0053737 -0.0062406 0.1916407 0.2583152 0.0322787;\ - -0.3584056 0.2114322 0.2014480 -0.0361067 -0.0260243;\ - -0.0182371 -0.0207407 -0.0522859 -0.0485276 0.0678171;\ - "; - - mat A55_t_times_B55 = - "\ - 0.430191 -0.042089 -0.458772 -0.162107 0.089220;\ - 0.069589 0.085881 -0.152563 0.348562 0.398588;\ - -0.080952 0.056788 0.067119 0.497201 0.348562;\ - -0.440028 0.233857 0.661467 0.067119 -0.152563;\ - -0.169075 0.251826 0.233857 0.056788 0.085881;\ - "; - - mat A55_times_B55_t = - "\ - -0.067496 0.127397 -0.156960 -0.290754 0.194019;\ - 0.147706 0.063996 -0.280946 0.315249 0.027205;\ - -0.154463 -0.099672 0.483274 -0.082829 -0.407868;\ - -0.296340 0.163712 -0.051598 -0.345899 0.025909;\ - 0.190504 -0.077421 -0.389354 0.028459 0.602316;\ - "; - - mat A55_t_times_B55_t = - "\ - 0.2459910 0.1179363 -0.1064851 0.4102518 -0.2351709;\ - -0.0601617 -0.0607142 0.0417989 0.0920243 0.0569989;\ - -0.2084090 -0.1502910 0.2694883 -0.0532584 -0.0455262;\ - -0.2934704 -0.0084887 0.2831677 -0.6435349 0.0509615;\ - -0.1519108 0.0794222 0.0751652 -0.3217347 0.0492501;\ - "; - - // - - mat two_times_A55_times_B55 = - "\ - -0.432157 0.329894 0.399838 -0.395324 -0.250517;\ - 0.304143 -0.293584 -0.699309 -0.376979 -0.098528;\ - 0.010747 -0.012481 0.383281 0.516630 0.064557;\ - -0.716811 0.422864 0.402896 -0.072213 -0.052049;\ - -0.036474 -0.041481 -0.104572 -0.097055 0.135634;\ - "; - - mat two_times_A55_t_times_B55 = - "\ - 0.860381 -0.084178 -0.917544 -0.324215 0.178440;\ - 0.139178 0.171762 -0.305125 0.697124 0.797177;\ - -0.161904 0.113577 0.134239 0.994402 0.697124;\ - -0.880056 0.467715 1.322933 0.134239 -0.305125;\ - -0.338149 0.503651 0.467715 0.113577 0.171762;\ - "; - - mat two_times_A55_times_B55_t = - "\ - -0.134991 0.254794 -0.313921 -0.581507 0.388038;\ - 0.295412 0.127992 -0.561892 0.630497 0.054410;\ - -0.308926 -0.199343 0.966549 -0.165659 -0.815736;\ - -0.592681 0.327425 -0.103196 -0.691798 0.051819;\ - 0.381007 -0.154842 -0.778709 0.056917 1.204632;\ - "; - - mat two_times_A55_t_times_B55_t = - "\ - 0.491982 0.235873 -0.212970 0.820504 -0.470342;\ - -0.120323 -0.121428 0.083598 0.184049 0.113998;\ - -0.416818 -0.300582 0.538977 -0.106517 -0.091052;\ - -0.586941 -0.016977 0.566335 -1.287070 0.101923;\ - -0.303822 0.158844 0.150330 -0.643469 0.098500;\ - "; - - // - - mat A55_times_two_times_B55 = - "\ - -0.432157 0.329894 0.399838 -0.395324 -0.250517;\ - 0.304143 -0.293584 -0.699309 -0.376979 -0.098528;\ - 0.010747 -0.012481 0.383281 0.516630 0.064557;\ - -0.716811 0.422864 0.402896 -0.072213 -0.052049;\ - -0.036474 -0.041481 -0.104572 -0.097055 0.135634;\ - "; - - mat A55_t_times_two_times_B55 = - "\ - 0.860381 -0.084178 -0.917544 -0.324215 0.178440;\ - 0.139178 0.171762 -0.305125 0.697124 0.797177;\ - -0.161904 0.113577 0.134239 0.994402 0.697124;\ - -0.880056 0.467715 1.322933 0.134239 -0.305125;\ - -0.338149 0.503651 0.467715 0.113577 0.171762;\ - "; - - mat A55_times_two_times_B55_t = - "\ - -0.134991 0.254794 -0.313921 -0.581507 0.388038;\ - 0.295412 0.127992 -0.561892 0.630497 0.054410;\ - -0.308926 -0.199343 0.966549 -0.165659 -0.815736;\ - -0.592681 0.327425 -0.103196 -0.691798 0.051819;\ - 0.381007 -0.154842 -0.778709 0.056917 1.204632;\ - "; - - mat A55_t_times_two_times_B55_t = - "\ - 0.491982 0.235873 -0.212970 0.820504 -0.470342;\ - -0.120323 -0.121428 0.083598 0.184049 0.113998;\ - -0.416818 -0.300582 0.538977 -0.106517 -0.091052;\ - -0.586941 -0.016977 0.566335 -1.287070 0.101923;\ - -0.303822 0.158844 0.150330 -0.643469 0.098500;\ - "; - - // - - mat two_times_A55_times_two_times_B55 = - "\ - -0.864315 0.659789 0.799676 -0.790648 -0.501034;\ - 0.608286 -0.587168 -1.398618 -0.753959 -0.197056;\ - 0.021495 -0.024962 0.766563 1.033261 0.129115;\ - -1.433623 0.845729 0.805792 -0.144427 -0.104097;\ - -0.072949 -0.082963 -0.209143 -0.194110 0.271268;\ - "; - - mat two_times_A55_t_times_two_times_B55 = - "\ - 1.720762508480000 -0.168355348408000 -1.835087231712000 -0.648429049028000 0.356879236660000;\ - 0.278356531136000 0.343524137236000 -0.610250174464000 1.394248666196000 1.594353519068000;\ - -0.323807331272000 0.227153811280000 0.268477507864000 1.988804839396000 1.394248666196000;\ - -1.760112014908000 0.935429101824000 2.645866173324000 0.268477507864000 -0.610250174464000;\ - -0.676298185096000 1.007302825388000 0.935429101824000 0.227153811280000 0.343524137236000;\ - "; - - mat two_times_A55_times_two_times_B55_t = - "\ - -0.269982894128000 0.509587393352000 -0.627841087236000 -1.163014609956000 0.776076770820000;\ - 0.590823646192000 0.255984095800000 -1.123783487476000 1.260994352388000 0.108820335424000;\ - -0.617851781596000 -0.398686484996000 1.933097389264000 -0.331317151044000 -1.631472813896000;\ - -1.185361203228000 0.654849621340000 -0.206391610268000 -1.383596433568000 0.103637571148000;\ - 0.762014443972000 -0.309683987468000 -1.557417410772000 0.113834257136000 2.409263641312000;\ - "; - - mat two_times_A55_t_times_two_times_B55_t = - "\ - 0.9839639038560000 0.4717451991920000 -0.4259405015320001 1.6410071127080001 -0.9406834141800000;\ - -0.2406466685920000 -0.2428568083480000 0.1671957402319999 0.3680971398560001 0.2279957477119999;\ - -0.8336360417759999 -0.6011639640800001 1.0779532920199999 -0.2130337897080000 -0.1821046293240000;\ - -1.1738814343720001 -0.0339548592960000 1.1326709857760002 -2.5741394118360001 0.2038460089720001;\ - -0.6076430403880000 0.3176888108440000 0.3006606227560001 -1.2869387091840001 0.1970004839200000;\ - "; - - // - - - REQUIRE( accu(abs( A55 * B55 - A55_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( A55.t() * B55 - A55_t_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( A55 * B55.t() - A55_times_B55_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A55.t() * B55.t() - A55_t_times_B55_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A55 * B55 - two_times_A55_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A55.t() * B55 - two_times_A55_t_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A55 * B55.t() - two_times_A55_times_B55_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A55.t() * B55.t() - two_times_A55_t_times_B55_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( A55 * 2 * B55 - A55_times_two_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( A55.t() * 2 * B55 - A55_t_times_two_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( A55 * 2 * B55.t() - A55_times_two_times_B55_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A55.t() * 2 * B55.t() - A55_t_times_two_times_B55_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A55 * 2*B55 - two_times_A55_times_two_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A55.t() * 2*B55 - two_times_A55_t_times_two_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A55 * 2*B55.t() - two_times_A55_times_two_times_B55_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A55.t() * 2*B55.t() - two_times_A55_t_times_two_times_B55_t )) == Approx(0.0) ); - - // - - REQUIRE( accu(abs( A55 * B55 - A55_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( A55.t().eval() * B55 - A55_t_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( A55 * B55.t().eval() - A55_times_B55_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A55.t().eval() * B55.t().eval() - A55_t_times_B55_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( (2*A55).eval() * B55 - two_times_A55_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A55.t()).eval() * B55 - two_times_A55_t_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A55).eval() * B55.t().eval() - two_times_A55_times_B55_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A55.t()).eval() * B55.t().eval() - two_times_A55_t_times_B55_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( A55 * (2 * B55).eval() - A55_times_two_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( A55.t().eval() * (2 * B55).eval() - A55_t_times_two_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( A55 * (2 * B55.t()).eval() - A55_times_two_times_B55_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A55.t().eval() * (2 * B55.t()).eval() - A55_t_times_two_times_B55_t )) == Approx(0.0) ); - - REQUIRE( accu(abs( (2*A55).eval() * (2*B55).eval() - two_times_A55_times_two_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A55.t()).eval() * (2*B55).eval() - two_times_A55_t_times_two_times_B55 )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A55).eval() * (2*B55.t()).eval() - two_times_A55_times_two_times_B55_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A55.t()).eval() * (2*B55.t()).eval() - two_times_A55_t_times_two_times_B55_t )) == Approx(0.0) ); - } - - - -TEST_CASE("mat_mul_real_6") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = fliplr(A); - - // - - mat A_times_B_t = - "\ - -0.064350 0.149875 -0.182277 -0.273462 0.206336;\ - 0.149875 0.079491 -0.298398 0.327168 0.035695;\ - -0.182277 -0.298398 0.707103 -0.235701 -0.516759;\ - -0.273462 0.327168 -0.235701 -0.220160 0.115474;\ - 0.206336 0.035695 -0.516759 0.115474 0.664298;\ - "; - - mat A_t_times_B = - "\ - 0.430191 -0.042089 -0.458772 -0.162107 0.089220 0.607990;\ - 0.069589 0.085881 -0.152563 0.348562 0.398588 0.089220;\ - -0.080952 0.056788 0.067119 0.497201 0.348562 -0.162107;\ - -0.440028 0.233857 0.661467 0.067119 -0.152563 -0.458772;\ - -0.169075 0.251826 0.233857 0.056788 0.085881 -0.042089;\ - 0.417147 -0.169075 -0.440028 -0.080952 0.069589 0.430191;\ - "; - - // - - mat two_times_A_times_B_t = - "\ - -0.128699 0.299749 -0.364555 -0.546925 0.412672;\ - 0.299749 0.158981 -0.596795 0.654336 0.071391;\ - -0.364555 -0.596795 1.414207 -0.471402 -1.033519;\ - -0.546925 0.654336 -0.471402 -0.440319 0.230948;\ - 0.412672 0.071391 -1.033519 0.230948 1.328595;\ - "; - - mat two_times_A_t_times_B = - "\ - 0.860381 -0.084178 -0.917544 -0.324215 0.178440 1.215980;\ - 0.139178 0.171762 -0.305125 0.697124 0.797177 0.178440;\ - -0.161904 0.113577 0.134239 0.994402 0.697124 -0.324215;\ - -0.880056 0.467715 1.322933 0.134239 -0.305125 -0.917544;\ - -0.338149 0.503651 0.467715 0.113577 0.171762 -0.084178;\ - 0.834294 -0.338149 -0.880056 -0.161904 0.139178 0.860381;\ - "; - - // - - mat A_times_two_times_B_t = - "\ - -0.128699 0.299749 -0.364555 -0.546925 0.412672;\ - 0.299749 0.158981 -0.596795 0.654336 0.071391;\ - -0.364555 -0.596795 1.414207 -0.471402 -1.033519;\ - -0.546925 0.654336 -0.471402 -0.440319 0.230948;\ - 0.412672 0.071391 -1.033519 0.230948 1.328595;\ - "; - - mat A_t_times_two_times_B = - "\ - 0.860381 -0.084178 -0.917544 -0.324215 0.178440 1.215980;\ - 0.139178 0.171762 -0.305125 0.697124 0.797177 0.178440;\ - -0.161904 0.113577 0.134239 0.994402 0.697124 -0.324215;\ - -0.880056 0.467715 1.322933 0.134239 -0.305125 -0.917544;\ - -0.338149 0.503651 0.467715 0.113577 0.171762 -0.084178;\ - 0.834294 -0.338149 -0.880056 -0.161904 0.139178 0.860381;\ - "; - - // - - mat two_times_A_times_two_times_B_t = - "\ - -0.257398626992 0.599498340296 -0.729109500804 -1.093849875492 0.825343113540;\ - 0.599498340296 0.317962274816 -1.193590692028 1.308671575684 0.142781030004;\ - -0.729109500804 -1.193590692028 2.828413151368 -0.942803741636 -2.067037385556;\ - -1.093849875492 1.308671575684 -0.942803741636 -0.880638524704 0.461896688368;\ - 0.825343113540 0.142781030004 -2.067037385556 0.461896688368 2.657190032672;\ - "; - - mat two_times_A_t_times_two_times_B = - "\ - 1.720762508480 -0.168355348408 -1.835087231712 -0.648429049028 0.356879236660 2.431960170292;\ - 0.278356531136 0.343524137236 -0.610250174464 1.394248666196 1.594353519068 0.356879236660;\ - -0.323807331272 0.227153811280 0.268477507864 1.988804839396 1.394248666196 -0.648429049028;\ - -1.760112014908 0.935429101824 2.645866173324 0.268477507864 -0.610250174464 -1.835087231712;\ - -0.676298185096 1.007302825388 0.935429101824 0.227153811280 0.343524137236 -0.168355348408;\ - 1.668587103756 -0.676298185096 -1.760112014908 -0.323807331272 0.278356531136 1.720762508480;\ - "; - - // - - REQUIRE( accu(abs( A*B.t() - A_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A.t()*B - A_t_times_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A*B.t() - two_times_A_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A)*B.t() - two_times_A_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A.t()*B - two_times_A_t_times_B )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A).t()*B - two_times_A_t_times_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( A*2*B.t() - A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A*(2*B).t() - A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A.t()*2*B - A_t_times_two_times_B )) == Approx(0.0) ); - REQUIRE( accu(abs( A.t()*(2*B) - A_t_times_two_times_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A*2*B.t() - two_times_A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A)*2*B.t() - two_times_A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A.t()*2*B - two_times_A_t_times_two_times_B )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A).t()*2*B - two_times_A_t_times_two_times_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A*(2*B).t() - two_times_A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A)*(2*B).t() - two_times_A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A.t()*(2*B) - two_times_A_t_times_two_times_B )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A).t()*(2*B) - two_times_A_t_times_two_times_B )) == Approx(0.0) ); - - // - - REQUIRE( accu(abs( A*B.t().eval() - A_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A.t().eval()*B - A_t_times_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A*B.t().eval() - two_times_A_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A)*B.t().eval() - two_times_A_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A.t()).eval()*B - two_times_A_t_times_B )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A).t().eval()*B - two_times_A_t_times_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( A*2*(B.t().eval()) - A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A*(2*B).t().eval() - A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( A.t().eval()*2*B - A_t_times_two_times_B )) == Approx(0.0) ); - REQUIRE( accu(abs( A.t().eval()*(2*B).eval() - A_t_times_two_times_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A*2*(B.t()).eval() - two_times_A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A)*(2*B.t()).eval() - two_times_A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A.t().eval()*2*B - two_times_A_t_times_two_times_B )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A).t().eval()*2*B - two_times_A_t_times_two_times_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*A*(2*B).t().eval() - two_times_A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A)*(2*B).t().eval() - two_times_A_times_two_times_B_t )) == Approx(0.0) ); - REQUIRE( accu(abs( 2*A.t().eval()*(2*B) - two_times_A_t_times_two_times_B )) == Approx(0.0) ); - REQUIRE( accu(abs( (2*A).t().eval()*(2*B) - two_times_A_t_times_two_times_B )) == Approx(0.0) ); - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/mat_neg.cpp armadillo-10.8.2+dfsg/tests/mat_neg.cpp --- armadillo-9.800.4+dfsg/tests/mat_neg.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/mat_neg.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("mat_neg_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = -A; - - REQUIRE( B(0,0) == Approx(-0.061198) ); - REQUIRE( B(1,0) == Approx(-0.437242) ); - REQUIRE( B(2,0) == Approx(+0.492474) ); - REQUIRE( B(3,0) == Approx(-0.336352) ); - REQUIRE( B(4,0) == Approx(-0.239585) ); - - REQUIRE( B(0,1) == Approx(-0.201990) ); - REQUIRE( B(1,1) == Approx(-0.058956) ); - REQUIRE( B(2,1) == Approx(+0.031309) ); - REQUIRE( B(3,1) == Approx(-0.411541) ); - REQUIRE( B(4,1) == Approx(+0.428913) ); - - REQUIRE( B(0,5) == Approx(-0.051408) ); - REQUIRE( B(1,5) == Approx(-0.035437) ); - REQUIRE( B(2,5) == Approx(+0.454499) ); - REQUIRE( B(3,5) == Approx(-0.373833) ); - REQUIRE( B(4,5) == Approx(-0.258704) ); - - REQUIRE( accu(B + A) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } diff -Nru armadillo-9.800.4+dfsg/tests/mat_plus.cpp armadillo-10.8.2+dfsg/tests/mat_plus.cpp --- armadillo-9.800.4+dfsg/tests/mat_plus.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/mat_plus.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2015 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - - -#include -#include "catch.hpp" - -using namespace arma; - - -TEST_CASE("mat_plus_1") - { - mat A = - "\ - 0.061198 0.201990 0.019678 -0.493936 -0.126745 0.051408;\ - 0.437242 0.058956 -0.149362 -0.045465 0.296153 0.035437;\ - -0.492474 -0.031309 0.314156 0.419733 0.068317 -0.454499;\ - 0.336352 0.411541 0.458476 -0.393139 -0.135040 0.373833;\ - 0.239585 -0.428913 -0.406953 -0.291020 -0.353768 0.258704;\ - "; - - mat B = fliplr(A); - - mat A_plus_B = - "\ - 0.112606 0.075245 -0.474258 -0.474258 0.075245 0.112606;\ - 0.472679 0.355109 -0.194827 -0.194827 0.355109 0.472679;\ - -0.946973 0.037008 0.733889 0.733889 0.037008 -0.946973;\ - 0.710185 0.276501 0.065337 0.065337 0.276501 0.710185;\ - 0.498289 -0.782681 -0.697973 -0.697973 -0.782681 0.498289;\ - "; - - mat X = A + B; - - REQUIRE( X(0,0) == Approx( 0.112606) ); - REQUIRE( X(1,0) == Approx( 0.472679) ); - REQUIRE( X(2,0) == Approx(-0.946973) ); - REQUIRE( X(3,0) == Approx( 0.710185) ); - REQUIRE( X(4,0) == Approx( 0.498289) ); - - REQUIRE( X(0,1) == Approx( 0.075245) ); - REQUIRE( X(1,1) == Approx( 0.355109) ); - REQUIRE( X(2,1) == Approx( 0.037008) ); - REQUIRE( X(3,1) == Approx( 0.276501) ); - REQUIRE( X(4,1) == Approx(-0.782681) ); - - REQUIRE( X(0,5) == Approx( 0.112606) ); - REQUIRE( X(1,5) == Approx( 0.472679) ); - REQUIRE( X(2,5) == Approx(-0.946973) ); - REQUIRE( X(3,5) == Approx( 0.710185) ); - REQUIRE( X(4,5) == Approx( 0.498289) ); - - - mat Y = (2*A + 2*B)/2; - - REQUIRE( Y(0,0) == Approx( 0.112606) ); - REQUIRE( Y(1,0) == Approx( 0.472679) ); - REQUIRE( Y(2,0) == Approx(-0.946973) ); - REQUIRE( Y(3,0) == Approx( 0.710185) ); - REQUIRE( Y(4,0) == Approx( 0.498289) ); - - REQUIRE( Y(0,1) == Approx( 0.075245) ); - REQUIRE( Y(1,1) == Approx( 0.355109) ); - REQUIRE( Y(2,1) == Approx( 0.037008) ); - REQUIRE( Y(3,1) == Approx( 0.276501) ); - REQUIRE( Y(4,1) == Approx(-0.782681) ); - - REQUIRE( Y(0,5) == Approx( 0.112606) ); - REQUIRE( Y(1,5) == Approx( 0.472679) ); - REQUIRE( Y(2,5) == Approx(-0.946973) ); - REQUIRE( Y(3,5) == Approx( 0.710185) ); - REQUIRE( Y(4,5) == Approx( 0.498289) ); - - - REQUIRE( accu(abs( mat(A+B) - A_plus_B )) == Approx(0.0) ); - REQUIRE( accu(abs( (A+B) - A_plus_B )) == Approx(0.0) ); - - REQUIRE( accu(abs( 2*(A+B) - 2*A_plus_B )) == Approx(0.0) ); - - // REQUIRE_THROWS( ); - } - - - -TEST_CASE("mat_plus_2") - { - mat A(5,6); A.fill(1.0); - mat B(5,6); B.fill(2.0); - mat C(5,6); C.fill(3.0); - - REQUIRE( accu(A + B) == Approx(double(5*6*3)) ); - - REQUIRE( accu(A + B + C) == Approx(double(5*6*6)) ); - - REQUIRE( accu(A + B/2 + C) == Approx(double(5*6*5)) ); - - mat X(6,5); - REQUIRE_THROWS( A+X ); // adding non-conformant matrices will throw unless ARMA_NO_DEBUG is defined - } - - - diff -Nru armadillo-9.800.4+dfsg/tests/README.txt armadillo-10.8.2+dfsg/tests/README.txt --- armadillo-9.800.4+dfsg/tests/README.txt 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/README.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -- The tests in this directory are intended to be run only on Linux or macOS -- The tests are a work-in-progress -- Armadillo must be installed before the tests can be compiled -- C++11 compiler is required to compile the tests -- To compile the tests, use "make" -- Run the tests by running the "main" executable - -Example: - -make clean -make -./main - diff -Nru armadillo-9.800.4+dfsg/tests/spcol.cpp armadillo-10.8.2+dfsg/tests/spcol.cpp --- armadillo-9.800.4+dfsg/tests/spcol.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/spcol.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("spcol_insert_test") - { - SpCol sp; - sp.set_size(10, 1); - // Ensure everything is empty. - for (size_t i = 0; i < 10; i++) - REQUIRE( sp(i) == 0.0 ); - - // Add an element. - sp(5, 0) = 43.234; - REQUIRE( sp.n_nonzero == 1 ); - REQUIRE( (double) sp(5, 0) == Approx(43.234) ); - - // Remove the element. - sp(5, 0) = 0.0; - REQUIRE( sp.n_nonzero == 0 ); - } - -TEST_CASE("col_iterator_test") - { - SpCol x(5, 1); - x(3) = 3.1; - x(0) = 4.2; - x(1) = 3.3; - x(1) = 5.5; // overwrite - x(2) = 4.5; - x(4) = 6.4; - - SpCol::iterator it = x.begin(); - REQUIRE( (double) *it == Approx(4.2) ); - REQUIRE( it.row() == 0 ); - REQUIRE( it.col() == 0 ); - ++it; - - REQUIRE( (double) *it == Approx(5.5) ); - REQUIRE( it.row() == 1); - REQUIRE( it.col() == 0); - ++it; - - REQUIRE( (double) *it == Approx(4.5) ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 0 ); - ++it; - - REQUIRE( (double) *it == Approx(3.1) ); - REQUIRE( it.row() == 3 ); - REQUIRE( it.col() == 0 ); - ++it; - - REQUIRE( (double) *it == Approx(6.4) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 0 ); - ++it; - - REQUIRE( it == x.end() ); - - // Now let's go backwards. - --it; // Get it off the end. - REQUIRE( (double) *it == Approx(6.4) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 0 ); - --it; - - REQUIRE( (double) *it == Approx(3.1) ); - REQUIRE( it.row() == 3); - REQUIRE( it.col() == 0); - --it; - - REQUIRE( (double) *it == Approx(4.5) ); - REQUIRE( it.row() == 2); - REQUIRE( it.col() == 0); - --it; - - REQUIRE( (double) *it == Approx(5.5) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 0 ); - --it; - - REQUIRE( (double) *it == Approx(4.2) ); - REQUIRE( it.row() == 0 ); - REQUIRE( it.col() == 0 ); - - REQUIRE( it == x.begin() ); - - // Try removing an element we iterated to. - ++it; - ++it; - *it = 0; - REQUIRE( x.n_nonzero == 4 ); - } - -TEST_CASE("basic_sp_col_operator_test") - { - // +=, -=, *=, /=, %= - SpCol a(6, 1); - a(0) = 3.4; - a(1) = 2.0; - - SpCol b(6, 1); - b(0) = 3.4; - b(3) = 0.4; - - double addResult[6] = {6.8, 2.0, 0.0, 0.4, 0.0, 0.0}; - double subResult[6] = {0.0, 2.0, 0.0, -0.4, 0.0, 0.0}; - - SpCol out = a; - out += b; - REQUIRE( out.n_nonzero == 3 ); - for (u32 r = 0; r < 6; r++) - { - REQUIRE( (double) out(r) == Approx(addResult[r]) ); - } - - out = a; - out -= b; - REQUIRE( out.n_nonzero == 2 ); - for (u32 r = 0; r < 6; r++) - { - REQUIRE( (double) out(r) == Approx(subResult[r]) ); - } - } - -/* -BOOST_AUTO_TEST_CASE(SparseSparseColMultiplicationTest) { - SpCol spaa(4, 1); - SpMat spbb(1, 4); - - spaa(0, 0) = 321.2; - spaa(1, 0) = .123; - spaa(2, 0) = 231.4; - spaa(3, 0) = .03214; - - spbb(0, 0) = 32.23; - spbb(0, 1) = 5.1; - spbb(0, 2) = 4.4; - spbb(0, 3) = .88; - - SpMat precision = spaa; - - precision *= spbb; //Wolfram alpha insisted on rounding.. - - spaa *= spbb; - - for (size_t i = 0; i < 4; i++) - for (size_t j = 0; j < 4; j++) - BOOST_REQUIRE_CLOSE((double) spaa(i, j), (double) precision(i, j), 1e-5); -} -*/ - -TEST_CASE("spcol_shed_row_test") - { - // On an SpCol - SpCol e(10); - e(1) = 5; - e(4) = 56; - e(5) = 6; - e(7) = 4; - e(8) = 2; - e(9) = -1; - e.shed_rows(4, 7); - - REQUIRE( e.n_cols == 1 ); - REQUIRE( e.n_rows == 6 ); - REQUIRE( e.n_nonzero == 3 ); - REQUIRE( (int) e[0] == 0 ); - REQUIRE( (int) e[1] == 5 ); - REQUIRE( (int) e[2] == 0 ); - REQUIRE( (int) e[3] == 0 ); - REQUIRE( (int) e[4] == 2 ); - REQUIRE( (int) e[5] == -1 ); - } - - - -TEST_CASE("spcol_col_constructor") - { - SpMat m(100, 100); - m.sprandu(100, 100, 0.3); - - SpCol c = m.col(0); - - vec v(c); - - for (uword i = 0; i < 100; ++i) - { - REQUIRE( v(i) == (double) c(i) ); - } - } diff -Nru armadillo-9.800.4+dfsg/tests/spmat.cpp armadillo-10.8.2+dfsg/tests/spmat.cpp --- armadillo-9.800.4+dfsg/tests/spmat.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/spmat.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,3231 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -// Does the matrix correctly report when it is empty? -TEST_CASE("empty_test") - { - bool testPassed = true; - - sp_imat test; - REQUIRE( test.is_empty() ); - - test.set_size(3, 4); - REQUIRE( test.is_empty() == false ); - } - -// Can we insert items into the matrix correctly? -TEST_CASE("insertion_test") - { - int correctResult[3][4] = - {{1, 0, 0, 0}, - {2, 3, 1, 0}, - {0, 9, 4, 0}}; - - // Now run the same test for the Armadillo sparse matrix. - SpMat arma_test; - arma_test.set_size(3, 4); - - // Fill the matrix (hopefully). - arma_test(0, 0) = 1; - arma_test(1, 0) = 2; - arma_test(1, 1) = 3; - arma_test(2, 1) = 9; - arma_test(1, 2) = 1; - arma_test(2, 2) = 4; - - for (uword i = 0; i < 3; i++) - { - for (uword j = 0; j < 4; j++) - { - REQUIRE( (int) arma_test(i, j) == correctResult[i][j] ); - } - } - } - -// Does sparse-sparse matrix multiplication work? -TEST_CASE("full_sparse_sparse_matrix_multiplication_test") - { - // Now perform the test again for SpMat. - SpMat spa(3, 3); - SpMat spb(3, 2); - int correctResult[3][2] = - {{ 46, 60}, - { 40, 52}, - {121, 160}}; - - spa(0, 0) = 1; - spa(0, 1) = 10; - spa(0, 2) = 3; - spa(1, 0) = 3; - spa(1, 1) = 4; - spa(1, 2) = 5; - spa(2, 0) = 12; - spa(2, 1) = 13; - spa(2, 2) = 14; - - spb(0, 0) = 1; - spb(0, 1) = 2; - spb(1, 0) = 3; - spb(1, 1) = 4; - spb(2, 0) = 5; - spb(2, 1) = 6; - - spa *= spb; - - REQUIRE( spa.n_rows == 3 ); - REQUIRE( spa.n_cols == 2 ); - - for (uword i = 0; i < 3; i++) - { - for (uword j = 0; j < 2; j++) - { - REQUIRE( (int) spa(i, j) == correctResult[i][j] ); - } - } - } - -TEST_CASE("sparse_sparse_matrix_multiplication_test") - { - SpMat spaa(10, 10); - spaa(1, 5) = 0.4; - spaa(0, 4) = 0.3; - spaa(0, 8) = 1.2; - spaa(3, 0) = 1.1; - spaa(3, 1) = 1.1; - spaa(3, 2) = 1.1; - spaa(4, 4) = 0.2; - spaa(4, 9) = 0.1; - spaa(6, 2) = 4.1; - spaa(6, 8) = 4.1; - spaa(7, 5) = 1.0; - spaa(8, 9) = 0.4; - spaa(9, 4) = 0.4; - - double correctResultB[10][10] = - {{ 0.00, 0.00, 0.00, 0.00, 0.06, 0.00, 0.00, 0.00, 0.00, 0.51 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.33, 0.44, 0.00, 0.00, 1.32, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.08, 0.00, 0.00, 0.00, 0.00, 0.02 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 1.64 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.16, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.08, 0.00, 0.00, 0.00, 0.00, 0.04 }}; - - spaa *= spaa; - - for (uword i = 0; i < 10; i++) - { - for (uword j = 0; j < 10; j++) - { - REQUIRE( (double) spaa(i, j) == Approx(correctResultB[i][j]) ); - } - } - } - -TEST_CASE("hadamard_product_test") - { - SpMat a(4, 4), b(4, 4); - - a(1, 1) = 1; - a(2, 1) = 1; - a(3, 3) = 1; - a(3, 0) = 1; - a(0, 2) = 1; - - b(1, 1) = 1; - b(2, 2) = 1; - b(3, 3) = 1; - b(3, 0) = 1; - b(0, 3) = 1; - b(3, 1) = 1; - - double correctResult[4][4] = - {{ 0, 0, 0, 0 }, - { 0, 1, 0, 0 }, - { 0, 0, 0, 0 }, - { 1, 0, 0, 1 }}; - - a %= b; - - for (uword i = 0; i < 4; i++) - { - for (uword j = 0; j < 4; j++) - { - REQUIRE( a(i, j) == correctResult[i][j] ); - } - } - - - SpMat c, d; - c.sprandu(30, 25, 0.1); - d.sprandu(30, 25, 0.1); - - mat e, f; - e = c; - f = d; - - c %= d; - e %= f; - - for (uword i = 0; i < 25; ++i) - { - for(uword j = 0; j < 30; ++j) - { - REQUIRE( (double) c(j, i) == Approx(e(j, i)) ); - } - } - } - -TEST_CASE("division_test") - { - SpMat a(2, 2), b(2, 2); - - a(0, 1) = 0.5; - - b(0, 1) = 1.0; - b(1, 0) = 5.0; - - a /= b; - - REQUIRE( std::isnan((double) a(0, 0)) ); - REQUIRE( (double) a(0, 1) == Approx(0.5) ); - REQUIRE( (double) a(1, 0) == Approx(1e-5) ); - REQUIRE( std::isnan((double) a(1, 1)) ); - } - -TEST_CASE("insert_delete_test") - { - SpMat sp; - sp.set_size(10, 10); - - // Ensure everything is empty. - for (uword i = 0; i < 100; i++) - { - REQUIRE( sp(i) == 0.0 ); - } - - // Add an element. - sp(5, 5) = 43.234; - REQUIRE( sp.n_nonzero == 1 ); - REQUIRE( (double) sp(5, 5) == Approx(43.234) ); - - // Remove the element. - sp(5, 5) = 0.0; - REQUIRE( sp.n_nonzero == 0 ); - } - -TEST_CASE("value_operator_test") - { - // Test operators that work with a single value. - // =(double), /=(double), *=(double) - SpMat sp(3, 4); - double correctResult[3][4] = {{1.5, 0.0, 0.0, 0.0}, - {2.1, 3.2, 0.9, 0.0}, - {0.0, 9.3, 4.0, -1.5}}; - sp(0, 0) = 1.5; - sp(1, 0) = 2.1; - sp(1, 1) = 3.2; - sp(1, 2) = 0.9; - sp(2, 1) = 9.3; - sp(2, 2) = 4.0; - sp(2, 3) = -1.5; - - // operator=(double) - SpMat work = sp; - work = 5.0; - REQUIRE( work.n_nonzero == 1 ); - REQUIRE( work.n_elem == 1 ); - REQUIRE( (double) work(0) == Approx(5.0) ); - - // operator*=(double) - work = sp; - work *= 2; - REQUIRE( work.n_nonzero == 7 ); - for (uword i = 0; i < 3; i++) - { - for (uword j = 0; j < 4; j++) - { - REQUIRE((double) work(i, j) == Approx(correctResult[i][j] * 2.0) ); - } - } - - // operator/=(double) - work = sp; - work /= 5.5; - REQUIRE( work.n_nonzero == 7 ); - for (uword i = 0; i < 3; i++) - { - for (uword j = 0; j < 4; j++) - { - REQUIRE((double) work(i, j) == Approx(correctResult[i][j] / 5.5) ); - } - } - } - -TEST_CASE("iterator_test") - { - SpMat x(5, 5); - x(4, 1) = 3.1; - x(1, 2) = 4.2; - x(1, 3) = 3.3; - x(1, 3) = 5.5; // overwrite - x(2, 3) = 4.5; - x(4, 4) = 6.4; - - SpMat::iterator it = x.begin(); - REQUIRE( (double) *it == Approx(3.1) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 1 ); - ++it; - - REQUIRE( (double) *it == Approx(4.2) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 2 ); - ++it; - - REQUIRE( (double) *it == Approx(5.5) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 3 ); - ++it; - - REQUIRE( (double) *it == Approx(4.5) ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 3 ); - ++it; - - REQUIRE( (double) *it == Approx(6.4) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 4 ); - ++it; - - REQUIRE( it == x.end() ); - - // Now let's go backwards. - --it; // Get it off the end. - REQUIRE( (double) *it == Approx(6.4) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 4 ); - --it; - - REQUIRE( (double) *it == Approx(4.5) ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 3 ); - --it; - - REQUIRE( (double) *it == Approx(5.5) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 3 ); - --it; - - REQUIRE( (double) *it == Approx(4.2) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 2 ); - --it; - - REQUIRE( (double) *it == Approx(3.1) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 1 ); - - REQUIRE( it == x.begin() ); - - // Try removing an element we iterated to. - ++it; - ++it; - *it = 0; - REQUIRE( x.n_nonzero == 4 ); -} - -TEST_CASE("row_iterator_test") - { - SpMat x(5, 5); - x(4, 1) = 3.1; - x(1, 2) = 4.2; - x(1, 3) = 3.3; - x(1, 3) = 5.5; // overwrite - x(2, 3) = 4.5; - x(4, 4) = 6.4; - - SpMat::row_iterator it = x.begin_row(); - REQUIRE( (double) *it == Approx(4.2) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 2 ); - ++it; - - REQUIRE( (double) *it == Approx(5.5) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 3 ); - ++it; - - REQUIRE( (double) *it == Approx(4.5) ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 3 ); - ++it; - - REQUIRE( (double) *it == Approx(3.1) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 1 ); - ++it; - - REQUIRE( (double) *it == Approx(6.4) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 4 ); - ++it; - -// REQUIRE( it == x.end_row() ); - - // Now let's go backwards. - --it; // Get it off the end. - REQUIRE( (double) *it == Approx(6.4) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 4 ); - --it; - - REQUIRE( (double) *it == Approx(3.1) ); - REQUIRE( it.row() == 4 ); - REQUIRE( it.col() == 1 ); - --it; - - REQUIRE( (double) *it == Approx(4.5) ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 3 ); - --it; - - REQUIRE( (double) *it == Approx(5.5) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 3 ); - --it; - - REQUIRE( (double) *it == Approx(4.2) ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 2 ); - - REQUIRE( it == x.begin_row() ); - - // Try removing an element we iterated to. - ++it; - ++it; - *it = 0; - REQUIRE( x.n_nonzero == 4 ); - } - -TEST_CASE("basic_sp_mat_operator_test") - { - // +=, -=, *=, /=, %= - SpMat a(6, 5); - a(0, 0) = 3.4; - a(4, 1) = 4.1; - a(5, 1) = 1.5; - a(3, 2) = 2.6; - a(4, 2) = 3.0; - a(1, 3) = 9.8; - a(4, 3) = 0.1; - a(2, 4) = 0.2; - a(3, 4) = 0.2; - a(4, 4) = 0.2; - a(5, 4) = 8.3; - - SpMat b(6, 5); - b(0, 0) = 3.4; - b(3, 0) = 0.4; - b(3, 1) = 0.5; - b(4, 1) = 1.2; - b(4, 2) = 3.0; - b(5, 2) = 1.1; - b(1, 3) = 0.6; - b(3, 3) = 1.0; - b(4, 4) = 7.3; - b(5, 4) = 7.4; - - double addResult[6][5] = {{6.8 , 0 , 0 , 0 , 0 }, - {0 , 0 , 0 , 10.4, 0 }, - {0 , 0 , 0 , 0 , 0.2 }, - {0.4 , 0.5 , 2.6 , 1.0 , 0.2 }, - {0 , 5.3 , 6.0 , 0.1 , 7.5 }, - {0 , 1.5 , 1.1 , 0 , 15.7}}; - - double subResult[6][5] = {{0 , 0 , 0 , 0 , 0 }, - {0 , 0 , 0 , 9.2 , 0 }, - {0 , 0 , 0 , 0 , 0.2 }, - {-0.4, -0.5, 2.6 , -1.0, 0.2 }, - {0 , 2.9 , 0 , 0.1 , -7.1}, - {0 , 1.5 , -1.1, 0 , 0.9 }}; - - SpMat out = a; - out += b; - REQUIRE( out.n_nonzero == 15 ); - for (uword r = 0; r < 6; r++) - { - for (uword c = 0; c < 5; c++) - { - REQUIRE( (double) out(r, c) == Approx(addResult[r][c]) ); - } - } - - out = a; - out -= b; - REQUIRE( out.n_nonzero == 13 ); - for (uword r = 0; r < 6; r++) - { - for (uword c = 0; c < 5; c++) - { - REQUIRE( (double) out(r, c) == Approx(subResult[r][c]) ); - } - } - } - -TEST_CASE("min_max_test") - { - SpMat a(6, 5); - a(0, 0) = 3.4; - a(4, 1) = 4.1; - a(5, 1) = 1.5; - a(3, 2) = 2.6; - a(4, 2) = 3.0; - a(1, 3) = 9.8; - a(4, 3) = 0.1; - a(2, 4) = 0.2; - a(3, 4) = -0.2; - a(4, 4) = 0.2; - a(5, 4) = 8.3; - - uword index, row, col; - REQUIRE( a.min() == Approx(-0.2) ); - REQUIRE( a.min(index) == Approx(-0.2) ); - REQUIRE( index == 27 ); - REQUIRE( a.min(row, col) == Approx(-0.2) ); - REQUIRE( row == 3 ); - REQUIRE( col == 4 ); - - REQUIRE( a.max() == Approx(9.8) ); - REQUIRE( a.max(index) == Approx(9.8) ); - REQUIRE( index == 19 ); - REQUIRE( a.max(row, col) == Approx(9.8) ); - REQUIRE( row == 1 ); - REQUIRE( col == 3 ); - } - -TEST_CASE("swap_row_test") - { - SpMat a(6, 5); - a(0, 0) = 3.4; - a(4, 1) = 4.1; - a(5, 1) = 1.5; - a(3, 2) = 2.6; - a(4, 2) = 3.0; - a(1, 3) = 9.8; - a(4, 3) = 0.1; - a(2, 4) = 0.2; - a(3, 4) = -0.2; - a(4, 4) = 0.2; - a(5, 4) = 8.3; - - /** - * [[3.4 0.0 0.0 0.0 0.0] - * [0.0 0.0 0.0 9.8 0.0] - * [0.0 0.0 0.0 0.0 0.2] - * [0.0 0.0 2.6 0.0 -0.2] - * [0.0 4.1 3.0 0.1 0.2] - * [0.0 1.5 0.0 0.0 8.3]] - */ - double swapOne[6][5] = - {{ 0.0, 0.0, 2.6, 0.0, -0.2}, - { 0.0, 0.0, 0.0, 9.8, 0.0}, - { 0.0, 0.0, 0.0, 0.0, 0.2}, - { 3.4, 0.0, 0.0, 0.0, 0.0}, - { 0.0, 4.1, 3.0, 0.1, 0.2}, - { 0.0, 1.5, 0.0, 0.0, 8.3}}; - - double swapTwo[6][5] = - {{ 0.0, 0.0, 2.6, 0.0, -0.2}, - { 0.0, 0.0, 0.0, 9.8, 0.0}, - { 0.0, 0.0, 0.0, 0.0, 0.2}, - { 3.4, 0.0, 0.0, 0.0, 0.0}, - { 0.0, 1.5, 0.0, 0.0, 8.3}, - { 0.0, 4.1, 3.0, 0.1, 0.2}}; - - a.swap_rows(0, 3); - - for (uword row = 0; row < a.n_rows; row++) - { - for (uword col = 0; col < a.n_cols; col++) - { - REQUIRE( (double) a(row, col) == Approx(swapOne[row][col]) ); - } - } - - a.swap_rows(4, 5); - - for (uword row = 0; row < a.n_rows; row++) - { - for (uword col = 0; col < a.n_cols; col++) - { - REQUIRE( (double) a(row, col) == Approx(swapTwo[row][col]) ); - } - } - } - -TEST_CASE("swap_col_test") - { - SpMat a(6, 5); - a(0, 0) = 3.4; - a(4, 1) = 4.1; - a(5, 1) = 1.5; - a(3, 2) = 2.6; - a(4, 2) = 3.0; - a(1, 3) = 9.8; - a(4, 3) = 0.1; - a(2, 4) = 0.2; - a(3, 4) = -0.2; - a(4, 4) = 0.2; - a(5, 4) = 8.3; - - mat b(6, 5); - b.zeros(6, 5); - b(0, 0) = 3.4; - b(4, 1) = 4.1; - b(5, 1) = 1.5; - b(3, 2) = 2.6; - b(4, 2) = 3.0; - b(1, 3) = 9.8; - b(4, 3) = 0.1; - b(2, 4) = 0.2; - b(3, 4) = -0.2; - b(4, 4) = 0.2; - b(5, 4) = 8.3; - - /** - * [[3.4 0.0 0.0 0.0 0.0] - * [0.0 0.0 0.0 9.8 0.0] - * [0.0 0.0 0.0 0.0 0.2] - * [0.0 0.0 2.6 0.0 -0.2] - * [0.0 4.1 3.0 0.1 0.2] - * [0.0 1.5 0.0 0.0 8.3]] - */ - - a.swap_cols(2, 3); - b.swap_cols(2, 3); - - for (uword row = 0; row < a.n_rows; row++) - { - for (uword col = 0; col < a.n_cols; col++) - { - REQUIRE( (double) a(row, col) == Approx(b(row, col)) ); - } - } - - a.swap_cols(0, 4); - b.swap_cols(0, 4); - - for (uword row = 0; row < a.n_rows; row++) - { - for (uword col = 0; col < a.n_cols; col++) - { - REQUIRE( (double) a(row, col) == Approx(b(row, col)) ); - } - } - - a.swap_cols(1, 4); - b.swap_cols(1, 4); - - for (uword row = 0; row < a.n_rows; row++) - { - for (uword col = 0; col < a.n_cols; col++) - { - REQUIRE( (double) a(row, col) == Approx(b(row, col)) ); - } - } - } - -TEST_CASE("shed_col_test") - { - SpMat a(2, 2); - a(0, 0) = 1; - a(1, 1) = 1; - - /** - * [[1 0] - * [0 1]] - * - * becomes - * - * [[0] - * [1]] - */ - - a.shed_col(0); - REQUIRE( a.n_cols == 1 ); - REQUIRE( a.n_rows == 2 ); - REQUIRE( a.n_elem == 2 ); - REQUIRE( a.n_nonzero == 1 ); - REQUIRE( a(0, 0) == 0 ); - REQUIRE( a(1, 0) == 1 ); - } - -TEST_CASE("shed_cols_test") - { - SpMat a(3, 3); - a(0, 0) = 1; - a(1, 1) = 1; - a(2, 2) = 1; - SpMat b(3, 3); - b(0, 0) = 1; - b(1, 1) = 1; - b(2, 2) = 1; - SpMat c(3, 3); - c(0, 0) = 1; - c(1, 1) = 1; - c(2, 2) = 1; - - /** - * [[1 0 0] - * [0 1 0] - * [0 0 1]] - * - * becomes - * - * [[0] - * [0] - * [1]] - */ - - a.shed_cols(0, 1); - REQUIRE( a.n_cols == 1 ); - REQUIRE( a.n_rows == 3 ); - REQUIRE( a.n_elem == 3 ); - REQUIRE( a.n_nonzero == 1 ); - REQUIRE( a(0, 0) == 0 ); - REQUIRE( a(1, 0) == 0 ); - REQUIRE( a(2, 0) == 1 ); - - b.shed_cols(1, 2); - REQUIRE( b.n_cols == 1 ); - REQUIRE( b.n_rows == 3 ); - REQUIRE( b.n_elem == 3 ); - REQUIRE( b.n_nonzero == 1 ); - REQUIRE( b(0, 0) == 1 ); - REQUIRE( b(1, 0) == 0 ); - REQUIRE( b(2, 0) == 0 ); - - c.shed_cols(0, 0); - c.shed_cols(1, 1); - REQUIRE( c.n_cols == 1 ); - REQUIRE( c.n_rows == 3 ); - REQUIRE( c.n_elem == 3 ); - REQUIRE( c.n_nonzero == 1 ); - REQUIRE( c(0, 0) == 0 ); - REQUIRE( c(1, 0) == 1 ); - REQUIRE( c(2, 0) == 0 ); - } - -TEST_CASE("shed_row_test") - { - SpMat a(3, 3); - a(0, 0) = 1; - a(1, 1) = 1; - a(2, 2) = 1; - Mat b(3, 3); - b.zeros(3, 3); - b(0, 0) = 1; - b(1, 1) = 1; - b(2, 2) = 1; - - /** - * [[1 0 0] - * [0 1 0] - * [0 0 1]] - * - * becomes - * - * [[1 0 0] - * [0 1 0]] - */ - a.shed_row(2); - b.shed_row(2); - REQUIRE( a.n_cols == 3 ); - REQUIRE( a.n_rows == 2 ); - REQUIRE( a.n_elem == 6 ); - REQUIRE( a.n_nonzero == 2 ); - for (uword row = 0; row < a.n_rows; row++) - { - for (uword col = 0; col < a.n_cols; col++) - { - REQUIRE( (double) a(row, col) == Approx(b(row, col)) ); - } - } - } - -TEST_CASE("shed_rows_test") - { - SpMat a(5, 5); - a(0, 0) = 1; - a(1, 1) = 1; - a(2, 2) = 1; - a(3, 3) = 1; - a(4, 4) = 1; - Mat b(5, 5); - b.zeros(5, 5); - b(0, 0) = 1; - b(1, 1) = 1; - b(2, 2) = 1; - b(3, 3) = 1; - b(4, 4) = 1; - - SpMat c = a; - Mat d = b; - - /** - * [[1 0 0 0 0] - * [0 1 0 0 0] - * [0 0 1 0 0] - * [0 0 0 1 0] - * [0 0 0 0 1]] - * - * becomes - * - * [[1 0 0 0 0] - * [0 1 0 0 0]] - */ - a.shed_rows(2,4); - b.shed_rows(2,4); - REQUIRE( a.n_cols == 5 ); - REQUIRE( a.n_rows == 2 ); - REQUIRE( a.n_elem == 10 ); - REQUIRE( a.n_nonzero == 2 ); - for (uword row = 0; row < a.n_rows; row++) - { - for (uword col = 0; col < a.n_cols; col++) - { - REQUIRE( (double) a(row, col) == Approx(b(row, col)) ); - } - } - - c.shed_rows(0, 2); - d.shed_rows(0, 2); - REQUIRE( c.n_cols == 5 ); - REQUIRE( c.n_rows == 2 ); - REQUIRE( c.n_elem == 10 ); - REQUIRE( c.n_nonzero == 2 ); - for (uword row = 0; row < c.n_rows; ++row) - { - for (uword col = 0; col < c.n_cols; ++col) - { - REQUIRE( (int) c(row, col) == d(row, col) ); - } - } - } - -TEST_CASE("sp_mat_reshape_columnwise_test") - { - // Input matrix: - // [[0 2 0] - // [1 3 0] - // [0 0 5] - // [0 4 6]] - // - // Output matrix: - // [[0 0 0 0] - // [1 2 4 5] - // [0 3 0 6]] - SpMat ref(4, 3); - ref(1, 0) = 1; - ref(0, 1) = 2; - ref(1, 1) = 3; - ref(3, 1) = 4; - ref(2, 2) = 5; - ref(3, 2) = 6; - - // Now reshape. - ref.reshape(3, 4); - - // Check everything. - REQUIRE( ref.n_cols == 4 ); - REQUIRE( ref.n_rows == 3 ); - - REQUIRE( (unsigned int) ref(0, 0) == 0 ); - REQUIRE( (unsigned int) ref(1, 0) == 1 ); - REQUIRE( (unsigned int) ref(2, 0) == 0 ); - REQUIRE( (unsigned int) ref(0, 1) == 0 ); - REQUIRE( (unsigned int) ref(1, 1) == 2 ); - REQUIRE( (unsigned int) ref(2, 1) == 3 ); - REQUIRE( (unsigned int) ref(0, 2) == 0 ); - REQUIRE( (unsigned int) ref(1, 2) == 4 ); - REQUIRE( (unsigned int) ref(2, 2) == 0 ); - REQUIRE( (unsigned int) ref(0, 3) == 0 ); - REQUIRE( (unsigned int) ref(1, 3) == 5 ); - REQUIRE( (unsigned int) ref(2, 3) == 6 ); - } - -// TEST_CASE("sp_mat_reshape_rowwise_test") -// { -// // Input matrix: -// // [[0 2 0] -// // [1 3 0] -// // [0 0 5] -// // [0 4 6]] -// // -// // Output matrix: -// // [[0 2 0 1] -// // [3 0 0 0] -// // [5 0 4 6]] -// SpMat ref(4, 3); -// ref(1, 0) = 1; -// ref(0, 1) = 2; -// ref(1, 1) = 3; -// ref(3, 1) = 4; -// ref(2, 2) = 5; -// ref(3, 2) = 6; -// -// // Now reshape. -// ref.reshape(3, 4, 1 /* row-wise */); -// -// // Check everything. -// REQUIRE( ref.n_cols == 4 ); -// REQUIRE( ref.n_rows == 3 ); -// -// REQUIRE( (unsigned int) ref(0, 0) == 0 ); -// REQUIRE( (unsigned int) ref(1, 0) == 3 ); -// REQUIRE( (unsigned int) ref(2, 0) == 5 ); -// REQUIRE( (unsigned int) ref(0, 1) == 2 ); -// REQUIRE( (unsigned int) ref(1, 1) == 0 ); -// REQUIRE( (unsigned int) ref(2, 1) == 0 ); -// REQUIRE( (unsigned int) ref(0, 2) == 0 ); -// REQUIRE( (unsigned int) ref(1, 2) == 0 ); -// REQUIRE( (unsigned int) ref(2, 2) == 4 ); -// REQUIRE( (unsigned int) ref(0, 3) == 1 ); -// REQUIRE( (unsigned int) ref(1, 3) == 0 ); -// REQUIRE( (unsigned int) ref(2, 3) == 6 ); -// } - -TEST_CASE("sp_mat_zeros_tests") - { - SpMat m(4, 3); - m(1, 0) = 1; - m(0, 1) = 2; - m(1, 1) = 3; - m(3, 1) = 4; - m(2, 2) = 5; - m(3, 2) = 6; - - // Now zero it out. - SpMat d = m; - - d.zeros(); - - REQUIRE( d.values[0] == 0 ); - REQUIRE( d.row_indices[0] == 0); - REQUIRE( d.col_ptrs[0] == 0 ); - REQUIRE( d.col_ptrs[1] == 0 ); - REQUIRE( d.col_ptrs[2] == 0 ); - REQUIRE( d.col_ptrs[3] == 0 ); - REQUIRE( d.n_cols == 3 ); - REQUIRE( d.n_rows == 4 ); - REQUIRE( d.n_elem == 12 ); - REQUIRE( d.n_nonzero == 0 ); - - // Now zero it out again. - d = m; - d.zeros(10); - - REQUIRE( d.values[0] == 0 ); - REQUIRE( d.row_indices[0] == 0); - REQUIRE( d.col_ptrs[0] == 0 ); - REQUIRE( d.col_ptrs[1] == 0 ); - REQUIRE( d.n_cols == 1 ); - REQUIRE( d.n_rows == 10 ); - REQUIRE( d.n_elem == 10 ); - REQUIRE( d.n_nonzero == 0 ); - - // Now zero it out again. - d = m; - d.zeros(5, 5); - - REQUIRE( d.values[0] == 0 ); - REQUIRE( d.row_indices[0] == 0); - REQUIRE( d.col_ptrs[0] == 0 ); - REQUIRE( d.col_ptrs[1] == 0 ); - REQUIRE( d.col_ptrs[2] == 0 ); - REQUIRE( d.col_ptrs[3] == 0 ); - REQUIRE( d.col_ptrs[4] == 0 ); - REQUIRE( d.col_ptrs[5] == 0 ); - REQUIRE( d.n_cols == 5 ); - REQUIRE( d.n_rows == 5 ); - REQUIRE( d.n_elem == 25 ); - REQUIRE( d.n_nonzero == 0 ); - } - - - -/** - * Check that eye() works. - */ -TEST_CASE("sp_mat_eye_test") - { - SpMat e = eye >(5, 5); - - REQUIRE( e.n_elem == 25 ); - REQUIRE( e.n_rows == 5 ); - REQUIRE( e.n_cols == 5 ); - REQUIRE( e.n_nonzero == 5 ); - - for (uword i = 0; i < 5; i++) - { - for (uword j = 0; j < 5; j++) - { - if (i == j) - REQUIRE( (double) e(i, j) == Approx(1.0) ); - else - REQUIRE( (double) e(i, j) == Approx(1e-5) ); - } - } - - // Just check that these compile and run. - e = eye >(5, 5); - e *= eye >(5, 5); - e %= eye >(5, 5); - e /= eye >(5, 5); - } - -/** - * Check that pow works. - * -TEST_CASE("sp_mat_pow_test") - { - SpMat a(3, 3); - a(0, 2) = 4.3; - a(1, 1) = -5.5; - a(2, 2) = -6.3; - - a += pow(a, 2); - - REQUIRE( (double) a(0, 0) == 0 ); - REQUIRE( (double) a(1, 0) == 0 ); - REQUIRE( (double) a(2, 0) == 0 ); - REQUIRE( (double) a(0, 1) == 0 ); - REQUIRE( (double) a(1, 1) == Approx(24.75) ); - REQUIRE( (double) a(2, 1) == 0 ); - REQUIRE( (double) a(0, 2) == Approx(22.79) ); - REQUIRE( (double) a(1, 2) == 0 ); - REQUIRE( (double) a(2, 2) == Approx(33.39) ); - - a = pow(a, 2); - a *= pow(a, 2); - a %= pow(a, 2); - a /= pow(a, 2); - } -*/ - - -// I hate myself. -#undef TEST_OPERATOR -#define TEST_OPERATOR(EOP_TEST, EOP) \ -TEST_CASE(EOP_TEST) \ - {\ - SpMat a(3, 3);\ - a(0, 2) = 4.3;\ - a(1, 1) = -5.5;\ - a(2, 2) = -6.3;\ - a(1, 0) = 0.001;\ - Mat b(3, 3);\ - b.zeros();\ - b(0, 2) = 4.3;\ - b(1, 1) = -5.5;\ - b(2, 2) = -6.3;\ - b(1, 0) = 0.001;\ - \ - SpMat c = EOP(a);\ - Mat d = EOP(b);\ - \ - if (c(0, 0) == c(0, 0) && d(0, 0) == d(0, 0))\ - REQUIRE( c(0, 0) == d(0, 0) );\ - if (c(1, 0) == c(1, 0) && d(1, 0) == d(1, 0))\ - REQUIRE( c(1, 0) == d(1, 0) );\ - if (c(2, 0) == c(2, 0) && d(2, 0) == d(2, 0))\ - REQUIRE( c(2, 0) == d(2, 0) );\ - if (c(0, 1) == c(0, 1) && d(0, 1) == d(0, 1))\ - REQUIRE( c(0, 1) == d(0, 1) );\ - if (c(1, 1) == c(1, 1) && d(1, 1) == d(1, 1))\ - REQUIRE( c(1, 1) == d(1, 1) );\ - if (c(2, 1) == c(2, 1) && d(2, 1) == d(2, 1))\ - REQUIRE( c(2, 1) == d(2, 1) );\ - if (c(0, 2) == c(0, 2) && d(0, 2) == d(0, 2))\ - REQUIRE( c(0, 2) == d(0, 2) );\ - if (c(1, 2) == c(1, 2) && d(1, 2) == d(1, 2))\ - REQUIRE( c(1, 2) == d(1, 2) );\ - if (c(2, 2) == c(2, 2) && d(2, 2) == d(2, 2))\ - REQUIRE( c(2, 2) == d(2, 2) );\ - \ - c -= EOP(a);\ - d -= EOP(b);\ - \ - if (c(0, 0) == c(0, 0) && d(0, 0) == d(0, 0))\ - REQUIRE( c(0, 0) == d(0, 0) );\ - if (c(1, 0) == c(1, 0) && d(1, 0) == d(1, 0))\ - REQUIRE( c(1, 0) == d(1, 0) );\ - if (c(2, 0) == c(2, 0) && d(2, 0) == d(2, 0))\ - REQUIRE( c(2, 0) == d(2, 0) );\ - if (c(0, 1) == c(0, 1) && d(0, 1) == d(0, 1))\ - REQUIRE( c(0, 1) == d(0, 1) );\ - if (c(1, 1) == c(1, 1) && d(1, 1) == d(1, 1))\ - REQUIRE( c(1, 1) == d(1, 1) );\ - if (c(2, 1) == c(2, 1) && d(2, 1) == d(2, 1))\ - REQUIRE( c(2, 1) == d(2, 1) );\ - if (c(0, 2) == c(0, 2) && d(0, 2) == d(0, 2))\ - REQUIRE( c(0, 2) == d(0, 2) );\ - if (c(1, 2) == c(1, 2) && d(1, 2) == d(1, 2))\ - REQUIRE( c(1, 2) == d(1, 2) );\ - if (c(2, 2) == c(2, 2) && d(2, 2) == d(2, 2))\ - REQUIRE( c(2, 2) == d(2, 2) );\ - \ - c %= EOP(a);\ - d %= EOP(b);\ - \ - if (c(0, 0) == c(0, 0) && d(0, 0) == d(0, 0))\ - REQUIRE( c(0, 0) == d(0, 0) );\ - if (c(1, 0) == c(1, 0) && d(1, 0) == d(1, 0))\ - REQUIRE( c(1, 0) == d(1, 0) );\ - if (c(2, 0) == c(2, 0) && d(2, 0) == d(2, 0))\ - REQUIRE( c(2, 0) == d(2, 0) );\ - if (c(0, 1) == c(0, 1) && d(0, 1) == d(0, 1))\ - REQUIRE( c(0, 1) == d(0, 1) );\ - if (c(1, 1) == c(1, 1) && d(1, 1) == d(1, 1))\ - REQUIRE( c(1, 1) == d(1, 1) );\ - if (c(2, 1) == c(2, 1) && d(2, 1) == d(2, 1))\ - REQUIRE( c(2, 1) == d(2, 1) );\ - if (c(0, 2) == c(0, 2) && d(0, 2) == d(0, 2))\ - REQUIRE( c(0, 2) == d(0, 2) );\ - if (c(1, 2) == c(1, 2) && d(1, 2) == d(1, 2))\ - REQUIRE( c(1, 2) == d(1, 2) );\ - if (c(2, 2) == c(2, 2) && d(2, 2) == d(2, 2))\ - REQUIRE( c(2, 2) == d(2, 2) );\ - \ - c *= EOP(a);\ - d *= EOP(b);\ - \ - if (c(0, 0) == c(0, 0) && d(0, 0) == d(0, 0))\ - REQUIRE( c(0, 0) == d(0, 0) );\ - if (c(1, 0) == c(1, 0) && d(1, 0) == d(1, 0))\ - REQUIRE( c(1, 0) == d(1, 0) );\ - if (c(2, 0) == c(2, 0) && d(2, 0) == d(2, 0))\ - REQUIRE( c(2, 0) == d(2, 0) );\ - if (c(0, 1) == c(0, 1) && d(0, 1) == d(0, 1))\ - REQUIRE( c(0, 1) == d(0, 1) );\ - if (c(1, 1) == c(1, 1) && d(1, 1) == d(1, 1))\ - REQUIRE( c(1, 1) == d(1, 1) );\ - if (c(2, 1) == c(2, 1) && d(2, 1) == d(2, 1))\ - REQUIRE( c(2, 1) == d(2, 1) );\ - if (c(0, 2) == c(0, 2) && d(0, 2) == d(0, 2))\ - REQUIRE( c(0, 2) == d(0, 2) );\ - if (c(1, 2) == c(1, 2) && d(1, 2) == d(1, 2))\ - REQUIRE( c(1, 2) == d(1, 2) );\ - if (c(2, 2) == c(2, 2) && d(2, 2) == d(2, 2))\ - REQUIRE( c(2, 2) == d(2, 2) );\ - \ - c /= EOP(a);\ - d /= EOP(b);\ - \ - if (c(0, 0) == c(0, 0) && d(0, 0) == d(0, 0))\ - REQUIRE( c(0, 0) == d(0, 0) );\ - if (c(1, 0) == c(1, 0) && d(1, 0) == d(1, 0))\ - REQUIRE( c(1, 0) == d(1, 0) );\ - if (c(2, 0) == c(2, 0) && d(2, 0) == d(2, 0))\ - REQUIRE( c(2, 0) == d(2, 0) );\ - if (c(0, 1) == c(0, 1) && d(0, 1) == d(0, 1))\ - REQUIRE( c(0, 1) == d(0, 1) );\ - if (c(1, 1) == c(1, 1) && d(1, 1) == d(1, 1))\ - REQUIRE( c(1, 1) == d(1, 1) );\ - if (c(2, 1) == c(2, 1) && d(2, 1) == d(2, 1))\ - REQUIRE( c(2, 1) == d(2, 1) );\ - if (c(0, 2) == c(0, 2) && d(0, 2) == d(0, 2))\ - REQUIRE( c(0, 2) == d(0, 2) );\ - if (c(1, 2) == c(1, 2) && d(1, 2) == d(1, 2))\ - REQUIRE( c(1, 2) == d(1, 2) );\ - if (c(2, 2) == c(2, 2) && d(2, 2) == d(2, 2))\ - REQUIRE( c(2, 2) == d(2, 2) );\ - } - -// Now run all the operators... -TEST_OPERATOR("sp_mat_abs_test", abs) -//TEST_OPERATOR("sp_mat_eps_test", eps); -//TEST_OPERATOR(expTest, exp); -//TEST_OPERATOR(exp2Test, exp2); -//TEST_OPERATOR(exp10Test, exp10); -//TEST_OPERATOR(trunc_expTest, trunc_exp); -//TEST_OPERATOR(logTest, log); -//TEST_OPERATOR(log2Test, log2); -//TEST_OPERATOR(log10Test, log10); -//TEST_OPERATOR(trunc_logTest, trunc_log); -TEST_OPERATOR("sp_mat_sqrt_test", sqrt) -TEST_OPERATOR("sp_mat_square_test", square) -TEST_OPERATOR("sp_mat_floor_test", floor) -TEST_OPERATOR("sp_mat_ceil_test", ceil) -//TEST_OPERATOR(cosTest, cos); -//TEST_OPERATOR(acosTest, acos); -//TEST_OPERATOR(coshTest, cosh); -//TEST_OPERATOR(acoshTest, acosh); -//TEST_OPERATOR(sinTest, sin); -//TEST_OPERATOR(asinTest, asin); -//TEST_OPERATOR(sinhTest, sinh); -//TEST_OPERATOR(asinhTest, asinh); -//TEST_OPERATOR(tanTest, tan); -//TEST_OPERATOR(tanhTest, tanh); -//TEST_OPERATOR(atanTest, atan); -//TEST_OPERATOR(atanhTest, atanh); - -/* -TEST_CASE("spmat_diskio_tests") - { - std::string file_names[] = {"raw_ascii.txt", - "raw_binary.bin", - "arma_ascii.csv", - "csv_ascii.csv", - "arma_binary.bin", - "pgm_binary.bin", - "coord_ascii.txt"}; - diskio dio; - SpMat m(4, 3); - m(0, 0) = 1; - m(3, 0) = 2; - m(0, 2) = 3; - m(3, 2) = 4; - m(2, 1) = 5; - m(1, 2) = 6; - - // Save the matrix. - REQUIRE( dio.save_raw_ascii(m, file_names[0]) ); -// REQUIRE( dio.save_raw_binary(m, file_names[1]) ); -// REQUIRE( dio.save_arma_ascii(m, file_names[2]) ); -// REQUIRE( dio.save_csv_ascii(m, file_names[3]) ); - REQUIRE( dio.save_arma_binary(m, file_names[4]) ); -// REQUIRE( dio.save_pgm_binary(m, file_names[5]) ); - REQUIRE( dio.save_coord_ascii(m, file_names[6]) ); - - // Load the files. - SpMat lm[7]; - std::string err; - REQUIRE( dio.load_raw_ascii(lm[0], file_names[0], err) ); -// REQUIRE( dio.load_raw_binary(lm[1], file_names[1], err) ); -// REQUIRE( dio.load_arma_ascii(lm[2], file_names[2], err) ); -// REQUIRE( dio.load_csv_ascii(lm[3], file_names[3], err) ); - REQUIRE( dio.load_arma_binary(lm[4], file_names[4], err) ); -// REQUIRE( dio.load_pgm_binary(lm[5], file_names[5], err) ); - REQUIRE( dio.load_coord_ascii(lm[6], file_names[6], err) ); - - // Now make sure all the matrices are identical. - for (uword i = 0; i < 7; i++) - { - for (uword r = 0; r < 4; r++) - { - for (uword c = 0; c < 3; c++) - { - REQUIRE( m(r, c) == lm[i](r, c) ); - } - } - } - - for (uword i = 0; i < 7; ++i) - { - remove(file_names[i].c_str()); - } - } -*/ - - -TEST_CASE("min_test") - { - SpCol a(5); - - a(0) = 3.0; - a(2) = 1.0; - - double res = min(a); - REQUIRE( res == Approx(1e-5) ); - - a(0) = -3.0; - a(2) = -1.0; - - res = min(a); - REQUIRE( res == Approx(-3.0) ); - - a(0) = 1.3; - a(1) = 2.4; - a(2) = 3.1; - a(3) = 4.4; - a(4) = 1.4; - - res = min(a); - REQUIRE( res == Approx(1.3) ); - - SpRow b(5); - - b(0) = 3.0; - b(2) = 1.0; - - res = min(b); - REQUIRE( res == Approx(1e-5) ); - - b(0) = -3.0; - b(2) = -1.0; - - res = min(b); - REQUIRE( res == Approx(-3.0) ); - - b(0) = 1.3; - b(1) = 2.4; - b(2) = 3.1; - b(3) = 4.4; - b(4) = 1.4; - - res = min(b); - REQUIRE( res == Approx(1.3) ); - - SpMat c(6, 5); - - c(0, 0) = 1.0; - c(1, 0) = 3.0; - c(2, 0) = 4.0; - c(3, 0) = 0.6; - c(4, 0) = 1.4; - c(5, 0) = 1.2; - c(3, 2) = 1.3; - c(2, 3) = -4.0; - c(4, 3) = -1.4; - c(5, 2) = -3.4; - c(5, 3) = -4.1; - - SpMat r = min(c, 0); - REQUIRE( r.n_rows == 1 ); - REQUIRE( r.n_cols == 5 ); - REQUIRE( (double) r(0, 0) == Approx(0.6) ); - REQUIRE( (double) r(0, 1) == Approx(1e-5) ); - REQUIRE( (double) r(0, 2) == Approx(-3.4) ); - REQUIRE( (double) r(0, 3) == Approx(-4.1) ); - REQUIRE( (double) r(0, 4) == Approx(1e-5) ); - - r = min(c, 1); - REQUIRE( r.n_rows == 6 ); - REQUIRE( r.n_cols == 1 ); - REQUIRE( (double) r(0, 0) == Approx(1e-5) ); - REQUIRE( (double) r(1, 0) == Approx(1e-5) ); - REQUIRE( (double) r(2, 0) == Approx(-4.0) ); - REQUIRE( (double) r(3, 0) == Approx(1e-5) ); - REQUIRE( (double) r(4, 0) == Approx(-1.4) ); - REQUIRE( (double) r(5, 0) == Approx(-4.1) ); - } - - -TEST_CASE("max_test") - { - SpCol a(5); - - a(0) = -3.0; - a(2) = -1.0; - - double resa = max(a); - REQUIRE( resa == Approx(1e-5) ); - - a(0) = 3.0; - a(2) = 1.0; - - resa = max(a); - REQUIRE( resa == Approx(3.0) ); - - a(0) = -1.3; - a(1) = -2.4; - a(2) = -3.1; - a(3) = -4.4; - a(4) = -1.4; - - resa = max(a); - REQUIRE( resa == Approx(-1.3) ); - - SpRow b(5); - - b(0) = -3.0; - b(2) = -1.0; - - resa = max(b); - REQUIRE( resa == Approx(1e-5) ); - - b(0) = 3.0; - b(2) = 1.0; - - resa = max(b); - REQUIRE( resa == Approx(3.0) ); - - b(0) = -1.3; - b(1) = -2.4; - b(2) = -3.1; - b(3) = -4.4; - b(4) = -1.4; - - resa = max(b); - REQUIRE( resa == Approx(-1.3) ); - - SpMat c(6, 5); - - c(0, 0) = 1.0; - c(1, 0) = 3.0; - c(2, 0) = 4.0; - c(3, 0) = 0.6; - c(4, 0) = -1.4; - c(5, 0) = 1.2; - c(3, 2) = 1.3; - c(2, 3) = -4.0; - c(4, 3) = -1.4; - c(5, 2) = -3.4; - c(5, 3) = -4.1; - - SpMat res = max(c, 0); - REQUIRE( res.n_rows == 1 ); - REQUIRE( res.n_cols == 5 ); - REQUIRE( (double) res(0, 0) == Approx(4.0) ); - REQUIRE( (double) res(0, 1) == Approx(1e-5) ); - REQUIRE( (double) res(0, 2) == Approx(1.3) ); - REQUIRE( (double) res(0, 3) == Approx(1e-5) ); - REQUIRE( (double) res(0, 4) == Approx(1e-5) ); - - res = max(c, 1); - REQUIRE( res.n_rows == 6 ); - REQUIRE( res.n_cols == 1 ); - REQUIRE( (double) res(0, 0) == Approx(1.0) ); - REQUIRE( (double) res(1, 0) == Approx(3.0) ); - REQUIRE( (double) res(2, 0) == Approx(4.0) ); - REQUIRE( (double) res(3, 0) == Approx(1.3) ); - REQUIRE( (double) res(4, 0) == Approx(1e-5) ); - REQUIRE( (double) res(5, 0) == Approx(1.2) ); - } - - -TEST_CASE("spmat_min_cx_test") -{ - SpCol > a(5); - - a(0) = std::complex(3.0, -2.0); - a(2) = std::complex(1.0, 1.0); - - std::complex res = min(a); - REQUIRE( res.real() == Approx(1e-5) ); - REQUIRE( res.imag() == Approx(1e-5) ); - - a(0) = std::complex(-3.0, -2.0); - a(2) = std::complex(-1.0, -1.0); - - res = min(a); - REQUIRE( res.real() == Approx(1e-5) ); - REQUIRE( res.imag() == Approx(1e-5) ); - - a(0) = std::complex(1.0, 0.5); - a(1) = std::complex(2.4, 1.4); - a(2) = std::complex(0.5, 0.5); - a(3) = std::complex(2.0, 2.0); - a(4) = std::complex(1.4, -1.4); - - res = min(a); - REQUIRE( res.real() == Approx(0.5) ); - REQUIRE( res.imag() == Approx(0.5) ); - - SpRow > b(5); - - b(0) = std::complex(3.0, -2.0); - b(2) = std::complex(1.0, 1.0); - - res = min(b); - REQUIRE( res.real() == Approx(1e-5) ); - REQUIRE( res.imag() == Approx(1e-5) ); - - b(0) = std::complex(-3.0, -2.0); - b(2) = std::complex(-1.0, -1.0); - - res = min(b); - REQUIRE( res.real() == Approx(1e-5) ); - REQUIRE( res.imag() == Approx(1e-5) ); - - b(0) = std::complex(1.0, 0.5); - b(1) = std::complex(2.4, 1.4); - b(2) = std::complex(0.5, 0.5); - b(3) = std::complex(2.0, 2.0); - b(4) = std::complex(1.4, -1.4); - - res = min(b); - REQUIRE( res.real() == Approx(0.5) ); - REQUIRE( res.imag() == Approx(0.5) ); - - SpMat > c(4, 3); - - c(0, 0) = std::complex(1.0, 2.0); - c(0, 1) = std::complex(0.5, 0.5); - c(0, 2) = std::complex(2.0, 4.0); - c(1, 1) = std::complex(-1.0, -2.0); - c(2, 1) = std::complex(-3.0, -3.0); - c(3, 1) = std::complex(0.25, 0.25); - - SpMat > r = min(c, 0); - REQUIRE( r.n_rows == 1 ); - REQUIRE( r.n_cols == 3 ); - REQUIRE( ((std::complex) r(0, 0)).real() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(0, 0)).imag() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(0, 1)).real() == Approx(0.25) ); - REQUIRE( ((std::complex) r(0, 1)).imag() == Approx(0.25) ); - REQUIRE( ((std::complex) r(0, 2)).real() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(0, 2)).imag() == Approx(1e-5) ); - - r = min(c, 1); - REQUIRE( r.n_rows == 4 ); - REQUIRE( r.n_cols == 1 ); - REQUIRE( ((std::complex) r(0, 0)).real() == Approx(0.5) ); - REQUIRE( ((std::complex) r(0, 0)).imag() == Approx(0.5) ); - REQUIRE( ((std::complex) r(1, 0)).real() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(1, 0)).imag() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(2, 0)).real() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(2, 0)).imag() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(3, 0)).real() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(3, 0)).imag() == Approx(1e-5) ); -} - - - -TEST_CASE("spmat_max_cx_test") -{ - SpCol > a(5); - - a(0) = std::complex(3.0, -2.0); - a(2) = std::complex(1.0, 1.0); - - std::complex res = max(a); - REQUIRE( res.real() == Approx(3.0) ); - REQUIRE( res.imag() == Approx(-2.0) ); - - a(0) = std::complex(0); - a(2) = std::complex(0); - - res = max(a); - REQUIRE( res.real() == Approx(1e-5) ); - REQUIRE( res.imag() == Approx(1e-5) ); - - a(0) = std::complex(1.0, 0.5); - a(1) = std::complex(2.4, 1.4); - a(2) = std::complex(0.5, 0.5); - a(3) = std::complex(2.0, 2.0); - a(4) = std::complex(1.4, -1.4); - - res = max(a); - REQUIRE( res.real() == Approx(2.0) ); - REQUIRE( res.imag() == Approx(2.0) ); - - SpRow > b(5); - - b(0) = std::complex(3.0, -2.0); - b(2) = std::complex(1.0, 1.0); - - res = max(b); - REQUIRE( res.real() == Approx(3.0) ); - REQUIRE( res.imag() == Approx(-2.0) ); - - b(0) = std::complex(0); - b(2) = std::complex(0); - - res = max(b); - REQUIRE( res.real() == Approx(1e-5) ); - REQUIRE( res.imag() == Approx(1e-5) ); - - b(0) = std::complex(1.0, 0.5); - b(1) = std::complex(2.4, 1.4); - b(2) = std::complex(0.5, 0.5); - b(3) = std::complex(2.0, 2.0); - b(4) = std::complex(1.4, -1.4); - - res = max(b); - REQUIRE( res.real() == Approx(2.0) ); - REQUIRE( res.imag() == Approx(2.0) ); - - SpMat > c(4, 3); - - c(0, 0) = std::complex(1.0, 2.0); - c(0, 1) = std::complex(0.5, 0.5); - c(1, 1) = std::complex(-1.0, -2.0); - c(2, 1) = std::complex(-3.0, -3.0); - c(3, 1) = std::complex(0.25, 0.25); - - SpMat > r = max(c, 0); - REQUIRE( r.n_rows == 1 ); - REQUIRE( r.n_cols == 3 ); - REQUIRE( ((std::complex) r(0, 0)).real() == Approx(1.0) ); - REQUIRE( ((std::complex) r(0, 0)).imag() == Approx(2.0) ); - REQUIRE( ((std::complex) r(0, 1)).real() == Approx(-3.0) ); - REQUIRE( ((std::complex) r(0, 1)).imag() == Approx(-3.0) ); - REQUIRE( ((std::complex) r(0, 2)).real() == Approx(1e-5) ); - REQUIRE( ((std::complex) r(0, 2)).imag() == Approx(1e-5) ); - - r = max(c, 1); - REQUIRE( r.n_rows == 4 ); - REQUIRE( r.n_cols == 1 ); - REQUIRE( ((std::complex) r(0, 0)).real() == Approx(1.0) ); - REQUIRE( ((std::complex) r(0, 0)).imag() == Approx(2.0) ); - REQUIRE( ((std::complex) r(1, 0)).real() == Approx(-1.0) ); - REQUIRE( ((std::complex) r(1, 0)).imag() == Approx(-2.0) ); - REQUIRE( ((std::complex) r(2, 0)).real() == Approx(-3.0) ); - REQUIRE( ((std::complex) r(2, 0)).imag() == Approx(-3.0) ); - REQUIRE( ((std::complex) r(3, 0)).real() == Approx(0.25) ); - REQUIRE( ((std::complex) r(3, 0)).imag() == Approx(0.25) ); - } - - - -TEST_CASE("spmat_complex_constructor_test") - { - // First make two sparse matrices. - SpMat a(8, 10); - SpMat b(8, 10); - - a(0, 0) = 4; - a(4, 2) = 5; - a(5, 3) = 6; - a(6, 3) = 7; - a(1, 4) = 1; - a(5, 4) = 6; - a(7, 6) = 3; - a(0, 7) = 2; - a(3, 7) = 3; - - b(0, 0) = 4; - b(4, 2) = 5; - b(7, 3) = 4; - b(1, 4) = 1; - b(3, 4) = 6; - b(5, 4) = -1; - b(6, 4) = 2; - b(7, 4) = 3; - b(6, 5) = 2; - b(6, 6) = 3; - b(3, 7) = 4; - b(6, 7) = 5; - - SpMat > c(a, b); - - REQUIRE( c.n_nonzero == 16 ); - REQUIRE( (std::complex) c(0, 0) == std::complex(4, 4) ); - REQUIRE( (std::complex) c(4, 2) == std::complex(5, 5) ); - REQUIRE( (std::complex) c(5, 3) == std::complex(6, 0) ); - REQUIRE( (std::complex) c(6, 3) == std::complex(7, 0) ); - REQUIRE( (std::complex) c(7, 3) == std::complex(0, 4) ); - REQUIRE( (std::complex) c(1, 4) == std::complex(1, 1) ); - REQUIRE( (std::complex) c(3, 4) == std::complex(0, 6) ); - REQUIRE( (std::complex) c(5, 4) == std::complex(6, -1) ); - REQUIRE( (std::complex) c(6, 4) == std::complex(0, 2) ); - REQUIRE( (std::complex) c(7, 4) == std::complex(0, 3) ); - REQUIRE( (std::complex) c(6, 5) == std::complex(0, 2) ); - REQUIRE( (std::complex) c(6, 6) == std::complex(0, 3) ); - REQUIRE( (std::complex) c(7, 6) == std::complex(3, 0) ); - REQUIRE( (std::complex) c(0, 7) == std::complex(2, 0) ); - REQUIRE( (std::complex) c(3, 7) == std::complex(3, 4) ); - REQUIRE( (std::complex) c(6, 7) == std::complex(0, 5) ); - } - - - -TEST_CASE("spmat_unary_operators_test") - { - SpMat a(3, 3); - SpMat b(3, 3); - - a(0, 0) = 1; - a(1, 2) = 4; - a(2, 2) = 5; - - b(0, 1) = 1; - b(1, 0) = 2; - b(1, 2) = -4; - b(2, 2) = 5; - - SpMat c = a + b; - - REQUIRE( c.n_nonzero == 4 ); - - REQUIRE( (double) c(0, 0) == 1 ); - REQUIRE( (double) c(1, 0) == 2 ); - REQUIRE( (double) c(2, 0) == 0 ); - REQUIRE( (double) c(0, 1) == 1 ); - REQUIRE( (double) c(1, 1) == 0 ); - REQUIRE( (double) c(2, 1) == 0 ); - REQUIRE( (double) c(0, 2) == 0 ); - REQUIRE( (double) c(1, 2) == 0 ); - REQUIRE( (double) c(2, 2) == 10 ); - - c = a - b; - - REQUIRE( c.n_nonzero == 4 ); - - REQUIRE( (double) c(0, 0) == 1 ); - REQUIRE( (double) c(1, 0) == -2 ); - REQUIRE( (double) c(2, 0) == 0 ); - REQUIRE( (double) c(0, 1) == -1 ); - REQUIRE( (double) c(1, 1) == 0 ); - REQUIRE( (double) c(2, 1) == 0 ); - REQUIRE( (double) c(0, 2) == 0 ); - REQUIRE( (double) c(1, 2) == 8 ); - REQUIRE( (double) c(2, 2) == 0 ); - - c = a % b; - - REQUIRE( c.n_nonzero == 2 ); - - REQUIRE( (double) c(0, 0) == 0 ); - REQUIRE( (double) c(1, 0) == 0 ); - REQUIRE( (double) c(2, 0) == 0 ); - REQUIRE( (double) c(0, 1) == 0 ); - REQUIRE( (double) c(1, 1) == 0 ); - REQUIRE( (double) c(2, 1) == 0 ); - REQUIRE( (double) c(0, 2) == 0 ); - REQUIRE( (double) c(1, 2) == -16 ); - REQUIRE( (double) c(2, 2) == 25 ); - - a(0, 0) = 4; - b(0, 0) = 2; -/* - c = a / b; - - REQUIRE( c.n_nonzero == 3 ); - - REQUIRE( (double) c(0, 0) == 2 ); - REQUIRE( (double) c(1, 0) == 0 ); - REQUIRE( (double) c(2, 0) == 0 ); - REQUIRE( (double) c(0, 1) == 0 ); - REQUIRE( (double) c(1, 1) == 0 ); - REQUIRE( (double) c(2, 1) == 0 ); - REQUIRE( (double) c(0, 2) == 0 ); - REQUIRE( (double) c(1, 2) == -1 ); - REQUIRE( (double) c(2, 2) == 1 ); -*/ - } - - - -TEST_CASE("spmat_unary_val_operators_test") - { - SpMat a(2, 2); - - a(0, 0) = 2.0; - a(1, 1) = -3.0; - - SpMat b = a * 3.0; - - REQUIRE( b.n_nonzero == 2 ); - REQUIRE( (double) b(0, 0) == Approx(6.0) ); - REQUIRE( (double) b(0, 1) == Approx(1e-5) ); - REQUIRE( (double) b(1, 0) == Approx(1e-5) ); - REQUIRE( (double) b(1, 1) == Approx(-9.0) ); - - b = a / 3.0; - - REQUIRE( b.n_nonzero == 2 ); - REQUIRE( (double) b(0, 0) == Approx(2.0 / 3.0) ); - REQUIRE( (double) b(0, 1) == Approx(1e-5) ); - REQUIRE( (double) b(1, 0) == Approx(1e-5) ); - REQUIRE( (double) b(1, 1) == Approx(-1.0) ); - } - - -TEST_CASE("spmat_sparse_unary_multiplication_test") - { - SpMat spaa(10, 10); - spaa(1, 5) = 0.4; - spaa(0, 4) = 0.3; - spaa(0, 8) = 1.2; - spaa(3, 0) = 1.1; - spaa(3, 1) = 1.1; - spaa(3, 2) = 1.1; - spaa(4, 4) = 0.2; - spaa(4, 9) = 0.1; - spaa(6, 2) = 4.1; - spaa(6, 8) = 4.1; - spaa(7, 5) = 1.0; - spaa(8, 9) = 0.4; - spaa(9, 4) = 0.4; - - double correctResultB[10][10] = - {{ 0.00, 0.00, 0.00, 0.00, 0.06, 0.00, 0.00, 0.00, 0.00, 0.51 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.33, 0.44, 0.00, 0.00, 1.32, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.08, 0.00, 0.00, 0.00, 0.00, 0.02 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 1.64 }, - { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.16, 0.00, 0.00, 0.00, 0.00, 0.00 }, - { 0.00, 0.00, 0.00, 0.00, 0.08, 0.00, 0.00, 0.00, 0.00, 0.04 }}; - - SpMat spab = spaa * spaa; - - for (uword i = 0; i < 10; i++) - { - for (uword j = 0; j < 10; j++) - { - REQUIRE( (double) spab(i, j) == Approx(correctResultB[i][j]) ); - } - } - - SpMat spac(15, 15); - spac(6, 10) = 0.4; - spac(5, 9) = 0.3; - spac(5, 13) = 1.2; - spac(8, 5) = 1.1; - spac(8, 6) = 1.1; - spac(8, 7) = 1.1; - spac(9, 9) = 0.2; - spac(9, 14) = 0.1; - spac(11, 7) = 4.1; - spac(11, 13) = 4.1; - spac(12, 10) = 1.0; - spac(13, 14) = 0.4; - spac(14, 9) = 0.4; - - spab = spaa * spac.submat(5, 5, 14, 14); - - for (uword i = 0; i < 10; i++) - { - for (uword j = 0; j < 10; j++) - { - REQUIRE( (double) spab(i, j) == Approx(correctResultB[i][j]) ); - } - } - } - - - -TEST_CASE("spmat_unary_operator_test_2") - { - SpMat a(3, 3); - a(0, 0) = 1; - a(0, 2) = 3.5; - a(1, 2) = 4.0; - a(2, 2) = -3.0; - - mat b(3, 3); - b.fill(3.0); - - mat c = a + b; - - REQUIRE( c(0, 0) == Approx(4.0) ); - REQUIRE( c(1, 0) == Approx(3.0) ); - REQUIRE( c(2, 0) == Approx(3.0) ); - REQUIRE( c(0, 1) == Approx(3.0) ); - REQUIRE( c(1, 1) == Approx(3.0) ); - REQUIRE( c(2, 1) == Approx(3.0) ); - REQUIRE( c(0, 2) == Approx(6.5) ); - REQUIRE( c(1, 2) == Approx(7.0) ); - REQUIRE( c(2, 2) == Approx(1e-5) ); - - c = a - b; - - REQUIRE( c(0, 0) == Approx(-2.0) ); - REQUIRE( c(1, 0) == Approx(-3.0) ); - REQUIRE( c(2, 0) == Approx(-3.0) ); - REQUIRE( c(0, 1) == Approx(-3.0) ); - REQUIRE( c(1, 1) == Approx(-3.0) ); - REQUIRE( c(2, 1) == Approx(-3.0) ); - REQUIRE( c(0, 2) == Approx(0.5) ); - REQUIRE( c(1, 2) == Approx(1.0) ); - REQUIRE( c(2, 2) == Approx(-6.0) ); - - SpMat d = a % b; - - REQUIRE( d.n_nonzero == 4 ); - REQUIRE( (double) d(0, 0) == Approx(3.0) ); - REQUIRE( (double) d(1, 0) == Approx(1e-5) ); - REQUIRE( (double) d(2, 0) == Approx(1e-5) ); - REQUIRE( (double) d(0, 1) == Approx(1e-5) ); - REQUIRE( (double) d(1, 1) == Approx(1e-5) ); - REQUIRE( (double) d(2, 1) == Approx(1e-5) ); - REQUIRE( (double) d(0, 2) == Approx(10.5) ); - REQUIRE( (double) d(1, 2) == Approx(12.0) ); - REQUIRE( (double) d(2, 2) == Approx(-9.0) ); - - d = a / b; - - REQUIRE( d.n_nonzero == 4 ); - REQUIRE( (double) d(0, 0) == Approx((1.0 / 3.0)) ); - REQUIRE( (double) d(1, 0) == Approx(1e-5) ); - REQUIRE( (double) d(2, 0) == Approx(1e-5) ); - REQUIRE( (double) d(0, 1) == Approx(1e-5) ); - REQUIRE( (double) d(1, 1) == Approx(1e-5) ); - REQUIRE( (double) d(2, 1) == Approx(1e-5) ); - REQUIRE( (double) d(0, 2) == Approx((3.5 / 3.0)) ); - REQUIRE( (double) d(1, 2) == Approx((4.0 / 3.0)) ); - REQUIRE( (double) d(2, 2) == Approx(-1.0) ); - - c = a * b; - - REQUIRE( (double) c(0, 0) == Approx(13.5) ); - REQUIRE( (double) c(1, 0) == Approx(12.0) ); - REQUIRE( (double) c(2, 0) == Approx(-9.0) ); - REQUIRE( (double) c(0, 1) == Approx(13.5) ); - REQUIRE( (double) c(1, 1) == Approx(12.0) ); - REQUIRE( (double) c(2, 1) == Approx(-9.0) ); - REQUIRE( (double) c(0, 2) == Approx(13.5) ); - REQUIRE( (double) c(1, 2) == Approx(12.0) ); - REQUIRE( (double) c(2, 2) == Approx(-9.0) ); - - c = b * a; - - REQUIRE( (double) c(0, 0) == Approx(3.0) ); - REQUIRE( (double) c(1, 0) == Approx(3.0) ); - REQUIRE( (double) c(2, 0) == Approx(3.0) ); - REQUIRE( (double) c(0, 1) == Approx(1e-5) ); - REQUIRE( (double) c(1, 1) == Approx(1e-5) ); - REQUIRE( (double) c(2, 1) == Approx(1e-5) ); - REQUIRE( (double) c(0, 2) == Approx(13.5) ); - REQUIRE( (double) c(1, 2) == Approx(13.5) ); - REQUIRE( (double) c(2, 2) == Approx(13.5) ); - } - - - -TEST_CASE("spmat_mat_operator_tests") - { - SpMat a(3, 3); - a(0, 0) = 2.0; - a(1, 2) = 3.5; - a(2, 1) = -2.0; - a(2, 2) = 4.5; - - mat b(3, 3); - b.fill(2.0); - - mat c(b); - - c += a; - - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(1e-5) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.5) ); - REQUIRE( (double) c(2, 2) == Approx(6.5) ); - - c = b + a; - - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(1e-5) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.5) ); - REQUIRE( (double) c(2, 2) == Approx(6.5) ); - - c = b; - c -= a; - - REQUIRE( (double) c(0, 0) == Approx(1e-5) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(4.0) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(-1.5) ); - REQUIRE( (double) c(2, 2) == Approx(-2.5) ); - - c = b - a; - - REQUIRE( (double) c(0, 0) == Approx(1e-5) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(4.0) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(-1.5) ); - REQUIRE( (double) c(2, 2) == Approx(-2.5) ); - - c = b; - c *= a; - - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(4.0) ); - REQUIRE( (double) c(2, 0) == Approx(4.0) ); - REQUIRE( (double) c(0, 1) == Approx(-4.0) ); - REQUIRE( (double) c(1, 1) == Approx(-4.0) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(0, 2) == Approx(16.0) ); - REQUIRE( (double) c(1, 2) == Approx(16.0) ); - REQUIRE( (double) c(2, 2) == Approx(16.0) ); - - mat e = b * a; - - REQUIRE( (double) e(0, 0) == Approx(4.0) ); - REQUIRE( (double) e(1, 0) == Approx(4.0) ); - REQUIRE( (double) e(2, 0) == Approx(4.0) ); - REQUIRE( (double) e(0, 1) == Approx(-4.0) ); - REQUIRE( (double) e(1, 1) == Approx(-4.0) ); - REQUIRE( (double) e(2, 1) == Approx(-4.0) ); - REQUIRE( (double) e(0, 2) == Approx(16.0) ); - REQUIRE( (double) e(1, 2) == Approx(16.0) ); - REQUIRE( (double) e(2, 2) == Approx(16.0) ); - - c = b; - c %= a; - - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(1e-5) ); - REQUIRE( (double) c(2, 0) == Approx(1e-5) ); - REQUIRE( (double) c(0, 1) == Approx(1e-5) ); - REQUIRE( (double) c(1, 1) == Approx(1e-5) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(0, 2) == Approx(1e-5) ); - REQUIRE( (double) c(1, 2) == Approx(7.0) ); - REQUIRE( (double) c(2, 2) == Approx(9.0) ); - - SpMat d = b % a; - - REQUIRE( d.n_nonzero == 4 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(1, 2) == Approx(7.0) ); - REQUIRE( (double) c(2, 2) == Approx(9.0) ); - - c = b; - c /= a; - - REQUIRE( c(0, 0) == Approx(1.0) ); - REQUIRE( std::isinf(c(1, 0)) ); - REQUIRE( std::isinf(c(2, 0)) ); - REQUIRE( std::isinf(c(0, 1)) ); - REQUIRE( std::isinf(c(1, 1)) ); - REQUIRE( c(2, 1) == Approx(-1.0) ); - REQUIRE( std::isinf(c(0, 2)) ); - REQUIRE( c(1, 2) == Approx(2.0 / 3.5) ); - REQUIRE( c(2, 2) == Approx(2.0 / 4.5) ); - } - - -TEST_CASE("spmat_empty_hadamard") - { - SpMat x(5, 5), y(5, 5), z; - - z = x % y; - - REQUIRE( z.n_nonzero == 0 ); - REQUIRE( z.n_rows == 5 ); - REQUIRE( z.n_cols == 5 ); - } - - - -TEST_CASE("spmat_sparse_dense_in_place") - { - SpMat a; - a.sprandu(50, 50, 0.1); - mat b; - b.randu(50, 50); - mat d( a); - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) a(r, c) != 0) - REQUIRE( (double) a(r, c) == Approx(d(r, c)) ); - else - REQUIRE( d(r, c) == Approx(1e-5) ); - } - } - - SpMat x; - mat y; - - x = a; - y = d; - - x *= b; - y *= b; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) a(r, c) != 0) - REQUIRE( (double) a(r, c) == Approx(d(r, c)) ); - else - REQUIRE( d(r, c) == Approx(1e-5) ); - } - } - - x = a; - y = d; - - x /= b; - y /= b; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) a(r, c) != 0) - REQUIRE( (double) a(r, c) == Approx(d(r, c)) ); - else - REQUIRE( d(r, c) == Approx(1e-5) ); - } - } - - x = a; - y = d; - - x %= b; - y %= b; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) a(r, c) != 0) - REQUIRE( (double) a(r, c) == Approx(d(r, c)) ); - else - REQUIRE(d(r, c) == Approx(1e-5) ); - } - } - } - - - -TEST_CASE("spmat_sparse_dense_not_in_place") - { - SpMat a; - a.sprandu(50, 50, 0.1); - mat b; - b.randu(50, 50); - mat d(a); - - SpMat x; - mat y; - mat z; - - y = a + b; - z = d + b; - - for (uword c = 0; c < 50; ++c) - { - for(uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - - y = a - b; - z = d - b; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - - y = a * b; - z = d * b; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - - y = a % b; - z = d % b; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - - y = a / b; - z = d / b; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - - y = b + a; - z = b + d; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - - y = b - a; - z = b - d; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - - y = b * a; - z = b * d; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - - y = b % a; - z = b % d; - - for (uword c = 0; c < 50; ++c) - { - for (uword r = 0; r < 50; ++r) - { - if ((double) y(r, c) != 0) - REQUIRE( (double) y(r, c) == Approx(z(r, c)) ); - else - REQUIRE( z(r, c) == Approx(1e-5) ); - } - } - } - - - -TEST_CASE("spmat_batch_insert_test") - { - Mat locations(2, 5); - locations(1, 0) = 1; - locations(0, 0) = 2; - locations(1, 1) = 1; - locations(0, 1) = 7; - locations(1, 2) = 4; - locations(0, 2) = 0; - locations(1, 3) = 4; - locations(0, 3) = 9; - locations(1, 4) = 5; - locations(0, 4) = 0; - - Col values(5); - values[0] = 1.5; - values[1] = -15.15; - values[2] = 2.2; - values[3] = 3.0; - values[4] = 5.0; - - SpMat m(locations, values, 10, 10, true); - - REQUIRE( m.n_nonzero == 5 ); - REQUIRE( m.n_rows == 10 ); - REQUIRE( m.n_cols == 10 ); - REQUIRE( (double) m(2, 1) == Approx(1.5) ); - REQUIRE( (double) m(7, 1) == Approx(-15.15) ); - REQUIRE( (double) m(0, 4) == Approx(2.2) ); - REQUIRE( (double) m(9, 4) == Approx(3.0) ); - REQUIRE( (double) m(0, 5) == Approx(5.0) ); - REQUIRE( m.col_ptrs[11] == std::numeric_limits::max() ); - - // Auto size detection. - SpMat n(locations, values, true); - - REQUIRE( n.n_nonzero == 5 ); - REQUIRE( n.n_rows == 10 ); - REQUIRE( n.n_cols == 6 ); - REQUIRE( (double) n(2, 1) == Approx(1.5) ); - REQUIRE( (double) n(7, 1) == Approx(-15.15) ); - REQUIRE( (double) n(0, 4) == Approx(2.2) ); - REQUIRE( (double) n(9, 4) == Approx(3.0) ); - REQUIRE( (double) n(0, 5) == Approx(5.0) ); - REQUIRE( n.col_ptrs[7] == std::numeric_limits::max() ); - } - - - -TEST_CASE("spmat_batch_insert_unsorted_test") - { - Mat locations(2, 5); - locations(1, 0) = 4; - locations(0, 0) = 0; - locations(1, 1) = 1; - locations(0, 1) = 2; - locations(1, 2) = 4; - locations(0, 2) = 9; - locations(1, 3) = 5; - locations(0, 3) = 0; - locations(1, 4) = 1; - locations(0, 4) = 7; - - Col values(5); - values[1] = 1.5; - values[4] = -15.15; - values[0] = 2.2; - values[2] = 3.0; - values[3] = 5.0; - - SpMat m(locations, values, 10, 10, true); - - REQUIRE( m.n_nonzero == 5 ); - REQUIRE( m.n_rows == 10 ); - REQUIRE( m.n_cols == 10 ); - REQUIRE( (double) m(2, 1) == Approx(1.5) ); - REQUIRE( (double) m(7, 1) == Approx(-15.15) ); - REQUIRE( (double) m(0, 4) == Approx(2.2) ); - REQUIRE( (double) m(9, 4) == Approx(3.0) ); - REQUIRE( (double) m(0, 5) == Approx(5.0) ); - - // Auto size detection. - SpMat n(locations, values, true); - - REQUIRE( n.n_nonzero == 5 ); - REQUIRE( n.n_rows == 10 ); - REQUIRE( n.n_cols == 6 ); - REQUIRE( (double) n(2, 1) == Approx(1.5) ); - REQUIRE( (double) n(7, 1) == Approx(-15.15) ); - REQUIRE( (double) n(0, 4) == Approx(2.2) ); - REQUIRE( (double) n(9, 4) == Approx(3.0) ); - REQUIRE( (double) n(0, 5) == Approx(5.0) ); - } - - - -TEST_CASE("spmat_batch_insert_empty_test") - { - Mat locations(2, 0); - Col values; - - SpMat m(locations, values, 10, 10, false); - - REQUIRE( m.n_nonzero == 0 ); - REQUIRE( m.n_rows == 10 ); - REQUIRE( m.n_cols == 10 ); - REQUIRE( m.col_ptrs[11] == std::numeric_limits::max() ); - - SpMat n(locations, values, false); - - REQUIRE( n.n_nonzero == 0 ); - REQUIRE( n.n_rows == 0 ); - REQUIRE( n.n_cols == 0 ); - REQUIRE( n.col_ptrs[1] == std::numeric_limits::max() ); - - SpMat o(locations, values, 10, 10, true); - - REQUIRE( o.n_nonzero == 0 ); - REQUIRE( o.n_rows == 10 ); - REQUIRE( o.n_cols == 10 ); - REQUIRE( o.col_ptrs[11] == std::numeric_limits::max() ); - - SpMat p(locations, values, true); - - REQUIRE( p.n_nonzero == 0 ); - REQUIRE( p.n_rows == 0 ); - REQUIRE( p.n_cols == 0 ); - REQUIRE( p.col_ptrs[1] == std::numeric_limits::max() ); - } - - -// Make sure a matrix is the same as the other one. -template -void CheckMatrices(const T1& a, const T2& b) -{ - REQUIRE( a.n_rows == b.n_rows ); - REQUIRE( a.n_cols == b.n_cols ); - for (uword i = 0; i < a.n_elem; ++i) - REQUIRE( (double) a[i] == Approx((double) b[i]) ); -} - -// Test the constructor written by Dirk. -TEST_CASE("spmat_dirk_constructor_test") - { - // Come up with some values and stuff. - vec values = "4.0 2.0 1.0 3.2 1.2 3.5"; - Col row_indices = "1 3 1 2 4 5"; - Col col_ptrs = "0 2 2 3 4 6"; - - // Ok, now make a matrix. - sp_mat M(row_indices, col_ptrs, values, 6, 5); - - REQUIRE( M.n_nonzero == 6 ); - - // Make the equivalent dense matrix. - mat D(6, 5); - D.fill(0); - D(1, 0) = 4.0; - D(3, 0) = 2.0; - D(1, 2) = 1.0; - D(2, 3) = 3.2; - D(4, 4) = 1.2; - D(5, 4) = 3.5; - - // So now let's just do a bunch of operations and make sure everything is the - // same. - sp_mat dm = M * M.t(); - mat dd = D * D.t(); - - CheckMatrices(dm, dd); - - dm = M.t() * M; - dd = D.t() * D; - - CheckMatrices(dm, dd); - - sp_mat am = M + M; - mat ad = D + D; - - CheckMatrices(am, ad); - - dm = M + D; - ad = D + M; - - CheckMatrices(dm, ad); - } - - - -TEST_CASE("spmat_dirk_constructor_test2") - { - // note the zero at (1,1) - vec values = "4.0 2.0 0.0 1.0 3.2 1.2 3.5"; - uvec row_indices = "1 3 1 1 2 4 5"; - uvec col_ptrs = "0 2 3 4 5 7"; - - // Ok, now make a matrix. - sp_mat M(row_indices, col_ptrs, values, 6, 5); - - REQUIRE( M.n_nonzero == 6 ); - - // Make the equivalent dense matrix. - mat D(6, 5); - D.fill(0); - D(1, 0) = 4.0; - D(3, 0) = 2.0; - D(1, 1) = 0.0; - D(1, 2) = 1.0; - D(2, 3) = 3.2; - D(4, 4) = 1.2; - D(5, 4) = 3.5; - - // So now let's just do a bunch of operations and make sure everything is the - // same. - sp_mat dm = M * M.t(); - mat dd = D * D.t(); - - CheckMatrices(dm, dd); - - dm = M.t() * M; - dd = D.t() * D; - - CheckMatrices(dm, dd); - - sp_mat am = M + M; - mat ad = D + D; - - CheckMatrices(am, ad); - - dm = M + D; - ad = D + M; - - CheckMatrices(dm, ad); - } - - - -TEST_CASE("spmat_clear_test") - { - sp_mat x; - x.sprandu(10, 10, 0.6); - - x.clear(); - - REQUIRE( x.n_cols == 0 ); - REQUIRE( x.n_rows == 0 ); - REQUIRE( x.n_nonzero == 0 ); - } - - - -TEST_CASE("spmat_batch_insert_zeroes_test") - { - Mat locations(2, 5); - locations(1, 0) = 1; - locations(0, 0) = 2; - locations(1, 1) = 1; - locations(0, 1) = 7; - locations(1, 2) = 4; - locations(0, 2) = 0; - locations(1, 3) = 4; - locations(0, 3) = 9; - locations(1, 4) = 5; - locations(0, 4) = 0; - - Col values(5); - values[0] = 1.5; - values[1] = -15.15; - values[2] = 2.2; - values[3] = 0.0; - values[4] = 5.0; - - SpMat m(locations, values, 10, 10, false, true); - - REQUIRE( m.n_nonzero == 4 ); - REQUIRE( m.n_rows == 10 ); - REQUIRE( m.n_cols == 10 ); - REQUIRE( (double) m(2, 1) == Approx(1.5) ); - REQUIRE( (double) m(7, 1) == Approx(-15.15) ); - REQUIRE( (double) m(0, 4) == Approx(2.2) ); - REQUIRE( (double) m(9, 4) == Approx(1e-5) ); - REQUIRE( (double) m(0, 5) == Approx(5.0) ); - - // Auto size detection. - SpMat n(locations, values, false); - - REQUIRE( n.n_nonzero == 4 ); - REQUIRE( n.n_rows == 10 ); - REQUIRE( n.n_cols == 6 ); - REQUIRE( (double) n(2, 1) == Approx(1.5) ); - REQUIRE( (double) n(7, 1) == Approx(-15.15) ); - REQUIRE( (double) n(0, 4) == Approx(2.2) ); - REQUIRE( (double) n(9, 4) == Approx(1e-5) ); - REQUIRE( (double) n(0, 5) == Approx(5.0) ); - } - - - -TEST_CASE("spmat_batch_insert_unsorted_case_zeroes") - { - Mat locations(2, 5); - locations(1, 0) = 4; - locations(0, 0) = 0; - locations(1, 1) = 1; - locations(0, 1) = 2; - locations(1, 2) = 4; - locations(0, 2) = 9; - locations(1, 3) = 5; - locations(0, 3) = 0; - locations(1, 4) = 1; - locations(0, 4) = 7; - - Col values(5); - values[1] = 1.5; - values[4] = -15.15; - values[0] = 2.2; - values[2] = 0.0; - values[3] = 5.0; - - SpMat m(locations, values, 10, 10, true); - - REQUIRE( m.n_nonzero == 4 ); - REQUIRE( m.n_rows == 10 ); - REQUIRE( m.n_cols == 10 ); - REQUIRE( (double) m(2, 1) == Approx(1.5) ); - REQUIRE( (double) m(7, 1) == Approx(-15.15) ); - REQUIRE( (double) m(0, 4) == Approx(2.2) ); - REQUIRE( (double) m(9, 4) == Approx(1e-5) ); - REQUIRE( (double) m(0, 5) == Approx(5.0) ); - REQUIRE( m.col_ptrs[11] == std::numeric_limits::max() ); - - // Auto size detection. - SpMat n(locations, values, true); - - REQUIRE( n.n_nonzero == 4 ); - REQUIRE( n.n_rows == 10 ); - REQUIRE( n.n_cols == 6 ); - REQUIRE( (double) n(2, 1) == Approx(1.5) ); - REQUIRE( (double) n(7, 1) == Approx(-15.15) ); - REQUIRE( (double) n(0, 4) == Approx(2.2) ); - REQUIRE( (double) n(9, 4) == Approx(1e-5) ); - REQUIRE( (double) n(0, 5) == Approx(5.0) ); - REQUIRE( n.col_ptrs[7] == std::numeric_limits::max() ); - } - - - -TEST_CASE("spmat_const_row_col_iterator_test") - { - mat X; - X.zeros(5, 5); - for (uword i = 0; i < 5; ++i) - { - X.col(i) += i; - } - - for (uword i = 0; i < 5; ++i) - { - X.row(i) += 3 * i; - } - - // Make sure default constructor works okay. - mat::const_row_col_iterator it; - // Make sure ++ operator, operator* and comparison operators work fine. - uword count = 0; - for (it = X.begin_row_col(); it != X.end_row_col(); ++it) - { - // Check iterator value. - REQUIRE( *it == (count % 5) * 3 + (count / 5) ); - - // Check iterator position. - REQUIRE( it.row() == count % 5 ); - REQUIRE( it.col() == count / 5 ); - - count++; - } - REQUIRE( count == 25 ); - it = X.end_row_col(); - do - { - --it; - count--; - - // Check iterator value. - REQUIRE( *it == (count % 5) * 3 + (count / 5) ); - - // Check iterator position. - REQUIRE( it.row() == count % 5 ); - REQUIRE( it.col() == count / 5 ); - } while (it != X.begin_row_col()); - - REQUIRE( count == 0 ); - } - - - -TEST_CASE("spmat_row_col_iterator_test") - { - mat X; - X.zeros(5, 5); - for (uword i = 0; i < 5; ++i) - { - X.col(i) += i; - } - - for (uword i = 0; i < 5; ++i) - { - X.row(i) += 3 * i; - } - - // Make sure default constructor works okay. - mat::row_col_iterator it; - // Make sure ++ operator, operator* and comparison operators work fine. - uword count = 0; - for (it = X.begin_row_col(); it != X.end_row_col(); ++it) - { - // Check iterator value. - REQUIRE( *it == (count % 5) * 3 + (count / 5) ); - - // Check iterator position. - REQUIRE( it.row() == count % 5 ); - REQUIRE( it.col() == count / 5 ); - - count++; - } - REQUIRE( count == 25 ); - it = X.end_row_col(); - do - { - --it; - count--; - - // Check iterator value. - REQUIRE( *it == (count % 5) * 3 + (count / 5) ); - - // Check iterator position. - REQUIRE( it.row() == count % 5 ); - REQUIRE( it.col() == count / 5 ); - } while (it != X.begin_row_col()); - - REQUIRE( count == 0 ); - } - - - -TEST_CASE("spmat_const_sprow_col_iterator_test") - { - sp_mat X(5, 5); - for (uword i = 0; i < 5; ++i) - { - X.col(i) += i; - } - - for (uword i = 0; i < 5; ++i) - { - X.row(i) += 3 * i; - } - - // Make sure default constructor works okay. - sp_mat::const_row_col_iterator it; - // Make sure ++ operator, operator* and comparison operators work fine. - uword count = 1; - for (it = X.begin_row_col(); it != X.end_row_col(); ++it) - { - // Check iterator value. - REQUIRE( *it == (count % 5) * 3 + (count / 5) ); - - // Check iterator position. - REQUIRE( it.row() == count % 5 ); - REQUIRE( it.col() == count / 5 ); - - count++; - } - REQUIRE( count == 25 ); - it = X.end_row_col(); - do - { - --it; - count--; - - // Check iterator value. - REQUIRE( *it == (count % 5) * 3 + (count / 5) ); - - // Check iterator position. - REQUIRE( it.row() == count % 5 ); - REQUIRE( it.col() == count / 5 ); - } while (it != X.begin_row_col()); - - REQUIRE( count == 1 ); - } - - - -TEST_CASE("spmat_sprow_col_iterator_test") - { - sp_mat X(5, 5); - for (uword i = 0; i < 5; ++i) - { - X.col(i) += i; - } - - for (uword i = 0; i < 5; ++i) - { - X.row(i) += 3 * i; - } - - // Make sure default constructor works okay. - sp_mat::row_col_iterator it; - // Make sure ++ operator, operator* and comparison operators work fine. - uword count = 1; - for (it = X.begin_row_col(); it != X.end_row_col(); ++it) - { - // Check iterator value. - REQUIRE( *it == (count % 5) * 3 + (count / 5) ); - - // Check iterator position. - REQUIRE( it.row() == count % 5 ); - REQUIRE( it.col() == count / 5 ); - - count++; - } - REQUIRE( count == 25 ); - it = X.end_row_col(); - do - { - --it; - count--; - - // Check iterator value. - REQUIRE( *it == (count % 5) * 3 + (count / 5) ); - - // Check iterator position. - REQUIRE( it.row() == count % 5 ); - REQUIRE( it.col() == count / 5 ); - } while (it != X.begin_row_col()); - - REQUIRE( count == 1 ); - } - - -TEST_CASE("spmat_row_iterator_constructor") - { - // Create a row iterator with an exact position. - Mat tmp = - { { 5.5, 0.0, 0.0 }, - { 0.0, 0.0, 6.5 }, - { 0.0, 7.5, 0.0 } }; - - SpMat X(tmp); - - SpMat::const_row_iterator cri(X, 0, 1); - - // This should end up at (1, 2) with value 6.5. - REQUIRE( cri.row() == 1 ); - REQUIRE( cri.col() == 2 ); - REQUIRE( (*cri) == Approx(6.5) ); - - cri = SpMat::const_row_iterator(X, 0, 0); - - // This should end up at (0, 0) with value 5.5. - REQUIRE( cri.row() == 0 ); - REQUIRE( cri.col() == 0 ); - REQUIRE( (*cri) == Approx(5.5) ); - - cri = SpMat::const_row_iterator(X, 2, 1); - - // This should end up at (2, 1) with value 7.5. - REQUIRE( cri.row() == 2 ); - REQUIRE( cri.col() == 1 ); - REQUIRE( (*cri) == Approx(7.5) ); - } - - -// Check that sparse + scalar works. -TEST_CASE("spmat_scalar_add") - { - sp_mat m; - m.sprandu(100, 200, 0.1); - - mat y = m + 3.0; - mat z = 3.0 + m; - - for (uword i = 0; i < m.n_cols; ++i) - { - for (uword j = 0; j < m.n_rows; ++j) - { - REQUIRE(m(j, i) == Approx(z(j, i) - 3)); - REQUIRE(m(j, i) == Approx(y(j, i) - 3)); - } - } - } - - -// Check that sparse - scalar works. -TEST_CASE("spmat_scalar_minus") - { - sp_mat m; - m.sprandu(100, 200, 0.1); - - mat y = m - 3.0; - mat z = 3.0 - m; - - for (uword i = 0; i < m.n_cols; ++i) - { - for (uword j = 0; j < m.n_rows; ++j) - { - REQUIRE(m(j, i) == Approx(3 - z(j, i))); - REQUIRE(m(j, i) == Approx(y(j, i) + 3)); - } - } - } - - -// Check that sparse / (sparse + eps) works. (and also for (sparse - eps) and (eps - sparse). -TEST_CASE("spmat_div_test") - { - sp_mat m; - m.sprandu(100, 200, 0.1); - - sp_mat m2; - m2.sprandu(100, 200, 0.5); // higher probability of collision - - sp_mat out = m / (m2 + 1.0); - sp_mat out2 = m / (m2 - 2.0); - sp_mat out3 = m / (2.0 - m2); - - REQUIRE(out.n_rows == m.n_rows); - REQUIRE(out.n_cols == m.n_cols); - REQUIRE(out.n_nonzero == m.n_nonzero); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - if (m(r, c) != 0.0) - { - REQUIRE((m(r, c) / (m2(r, c) + 1.0)) == Approx(out(r, c))); - REQUIRE((m(r, c) / (m2(r, c) - 2.0)) == Approx(out2(r, c))); - REQUIRE((m(r, c) / (2.0 - m2(r, c))) == Approx(out3(r, c))); - } - else - { - REQUIRE(out(r, c) == 0.0); - REQUIRE(out2(r, c) == 0.0); - REQUIRE(out3(r, c) == 0.0); - } - } - } - } - - - -// Check that sparse % (sparse + eps) works. (and also for (sparse - eps) and (eps - sparse). -TEST_CASE("spmat_schur_test") - { - sp_mat m; - m.sprandu(100, 200, 0.1); - - sp_mat m2; - m2.sprandu(100, 200, 0.5); // higher probability of collision - - sp_mat out = m % (m2 + 1.0); - sp_mat out2 = m % (m2 - 2.0); - sp_mat out3 = m % (2.0 - m2); - - REQUIRE(out.n_rows == m.n_rows); - REQUIRE(out.n_cols == m.n_cols); - REQUIRE(out.n_nonzero == m.n_nonzero); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - if (m(r, c) != 0.0) - { - REQUIRE((m(r, c) * (m2(r, c) + 1.0)) == Approx(out(r, c))); - REQUIRE((m(r, c) * (m2(r, c) - 2.0)) == Approx(out2(r, c))); - REQUIRE((m(r, c) * (2.0 - m2(r, c))) == Approx(out3(r, c))); - } - else - { - REQUIRE(out(r, c) == 0.0); - REQUIRE(out2(r, c) == 0.0); - REQUIRE(out3(r, c) == 0.0); - } - } - } - } - - - -// Make sure this compiles and works. -TEST_CASE("spmat_repeated_add_subtract") - { - sp_mat m; - m.sprandu(100, 200, 0.1); - - // p: plus, m: minus, n: pre-minus - mat out_pp = m + 3 + 3; - mat out_pm = m + 3 - 3; - mat out_pn = 3 - (m + 3); - mat out_mp = m - 3 + 3; - mat out_mm = m - 3 - 3; - mat out_mn = 3 - (m - 3); - mat out_np = (3 - m) + 3; - mat out_nm = (3 - m) - 3; - mat out_nn = 3 - (3 - m); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - REQUIRE(out_pp(r, c) == Approx(m(r, c) + 6)); - REQUIRE(out_pm(r, c) == Approx(m(r, c))); - REQUIRE(out_pn(r, c) == Approx(-m(r, c))); - REQUIRE(out_mp(r, c) == Approx(m(r, c))); - REQUIRE(out_mm(r, c) == Approx(m(r, c) - 6)); - REQUIRE(out_mn(r, c) == Approx(6 - m(r, c))); - REQUIRE(out_np(r, c) == Approx(6 - m(r, c))); - REQUIRE(out_nm(r, c) == Approx(-m(r, c))); - REQUIRE(out_nn(r, c) == Approx(m(r, c))); - } - } - } - - - -// If we wrap an sp_mat() constructor around a (sparse + plus) it should force -// evaluate into a sparse matrix. -TEST_CASE("spmat_force_plus_minus_sparse") - { - // We can't test that our desired optimization is used but we can test that it - // compiles. - sp_mat m; - m.sprandu(100, 200, 0.1); - - sp_mat out1(m + 1); - sp_mat out2(m - 1); - sp_mat out3(2 - m); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - REQUIRE(out1(r, c) == Approx(m(r, c) + 1)); - REQUIRE(out2(r, c) == Approx(m(r, c) - 1)); - REQUIRE(out3(r, c) == Approx(2 - m(r, c))); - } - } - } - - - -// Test elementwise max(). -TEST_CASE("spmat_elementwise_max") - { - sp_mat m, n; - m.sprandu(100, 200, 0.1); - n.sprandu(100, 200, 0.2); - - sp_mat out = max(m, n); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - REQUIRE(out(r, c) == Approx(std::max((double) m(r, c), (double) n(r, c)))); - } - } - } - - - -// Test elementwise max() with a dense object. -TEST_CASE("spmat_mat_elementwise_max") - { - sp_mat m; - mat n; - m.sprandu(100, 200, 0.1); - n.randu(100, 200); - n -= 0.5; - - mat out1 = max(m, n); - mat out2 = max(n, m); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - REQUIRE(out1(r, c) == Approx(std::max((double) m(r, c), (double) n(r, c)))); - REQUIRE(out2(r, c) == Approx(std::max((double) m(r, c), (double) n(r, c)))); - } - } - } - - - -// Test elementwise complex max(). -TEST_CASE("spmat_elementwise_max_cx") - { - sp_cx_mat m, n; - m.sprandu(100, 200, 0.1); - n.sprandu(100, 200, 0.2); - - sp_cx_mat out = arma::max(m, n); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - if (std::abs(std::complex(m(r, c))) > std::abs(std::complex(n(r, c)))) - REQUIRE(std::abs(std::complex(out(r, c)) - std::complex(m(r, c))) == Approx(0.0)); - else - REQUIRE(std::abs(std::complex(out(r, c)) - std::complex(n(r, c))) == Approx(0.0)); - } - } - } - - - -// Test elementwise min(). -TEST_CASE("spmat_elementwise_min") - { - sp_mat m, n; - m.sprandu(100, 200, 0.1); - n.sprandu(100, 200, 0.2); - - sp_mat out = min(m, n); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - REQUIRE(out(r, c) == Approx(std::min((double) m(r, c), (double) n(r, c)))); - } - } - } - - - -// Test elementwise min() with a dense object. -TEST_CASE("spmat_mat_elementwise_min") - { - sp_mat m; - mat n; - m.sprandu(100, 200, 0.1); - n.randu(100, 200); - n -= 0.5; - - mat out1 = min(m, n); - mat out2 = min(n, m); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - REQUIRE(out1(r, c) == Approx(std::min((double) m(r, c), (double) n(r, c)))); - REQUIRE(out2(r, c) == Approx(std::min((double) m(r, c), (double) n(r, c)))); - } - } - } - - - -// Test elementwise complex min(). -TEST_CASE("spmat_elementwise_min_cx") - { - sp_cx_mat m, n; - m.sprandu(100, 200, 0.1); - n.sprandu(100, 200, 0.2); - - sp_cx_mat out = arma::min(m, n); - - for (uword c = 0; c < m.n_cols; ++c) - { - for (uword r = 0; r < m.n_rows; ++r) - { - if (std::abs(std::complex(m(r, c))) < std::abs(std::complex(n(r, c)))) - REQUIRE(std::abs(std::complex(out(r, c)) - std::complex(m(r, c))) == Approx(0.0)); - else - REQUIRE(std::abs(std::complex(out(r, c)) - std::complex(n(r, c))) == Approx(0.0)); - } - } - } - - -// Test vectorise() on a matrix. -TEST_CASE("spmat_vectorise_matrix") - { - sp_mat m; - m.sprandu(10, 10, 0.1); - - sp_vec c = vectorise(m); - sp_mat d = vectorise(m); - sp_rowvec e = vectorise(m).t(); - - for (uword i = 0; i < c.n_elem; ++i) - { - REQUIRE(c[i] == Approx(m[i])); - REQUIRE(d[i] == Approx(m[i])); - REQUIRE(e[i] == Approx(m[i])); - } - } - - - -// Test vectorise() as an alias. -TEST_CASE("spmat_vectorise_alias") - { - sp_mat m; - m.sprandu(10, 10, 0.1); - - sp_mat n(m); - n = vectorise(n); - - REQUIRE(n.n_rows == 100); - REQUIRE(n.n_cols == 1); - for (uword i = 0; i < n.n_elem; ++i) - { - REQUIRE(n[i] == Approx(m[i])); - } - } - - - -// Test vectorise() with the dimension argument. -TEST_CASE("spmat_vectorise_dimension") - { - sp_mat m; - m.sprandu(10, 10, 0.1); - sp_mat n = m.t(); - - sp_vec c = vectorise(m, 0); - sp_rowvec d = vectorise(m, 1); - sp_rowvec e = vectorise(m.t(), 1); - sp_vec f = vectorise(m.t(), 0); - - for (uword i = 0; i < m.n_elem; ++i) - { - REQUIRE(c[i] == Approx(m[i])); - REQUIRE(d[i] == Approx(n[i])); - REQUIRE(e[i] == Approx(m[i])); - REQUIRE(f[i] == Approx(n[i])); - } - } - - - -// Test vectorise() with an alias and a dimension argument. -TEST_CASE("spmat_vectorise_dimension_alias") - { - sp_mat m; - m.sprandu(10, 10, 0.1); - sp_mat n(m); - - m = arma::vectorise(m, 0); - - REQUIRE(m.n_rows == 100); - REQUIRE(m.n_cols == 1); - for (uword i = 0; i < m.n_elem; ++i) - { - REQUIRE(m[i] == Approx(n[i])); - } - - m.sprandu(10, 10, 0.1); - n = m.t(); - - m = arma::vectorise(m, 1); - - REQUIRE(m.n_rows == 1); - REQUIRE(m.n_cols == 100); - for (uword i = 0; i < m.n_elem; ++i) - { - REQUIRE(m[i] == Approx(n[i])); - } - } diff -Nru armadillo-9.800.4+dfsg/tests/sprow.cpp armadillo-10.8.2+dfsg/tests/sprow.cpp --- armadillo-9.800.4+dfsg/tests/sprow.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/sprow.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("sprow_shed_col_test") - { - - SpRow d(10); - d[3] = 2; - d[4] = 6; - d[6] = 2; - d[7] = 9; - d[8] = 1; - d[9] = -2; - - d.shed_cols(4, 7); - REQUIRE( d.n_cols == 6 ); - REQUIRE( d.n_rows == 1 ); - REQUIRE( d.n_elem == 6 ); - REQUIRE( d.n_nonzero == 3 ); - REQUIRE( d[0] == 0 ); - REQUIRE( d[1] == 0 ); - REQUIRE( d[2] == 0 ); - REQUIRE( d[3] == 2 ); - REQUIRE( d[4] == 1 ); - REQUIRE( d[5] == -2 ); - } - - - -TEST_CASE("sprow_row_constructor_test") - { - SpMat m(100, 100); - m.sprandu(100, 100, 0.3); - - SpRow r = m.row(0); - - rowvec v(r); - - for (uword i = 0; i < 100; ++i) - { - REQUIRE( v(i) == (double) r(i) ); - } - } diff -Nru armadillo-9.800.4+dfsg/tests/spsubview.cpp armadillo-10.8.2+dfsg/tests/spsubview.cpp --- armadillo-9.800.4+dfsg/tests/spsubview.cpp 2016-06-16 16:20:26.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests/spsubview.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1538 +0,0 @@ -// Copyright 2011-2017 Ryan Curtin (http://www.ratml.org/) -// Copyright 2017 National ICT Australia (NICTA) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ------------------------------------------------------------------------ - -#include - -#include "catch.hpp" - -using namespace arma; - -TEST_CASE("sp_subview_tests") - { - Mat ref(4,4); - ref.eye(4,4); - - SpMat X(4,4); - X.eye(4,4); - - /* - * [[1,0,0,0] [[2,0,0,0] - * [0,1,0,0] -> [0,2,0,0] - * [0,0,1,0] [0,0,2,0] - * [0,0,0,1]] [0,0,0,1]] - */ - ref.submat(0, 0, 2, 2) *= 2; - X.submat(0, 0, 2, 2) *= 2; - - for (uword i = 0; i < 4; i++) - { - for (uword j = 0; j < 4; j++) - { - REQUIRE( (double) ref(i, j) == Approx((double) X(i, j)) ); - } - } - - /* - * [[2,0,0,0] [[2,0,0,0] - * [0,2,0,0] -> [0,1,0,0] - * [0,0,2,0] [0,0,1,0] - * [0,0,0,1]] [0,0,0,.5]] - */ - ref.submat(1, 1, 3, 3) /= 2; - X.submat(1, 1, 3, 3) /= 2; - - for (uword i = 0; i < 4; i++) - { - for (uword j = 0; j < 4; j++) - { - REQUIRE( (double) ref(i, j) == Approx((double) X(i, j)) ); - } - } - - span s(1, 2); - ref.submat(s, s) += 10; - X.submat(s, s) += 10; - - for (uword i = 0; i < 4; i++) - { - for (uword j = 0; j < 4; j++) - { - REQUIRE( (double) ref(i, j) == Approx((double) X(i, j)) ); - } - } - } - - - -TEST_CASE("sp_subview_const_test") - { - Mat ref(4, 4); - ref.eye(4, 4); - - SpMat X(4, 4); - X.eye(4, 4); - - const SpSubview subX = X.submat(span(0, 2), span::all); -/* - X.print("x"); - for (size_t i = 0; i < 3; ++i) - { - for (size_t j = 0; j < 4; ++j) - { - printf("%f ", subX(i, j)); - } - printf("\n"); - } -*/ - } - - - -TEST_CASE("sp_subview_multiplication_test") - { - // Ensure matrix multiplication with subviews works correctly. - SpMat a(2, 5); - SpMat b(5, 2); - - a(1, 3) = 1; - a(0, 0) = 2; - a(1, 2) = 1.5; - - b(4, 1) = 3; - b(3, 0) = 2; - b(1, 0) = 1; - b(0, 0) = 0.6; - - b *= a; - - REQUIRE( b.n_cols == 5 ); - REQUIRE( b.n_rows == 5 ); - REQUIRE( b.n_elem == 25 ); - REQUIRE( b.n_nonzero == 5 ); - - REQUIRE( (double) b(0, 0) == Approx(1.2) ); - REQUIRE( (double) b(0, 1) == Approx(1e-5) ); - REQUIRE( (double) b(0, 2) == Approx(1e-5) ); - REQUIRE( (double) b(0, 3) == Approx(1e-5) ); - REQUIRE( (double) b(0, 4) == Approx(1e-5) ); - REQUIRE( (double) b(1, 0) == Approx(2.0) ); - REQUIRE( (double) b(1, 1) == Approx(1e-5) ); - REQUIRE( (double) b(1, 2) == Approx(1e-5) ); - REQUIRE( (double) b(1, 3) == Approx(1e-5) ); - REQUIRE( (double) b(1, 4) == Approx(1e-5) ); - REQUIRE( (double) b(2, 0) == Approx(1e-5) ); - REQUIRE( (double) b(2, 1) == Approx(1e-5) ); - REQUIRE( (double) b(2, 2) == Approx(1e-5) ); - REQUIRE( (double) b(2, 3) == Approx(1e-5) ); - REQUIRE( (double) b(2, 4) == Approx(1e-5) ); - REQUIRE( (double) b(3, 0) == Approx(4.0) ); - REQUIRE( (double) b(3, 1) == Approx(1e-5) ); - REQUIRE( (double) b(3, 2) == Approx(1e-5) ); - REQUIRE( (double) b(3, 3) == Approx(1e-5) ); - REQUIRE( (double) b(3, 4) == Approx(1e-5) ); - REQUIRE( (double) b(4, 0) == Approx(1e-5) ); - REQUIRE( (double) b(4, 1) == Approx(1e-5) ); - REQUIRE( (double) b(4, 2) == Approx(4.5) ); - REQUIRE( (double) b(4, 3) == Approx(3.0) ); - REQUIRE( (double) b(4, 4) == Approx(1e-5) ); - } - - - -TEST_CASE("sp_subview_multiplication_test_2") - { - // Ensure matrix multiplication with subviews works correctly. - SpMat a(4, 5); - SpMat b(5, 2); - - a(2, 3) = 1; - a(3, 1) = 1.4; - a(0, 0) = 2; - a(1, 0) = 2; - a(2, 2) = 1.5; - - b(4, 1) = 3; - b(3, 0) = 2; - b(1, 0) = 1; - b(0, 0) = 0.6; - - b *= a.rows(1, 2); - - REQUIRE( b.n_cols == 5 ); - REQUIRE( b.n_rows == 5 ); - REQUIRE( b.n_elem == 25 ); - REQUIRE( b.n_nonzero == 5 ); - - REQUIRE( (double) b(0, 0) == Approx(1.2) ); - REQUIRE( (double) b(0, 1) == Approx(1e-5) ); - REQUIRE( (double) b(0, 2) == Approx(1e-5) ); - REQUIRE( (double) b(0, 3) == Approx(1e-5) ); - REQUIRE( (double) b(0, 4) == Approx(1e-5) ); - REQUIRE( (double) b(1, 0) == Approx(2.0) ); - REQUIRE( (double) b(1, 1) == Approx(1e-5) ); - REQUIRE( (double) b(1, 2) == Approx(1e-5) ); - REQUIRE( (double) b(1, 3) == Approx(1e-5) ); - REQUIRE( (double) b(1, 4) == Approx(1e-5) ); - REQUIRE( (double) b(2, 0) == Approx(1e-5) ); - REQUIRE( (double) b(2, 1) == Approx(1e-5) ); - REQUIRE( (double) b(2, 2) == Approx(1e-5) ); - REQUIRE( (double) b(2, 3) == Approx(1e-5) ); - REQUIRE( (double) b(2, 4) == Approx(1e-5) ); - REQUIRE( (double) b(3, 0) == Approx(4.0) ); - REQUIRE( (double) b(3, 1) == Approx(1e-5) ); - REQUIRE( (double) b(3, 2) == Approx(1e-5) ); - REQUIRE( (double) b(3, 3) == Approx(1e-5) ); - REQUIRE( (double) b(3, 4) == Approx(1e-5) ); - REQUIRE( (double) b(4, 0) == Approx(1e-5) ); - REQUIRE( (double) b(4, 1) == Approx(1e-5) ); - REQUIRE( (double) b(4, 2) == Approx(4.5) ); - REQUIRE( (double) b(4, 3) == Approx(3.0) ); - REQUIRE( (double) b(4, 4) == Approx(1e-5) ); - } - - - -TEST_CASE("sp_subview_unary_operators_test") - { - SpMat a(3, 3); - SpMat b(5, 5); - - a(0, 0) = 1; - a(1, 2) = 4; - a(2, 2) = 5; - - b(2, 3) = 1; - b(3, 2) = 2; - b(3, 4) = -4; - b(4, 4) = 5; - - SpMat c = a + b.submat(2, 2, 4, 4); - - REQUIRE( c.n_nonzero == 4 ); - - REQUIRE( (double) c(0, 0) == 1 ); - REQUIRE( (double) c(1, 0) == 2 ); - REQUIRE( (double) c(2, 0) == 0 ); - REQUIRE( (double) c(0, 1) == 1 ); - REQUIRE( (double) c(1, 1) == 0 ); - REQUIRE( (double) c(2, 1) == 0 ); - REQUIRE( (double) c(0, 2) == 0 ); - REQUIRE( (double) c(1, 2) == 0 ); - REQUIRE( (double) c(2, 2) == 10 ); - - c = a - b.submat(2, 2, 4, 4); - - REQUIRE( c.n_nonzero == 4 ); - - REQUIRE( (double) c(0, 0) == 1 ); - REQUIRE( (double) c(1, 0) == -2 ); - REQUIRE( (double) c(2, 0) == 0 ); - REQUIRE( (double) c(0, 1) == -1 ); - REQUIRE( (double) c(1, 1) == 0 ); - REQUIRE( (double) c(2, 1) == 0 ); - REQUIRE( (double) c(0, 2) == 0 ); - REQUIRE( (double) c(1, 2) == 8 ); - REQUIRE( (double) c(2, 2) == 0 ); - - c = a % b.submat(2, 2, 4, 4); - - REQUIRE( c.n_nonzero == 2 ); - - REQUIRE( (double) c(0, 0) == 0 ); - REQUIRE( (double) c(1, 0) == 0 ); - REQUIRE( (double) c(2, 0) == 0 ); - REQUIRE( (double) c(0, 1) == 0 ); - REQUIRE( (double) c(1, 1) == 0 ); - REQUIRE( (double) c(2, 1) == 0 ); - REQUIRE( (double) c(0, 2) == 0 ); - REQUIRE( (double) c(1, 2) == -16 ); - REQUIRE( (double) c(2, 2) == 25 ); - - a(0, 0) = 4; - b(2, 2) = 2; -/* - c = a / b.submat(2, 2, 4, 4); - - REQUIRE( c.n_nonzero == 3 ); - - REQUIRE( (double) c(0, 0) == 2 ); - REQUIRE( (double) c(1, 0) == 0 ); - REQUIRE( (double) c(2, 0) == 0 ); - REQUIRE( (double) c(0, 1) == 0 ); - REQUIRE( (double) c(1, 1) == 0 ); - REQUIRE( (double) c(2, 1) == 0 ); - REQUIRE( (double) c(0, 2) == 0 ); - REQUIRE( (double) c(1, 2) == -1 ); - REQUIRE( (double) c(2, 2) == 1 ); -*/ - } - - -TEST_CASE("sp_subview_mat_operator_tests") - { - SpMat a(6, 10); - a(2, 2) = 2.0; - a(3, 4) = 3.5; - a(4, 3) = -2.0; - a(4, 4) = 4.5; - a(5, 1) = 3.2; - a(0, 1) = 1.3; - a(1, 1) = -4.0; - a(5, 3) = 5.3; - - mat b(3, 3); - b.fill(2.0); - - mat c(b); - - c += a.submat(2, 2, 4, 4); - - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(1e-5) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.5) ); - REQUIRE( (double) c(2, 2) == Approx(6.5) ); - - c = b + a.submat(2, 2, 4, 4); - - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(1e-5) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.5) ); - REQUIRE( (double) c(2, 2) == Approx(6.5) ); - - c = b; - c -= a.submat(2, 2, 4, 4); - - REQUIRE( (double) c(0, 0) == Approx(1e-5) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(4.0) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(-1.5) ); - REQUIRE( (double) c(2, 2) == Approx(-2.5) ); - - c = b - a.submat(2, 2, 4, 4); - - REQUIRE( (double) c(0, 0) == Approx(1e-5) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(4.0) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(-1.5) ); - REQUIRE( (double) c(2, 2) == Approx(-2.5) ); - - c = b; - c *= a.submat(2, 2, 4, 4); - - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(4.0) ); - REQUIRE( (double) c(2, 0) == Approx(4.0) ); - REQUIRE( (double) c(0, 1) == Approx(-4.0) ); - REQUIRE( (double) c(1, 1) == Approx(-4.0) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(0, 2) == Approx(16.0) ); - REQUIRE( (double) c(1, 2) == Approx(16.0) ); - REQUIRE( (double) c(2, 2) == Approx(16.0) ); - - mat e = b * a.submat(2, 2, 4, 4); - - REQUIRE( (double) e(0, 0) == Approx(4.0) ); - REQUIRE( (double) e(1, 0) == Approx(4.0) ); - REQUIRE( (double) e(2, 0) == Approx(4.0) ); - REQUIRE( (double) e(0, 1) == Approx(-4.0) ); - REQUIRE( (double) e(1, 1) == Approx(-4.0) ); - REQUIRE( (double) e(2, 1) == Approx(-4.0) ); - REQUIRE( (double) e(0, 2) == Approx(16.0) ); - REQUIRE( (double) e(1, 2) == Approx(16.0) ); - REQUIRE( (double) e(2, 2) == Approx(16.0) ); - - c = b; - c %= a.submat(2, 2, 4, 4); - - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(1e-5) ); - REQUIRE( (double) c(2, 0) == Approx(1e-5) ); - REQUIRE( (double) c(0, 1) == Approx(1e-5) ); - REQUIRE( (double) c(1, 1) == Approx(1e-5) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(0, 2) == Approx(1e-5) ); - REQUIRE( (double) c(1, 2) == Approx(7.0) ); - REQUIRE( (double) c(2, 2) == Approx(9.0) ); - - SpMat d = b % a.submat(2, 2, 4, 4); - - REQUIRE( d.n_nonzero == 4 ); - REQUIRE( (double) d(0, 0) == Approx(4.0) ); - REQUIRE( (double) d(2, 1) == Approx(-4.0) ); - REQUIRE( (double) d(1, 2) == Approx(7.0) ); - REQUIRE( (double) d(2, 2) == Approx(9.0) ); - - c = b; - c /= a.submat(2, 2, 4, 4); - - REQUIRE( c(0, 0) == Approx(1.0) ); - REQUIRE( std::isinf(c(1, 0)) ); - REQUIRE( std::isinf(c(2, 0)) ); - REQUIRE( std::isinf(c(0, 1)) ); - REQUIRE( std::isinf(c(1, 1)) ); - REQUIRE( c(2, 1) == Approx(-1.0) ); - REQUIRE( std::isinf(c(0, 2)) ); - REQUIRE( c(1, 2) == Approx(2.0 / 3.5) ); - REQUIRE( c(2, 2) == Approx(2.0 / 4.5) ); - } - - - -TEST_CASE("sp_subview_base_test") - { - SpMat a(6, 10); - a(2, 2) = 2.0; - a(3, 4) = 3.5; - a(4, 3) = -2.0; - a(4, 4) = 4.5; - a(5, 1) = 3.2; - a(0, 1) = 1.3; - a(1, 1) = -4.0; - a(5, 3) = 5.3; - - mat b(3, 3); - b.fill(2.0); - - SpMat c = a; - c.submat(2, 2, 4, 4) = b; - - REQUIRE( c.n_nonzero == 13 ); - REQUIRE( (double) c(2, 2) == Approx(2.0) ); - REQUIRE( (double) c(3, 2) == Approx(2.0) ); - REQUIRE( (double) c(4, 2) == Approx(2.0) ); - REQUIRE( (double) c(2, 3) == Approx(2.0) ); - REQUIRE( (double) c(3, 3) == Approx(2.0) ); - REQUIRE( (double) c(4, 3) == Approx(2.0) ); - REQUIRE( (double) c(2, 4) == Approx(2.0) ); - REQUIRE( (double) c(3, 4) == Approx(2.0) ); - REQUIRE( (double) c(4, 4) == Approx(2.0) ); - - c = a; - c.submat(2, 2, 4, 4) += b; - - REQUIRE( c.n_nonzero == 12 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(3, 2) == Approx(2.0) ); - REQUIRE( (double) c(4, 2) == Approx(2.0) ); - REQUIRE( (double) c(2, 3) == Approx(2.0) ); - REQUIRE( (double) c(3, 3) == Approx(2.0) ); - REQUIRE( (double) c(4, 3) == Approx(1e-5) ); - REQUIRE( (double) c(2, 4) == Approx(2.0) ); - REQUIRE( (double) c(3, 4) == Approx(5.5) ); - REQUIRE( (double) c(4, 4) == Approx(6.5) ); - - Mat d = a.submat(2, 2, 4, 4) + b; - c = a.submat(2, 2, 4, 4) + b; - - REQUIRE( c.n_nonzero == 8 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(2.0) ); - REQUIRE( (double) c(2, 0) == Approx(2.0) ); - REQUIRE( (double) c(0, 1) == Approx(2.0) ); - REQUIRE( (double) c(1, 1) == Approx(2.0) ); - REQUIRE( (double) c(2, 1) == Approx(1e-5) ); - REQUIRE( (double) c(0, 2) == Approx(2.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.5) ); - REQUIRE( (double) c(2, 2) == Approx(6.5) ); - - c = a; - c.submat(2, 2, 4, 4) -= b; - - REQUIRE( c.n_nonzero == 12 ); - REQUIRE( (double) c(2, 2) == Approx(1e-5) ); - REQUIRE( (double) c(3, 2) == Approx(-2.0) ); - REQUIRE( (double) c(4, 2) == Approx(-2.0) ); - REQUIRE( (double) c(2, 3) == Approx(-2.0) ); - REQUIRE( (double) c(3, 3) == Approx(-2.0) ); - REQUIRE( (double) c(4, 3) == Approx(-4.0) ); - REQUIRE( (double) c(2, 4) == Approx(-2.0) ); - REQUIRE( (double) c(3, 4) == Approx(1.5) ); - REQUIRE( (double) c(4, 4) == Approx(2.5) ); - - c = a.submat(2, 2, 4, 4) - b; - - REQUIRE( c.n_nonzero == 8 ); - REQUIRE( (double) c(0, 0) == Approx(1e-5) ); - REQUIRE( (double) c(1, 0) == Approx(-2.0) ); - REQUIRE( (double) c(2, 0) == Approx(-2.0) ); - REQUIRE( (double) c(0, 1) == Approx(-2.0) ); - REQUIRE( (double) c(1, 1) == Approx(-2.0) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(0, 2) == Approx(-2.0) ); - REQUIRE( (double) c(1, 2) == Approx(1.5) ); - REQUIRE( (double) c(2, 2) == Approx(2.5) ); - - c = a; - c.submat(2, 2, 4, 4) *= b; - - REQUIRE( c.n_nonzero == 13 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(3, 2) == Approx(7.0) ); - REQUIRE( (double) c(4, 2) == Approx(5.0) ); - REQUIRE( (double) c(2, 3) == Approx(4.0) ); - REQUIRE( (double) c(3, 3) == Approx(7.0) ); - REQUIRE( (double) c(4, 3) == Approx(5.0) ); - REQUIRE( (double) c(2, 4) == Approx(4.0) ); - REQUIRE( (double) c(3, 4) == Approx(7.0) ); - REQUIRE( (double) c(4, 4) == Approx(5.0) ); - - c = a.submat(2, 2, 4, 4) * b; - - REQUIRE( c.n_nonzero == 9 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 0) == Approx(7.0) ); - REQUIRE( (double) c(2, 0) == Approx(5.0) ); - REQUIRE( (double) c(0, 1) == Approx(4.0) ); - REQUIRE( (double) c(1, 1) == Approx(7.0) ); - REQUIRE( (double) c(2, 1) == Approx(5.0) ); - REQUIRE( (double) c(0, 2) == Approx(4.0) ); - REQUIRE( (double) c(1, 2) == Approx(7.0) ); - REQUIRE( (double) c(2, 2) == Approx(5.0) ); - - c = a.submat(2, 2, 4, 4) % b; - - REQUIRE( c.n_nonzero == 4 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(1, 2) == Approx(7.0) ); - REQUIRE( (double) c(2, 2) == Approx(9.0) ); - - c = a; - c.submat(2, 2, 4, 4) %= b; - - REQUIRE( c.n_nonzero == 8 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(4, 3) == Approx(-4.0) ); - REQUIRE( (double) c(3, 4) == Approx(7.0) ); - REQUIRE( (double) c(4, 4) == Approx(9.0) ); - - c = a.submat(2, 2, 4, 4) / b; - - REQUIRE( c.n_nonzero == 4 ); - REQUIRE( (double) c(0, 0) == Approx(1.0) ); - REQUIRE( (double) c(2, 1) == Approx(-1.0) ); - REQUIRE( (double) c(1, 2) == Approx(3.5 / 2.0) ); - REQUIRE( (double) c(2, 2) == Approx(4.5 / 2.0) ); - - c = a; - c.submat(2, 2, 4, 4) /= b; - - REQUIRE( c.n_nonzero == 8 ); - REQUIRE( (double) c(2, 2) == Approx(1.0) ); - REQUIRE( (double) c(4, 3) == Approx(-1.0) ); - REQUIRE( (double) c(3, 4) == Approx(3.5 / 2.0) ); - REQUIRE( (double) c(4, 4) == Approx(4.5 / 2.0) ); - } - - - -TEST_CASE("sp_subview_sp_mat_test") - { - SpMat a(6, 10); - a(2, 2) = 2.0; - a(3, 4) = 3.5; - a(4, 3) = -2.0; - a(4, 4) = 4.5; - a(5, 1) = 3.2; - a(0, 1) = 1.3; - a(1, 1) = -4.0; - a(5, 3) = 5.3; - - SpMat b(3, 3); - b(0, 0) = 2.0; - b(1, 2) = 1.5; - b(2, 1) = 2.0; - - SpMat c = a; - c.submat(2, 2, 4, 4) = b; - - REQUIRE( c.n_nonzero == 7 ); - REQUIRE( (double) c(2, 2) == Approx(2.0) ); - REQUIRE( (double) c(3, 4) == Approx(1.5) ); - REQUIRE( (double) c(4, 3) == Approx(2.0) ); - - c = a; - c.submat(2, 2, 4, 4) += b; - - REQUIRE( c.n_nonzero == 7 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(3, 4) == Approx(5.0) ); - REQUIRE( (double) c(4, 4) == Approx(4.5) ); - - c = a.submat(2, 2, 4, 4) + b; - - REQUIRE( c.n_nonzero == 3 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.0) ); - REQUIRE( (double) c(2, 2) == Approx(4.5) ); - - c = a; - c.submat(2, 2, 4, 4) -= b; - - REQUIRE( c.n_nonzero == 7 ); - REQUIRE( (double) c(2, 2) == Approx(1e-5) ); - REQUIRE( (double) c(3, 2) == Approx(1e-5) ); - REQUIRE( (double) c(4, 2) == Approx(1e-5) ); - REQUIRE( (double) c(2, 3) == Approx(1e-5) ); - REQUIRE( (double) c(3, 3) == Approx(1e-5) ); - REQUIRE( (double) c(4, 3) == Approx(-4.0) ); - REQUIRE( (double) c(2, 4) == Approx(1e-5) ); - REQUIRE( (double) c(3, 4) == Approx(2.0) ); - REQUIRE( (double) c(4, 4) == Approx(4.5) ); - - c = a.submat(2, 2, 4, 4) - b; - - REQUIRE( c.n_nonzero == 3 ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(1, 2) == Approx(2.0) ); - REQUIRE( (double) c(2, 2) == Approx(4.5) ); - - c = a; - c.submat(2, 2, 4, 4) *= b; - - REQUIRE( c.n_nonzero == 8 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(3, 3) == Approx(7.0) ); - REQUIRE( (double) c(4, 3) == Approx(9.0) ); - REQUIRE( (double) c(4, 4) == Approx(-3.0) ); - - c = a.submat(2, 2, 4, 4) * b; - - REQUIRE( c.n_nonzero == 4 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 1) == Approx(7.0) ); - REQUIRE( (double) c(2, 1) == Approx(9.0) ); - REQUIRE( (double) c(2, 2) == Approx(-3.0) ); - c = a.submat(2, 2, 4, 4) % b; - - REQUIRE( c.n_nonzero == 3 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.25) ); - REQUIRE( (double) c(2, 2) == Approx(1e-5) ); - - c = a; - c.submat(2, 2, 4, 4) %= b; - - REQUIRE( c.n_nonzero == 7 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(4, 3) == Approx(-4.0) ); - REQUIRE( (double) c(3, 4) == Approx(5.25) ); - REQUIRE( (double) c(4, 4) == Approx(1e-5) ); - -// c = a.submat(2, 2, 4, 4) / b; - -// REQUIRE( c.n_nonzero == 9 ); -// REQUIRE( (double) c(0, 0) == Approx(1.0) ); -// REQUIRE( (double) c(1, 0) != (double) c(1, 0) ); -// REQUIRE( (double) c(2, 0) != (double) c(2, 0) ); -// REQUIRE( (double) c(0, 1) != (double) c(0, 1) ); -// REQUIRE( (double) c(1, 1) != (double) c(1, 1) ); -// REQUIRE( (double) c(2, 1) == Approx(-1.0) ); -// REQUIRE( (double) c(0, 2) != (double) c(0, 2) ); -// REQUIRE( (double) c(1, 2) == Approx((3.5 / 1.5)) ); -// REQUIRE( std::isinf((double) c(2, 2)) ); - - c = a; - c.submat(2, 2, 4, 4) /= b; - - REQUIRE( c.n_nonzero == 13 ); - REQUIRE( (double) c(2, 2) == Approx(1.0) ); - REQUIRE( (double) c(3, 2) != (double) c(3, 2)); - REQUIRE( (double) c(4, 2) != (double) c(4, 2)); - REQUIRE( (double) c(2, 3) != (double) c(2, 3)); - REQUIRE( (double) c(3, 3) != (double) c(3, 3)); - REQUIRE( (double) c(4, 3) == Approx(-1.0) ); - REQUIRE( (double) c(2, 4) != (double) c(2, 4) ); - REQUIRE( (double) c(3, 4) == Approx((3.5 / 1.5)) ); - REQUIRE( std::isinf((double) c(4, 4)) ); - } - - - -TEST_CASE("sp_subview_sp_subview_tests") - { - SpMat a(6, 10); - a(2, 2) = 2.0; - a(3, 4) = 3.5; - a(4, 3) = -2.0; - a(4, 4) = 4.5; - a(5, 1) = 3.2; - a(0, 1) = 1.3; - a(1, 1) = -4.0; - a(5, 3) = 5.3; - - SpMat b(5, 5); - b(0, 0) = 1.0; - b(0, 1) = 1.0; - b(0, 2) = 1.0; - b(0, 3) = 1.0; - b(0, 4) = 1.0; - b(1, 0) = 1.0; - b(2, 0) = 1.0; - b(3, 0) = 1.0; - b(4, 0) = 1.0; - b(4, 1) = 1.0; - b(4, 2) = 1.0; - b(4, 3) = 1.0; - b(4, 4) = 1.0; - b(3, 4) = 1.0; - b(2, 4) = 1.0; - b(1, 4) = 1.0; - b(1, 1) = 2.0; - b(2, 3) = 1.5; - b(3, 2) = 2.0; - - SpMat c = a; - c.submat(2, 2, 4, 4) = b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 7 ); - REQUIRE( (double) c(2, 2) == Approx(2.0) ); - REQUIRE( (double) c(3, 4) == Approx(1.5) ); - REQUIRE( (double) c(4, 3) == Approx(2.0) ); - - c = a; - c.submat(2, 2, 4, 4) += b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 7 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(3, 4) == Approx(5.0) ); - REQUIRE( (double) c(4, 4) == Approx(4.5) ); - - c = a.submat(2, 2, 4, 4) + b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 3 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.0) ); - REQUIRE( (double) c(2, 2) == Approx(4.5) ); - - c = a; - c.submat(2, 2, 4, 4) -= b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 7 ); - REQUIRE( (double) c(2, 2) == Approx(1e-5) ); - REQUIRE( (double) c(3, 2) == Approx(1e-5) ); - REQUIRE( (double) c(4, 2) == Approx(1e-5) ); - REQUIRE( (double) c(2, 3) == Approx(1e-5) ); - REQUIRE( (double) c(3, 3) == Approx(1e-5) ); - REQUIRE( (double) c(4, 3) == Approx(-4.0) ); - REQUIRE( (double) c(2, 4) == Approx(1e-5) ); - REQUIRE( (double) c(3, 4) == Approx(2.0) ); - REQUIRE( (double) c(4, 4) == Approx(4.5) ); - - c = a.submat(2, 2, 4, 4) - b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 3 ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(1, 2) == Approx(2.0) ); - REQUIRE( (double) c(2, 2) == Approx(4.5) ); - - c = a; - c.submat(2, 2, 4, 4) *= b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 8 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(3, 3) == Approx(7.0) ); - REQUIRE( (double) c(4, 3) == Approx(9.0) ); - REQUIRE( (double) c(4, 4) == Approx(-3.0) ); - c = a.submat(2, 2, 4, 4) * b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 4 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(1, 1) == Approx(7.0) ); - REQUIRE( (double) c(2, 1) == Approx(9.0) ); - REQUIRE( (double) c(2, 2) == Approx(-3.0) ); - - c = a.submat(2, 2, 4, 4) % b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 3 ); - REQUIRE( (double) c(0, 0) == Approx(4.0) ); - REQUIRE( (double) c(2, 1) == Approx(-4.0) ); - REQUIRE( (double) c(1, 2) == Approx(5.25) ); - REQUIRE( (double) c(2, 2) == Approx(1e-5) ); - - c = a; - c.submat(2, 2, 4, 4) %= b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 7 ); - REQUIRE( (double) c(2, 2) == Approx(4.0) ); - REQUIRE( (double) c(4, 3) == Approx(-4.0) ); - REQUIRE( (double) c(3, 4) == Approx(5.25) ); - REQUIRE( (double) c(4, 4) == Approx(1e-5) ); - -// c = a.submat(2, 2, 4, 4) / b.submat(1, 1, 3, 3); - -// REQUIRE( c.n_nonzero == 9 ); -// REQUIRE( (double) c(0, 0) == Approx(1.0) ); -// REQUIRE( (double) c(1, 0) != (double) c(1, 0) ); -// REQUIRE( (double) c(2, 0) != (double) c(2, 0) ); -// REQUIRE( (double) c(0, 1) != (double) c(0, 1) ); -// REQUIRE( (double) c(1, 1) != (double) c(1, 1) ); -// REQUIRE( (double) c(2, 1) == Approx(-1.0) ); -// REQUIRE( (double) c(0, 2) != (double) c(0, 2) ); -// REQUIRE( (double) c(1, 2) == Approx((3.5 / 1.5)) ); -// REQUIRE( std::isinf((double) c(2, 2)) ); - - c = a; - c.submat(2, 2, 4, 4) /= b.submat(1, 1, 3, 3); - - REQUIRE( c.n_nonzero == 13 ); - REQUIRE( (double) c(2, 2) == Approx(1.0) ); - REQUIRE( (double) c(3, 2) != (double) c(3, 2) ); - REQUIRE( (double) c(4, 2) != (double) c(4, 2) ); - REQUIRE( (double) c(2, 3) != (double) c(2, 3) ); - REQUIRE( (double) c(3, 3) != (double) c(3, 3) ); - REQUIRE( (double) c(4, 3) == Approx(-1.0) ); - REQUIRE( (double) c(2, 4) != (double) c(2, 4) ); - REQUIRE( (double) c(3, 4) == Approx((3.5 / 1.5)) ); - REQUIRE( std::isinf((double) c(4, 4)) ); - } - - - -TEST_CASE("sp_subview_iterators_test") - { - SpMat b(5, 5); - b(0, 0) = 1.0; - b(0, 1) = 1.0; - b(0, 2) = 1.0; - b(0, 3) = 1.0; - b(0, 4) = 1.0; - b(1, 0) = 1.0; - b(2, 0) = 1.0; - b(3, 0) = 1.0; - b(4, 0) = 1.0; - b(4, 1) = 1.0; - b(4, 2) = 1.0; - b(4, 3) = 1.0; - b(4, 4) = 1.0; - b(3, 4) = 1.0; - b(2, 4) = 1.0; - b(1, 4) = 1.0; - b(1, 1) = 2.0; - b(2, 3) = 1.5; - b(3, 2) = 2.0; - - // [[1.0 1.0 1.0 1.0 1.0] - // [1.0 2.0 0.0 0.0 1.0] - // [1.0 0.0 0.0 1.5 1.0] - // [1.0 0.0 2.0 0.0 1.0] - // [1.0 1.0 1.0 1.0 1.0]] - SpSubview s = b.submat(1, 1, 3, 3); - - SpSubview::iterator it = s.begin(); - - REQUIRE( it.pos() == 0 ); - REQUIRE( it.skip_pos == 6 ); - REQUIRE( it.row() == 0 ); - REQUIRE( it.col() == 0 ); - REQUIRE( (double) (*it) == Approx(2.0) ); - - ++it; - - REQUIRE( it.pos() == 1 ); - REQUIRE( it.skip_pos == 8 ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 1 ); - REQUIRE( (double) (*it) == Approx(2.0) ); - - ++it; - - REQUIRE( it.pos() == 2 ); - REQUIRE( it.skip_pos == 10 ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 2 ); - REQUIRE( (double) (*it) == Approx(1.5) ); - - *it = 4.3; - - REQUIRE( (double) (*it) == Approx(4.3) ); - - ++it; - - REQUIRE( it.pos() == s.n_nonzero ); - - --it; - - REQUIRE( it.pos() == 2 ); - REQUIRE( it.skip_pos == 10 ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 2 ); - REQUIRE( (double) (*it) == Approx(4.3) ); - - --it; - - REQUIRE( it.pos() == 1 ); - REQUIRE( it.skip_pos == 8 ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 1 ); - REQUIRE( (double) (*it) == Approx(2.0) ); - - --it; - - REQUIRE( it.pos() == 0 ); - REQUIRE( it.skip_pos == 6 ); - REQUIRE( it.row() == 0 ); - REQUIRE( it.col() == 0 ); - REQUIRE( (double) (*it) == Approx(2.0) ); - - SpMat c(5, 5); - c(1, 1) = 2.0; - c(2, 3) = 1.5; - c(3, 2) = 2.0; - - SpSubview ss = c.submat(1, 1, 3, 3); - - SpSubview::iterator sit = ss.begin(); - - REQUIRE( sit.pos() == 0 ); - REQUIRE( sit.skip_pos == 0 ); - REQUIRE( sit.row() == 0 ); - REQUIRE( sit.col() == 0 ); - REQUIRE( (double) (*sit) == Approx(2.0) ); - - ++sit; - - REQUIRE( sit.pos() == 1 ); - REQUIRE( sit.skip_pos == 0 ); - REQUIRE( sit.row() == 2 ); - REQUIRE( sit.col() == 1 ); - REQUIRE( (double) (*sit) == Approx(2.0) ); - - ++sit; - - REQUIRE( sit.pos() == 2 ); - REQUIRE( sit.skip_pos == 0 ); - REQUIRE( sit.row() == 1 ); - REQUIRE( sit.col() == 2 ); - REQUIRE( (double) (*sit) == Approx(1.5) ); - - *sit = 4.2; - - REQUIRE( (double) (*sit) == Approx(4.2) ); - - ++sit; - - REQUIRE( sit.pos() == ss.n_nonzero ); - - --sit; - - REQUIRE( sit.pos() == 2 ); - REQUIRE( sit.skip_pos == 0 ); - REQUIRE( sit.row() == 1 ); - REQUIRE( sit.col() == 2 ); - REQUIRE( (double) (*sit) == Approx(4.2) ); - - --sit; - - REQUIRE( sit.pos() == 1 ); - REQUIRE( sit.skip_pos == 0 ); - REQUIRE( sit.row() == 2 ); - REQUIRE( sit.col() == 1 ); - REQUIRE( (double) (*sit) == Approx(2.0) ); - - --sit; - - REQUIRE( sit.pos() == 0 ); - REQUIRE( sit.skip_pos == 0 ); - REQUIRE( sit.row() == 0 ); - REQUIRE( sit.col() == 0 ); - REQUIRE( (double) (*sit) == Approx(2.0) ); - } - - -TEST_CASE("sp_subview_row_iterators_test") - { - SpMat b(5, 5); - b(0, 0) = 1.0; - b(0, 1) = 1.0; - b(0, 2) = 1.0; - b(0, 3) = 1.0; - b(0, 4) = 1.0; - b(1, 0) = 1.0; - b(2, 0) = 1.0; - b(3, 0) = 1.0; - b(4, 0) = 1.0; - b(4, 1) = 1.0; - b(4, 2) = 1.0; - b(4, 3) = 1.0; - b(4, 4) = 1.0; - b(3, 4) = 1.0; - b(2, 4) = 1.0; - b(1, 4) = 1.0; - b(1, 1) = 2.0; - b(2, 3) = 1.5; - b(3, 2) = 2.0; - - // [[1.0 1.0 1.0 1.0 1.0] - // [1.0 2.0 0.0 0.0 1.0] - // [1.0 0.0 0.0 1.5 1.0] - // [1.0 0.0 2.0 0.0 1.0] - // [1.0 1.0 1.0 1.0 1.0]] - SpSubview s = b.submat(1, 1, 3, 3); - - SpSubview::row_iterator it = s.begin_row(); - - REQUIRE( it.pos() == 0 ); - REQUIRE( it.row() == 0 ); - REQUIRE( it.col() == 0 ); - REQUIRE( it.actual_pos == 6 ); - REQUIRE( (double) (*it) == Approx(2.0) ); - - ++it; - - REQUIRE( it.pos() == 1 ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 2 ); - REQUIRE( it.actual_pos == 12 ); - REQUIRE( (double) (*it) == Approx(1.5) ); - - ++it; - - REQUIRE( it.pos() == 2 ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 1 ); - REQUIRE( it.actual_pos == 9 ); - REQUIRE( (double) (*it) == Approx(2.0) ); - - ++it; - - REQUIRE( it.pos() == s.n_nonzero ); - - --it; - - REQUIRE( it.pos() == 2 ); - REQUIRE( it.row() == 2 ); - REQUIRE( it.col() == 1 ); - REQUIRE( it.actual_pos == 9 ); - REQUIRE( (double) (*it) == Approx(2.0) ); - - (*it) = 4.0; - - REQUIRE( (double) (*it) == Approx(4.0) ); - - --it; - - REQUIRE( it.pos() == 1 ); - REQUIRE( it.row() == 1 ); - REQUIRE( it.col() == 2 ); - REQUIRE( it.actual_pos == 12 ); - REQUIRE( (double) (*it) == Approx(1.5) ); - - --it; - - REQUIRE( it.pos() == 0 ); - REQUIRE( it.row() == 0 ); - REQUIRE( it.col() == 0 ); - REQUIRE( it.actual_pos == 6 ); - REQUIRE( (double) (*it) == Approx(2.0) ); - - // now a different matrix - SpMat c(5, 5); - c(1, 1) = 2.0; - c(2, 3) = 1.5; - c(3, 2) = 2.0; - - SpSubview ss = c.submat(0, 0, 3, 3); - - SpSubview::row_iterator sit = ss.begin_row(); - - REQUIRE( sit.pos() == 0 ); - REQUIRE( sit.row() == 1 ); - REQUIRE( sit.col() == 1 ); - REQUIRE( (double) (*sit) == Approx(2.0) ); - - ++sit; - - REQUIRE( sit.pos() == 1 ); - REQUIRE( sit.row() == 2 ); - REQUIRE( sit.col() == 3 ); - REQUIRE( (double) (*sit) == Approx(1.5) ); - - ++sit; - - REQUIRE( sit.pos() == 2 ); - REQUIRE( sit.row() == 3 ); - REQUIRE( sit.col() == 2 ); - REQUIRE( (double) (*sit) == Approx(2.0) ); - - ++sit; - - REQUIRE( sit.pos() == ss.n_nonzero ); - - --sit; - - REQUIRE( sit.pos() == 2 ); - REQUIRE( sit.row() == 3 ); - REQUIRE( sit.col() == 2 ); - REQUIRE( (double) (*sit) == Approx(2.0) ); - - (*sit) = 4.0; - - REQUIRE( (double) (*sit) == Approx(4.0) ); - - --sit; - - REQUIRE( sit.pos() == 1 ); - REQUIRE( sit.row() == 2 ); - REQUIRE( sit.col() == 3 ); - REQUIRE( (double) (*sit) == Approx(1.5) ); - - --sit; - - REQUIRE( sit.pos() == 0 ); - REQUIRE( sit.row() == 1 ); - REQUIRE( sit.col() == 1 ); - REQUIRE( (double) (*sit) == Approx(2.0) ); - } - - -TEST_CASE("sp_subview_sp_base_add_subtract_modulo") - { - SpMat m; - m.sprandu(100, 100, 0.1); - - SpMat n; - n.sprandu(50, 50, 0.1); - - Mat x(m); - Mat y(n); - - m.submat(25, 25, 74, 74) += n; - x.submat(25, 25, 74, 74) += y; - - for (uword c = 0; c < 100; ++c) - { - for (uword r = 0; r < 100; ++r) - { - REQUIRE( (double) m(r, c) == Approx(x(r, c)) ); - } - } - - m.sprandu(100, 100, 0.1); - n.sprandu(50, 50, 0.1); - - x = m; - y = n; - - m.submat(25, 25, 74, 74) -= n; - x.submat(25, 25, 74, 74) -= y; - - for (uword c = 0; c < 100; ++c) - { - for (uword r = 0; r < 100; ++r) - { - REQUIRE( (double) m(r, c) == Approx(x(r, c)) ); - } - } - - m.sprandu(100, 100, 0.1); - n.sprandu(50, 50, 0.1); - - x = m; - y = n; - - m.submat(25, 25, 74, 74) %= n; - x.submat(25, 25, 74, 74) %= y; - - for( uword c = 0; c < 100; ++c) - { - for( uword r = 0; r < 100; ++r) - { - REQUIRE( (double) m(r, c) == Approx(x(r, c)) ); - } - } - } - -TEST_CASE("sp_subview_hadamard") - { - SpMat x; - x.sprandu(100, 100, 0.1); - Mat d(x); - - SpMat y; - y.sprandu(200, 200, 0.1); - Mat dy(y); - - x %= y.submat(50, 50, 149, 149); - d %= dy.submat(50, 50, 149, 149); - - for (uword c = 0; c < 100; ++c) - { - for (uword r = 0; r < 100; ++r) - { - REQUIRE( (double) x(r, c) == Approx(d(r, c)) ); - } - } - } - - -TEST_CASE("sp_subview_subviews_test") - { - SpMat m(20, 20); - m.sprandu(20, 20, 0.3); - - // Get a subview. - SpSubview s = m.submat(1, 1, 10, 10); // 10x10 - const SpSubview c = m.submat(1, 1, 10, 10); - - SpSubview t = s.row(1); - const SpSubview d = c.row(1); - - REQUIRE( t.n_rows == 1 ); - REQUIRE( t.n_cols == 10 ); - REQUIRE( d.n_rows == 1 ); - REQUIRE( d.n_cols == 10 ); - REQUIRE( t.aux_row1 == 2 ); - REQUIRE( t.aux_col1 == 1 ); - for (uword i = 0; i < 10; ++i) - { - REQUIRE( (double) t[i] == (double) m(2, i + 1) ); - REQUIRE( d[i] == (double) m(2, i + 1) ); - } - - SpSubview t1 = s.col(2); - const SpSubview d1 = c.col(2); - - REQUIRE( t1.n_rows == 10 ); - REQUIRE( t1.n_cols == 1 ); - REQUIRE( d1.n_rows == 10 ); - REQUIRE( d1.n_cols == 1 ); - for (uword i = 0; i < 10; ++i) - { - REQUIRE( (double) t1[i] == (double) m(i + 1, 3) ); - REQUIRE( d1[i] == (double) m(i + 1, 3) ); - } - - SpSubview t2 = s.rows(3, 5); - const SpSubview d2 = c.rows(3, 5); - - REQUIRE( t2.n_rows == 3 ); - REQUIRE( t2.n_cols == 10 ); - REQUIRE( d2.n_rows == 3 ); - REQUIRE( d2.n_cols == 10 ); - for (uword j = 0; j < 3; ++j) - { - for (uword i = 0; i < 10; ++i) - { - REQUIRE( (double) t2(j, i) == (double) m(4 + j, i + 1) ); - REQUIRE( d2(j, i) == (double) m(4 + j, i + 1) ); - } - } - - SpSubview t3 = s.cols(4, 6); - const SpSubview d3 = c.cols(4, 6); - - REQUIRE( t3.n_rows == 10 ); - REQUIRE( t3.n_cols == 3 ); - REQUIRE( d3.n_rows == 10 ); - REQUIRE( d3.n_cols == 3 ); - for (uword j = 0; j < 3; ++j) - { - for (uword i = 0; i < 10; ++i) - { - REQUIRE( (double) t3(i, j) == (double) m(i + 1, 5 + j) ); - REQUIRE( d3(i, j) == (double) m(i + 1, 5 + j) ); - } - } - - SpSubview t4 = s.submat(1, 1, 6, 6); - const SpSubview d4 = c.submat(1, 1, 6, 6); - - REQUIRE( t4.n_rows == 6 ); - REQUIRE( t4.n_cols == 6 ); - REQUIRE( d4.n_rows == 6 ); - REQUIRE( d4.n_cols == 6 ); - for (uword j = 0; j < 6; ++j) - { - for (uword i = 0; i < 6; ++i) - { - REQUIRE( (double) t4(i, j) == (double) m(i + 2, 2 + j) ); - REQUIRE( d4(i, j) == (double) m(i + 2, 2 + j) ); - } - } - - SpSubview t5 = s.submat(span(2, 8), span(2, 5)); - const SpSubview d5 = c.submat(span(2, 8), span(2, 5)); - - REQUIRE( t5.n_rows == 7 ); - REQUIRE( t5.n_cols == 4 ); - REQUIRE( d5.n_rows == 7 ); - REQUIRE( d5.n_cols == 4 ); - for (uword j = 0; j < 4; ++j) - { - for (uword i = 0; i < 7; ++i) - { - REQUIRE( (double) t5(i, j) == (double) m(i + 3, 3 + j) ); - REQUIRE( d5(i, j) == (double) m(i + 3, 3 + j) ); - } - } - - SpSubview t6 = s(4, span(1, 5)); - const SpSubview d6 = c(4, span(1, 5)); - - REQUIRE( t6.n_rows == 1 ); - REQUIRE( t6.n_cols == 5 ); - REQUIRE( d6.n_rows == 1 ); - REQUIRE( d6.n_cols == 5 ); - for (uword i = 0; i < 5; ++i) - { - REQUIRE( (double) t6(i) == (double) m(5, 2 + i) ); - REQUIRE( d6(i) == (double) m(5, 2 + i) ); - } - - SpSubview t7 = s(span(1, 5), 4); - const SpSubview d7 = c(span(1, 5), 4); - - REQUIRE( t7.n_rows == 5 ); - REQUIRE( t7.n_cols == 1 ); - REQUIRE( d7.n_rows == 5 ); - REQUIRE( d7.n_cols == 1 ); - for (uword i = 0; i < 5; ++i) - { - REQUIRE( (double) t7(i) == (double) m(2 + i, 5) ); - REQUIRE( d7(i) == (double) m(2 + i, 5) ); - } - - SpSubview t8 = s(span(1, 9), span(7, 8)); - const SpSubview d8 = c(span(1, 9), span(7, 8)); - - REQUIRE( t8.n_rows == 9 ); - REQUIRE( t8.n_cols == 2 ); - REQUIRE( d8.n_rows == 9 ); - REQUIRE( d8.n_cols == 2 ); - for (uword j = 0; j < 2; ++j) - { - for (uword i = 0; i < 9; ++i) - { - REQUIRE( (double) t8(i, j) == (double) m(i + 2, 8 + j) ); - REQUIRE( d8(i, j) == (double) m(i + 2, 8 + j) ); - } - } - } - - - -TEST_CASE("sp_subview_assignment_sp_base") - { - mat d(51, 51); - d.fill(7.0); // Why not? - mat dd(d); - - sp_mat e; - e.sprandu(50, 50, 0.3); - mat ed(e); // Dense copy. - - d.submat(0, 0, 49, 49) = e; - dd.submat(0, 0, 49, 49) = ed; - - for (uword i = 0; i < d.n_elem; ++i) - { - REQUIRE( d[i] == Approx(dd[i]) ); - } - } - - - -TEST_CASE("sp_subview_addition_sp_base") - { - mat d(51, 51); - d.fill(7.0); // Why not? - mat dd(d); - - sp_mat e; - e.sprandu(50, 50, 0.3); - mat ed(e); // Dense copy. - - d.submat(0, 0, 49, 49) += e; - dd.submat(0, 0, 49, 49) += ed; - - for (uword i = 0; i < d.n_elem; ++i) - { - REQUIRE( d[i] == Approx(dd[i]) ); - } - } - - -TEST_CASE("sp_subview_subtraction_sp_base") - { - mat d(51, 51); - d.fill(7.0); // Why not? - mat dd(d); - - sp_mat e; - e.sprandu(50, 50, 0.3); - mat ed(e); // Dense copy. - - d.submat(0, 0, 49, 49) -= e; - dd.submat(0, 0, 49, 49) -= ed; - - for (uword i = 0; i < d.n_elem; ++i) - { - REQUIRE( d[i] == Approx(dd[i]) ); - } - } - - - -TEST_CASE("sp_subview_schur_sp_base") - { - mat d(51, 51); - d.fill(7.0); // Why not? - mat dd(d); - - sp_mat e; - e.sprandu(50, 50, 0.3); - mat ed(e); // Dense copy. - - d.submat(0, 0, 49, 49) %= e; - dd.submat(0, 0, 49, 49) %= ed; - - for (uword i = 0; i < d.n_elem; ++i) - { - REQUIRE( d[i] == Approx(dd[i]) ); - } - } - - - -TEST_CASE("sp_subview_division_sp_base") - { - mat d(51, 51); - d.fill(7.0); // Why not? - mat dd(d); - - sp_mat e; - e.sprandu(50, 50, 0.3); - mat ed(e); // Dense copy. - - d.submat(0, 0, 49, 49) /= e; - dd.submat(0, 0, 49, 49) /= ed; - - for (uword i = 0; i < d.n_elem; ++i) - { - if (std::isinf(d[i])) - REQUIRE( std::isinf(dd[i]) ); - else - REQUIRE( d[i] == Approx(dd[i]) ); - } - } - - - -TEST_CASE("sp_subview_row_iterator_constructor") - { - // Create a row iterator with an exact position. - Mat tmp = - { { 1.1, 1.2, 1.3, 1.4, 1.5 }, - { 2.1, 5.5, 0.0, 0.0, 3.1 }, - { 2.2, 0.0, 0.0, 6.5, 3.2 }, - { 2.3, 0.0, 7.5, 0.0, 3.3 }, - { 2.4, 4.2, 4.3, 4.4, 3.4 } }; - - SpMat X(tmp); - SpSubview sv = X.submat(1, 1, 3, 3); - - // Now create an iterator to an exact position. - SpSubview::const_row_iterator cri(sv, 0, 1); - - // This should end up at (1, 2) with value 6.5. - REQUIRE( cri.row() == 1 ); - REQUIRE( cri.col() == 2 ); - REQUIRE( (*cri) == Approx(6.5) ); - - cri = SpSubview::const_row_iterator(sv, 0, 0); - - // This should end up at (0, 0) with value 5.5. - REQUIRE( cri.row() == 0 ); - REQUIRE( cri.col() == 0 ); - REQUIRE( (*cri) == Approx(5.5) ); - - cri = SpSubview::const_row_iterator(sv, 2, 1); - - // This should end up at (2, 1) with value 7.5. - REQUIRE( cri.row() == 2 ); - REQUIRE( cri.col() == 1 ); - REQUIRE( (*cri) == Approx(7.5) ); - } - - - -TEST_CASE("sp_subview_row_iterator_test_1") - { - Mat tmp = - { { 1.1, 1.2, 1.3, 1.4, 1.5 }, - { 2.1, 5.5, 0.0, 0.0, 3.1 }, - { 2.2, 0.0, 0.0, 6.5, 3.2 }, - { 2.3, 0.0, 7.5, 0.0, 3.3 }, - { 2.4, 4.2, 4.3, 4.4, 3.4 } }; - - SpMat X(tmp); - SpSubview sv = X.submat(1, 1, 3, 3); - - SpSubview::row_iterator it = sv.begin_row(); - SpSubview::row_iterator it2 = sv.begin_row(); - - ++it; - --it; - - REQUIRE( it.row() == it2.row() ); - REQUIRE( it.col() == it2.col() ); - REQUIRE( (*it) == Approx(*it2) ); - REQUIRE( it.pos() == it2.pos() ); - } - - - -TEST_CASE("sp_subview_row_iterator_test_2") - { - // Make sure the loop terminates. - Mat tmp = - { { 1.1, 1.2, 1.3, 1.4, 1.5 }, - { 2.1, 5.5, 0.0, 0.0, 3.1 }, - { 2.2, 0.0, 0.0, 6.5, 3.2 }, - { 2.3, 0.0, 7.5, 0.0, 3.3 }, - { 2.4, 4.2, 4.3, 4.4, 3.4 } }; - - SpMat X(tmp); - SpSubview sv = X.submat(1, 1, 3, 3); - - SpSubview::row_iterator it = sv.end_row(sv.n_rows - 1); // points to past-the-end - SpSubview::row_iterator it_end = sv.begin_row(); - - do { - --it; - } while(it != it_end); - - REQUIRE( true ); - } diff -Nru armadillo-9.800.4+dfsg/tests1/CMakeLists.txt armadillo-10.8.2+dfsg/tests1/CMakeLists.txt --- armadillo-9.800.4+dfsg/tests1/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests1/CMakeLists.txt 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,5 @@ +add_executable(smoke_test smoke_test.cpp) +target_link_libraries(smoke_test PRIVATE armadillo) +enable_testing() + +add_test(NAME smoke_test COMMAND smoke_test) diff -Nru armadillo-9.800.4+dfsg/tests1/smoke_test.cpp armadillo-10.8.2+dfsg/tests1/smoke_test.cpp --- armadillo-9.800.4+dfsg/tests1/smoke_test.cpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests1/smoke_test.cpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,27 @@ +#include +#include + +using namespace arma; + +int +main() + { + std::cout << "*** smoke test start" << std::endl; + + uword N = 5; + + mat A = reshape(regspace(1, N*N), N, N); + + A.diag() += randu(N); + + mat B; + + bool status = expmat(B,A); + + A.print("A:"); + B.print("B:"); + + std::cout << ((status) ? "*** smoke test okay" : "*** smoke test failed") << std::endl; + + return (status) ? 0 : -1; + } diff -Nru armadillo-9.800.4+dfsg/tests2/attributes.cpp armadillo-10.8.2+dfsg/tests2/attributes.cpp --- armadillo-9.800.4+dfsg/tests2/attributes.cpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests2/attributes.cpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2015 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +#include +#include "catch.hpp" + +using namespace arma; + + +TEST_CASE("attributes_1") + { + mat A(5,6); + REQUIRE(A.n_rows == 5); + REQUIRE(A.n_cols == 6); + REQUIRE(A.n_elem == 30); + + vec B(5); + REQUIRE(B.n_rows == 5); + REQUIRE(B.n_cols == 1); + REQUIRE(B.n_elem == 5); + + rowvec C(6); + REQUIRE(C.n_rows == 1); + REQUIRE(C.n_cols == 6); + REQUIRE(C.n_elem == 6); + + cube D(5,6,2); + REQUIRE(D.n_rows == 5); + REQUIRE(D.n_cols == 6); + REQUIRE(D.n_slices == 2); + REQUIRE(D.n_elem == 60); + + sp_mat E(50,60); + E(0,0) = 1.0; + E(E.n_rows-1,E.n_cols-1) = 1.0; + + REQUIRE(E.n_rows == 50); + REQUIRE(E.n_cols == 60); + REQUIRE(E.n_elem == 3000); + REQUIRE(E.n_nonzero == 2); + + field G(5,6,2); + REQUIRE(G.n_rows == 5); + REQUIRE(G.n_cols == 6); + REQUIRE(G.n_slices == 2); + REQUIRE(G.n_elem == 60); + } + + + diff -Nru armadillo-9.800.4+dfsg/tests2/bounds.cpp armadillo-10.8.2+dfsg/tests2/bounds.cpp --- armadillo-9.800.4+dfsg/tests2/bounds.cpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests2/bounds.cpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2015 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2015 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +#include +#include "catch.hpp" + +using namespace arma; + + +TEST_CASE("bounds_1") + { + const uword n_rows = 5; + const uword n_cols = 6; + + mat A(n_rows, n_cols, fill::zeros); + + REQUIRE_NOTHROW( A(n_rows-1,n_cols-1) = 0 ); + + // out of bounds access will throw unless ARMA_NO_DEBUG is defined + REQUIRE_THROWS( A(n_rows,n_cols) = 0 ); + } + + + diff -Nru armadillo-9.800.4+dfsg/tests2/catch.hpp armadillo-10.8.2+dfsg/tests2/catch.hpp --- armadillo-9.800.4+dfsg/tests2/catch.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-10.8.2+dfsg/tests2/catch.hpp 2016-06-16 16:24:22.000000000 +0000 @@ -0,0 +1,17966 @@ +/* + * Catch v2.13.8 + * Generated: 2022-01-03 21:20:09.589503 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. + * + * 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) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 8 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html +#ifdef __APPLE__ +# include +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define CATCH_CPP14_OR_GREATER +# endif + +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + +#endif + +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) + +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING + +# endif +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#if defined(_MSC_VER) + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +# if !defined(__clang__) // Handle Clang masquerading for msvc + +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL + +// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) +# endif // __clang__ + +#endif // _MSC_VER + +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif + +//////////////////////////////////////////////////////////////////////////////// +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # include + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) + +#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_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN +#endif + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC +#endif + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) +#else +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) +#endif + +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include +#include +#include + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + + bool empty() const noexcept { return file[0] == '\0'; } + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include +#include +#include +#include + +namespace Catch { + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. + class StringRef { + public: + using size_type = std::size_t; + using const_iterator = const char*; + + private: + static constexpr char const* const s_empty = ""; + + char const* m_start = s_empty; + size_type m_size = 0; + + public: // construction + constexpr StringRef() noexcept = default; + + StringRef( char const* rawChars ) noexcept; + + constexpr StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + explicit operator std::string() const { + return std::string(m_start, m_size); + } + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } + + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } + + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + constexpr auto size() const noexcept -> size_type { + return m_size; + } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; + + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } + }; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } +} // namespace Catch + +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); +} + +// end catch_stringref.h +// start catch_preprocessor.hpp + + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif + +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template struct TypeList {};\ + template\ + constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template