diff -Nru armadillo-10.8.2+dfsg/CHANGELOG.html armadillo-12.6.1+dfsg/CHANGELOG.html --- armadillo-10.8.2+dfsg/CHANGELOG.html 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/CHANGELOG.html 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,10 @@ + + +
+The list of changes is part of the documentation: + + + diff -Nru armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindATLAS.cmake armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindATLAS.cmake --- armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindATLAS.cmake 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindATLAS.cmake 2016-06-16 16:27:01.000000000 +0000 @@ -1,20 +1,3 @@ -find_path(ATLAS_CBLAS_INCLUDE_DIR -NAMES cblas.h -PATHS /usr/include/atlas/ /usr/include/ /usr/local/include/atlas/ /usr/local/include/ -) - -find_path(ATLAS_CLAPACK_INCLUDE_DIR -NAMES clapack.h -PATHS /usr/include/atlas/ /usr/include/ /usr/local/include/atlas/ /usr/local/include/ -) - -if(ATLAS_CBLAS_INCLUDE_DIR AND ATLAS_CLAPACK_INCLUDE_DIR) - if(ATLAS_CBLAS_INCLUDE_DIR STREQUAL ATLAS_CLAPACK_INCLUDE_DIR) - set(ATLAS_INCLUDE_DIR ${ATLAS_CBLAS_INCLUDE_DIR}) - endif() -endif() - - set(ATLAS_NAMES) set(ATLAS_NAMES ${ATLAS_NAMES} tatlas) set(ATLAS_NAMES ${ATLAS_NAMES} satlas) @@ -45,7 +28,7 @@ endif() -if(ATLAS_LIBRARY AND ATLAS_INCLUDE_DIR) +if(ATLAS_LIBRARY) set(ATLAS_LIBRARIES ${ATLAS_LIBRARY}) set(ATLAS_FOUND "YES") else() @@ -64,4 +47,4 @@ endif() -# mark_as_advanced(ATLAS_LIBRARY ATLAS_INCLUDE_DIR) +# mark_as_advanced(ATLAS_LIBRARY) diff -Nru armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindBLAS.cmake armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindBLAS.cmake --- armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindBLAS.cmake 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindBLAS.cmake 2016-06-16 16:27:01.000000000 +0000 @@ -8,7 +8,7 @@ SET(BLAS_NAMES ${BLAS_NAMES} blas) FIND_LIBRARY(BLAS_LIBRARY NAMES ${BLAS_NAMES} - PATHS /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib + PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib ) IF (BLAS_LIBRARY) diff -Nru armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindLAPACK.cmake armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindLAPACK.cmake --- armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindLAPACK.cmake 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindLAPACK.cmake 2016-06-16 16:27:01.000000000 +0000 @@ -8,7 +8,7 @@ SET(LAPACK_NAMES ${LAPACK_NAMES} lapack) FIND_LIBRARY(LAPACK_LIBRARY NAMES ${LAPACK_NAMES} - PATHS /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib + PATHS ${CMAKE_SYSTEM_LIBRARY_PATH} /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib ) IF (LAPACK_LIBRARY) diff -Nru armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindMKL.cmake armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindMKL.cmake --- armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindMKL.cmake 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindMKL.cmake 2016-06-16 16:27:01.000000000 +0000 @@ -24,9 +24,15 @@ set(MKL_ARCH ia32) endif() -set(MKL_ROOT $ENV{MKLROOT} CACHE TYPE STRING) +# set(MKL_ROOT $ENV{MKLROOT} CACHE TYPE STRING) +# +# if(NOT MKL_ROOT) +# set(MKL_ROOT "/opt/intel/mkl") +# endif() -if(NOT MKL_ROOT) +if(DEFINED ENV{MKLROOT}) + set(MKL_ROOT $ENV{MKLROOT}) +else() set(MKL_ROOT "/opt/intel/mkl") endif() diff -Nru armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindSuperLU5.cmake armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindSuperLU5.cmake --- armadillo-10.8.2+dfsg/cmake_aux/Modules/ARMA_FindSuperLU5.cmake 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/cmake_aux/Modules/ARMA_FindSuperLU5.cmake 2016-06-16 16:27:01.000000000 +0000 @@ -6,15 +6,8 @@ # SuperLU_INCLUDE_DIR - directory of SuperLU headers find_path(SuperLU_INCLUDE_DIR slu_ddefs.h - /usr/include/superlu/ - /usr/include/SuperLU/ - /usr/include/ - /usr/local/include/superlu/ - /usr/local/include/SuperLU/ - /usr/local/include/ - /opt/local/include/superlu/ - /opt/local/include/SuperLU/ - /opt/local/include/ + PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} /usr/include /usr/local/include /opt/local/include + PATH_SUFFIXES superlu SuperLU "" ) find_library(SuperLU_LIBRARY diff -Nru armadillo-10.8.2+dfsg/CMakeLists.txt armadillo-12.6.1+dfsg/CMakeLists.txt --- armadillo-10.8.2+dfsg/CMakeLists.txt 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/CMakeLists.txt 2016-06-16 16:27:01.000000000 +0000 @@ -16,16 +16,16 @@ # ------------------------------------------------------------------------ -## NOTE: If you prefer to link your programs directly with BLAS and LAPACK, +## NOTE: If you prefer to link your programs _directly_ with OpenBLAS, BLAS or LAPACK, ## NOTE: do not use this installer. ## NOTE: To use Armadillo without installation, compile your programs along these lines: -## NOTE: g++ prog.cpp -o prog -O2 -I /home/blah/armadillo-7.200.3/include -DARMA_DONT_USE_WRAPPER -lblas -llapack -## NOTE: The above command line assumes that you have unpacked the armadillo archive into /home/blah/ -## NOTE: You will need to adjust this for later versions of Armadillo (ie. change the 7.200.3 part) +## NOTE: g++ prog.cpp -o prog -O2 -I /home/user/armadillo-12.2.0/include -DARMA_DONT_USE_WRAPPER -lopenblas -llapack +## NOTE: The above command line assumes that you have unpacked the armadillo archive into /home/user/ +## NOTE: You will need to adjust this for newer versions of Armadillo (ie. "12.2.0" needs to be changed), ## NOTE: and/or if you have unpacked the armadillo archive into a different directory. -## NOTE: Replace -lblas with -lopenblas if you have OpenBLAS (recommended). +## NOTE: Replace -lopenblas with -lblas if you don't have OpenBLAS. ## NOTE: On macOS, replace -lblas -llapack with -framework Accelerate -## NOTE: More details: http://arma.sourceforge.net/faq.html +## NOTE: More details: https://arma.sourceforge.net/faq.html cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) @@ -56,7 +56,6 @@ 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! @@ -96,7 +95,10 @@ 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") + message(STATUS "Detected gcc 4.8.3 or newer") + if(${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 6.1.0) + message(STATUS "*** WARNING: support for gcc versions older than 6.1 is deprecated") + endif() 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") @@ -109,7 +111,7 @@ 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") + message(STATUS "Detected Clang 6.0 or newer") 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") @@ -120,7 +122,7 @@ 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") + message(STATUS "Detected AppleClang 8.0 or newer") 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") @@ -192,12 +194,6 @@ option(BUILD_SHARED_LIBS "build shared library" ON) 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 . @@ -216,9 +212,13 @@ ## 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 . +option(BUILD_SMOKE_TEST "Build the smoke test" ON) +# set(BUILD_SMOKE_TEST false) +## uncomment the above line to disable building the smoke test; +## you can also disable building the smoke test directly on the command line: +## cmake -D BUILD_SMOKE_TEST=false . +## +## to run the smoke test on the command line: ## make ## ctest @@ -243,14 +243,15 @@ 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 "*** Options:" ) +message(STATUS "BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}" ) +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") @@ -324,16 +325,19 @@ else() + if(ALLOW_FLEXIBLAS_LINUX AND (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) + include(ARMA_FindFlexiBLAS) + else() + set(FlexiBLAS_FOUND false) + endif() + include(ARMA_FindMKL) include(ARMA_FindOpenBLAS) - include(ARMA_FindATLAS) + include(ARMA_FindATLAS) # TODO: remove support for ATLAS in next major version include(ARMA_FindBLAS) include(ARMA_FindLAPACK) - if(ALLOW_FLEXIBLAS_LINUX AND (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) - include(ARMA_FindFlexiBLAS) - endif() - + message(STATUS "FlexiBLAS_FOUND = ${FlexiBLAS_FOUND}" ) message(STATUS " MKL_FOUND = ${MKL_FOUND}" ) message(STATUS " OpenBLAS_FOUND = ${OpenBLAS_FOUND}" ) message(STATUS " ATLAS_FOUND = ${ATLAS_FOUND}" ) @@ -342,8 +346,6 @@ if(FlexiBLAS_FOUND) - message(STATUS "FlexiBLAS_FOUND = ${FlexiBLAS_FOUND}" ) - set(ARMA_USE_LAPACK true) set(ARMA_USE_BLAS true) @@ -415,10 +417,12 @@ if(ATLAS_FOUND) set(ARMA_USE_ATLAS true) - set(ARMA_ATLAS_INCLUDE_DIR ${ATLAS_INCLUDE_DIR}) set(ARMA_LIBS ${ARMA_LIBS} ${ATLAS_LIBRARIES}) - message(STATUS "ATLAS_INCLUDE_DIR = ${ATLAS_INCLUDE_DIR}") + message(STATUS "") + message(STATUS "*** NOTE: support for ATLAS is deprecated and will be removed;") + message(STATUS "*** NOTE: recommend to use OpenBLAS or FlexiBLAS instead.") + message(STATUS "") endif() if(BLAS_FOUND) @@ -445,52 +449,6 @@ endif() -find_package(PkgConfig) - - -if(DETECT_HDF5) - find_package(HDF5 QUIET COMPONENTS C) - - if(NOT HDF5_FOUND) - # On Debian systems, the HDF5 package has been split into multiple packages - # so that it is co-installable. But this may mean that the include files - # are hidden somewhere very odd that the FindHDF5.cmake script will not - # find. Thus, we'll also quickly check pkgconfig to see if there is - # information on what to use there. - if (PKG_CONFIG_FOUND) - pkg_check_modules(HDF5 hdf5) - # But using pkgconfig is a little weird because HDF5_LIBRARIES won't be - # filled with exact library paths, like the other scripts. So instead - # what we get is HDF5_LIBRARY_DIRS which is the equivalent of what we'd - # pass to -L. So we have to add those... - if (HDF5_FOUND) - link_directories("${HDF5_LIBRARY_DIRS}") - endif() - endif() - endif() - - message(STATUS "HDF5_FOUND = ${HDF5_FOUND}") - if(HDF5_FOUND) - set(ARMA_USE_HDF5_ALT true) - set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${HDF5_INCLUDE_DIRS}) - set(ARMA_LIBS ${ARMA_LIBS} ${HDF5_LIBRARIES}) - # Since we called HDF5 with no arguments, the script will find only the C - # bindings. So HDF5_INCLUDE_DIRS may now contain one or two elements; if it - # contains two, the first is what the user passed as HDF5_INCLUDE_DIR and we - # should use that as ARMA_HDF5_INCLUDE_DIR. Otherwise, the one entry in - # HDF5_INCLUDE_DIRS is the correct include directory. So, in either case we - # can use the first element in the list. Issue a status message, too, just - # for good measure. - list(GET HDF5_INCLUDE_DIRS 0 ARMA_HDF5_INCLUDE_DIR) - message(STATUS "ARMA_HDF5_INCLUDE_DIR = ${ARMA_HDF5_INCLUDE_DIR}") - message(STATUS "") - message(STATUS "*** If use of HDF5 is causing problems,") - message(STATUS "*** rerun cmake with HDF5 detection disabled:") - message(STATUS "*** cmake -D DETECT_HDF5=false .") - message(STATUS "") - endif() -endif() - include(ARMA_FindARPACK) message(STATUS "ARPACK_FOUND = ${ARPACK_FOUND}") @@ -534,7 +492,6 @@ 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}") diff -Nru armadillo-10.8.2+dfsg/configure armadillo-12.6.1+dfsg/configure --- armadillo-10.8.2+dfsg/configure 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/configure 2016-06-16 16:27:01.000000000 +0000 @@ -6,7 +6,7 @@ { (cmake --version) /dev/null 2>&1 || { - echo "error: cmake (version 2.8 or later) must be present to configure and install Armadillo" + echo "error: cmake (version 2.8 or newer) must be present to configure and install Armadillo" echo "" echo "cmake might be available as a package for your system," echo "or can be downloaded from http://cmake.org" diff -Nru armadillo-10.8.2+dfsg/debian/changelog armadillo-12.6.1+dfsg/debian/changelog --- armadillo-10.8.2+dfsg/debian/changelog 2022-09-22 05:00:28.000000000 +0000 +++ armadillo-12.6.1+dfsg/debian/changelog 2023-09-17 20:06:11.000000000 +0000 @@ -1,8 +1,68 @@ -armadillo (1:10.8.2+dfsg-1~18.04.sav0) bionic; urgency=medium +armadillo (1:12.6.1+dfsg-2~18.04.sav0) bionic; urgency=medium * Backport to Bionic + * Build with GCC 8.5.0 as for all latest backported linear algebra packages: + - debian/control: Add g++ (>= 4:8.4.0-1~) BD (ppa:savoury1/gcc-defaults-8) - -- Rob Savoury Wed, 21 Sep 2022 22:00:28 -0700 + -- Rob Savoury Sun, 17 Sep 2023 13:06:11 -0700 + +armadillo (1:12.6.1+dfsg-2) unstable; urgency=medium + + * Upload to unstable + + -- Kumar Appaiah Thu, 31 Aug 2023 09:28:39 +0530 + +armadillo (1:12.6.1+dfsg-1) experimental; urgency=medium + + [ Debian Janitor ] + * Trim trailing whitespace. + * Use secure URI in Homepage field. + * Remove field Section on binary package libarmadillo11 that duplicates + source. + * Remove constraints unnecessary since buster (oldstable): + + Build-Depends: Drop versioned constraint on dpkg-dev and libsuperlu-dev. + + libarmadillo-dev: Drop versioned constraint on libsuperlu-dev in Depends. + + [ Kumar Appaiah ] + * New upstream release + * soname update to 12, add libarmadillo12 package + * Override Lintian error saying that docs.html is autogenerated + * Standards version is now 4.6.2 (no changes) + + -- Kumar Appaiah Fri, 28 Jul 2023 19:06:12 +0530 + +armadillo (1:11.4.2+dfsg-1) unstable; urgency=medium + + * New upstream release + + -- Kumar Appaiah Sat, 29 Oct 2022 19:42:52 +0530 + +armadillo (1:11.2.3+dfsg-1) unstable; urgency=medium + + * New upstream release + * Build depend on debhelper 10 or more + * Update standards version (no changes) + + -- Kumar Appaiah Wed, 27 Jul 2022 09:42:57 +0530 + +armadillo (1:11.1.1+dfsg-3) unstable; urgency=medium + + * Reupload (source-only) + + -- Kumar Appaiah Mon, 13 Jun 2022 08:47:27 +0530 + +armadillo (1:11.1.1+dfsg-2) unstable; urgency=medium + + * Upload to unstable + + -- Kumar Appaiah Sat, 11 Jun 2022 15:16:12 +0530 + +armadillo (1:11.1.1+dfsg-1) experimental; urgency=medium + + * New upstream release + * soname is now 11, add libarmadillo11 package + + -- Kumar Appaiah Wed, 18 May 2022 20:23:37 +0530 armadillo (1:10.8.2+dfsg-1) unstable; urgency=medium @@ -823,4 +883,3 @@ * Initial release (Closes: #521978) -- Kumar Appaiah Wed, 25 Mar 2009 15:02:42 -0500 - diff -Nru armadillo-10.8.2+dfsg/debian/control armadillo-12.6.1+dfsg/debian/control --- armadillo-10.8.2+dfsg/debian/control 2022-02-07 15:32:21.000000000 +0000 +++ armadillo-12.6.1+dfsg/debian/control 2023-09-17 20:06:07.000000000 +0000 @@ -2,10 +2,10 @@ Priority: optional 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.5.1 +Build-Depends: debhelper (>= 10), g++ (>= 4:8.4.0-1~), libblas-dev, liblapack-dev, cmake, libarpack2-dev, libsuperlu-dev, quilt +Standards-Version: 4.6.2 Section: libs -Homepage: http://arma.sourceforge.net/ +Homepage: https://arma.sourceforge.net/ Vcs-Git: https://salsa.debian.org/science-team/armadillo.git Vcs-Browser: https://salsa.debian.org/science-team/armadillo @@ -13,7 +13,7 @@ Section: libdevel Architecture: any Suggests: libitpp-dev -Depends: libarmadillo10 (= ${binary:Version}), ${misc:Depends}, libarpack2-dev, libhdf5-dev, libsuperlu-dev (>= 5.2) +Depends: libarmadillo12 (= ${binary:Version}), ${misc:Depends}, libarpack2-dev, libhdf5-dev, libsuperlu-dev Replaces: libarmadillo-doc (<= 1.1.2-1) Conflicts: libarmadillo-doc Description: streamlined C++ linear algebra library - Headers @@ -25,8 +25,7 @@ . This package has the development libraries and headers for Armadillo. -Package: libarmadillo10 -Section: libs +Package: libarmadillo12 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: streamlined C++ linear algebra library diff -Nru armadillo-10.8.2+dfsg/debian/libarmadillo10.docs armadillo-12.6.1+dfsg/debian/libarmadillo10.docs --- armadillo-10.8.2+dfsg/debian/libarmadillo10.docs 2022-02-07 15:32:21.000000000 +0000 +++ armadillo-12.6.1+dfsg/debian/libarmadillo10.docs 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -README.md -docs.html diff -Nru armadillo-10.8.2+dfsg/debian/libarmadillo10.install armadillo-12.6.1+dfsg/debian/libarmadillo10.install --- armadillo-10.8.2+dfsg/debian/libarmadillo10.install 2022-02-07 15:32:21.000000000 +0000 +++ armadillo-12.6.1+dfsg/debian/libarmadillo10.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/*.so.* usr/lib diff -Nru armadillo-10.8.2+dfsg/debian/libarmadillo12.docs armadillo-12.6.1+dfsg/debian/libarmadillo12.docs --- armadillo-10.8.2+dfsg/debian/libarmadillo12.docs 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/debian/libarmadillo12.docs 2022-11-23 04:44:19.000000000 +0000 @@ -0,0 +1,2 @@ +README.md +docs.html diff -Nru armadillo-10.8.2+dfsg/debian/libarmadillo12.install armadillo-12.6.1+dfsg/debian/libarmadillo12.install --- armadillo-10.8.2+dfsg/debian/libarmadillo12.install 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/debian/libarmadillo12.install 2022-11-23 04:44:19.000000000 +0000 @@ -0,0 +1 @@ +usr/lib/*.so.* usr/lib diff -Nru armadillo-10.8.2+dfsg/debian/rules armadillo-12.6.1+dfsg/debian/rules --- armadillo-10.8.2+dfsg/debian/rules 2022-02-07 15:32:21.000000000 +0000 +++ armadillo-12.6.1+dfsg/debian/rules 2023-07-28 13:48:20.000000000 +0000 @@ -27,7 +27,7 @@ rm -f CMakeCache.txt cmake_install.cmake rm -rf CMakeFiles rm -f install_manifest.txt include/armadillo_bits/config.hpp examples/Makefile - rm -f ArmadilloConfig.cmake ArmadilloConfigVersion.cmake + rm -f ArmadilloConfig.cmake ArmadilloConfigVersion.cmake rm -rf InstallFiles tmp *.o a.out dh_clean --exclude ./src/include/armadillo_bits/dgemm_proto.hpp.orig diff -Nru armadillo-10.8.2+dfsg/debian/source/lintian-overrides armadillo-12.6.1+dfsg/debian/source/lintian-overrides --- armadillo-10.8.2+dfsg/debian/source/lintian-overrides 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/debian/source/lintian-overrides 2023-07-28 13:57:03.000000000 +0000 @@ -0,0 +1,2 @@ +# docs.html is not autogenerated +armadillo: source-is-missing [docs.html] diff -Nru armadillo-10.8.2+dfsg/docs.html armadillo-12.6.1+dfsg/docs.html --- armadillo-10.8.2+dfsg/docs.html 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/docs.html 2016-06-16 16:27:01.000000000 +0000 @@ -150,7 +150,7 @@ [top] -API Documentation for Armadillo 10.8 +API Documentation for Armadillo 12.6


@@ -174,11 +174,11 @@
  • -If you discover any bugs or regressions, please report them +If you discover any bugs or regressions, please report them

  • -History of API additions +History of API additions
  • @@ -198,7 +198,7 @@
    Conrad Sanderson and Ryan Curtin.
    Armadillo: a template-based C++ library for linear algebra. -
    Journal of Open Source Software, Vol. 1, pp. 26, 2016. +
    Journal of Open Source Software, Vol. 1, No. 2, pp. 26, 2016.

    Conrad Sanderson and Ryan Curtin. @@ -289,9 +289,9 @@ .each_slice repeated operations on each slice of cube (aka "broadcasting")     .set_imag / .set_real set imaginary/real part -.insert_rows/cols/slices insert vector/matrix/cube at specified row/column/slice -.shed_rows/cols/slices remove specified rows/columns/slices -.swap_rows/cols swap specified rows or columns +.insert_rows / cols / slices insert vector/matrix/cube at specified row/column/slice +.shed_rows / cols / slices remove specified rows/columns/slices +.swap_rows / cols swap specified rows or columns .swap swap contents with given object     .memptr raw pointer to memory @@ -303,7 +303,8 @@ iterators (submatrices) iterators and associated member functions for submatrices & subcubes compat. container functions compatibility container functions     -.as_col / .as_row  return flattened matrix as column or row vector +.as_col / .as_row return flattened matrix as column or row vector +.col_as_mat / .row_as_mat return matrix representation of cube column or cube row .t / .st  return matrix transpose .i      return inverse of square matrix .min / .max return extremum value @@ -324,7 +325,7 @@     .is_zero check whether all elements are zero .is_finite check whether all elements are finite -.has_inf check whether any element is +-Inf +.has_inf check whether any element is ±infinity .has_nan check whether any element is NaN     .print print object to std::cout or user specified stream @@ -339,7 +340,7 @@
    -Generated Vectors/Matrices/Cubes +Generated Vectors / Matrices / Cubes
      @@ -350,12 +351,13 @@ - + + - + - +
      eye generate identity matrix
      ones generate object filled with ones
      zeros generate object filled with zeros
      randu / randn generate object with random values (uniform and normal distributions)
      randu generate object with random values (uniform distribution)
      randn generate object with random values (normal distribution)
      randg generate object with random values (gamma distribution)
      randi generate object with random integer values in specified interval
      randi generate object with random integer values in specified interval
      speye generate sparse identity matrix
      spones generate sparse matrix with non-zero elements set to one
      sprandu / sprandn generate sparse matrix with non-zero elements set to random values
      sprandu / sprandn generate sparse matrix with non-zero elements set to random values
      toeplitz generate Toeplitz matrix
      @@ -363,7 +365,7 @@
      -Functions of Vectors/Matrices/Cubes +Functions of Vectors / Matrices / Cubes
        @@ -385,61 +387,66 @@ + - + - + - + + - - + + - - + + - - + + - - + + - - + + - + + + + - - - - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + - + + - - + +
        det determinant
        diagmat generate diagonal matrix from given matrix or vector
        diagvec extract specified diagonal
        diags / spdiags generate band matrix from given set of vectors
        diff differences between adjacent elements
        dot / cdot / norm_dot dot product
        eps obtain distance of each element to next largest floating point representation
        eps obtain distance of each element to next largest floating point representation
        expmat matrix exponential
        expmat_sym matrix exponential of symmetric matrix
        find find indices of non-zero elements, or elements satisfying a relational condition
        find find indices of non-zero elements, or elements satisfying a relational condition
        find_finite find indices of finite elements
        find_nonfinite find indices of non-finite elements
        find_unique find indices of unique elements
        find_nan find indices of NaN elements
        find_unique find indices of unique elements
        fliplr / flipud flip matrix left to right or upside down
        imag / real extract imaginary/real part
        ind2sub convert linear index to subscripts
        imag / real extract imaginary/real part
        ind2sub convert linear index to subscripts
        index_min / index_max indices of extremum values
        inplace_trans in-place transpose
        intersect find common elements in two vectors/matrices
        inplace_trans in-place transpose
        intersect find common elements in two vectors/matrices
        join_rows / join_cols concatenation of matrices
        join_slices concatenation of cubes
        kron Kronecker tensor product
        join_slices concatenation of cubes
        kron Kronecker tensor product
        log_det log determinant
        log_det_sympd log determinant of symmetric positive definite matrix
        logmat matrix logarithm
        log_det_sympd log determinant of symmetric positive definite matrix
        logmat matrix logarithm
        logmat_sympd matrix logarithm of symmetric matrix
        min / max return extremum values
        nonzeros return non-zero values
        min / max return extremum values
        nonzeros return non-zero values
        norm various norms of vectors and matrices
        normalise normalise vectors to unit p-norm
        norm2est fast estimate of the matrix 2-norm
        normalise normalise vectors to unit p-norm
        pow element-wise power
        powmat matrix power
        prod product of elements
        powmat matrix power
        rank rank of matrix
        rcond reciprocal of condition number
        repelem replicate elements
        repmat replicate matrix in block-like fashion
        rank rank of matrix
        rcond reciprocal condition number
        repelem replicate elements
        repmat replicate matrix in block-like fashion
        reshape change size while keeping elements
        resize change size while keeping elements and preserving layout
        reverse reverse order of elements
        resize change size while keeping elements and preserving layout
        reverse reverse order of elements
        roots roots of polynomial
        shift shift elements
        shuffle randomly shuffle elements
        shift shift elements
        shuffle randomly shuffle elements
        size obtain dimensions of given object
        sort sort elements
        sort_index vector describing sorted order of elements
        sort sort elements
        sort_index vector describing sorted order of elements
        sqrtmat square root of matrix
        sqrtmat_sympd square root of symmetric matrix
        sum sum of elements
        sqrtmat_sympd square root of symmetric matrix
        sum sum of elements
        sub2ind convert subscripts to linear index
        symmatu / symmatl generate symmetric matrix from given matrix
        trace sum of diagonal elements
        symmatu / symmatl generate symmetric matrix from given matrix
        trace sum of diagonal elements
        trans transpose of matrix
        trapz trapezoidal numerical integration
        trimatu / trimatl copy upper/lower triangular part
        trapz trapezoidal numerical integration
        trimatu / trimatl copy upper/lower triangular part
        trimatu_ind / trimatl_ind obtain indices of upper/lower triangular part
        unique return unique elements
        unique return unique elements
        vecnorm obtain vector norm of each row or column of a matrix
        vectorise flatten matrix into vector
        misc functions miscellaneous element-wise functions: exp, log, pow, sqrt, round, sign, ...
        trig functions trigonometric element-wise functions: cos, sin, ...
        misc functions miscellaneous element-wise functions: exp, log, sqrt, round, sign, ...
        trig functions trigonometric element-wise functions: cos, sin, tan, ...
      @@ -460,7 +467,7 @@ lu   lower-upper decomposition null orthonormal basis of null space orth orthonormal basis of range space -pinv pseudo-inverse +pinv pseudo-inverse / generalised inverse qr   QR decomposition qr_econ economical QR decomposition qz   generalised Schur decomposition @@ -481,8 +488,9 @@ eigs_sym limited number of eigenvalues & eigenvectors of sparse symmetric real matrix eigs_gen limited number of eigenvalues & eigenvectors of sparse general square matrix -spsolve solve sparse systems of linear equations svds truncated svd: limited number of singular values & singular vectors of sparse matrix +spsolve solve sparse systems of linear equations +spsolve_factoriser factoriser for solving sparse systems of linear equations
    @@ -539,7 +547,7 @@
      - + @@ -547,7 +555,7 @@ - + @@ -691,7 +699,7 @@
    • -Functions which use LAPACK or ATLAS (generally matrix decompositions) are only valid for the following types: +Functions which use LAPACK (generally matrix decompositions) are only valid for the following types: mat, dmat, fmat, cx_mat, cx_dmat, cx_fmat

    • @@ -730,7 +738,7 @@ - +
      constants pi, inf, NaN, speed of light, ...
      constants pi, inf, NaN, eps, speed of light, ...
      wall_clock timer for measuring number of elapsed seconds
      output streams streams for printing warnings and errors
      uword / sword shorthand for unsigned and signed integers
      Matlab/Armadillo syntax differences examples of Matlab syntax and conceptually corresponding Armadillo syntax
      example program short example program
      config.hpp configuration options
      API additions API stability and list of API additions
      API additions API stability and list of API additions
      fill::eye ↦ set the elements on the main diagonal to 1 and off-diagonal elements to 0
      fill::randu ↦ set all elements to random values from a uniform distribution in the [0,1] interval
      fill::randn ↦ set all elements to random values from a normal/Gaussian distribution with zero mean and unit variance
      fill::value(scalar) ↦ set all elements to specified scalar (Armadillo 10.6 and later)
      fill::value(scalar) ↦ set all elements to specified scalar
      fill::none ↦ do not initialise the elements
      @@ -740,19 +748,18 @@
    • Caveat:
        +
      • since Armadillo 10.5, the elements are initialised to zero by default
      • -in Armadillo 10.4 and earlier versions, the elements are not initialised during construction unless fill_form is specified -
        (ie. without specifying fill_form, the elements may contain garbage values, including NaN) +in Armadillo 10.4 and older versions, the elements are not initialised unless fill_form is specified; +ie. without specifying fill_form, the elements may contain garbage values, including NaN
      • -
      • in Armadillo 10.5 and later versions, by default the elements are initialised to zero during construction

    • For the mat(string) constructor, the format is elements separated by spaces, and rows denoted by semicolons; -for example, the 2x2 identity matrix can be created using "1 0; 0 1". -
      -Caveat: string based initialisation is slower than directly setting the elements or using element initialisation. +for example, the 2x2 identity matrix can be created using "1 0; 0 1"; +note that string based initialisation is slower than directly setting the elements or using element initialisation

    • @@ -783,7 +790,7 @@ (ie. the matrix is directly using auxiliary memory)
      • -when strict is set to false, the matrix will use the auxiliary memory until a size change +when strict is set to false, the matrix will use the auxiliary memory until a size change or an aliasing event
      • when strict is set to true, the matrix will be bound to the auxiliary memory for its lifetime; @@ -813,11 +820,18 @@ For convenience, there are several pre-defined typedefs for each matrix type (where the types are: umat, imat, fmat, mat, cx_fmat, cx_mat). The typedefs specify a square matrix size, ranging from 2x2 to 9x9. -The typedefs were defined by simply appending a two digit form of the size to the matrix type --- for example, mat33 is equivalent to mat::fixed<3,3>, +The typedefs were defined by appending a two digit form of the size to the matrix type; +examples: mat33 is equivalent to mat::fixed<3,3>, while cx_mat44 is equivalent to cx_mat::fixed<4,4>.

      +mat::fixed<n_rows, n_cols>(fill_form) +
      +
      +
        +Create a fixed size matrix, with the elements explicitly initialised according to fill_form +
      +
      mat::fixed<n_rows, n_cols>(const ptr_aux_mem)

      @@ -856,6 +870,7 @@

    +
  • See also:
      @@ -890,7 +906,7 @@
    • element iterators
    • .eval()
    • conv_to() (convert between matrix types)
    • -
    • explanation of typedef (cplusplus.com) +
    • explanation of typedef (cplusplus.com)
    • Col class
    • Row class
    • Cube class
    • @@ -1097,11 +1113,11 @@
    • Caveat:
        +
      • since Armadillo 10.5, the elements are initialised to zero by default
      • -in Armadillo 10.4 and earlier versions, the elements are not initialised during construction unless fill_form is specified, as per the Mat class -
        (ie. without specifying fill_form, the elements may contain garbage values, including NaN) +in Armadillo 10.4 and older versions, the elements are not initialised unless fill_form is specified; +ie. without specifying fill_form, the elements may contain garbage values, including NaN; see the Mat class for details on fill_form
      • -
      • in Armadillo 10.5 and later versions, by default the elements are initialised to zero during construction

    • @@ -1126,7 +1142,7 @@ (ie. the vector is directly using auxiliary memory)
      • -when strict is set to false, the vector will use the auxiliary memory until a size change +when strict is set to false, the vector will use the auxiliary memory until a size change or an aliasing event
      • when strict is set to true, the vector will be bound to the auxiliary memory for its lifetime; @@ -1156,11 +1172,18 @@ For convenience, there are several pre-defined typedefs for each vector type (where the types are: uvec, ivec, fvec, vec, cx_fvec, cx_vec as well as the corresponding colvec versions). The pre-defined typedefs specify vector sizes ranging from 2 to 9. -The typedefs were defined by simply appending a single digit form of the size to the vector type --- for example, vec3 is equivalent to vec::fixed<3>, +The typedefs were defined by appending a single digit form of the size to the vector type; +examples: vec3 is equivalent to vec::fixed<3>, while cx_vec4 is equivalent to cx_vec::fixed<4>.

      +vec::fixed<number_of_elements>(fill_form) +
      +
      +
        +Create a fixed size column vector, with the elements explicitly initialised according to fill_form +
      +
      vec::fixed<number_of_elements>(const ptr_aux_mem)

      @@ -1177,7 +1200,7 @@
         vec x(10);
        -vec y(10, fill::zeros);
        +vec y(10, fill::ones);
         
         mat A(10, 10, fill::randu);
         vec z = A.col(5); // extract a column vector
        @@ -1185,6 +1208,7 @@
         

      +
    • See also:

    • @@ -6583,7 +6663,7 @@
    • For objects with complex elements: return true if for each element, each component (real and imaginary) has an absolute value ≤ tolerance; return false otherwise

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

    • Examples: @@ -6843,8 +6923,8 @@

    • @@ -6900,7 +6980,7 @@


      -saving/loading matrices & cubes +saving / loading matrices & cubes

      @@ -7097,6 +7177,18 @@
    • +Caveat: +for saving / loading HDF5 files, support for HDF5 must be enabled within Armadillo's configuration; +the hdf5.h header file must be available on your system and you will need to link with the HDF5 library (eg. -lhdf5). +HDF5 support can be enabled by defining ARMA_USE_HDF5 before including the armadillo header: +
      + +#define ARMA_USE_HDF5 +
      #include <armadillo> +
      +
    • +
      +
    • By providing either hdf5_name(filename, dataset) or hdf5_name(filename, dataset, settings), the file_type type is assumed to be hdf5_binary

      @@ -7113,7 +7205,7 @@
    • - +
      hdf5_opts::trans    save/load the data with columns transposed to rows (and vice versa)
      hdf5_opts::append    instead of overwriting the file, append the specified dataset to the file;
      the specified dataset must not already exist in the file
      hdf5_opts::replace   instead of overwriting the file, replace the specified dataset in the file
      caveat: HDF5 v1.8 may not automatically reclaim deleted space; use h5repack to clean HDF5 files
      hdf5_opts::replace   instead of overwriting the file, replace the specified dataset in the file
      caveat: HDF5 may not automatically reclaim deleted space; use h5repack to clean HDF5 files

      the above settings can be combined using the + operator; for example: hdf5_opts::trans + hdf5_opts::append @@ -7122,12 +7214,6 @@
    • -Caveat: -for saving/loading HDF5 files, support for HDF5 must be enabled within Armadillo's configuration; -the hdf5.h header file must be available on your system and you will need to link with the HDF5 library (eg. -lhdf5) -
    • -
      -
    • By providing either csv_name(filename, header) or csv_name(filename, header, settings), the file is assumed to have data in comma separated value (CSV) text format
      @@ -7144,7 +7230,8 @@ - + +
      csv_opts::trans    save/load the data with columns transposed to rows (and vice versa)
      csv_opts::no_header   assume there is no header line; the header argument is not referenced
      csv_opts::semicolon   use semicolon (;) instead of comma (,) as the separator character (Armadillo 10.6 and later)
      csv_opts::semicolon   use semicolon (;) instead of comma (,) as the separator character
      csv_opts::strict    interpret missing values as NaN (not applicable to sparse matrices)

      the above settings can be combined using the + operator; for example: csv_opts::trans + csv_opts::no_header @@ -7201,7 +7288,7 @@

    • @@ -7209,7 +7296,7 @@


      -saving/loading fields +saving / loading fields

      @@ -7319,7 +7406,7 @@
    • See also:

    • @@ -7332,7 +7419,7 @@


      -Generated Vectors/Matrices/Cubes +Generated Vectors / Matrices / Cubes

      @@ -7495,6 +7582,7 @@
      @@ -7528,6 +7616,7 @@ See also: @@ -7611,15 +7700,23 @@
    • +Caveat: specifying fill::ones during object construction is more compact, eg. mat A(5, 6, fill::ones) +
    • +
      +
    • Examples:
        -vec  v = ones<vec>(10);
        -uvec u = ones<uvec>(11);
        -mat  A = ones<mat>(5,6);
        -cube Q = ones<cube>(5,6,7);
        +   vec v = ones(10);    // or: vec v(10, fill::ones);
        +  uvec u = ones<uvec>(10);
        +rowvec r = ones<rowvec>(10);
         
        -mat  B = 123.0 * ones<mat>(5,6);
        + mat A = ones(5,6);     // or: mat A(5, 6, fill::ones);
        +fmat B = ones<fmat>(5,6);
        +umat C = ones<umat>(5,6);
        +
        + cube Q = ones(5,6,7);  // or: cube Q(5, 6, 7, fill::ones);
        +fcube R = ones<fcube>(5,6,7);
         
    • @@ -7628,12 +7725,12 @@ See also: @@ -7664,13 +7761,23 @@
    • +Caveat: specifying fill::zeros during object construction is more compact, eg. mat A(5, 6, fill::zeros) +
    • +
      +
    • Examples:
        -vec  v = zeros<vec>(10);
        -uvec u = zeros<uvec>(11);
        -mat  A = zeros<mat>(5,6);
        -cube Q = zeros<cube>(5,6,7);
        +   vec v = zeros(10);    // or: vec v(10, fill::zeros);
        +  uvec u = zeros<uvec>(10);
        +rowvec r = zeros<rowvec>(10);
        +
        + mat A = zeros(5,6);     // or: mat A(5, 6, fill::zeros);
        +fmat B = zeros<fmat>(5,6);
        +umat C = zeros<umat>(5,6);
        +
        + cube Q = zeros(5,6,7);  // or: cube Q(5, 6, 7, fill::zeros);
        +fcube R = zeros<fcube>(5,6,7);
         
    • @@ -7679,9 +7786,9 @@ See also: @@ -7689,38 +7796,43 @@


      - -randu( ) + +randu( ) +
      randu( distr_param(a,b) ) +

      randu( n_elem ) +
      randu( n_elem, distr_param(a,b) ) +

      randu( n_rows, n_cols ) +
      randu( n_rows, n_cols, distr_param(a,b) ) +

      randu( n_rows, n_cols, n_slices ) -
      randu( size(X) ) +
      randu( n_rows, n_cols, n_slices, distr_param(a,b) )
      -
      randn( ) -
      randn( n_elem ) -
      randn( n_rows, n_cols ) -
      randn( n_rows, n_cols, n_slices ) -
      randn( size(X) ) +
      randu( size(X) ) +
      randu( size(X), distr_param(a,b) )
      • -Generate a scalar, vector, matrix or cube with the elements set to random floating point values -
      • -
        -
      • randu() uses a uniform distribution in the [0,1] interval +Generate a scalar, vector, matrix or cube with the elements set to random floating point values uniformly distributed in the [a,b] interval

      • -
      • randn() uses a normal/Gaussian distribution with zero mean and unit variance +
      • The default distribution parameters are a = 0 and b = 1

      • Usage:
        • scalar_type s = randu<scalar_type>( ), where scalar_type ∈ { float, double, cx_float, cx_double }
        • +
        • scalar_type s = randu<scalar_type>( distr_param(a,b) ), where scalar_type ∈ { float, double, cx_float, cx_double }
        • +
        • vector_type v = randu<vector_type>( n_elem )
        • +
        • vector_type v = randu<vector_type>( n_elem, distr_param(a,b) )
        • +
        • matrix_type X = randu<matrix_type>( n_rows, n_cols )
        • -
        • matrix_type Y = randu<matrix_type>( size(X) )
        • +
        • matrix_type X = randu<matrix_type>( n_rows, n_cols, distr_param(a,b) )
        • +
        • cube_type Q = randu<cube_type>( n_rows, n_cols, n_slices )
        • -
        • cube_type R = randu<cube_type>( size(Q) )
        • +
        • cube_type Q = randu<cube_type>( n_rows, n_cols, n_slices, distr_param(a,b) )

      • @@ -7729,17 +7841,27 @@
      • -Caveat: to generate a matrix with random integer values instead of floating point values, -use randi() instead +Caveat: to generate a matrix with random integer values instead of floating point values, use randi() instead

      • Examples:


        - -randg( ) -
        randg( distr_param(a,b) ) + +randn( ) +
        randn( distr_param(mu,sd) )
        -
        randg( n_elem ) -
        randg( n_elem, distr_param(a,b) ) +
        randn( n_elem ) +
        randn( n_elem, distr_param(mu,sd) )
        -
        randg( n_rows, n_cols ) -
        randg( n_rows, n_cols, distr_param(a,b) ) +
        randn( n_rows, n_cols ) +
        randn( n_rows, n_cols, distr_param(mu,sd) )
        -
        randg( n_rows, n_cols, n_slices ) -
        randg( n_rows, n_cols, n_slices, distr_param(a,b) ) +
        randn( n_rows, n_cols, n_slices ) +
        randn( n_rows, n_cols, n_slices, distr_param(mu,sd) )
        -
        randg( size(X) ) -
        randg( size(X), distr_param(a,b) ) +
        randn( size(X) ) +
        randn( size(X), distr_param(mu,sd) )
        • -Generate a scalar, vector, matrix or cube with the elements set to random values from a gamma distribution: +Generate a scalar, vector, matrix or cube with the elements set to random values with normal / Gaussian distribution, parameterised by mean mu and standard deviation sd +
        • +
          +
        • The default distribution parameters are mu = 0 and sd = 1 +
        • +
          +
        • +Usage:
            -
      - - - +
    • scalar_type s = randn<scalar_type>( ), where scalar_type ∈ { float, double, cx_float, cx_double }
    • +
    • scalar_type s = randn<scalar_type>( distr_param(mu,sd) ), where scalar_type ∈ { float, double, cx_float, cx_double }
    • +
      +
    • vector_type v = randn<vector_type>( n_elem )
    • +
    • vector_type v = randn<vector_type>( n_elem, distr_param(mu,sd) )
    • +
      +
    • matrix_type X = randn<matrix_type>( n_rows, n_cols )
    • +
    • matrix_type X = randn<matrix_type>( n_rows, n_cols, distr_param(mu,sd) )
    • +
      +
    • cube_type Q = randn<cube_type>( n_rows, n_cols, n_slices )
    • +
    • cube_type Q = randn<cube_type>( n_rows, n_cols, n_slices, distr_param(mu,sd) )
    • + + +
      +
    • +To change the RNG seed, use arma_rng::set_seed(value) or arma_rng::set_seed_random() functions +
    • +
      +
    • +Examples: +
        +
        +double a = randn();
        +double b = randn(distr_param(10,5));
        +
        +vec v1 = randn(5);    // or: vec v1(5, fill::randn);
        +vec v2 = randn(5, distr_param(10,5));
        +
        +rowvec r1 = randn<rowvec>(5);
        +rowvec r2 = randn<rowvec>(5, distr_param(10,5));
        +
        +mat A1 = randn(5, 6);  // or: mat A1(5, 6, fill::randn);
        +mat A2 = randn(5, 6, distr_param(10,5));
        +
        +fmat B1 = randn<fmat>(5, 6);
        +fmat B2 = randn<fmat>(5, 6, distr_param(10,5));
        +
        +arma_rng::set_seed_random();  // set the seed to a random value
        +
        +
      +
    • +
    • See also: + +
    • +
      + + +


      + +randg( ) +
      randg( distr_param(a,b) ) +
      +
      randg( n_elem ) +
      randg( n_elem, distr_param(a,b) ) +
      +
      randg( n_rows, n_cols ) +
      randg( n_rows, n_cols, distr_param(a,b) ) +
      +
      randg( n_rows, n_cols, n_slices ) +
      randg( n_rows, n_cols, n_slices, distr_param(a,b) ) +
      +
      randg( size(X) ) +
      randg( size(X), distr_param(a,b) ) +
        +
      • +Generate a scalar, vector, matrix or cube with the elements set to random values from a gamma distribution: +
          +
        x a-1 exp( -x / b )
      + + + @@ -7816,13 +8021,9 @@
    • matrix_type X = randg<matrix_type>( n_rows, n_cols )
    • matrix_type X = randg<matrix_type>( n_rows, n_cols, distr_param(a,b) )
    • -
    • matrix_type Y = randg<matrix_type>( size(X) )
    • -
    • matrix_type Y = randg<matrix_type>( size(X), distr_param(a,b) )

    • cube_type Q = randg<cube_type>( n_rows, n_cols, n_slices )
    • cube_type Q = randg<cube_type>( n_rows, n_cols, n_slices, distr_param(a,b) )
    • -
    • cube_type R = randg<cube_type>( size(Q) )
    • -
    • cube_type R = randg<cube_type>( size(Q), distr_param(a,b) )

    • @@ -7834,20 +8035,29 @@ Examples:
        -vec v = randg<vec>(100, distr_param(2,1));
        +vec v1 = randg(100);
        +vec v2 = randg(100, distr_param(2,1));
         
        -mat X = randg<mat>(10, 10, distr_param(2,1));
        +rowvec r1 = randg<rowvec>(100);
        +rowvec r2 = randg<rowvec>(100, distr_param(2,1));
        +
        +mat A1 = randg(10, 10);
        +mat A2 = randg(10, 10, distr_param(2,1));
        +
        +fmat B1 = randg<fmat>(10, 10);
        +fmat B2 = randg<fmat>(10, 10, distr_param(2,1));
         
    • See also:

    • @@ -7871,7 +8081,7 @@
      randi( size(X), distr_param(a,b) )
      • -Generate a scalar, vector, matrix or cube with the elements set to random integer values in the [a,b] interval +Generate a scalar, vector, matrix or cube with the elements set to random integer values uniformly distributed in the [a,b] interval

      • The default distribution parameters are a = 0 and b = maximum_int @@ -7888,13 +8098,9 @@
      • matrix_type X = randi<matrix_type>( n_rows, n_cols )
      • matrix_type X = randi<matrix_type>( n_rows, n_cols, distr_param(a,b) )
      • -
      • matrix_type Y = randi<matrix_type>( size(X) )
      • -
      • matrix_type Y = randi<matrix_type>( size(X), distr_param(a,b) )

      • cube_type Q = randi<cube_type>( n_rows, n_cols, n_slices )
      • cube_type Q = randi<cube_type>( n_rows, n_cols, n_slices, distr_param(a,b) )
      • -
      • cube_type R = randi<cube_type>( size(Q) )
      • -
      • cube_type R = randi<cube_type>( size(Q), distr_param(a,b) )

      @@ -7903,16 +8109,21 @@
    • -Caveat: to generate a continuous distribution with floating point values (ie. float or double), use randu() instead +Caveat: to generate a matrix with random floating point values (ie. float or double) instead of integers, use randu() instead

    • Examples:
    •   x a-1 exp( -x / b )
      p(x | a,b) = 
      + + + + +
      val = det( A )   (form 1)
      det( val, A )   (form 2)
      @@ -9240,9 +9547,9 @@
    • any()
    • clamp()
    • .transform()
    • -
    • approx_equal()
    • find_finite()
    • find_nonfinite()
    • +
    • find_nan()
    • find_unique()
    • nonzeros()
    • unique()
    • @@ -9290,6 +9597,7 @@
      • find()
      • find_nonfinite()
      • +
      • find_nan()
      • .is_finite()
      • .replace()
      • .has_inf()
      • @@ -9331,7 +9639,7 @@
      • -Caveat: to replace instances of a specific non-finite value (eg. nan or inf), +Caveat: to replace instances of a specific non-finite value (eg. NaN or Inf), it is more efficient to use .replace()

      • @@ -9340,6 +9648,7 @@


        + +find_nan( X ) +
          +
        • Return a column vector containing the indices of elements of X that are NaN (not-a-number)
        • +
          +
        • The output vector must have the type uvec +(ie. the indices are stored as unsigned integers of type uword) +
        • +
          +
        • +X is interpreted as a vector, with column-by-column ordering of the elements of X +
        • +
          +
        • +Examples: +
            +
            +mat A(5, 5, fill::randu);
            +
            +A(2,3) = datum::nan;
            +
            +uvec indices = find_nan(A);
            +
            +
          +
        • +
          +
        • +Caveat: to replace instances of NaN values, +it is more efficient to use .replace() +
        • +
          +
        • +See also: + +
        • +
          +
        + +


        find_unique( X )
        find_unique( X, ascending_indices ) @@ -9474,8 +9830,8 @@ - - + +
        uvec sub = ind2sub( size(X), index )   (form 1)
        umat sub = ind2sub( size(X), vector_of_indices )   (form 2)
        uvec sub = ind2sub( size(X), index )   (form 1)
        umat sub = ind2sub( size(X), vector_of_indices )   (form 2)
          @@ -9492,11 +9848,11 @@
        • -When only one index is given (form 1), the subscripts are returned in a vector of type uvec +When only one index is given (form 1), the subscripts are returned in a vector of type uvec

        • -When a vector of indices (of type uvec) is given (form 2), the corresponding subscripts are returned in each column of an m x n matrix of type umat; +When a vector of indices (of type uvec) is given (form 2), the corresponding subscripts are returned in each column of an m x n matrix of type umat; m=2 for matrix subscripts, while m=3 for cube subscripts

        • @@ -9700,8 +10056,8 @@ - - + +
          C = intersect( A, B )   (form 1)
          intersect( C, iA, iB, A, B )   (form 2)
          C = intersect( A, B )   (form 1)
          intersect( C, iA, iB, A, B )   (form 2)

          @@ -9993,27 +10347,23 @@ - - + +
          log_det_sympd( result, A )   (form 1)
          result = log_det_sympd( A )   (form 2)
          result = log_det_sympd( A )   (form 1)
          log_det_sympd( result, A )   (form 2)
            -
          • -Log determinant of symmetric positive definite matrix A -
          • +
          • Log determinant of symmetric positive definite matrix A

          • -
          • -If A is not square sized, a std::logic_error exception is thrown -
          • +
          • form 1: return the log determinant

          • -
          • form 1: store the calculated log determinant in result and return a bool indicating success
          • +
          • form 2: store the calculated log determinant in result and return a bool indicating success

          • -
          • form 2: return the log determinant
          • +
          • If A is not square sized, a std::logic_error exception is thrown

          • If the log determinant cannot be found:
              -
            • log_det_sympd(result, A) returns a bool set to false (exception is not thrown)
            • result = log_det_sympd(A) throws a std::runtime_error exception
            • +
            • log_det_sympd(result, A) returns a bool set to false (exception is not thrown)

          • @@ -10025,10 +10375,10 @@ mat B = A.t() * A; // make symmetric matrix -double result1; -bool success = log_det_sympd(result1, B); // form 1 +double result1 = log_det_sympd(B); // form 1 -double result2 = log_det_sympd(B); // form 2 +double result2; +bool success = log_det_sympd(result2, B); // form 2
          @@ -10037,10 +10387,9 @@ See also:
          @@ -10062,9 +10411,12 @@

        -
      • Caveat: if matrix A is symmetric positive definite, using logmat_sympd() is faster
      • -
        -
      • Caveat: the matrix logarithm operation is generally not the same as applying the log() function to each element
      • +
      • Caveats: +
          +
        • the matrix logarithm operation is generally not the same as applying the log() function to each element
        • +
        • if matrix A is symmetric positive definite, using logmat_sympd() is faster
        • +
        +

      • Examples: @@ -10108,10 +10460,10 @@

      • -
      • Caveat: the matrix logarithm operation is generally not the same as applying the log() function to each element
      • +
      • Caveat: the matrix logarithm operation is generally not the same as applying the log() function to each element

      • Examples: @@ -10136,7 +10488,7 @@
      • miscellaneous element-wise functions
      • matrix logarithm in Wikipedia
      • positive definite matrix in Wikipedia
      • -
      • positive definite matrix in MathWorld
      • +
      • positive definite matrix in MathWorld

      @@ -10222,7 +10574,6 @@
    • statistics functions
    • running_stat - class for running statistics of scalars
    • running_stat_vec - class for running statistics of vectors
    • -
    • ensmallen - library for finding minimum of arbitrary function

  • @@ -10275,6 +10626,7 @@
  • find()
  • unique()
  • vectorise() +
  • .clean()
  • .for_each()
  • @@ -10287,7 +10639,7 @@
    norm( X, p ) + +


    + +norm2est( X ) +
    norm2est( X, tol ) +
    norm2est( X, tol, max_iter ) +
      +
    • +Fast estimate of the 2-norm (spectral norm) of X, where X is a dense or sparse matrix +
    • +
      +
    • +The estimate is found via an iterative algorithm which finishes when one of the following conditions is met: +
        +
      • +the relative difference between two consecutive estimates is less than the specified tolerance, +ie. |est1 - est2| / max(est1 , est2) < tol +
      • +
      • the number of iterations is equal to max_iter
      • +
      +
    • +
      +
    • +The optional argument tol specifies the tolerance for the relative difference; by default tol = 1e-6 is used +
    • +
      +
    • +The optional argument max_iter specifies the maximum number of iterations; by default max_iter = 100 is used +
    • +
      +
    • +Examples: +
        +
        +mat X(2000, 3000, fill::randu);
        +
        +double x = norm2est(X);
        +double y = norm2est(X, 1e-5);
        +double z = norm2est(X, 1e-4, 10);
        +
        +
      +
    • +
      +
    • +See also: +

    • @@ -10383,44 +10793,64 @@ See also:


    - -prod( V ) -
    prod( M ) -
    prod( M, dim ) + + + + + + + + + +
    pow( A, scalar )   (form 1)
    pow( A, B )   (form 2)
    pow( M.each_col(), C )   (form 3)
    pow( M.each_row(), R )   (form 4)
    pow( Q.each_slice(), M )   (form 5)
      -
    • -For vector V, return the product of all elements -
    • +
    • Element-wise power operations

    • -
    • -For matrix M, return the product of elements in each column (dim = 0), or each row (dim = 1) -
    • +
    • form 1: raise all elements in A to the power denoted by the given scalar

    • -
    • -The dim argument is optional; by default dim = 0 is used -
    • +
    • form 2: raise each element in A to the power denoted by the corresponding element in B; +
      the sizes of A and B must be the same
    • +
      +
    • form 3: for each column vector of matrix M, raise each element to the power denoted by the corresponding element in column vector C; +
      the number of rows in M and C must be the same
    • +
      +
    • form 4: for each row vector of matrix M, raise each element to the power denoted by the corresponding element in row vector R; +
      the number of columns in M and R must be the same
    • +
      +
    • form 5: for each slice of cube Q, raise each element to the power denoted by the corresponding element in matrix M; +
      the number of rows and columns in Q and M must be the same
    • +
      +
    • Caveats: +
        +
      • to raise all elements to the power 2, use square() instead
      • +
      • for the matrix power operation, which takes into account matrix structure, use powmat()
      • +

    • Examples:
        -colvec v(10, fill::randu);
        -double x = prod(v);
        +mat A(5, 6, fill::randu);
        +mat B(5, 6, fill::randu);
         
        -mat M(10, 10, fill::randu);
        +mat X = pow(A, 3.45);
        +mat Y = pow(A, B);
         
        -rowvec a = prod(M);
        -rowvec b = prod(M,0);
        -colvec c = prod(M,1);
        +   vec C(5, fill::randu);
        +rowvec R(6, fill::randu);
        +
        +mat Z1 = pow(A.each_col(), C);
        +mat Z2 = pow(A.each_row(), R);
         
    • @@ -10428,8 +10858,11 @@
    • See also:

    • @@ -10461,10 +10894,10 @@
    • Caveats:
        +
      • the matrix power operation is generally not the same as applying the pow() function to each element
      • 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

    • @@ -10483,6 +10916,7 @@
    • See also:


      - -rank( X ) + +prod( V ) +
      prod( M ) +
      prod( M, dim ) +
        +
      • +For vector V, return the product of all elements +
      • +
        +
      • +For matrix M, return the product of elements in each column (dim = 0), or each row (dim = 1) +

      • -rank( X, tolerance ) +
      • +The dim argument is optional; by default dim = 0 is used +
      • +
        +
      • +Examples:
          -
        • Return the rank of matrix X, based on on singular value decomposition
        • +
          +colvec v(10, fill::randu);
          +double x = prod(v);
          +
          +mat M(10, 10, fill::randu);
          +
          +rowvec a = prod(M);
          +rowvec b = prod(M,0);
          +colvec c = prod(M,1);
          +
          +
        +
      • +
        +
      • +See also: + +
      • +
        +
      + +


      + + + + + + + + + +
      r = rank( X )   (form 1)
      r = rank( X, tolerance )    
        
      rank( r, X )   (form 2)
      rank( r, X, tolerance )    
      +
        +
      • Calculate the rank of matrix X, based on singular value decomposition
      • +
        +
      • form 1: return the rank
      • +
        +
      • form 2: store the calculated rank in r and return a bool indicating success

      • 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 set to max_rc · max_sv · epsilon, where:
          -
        • m = number of rows and n = number of columns in X
        • +
        • max_rc = max(X.n_rows, X.n_cols)
        • max_sv = maximum singular value of X
        • -
        • datum::eps = difference between 1 and the least value greater than 1 that is representable
        • +
        • epsilon = difference between 1 and the least value greater than 1 that is representable

      • -
      • If the decomposition fails, a std::runtime_error exception is thrown
      • -
        -
      • -Caveat: to confirm whether a matrix is singular, use rcond() or cond() +
      • If the calculation fails: +
          +
        • r = rank(X) throws a std::runtime_error exception
        • +
        • rank(r,X) returns a bool set to false (exception is not thrown)
        • +

      • @@ -10528,7 +11017,10 @@
         mat A(4, 5, fill::randu);
         
        -uword r = rank(A);
        +uword r1 = rank(A);           // form 1
        +
        +uword r2;
        +bool success = rank(r2,  A);  // form 2
         
    • @@ -10536,13 +11028,12 @@
    • See also:

    • @@ -10553,7 +11044,7 @@ rcond( A )
      • -Return the 1-norm estimate of the reciprocal of the condition number of square matrix A +Return the 1-norm estimate of the reciprocal condition number of square matrix A

      • @@ -10706,15 +11197,14 @@ Caveats:
      • @@ -10764,8 +11254,7 @@
      • Caveat: -do not use resize() to change the size without preserving data; -use .set_size() instead, which is much faster +to change the size without preserving data, use .set_size() instead, which is much faster

      • @@ -10973,7 +11462,8 @@
      • shift()
      • sort()
      • unique()
      • -
      • randu() / randn()
      • +
      • randi()
      • +
      • randperm()

      @@ -10985,32 +11475,37 @@
      size( n_rows, n_cols )
      -size( n_rows, n_cols, n_slices ) -
      @@ -11317,7 +11815,7 @@
    • -The argument size(X) can be replaced with size(n_rows, n_cols) or size(n_rows, n_cols, n_slices) +The argument size(X) can be replaced with size(n_rows, n_cols) or size(n_rows, n_cols, n_slices)

    • @@ -11395,7 +11893,7 @@
    • trimatu() / trimatl()
    • .is_symmetric()
    • .is_hermitian()
    • -
    • Symmetric matrix in Wikipedia
    • +
    • Symmetric matrix in Wikipedia

    @@ -11410,8 +11908,7 @@
  • -If X is an expression, -the function aims to use optimised expression evaluations to calculate only the diagonal elements +If X is an expression, the evaluation of the expression aims to calculate only the diagonal elements

  • @@ -11432,6 +11929,7 @@
  • as_scalar()
  • .diag()
  • diagvec()
  • +
  • diagmat()
  • sum()
  • @@ -11523,11 +12021,11 @@
  • See also:
  • @@ -11592,8 +12090,8 @@
  • symmatu() / symmatl()
  • diagmat()
  • nonzeros()
  • -
  • Triangular matrix in MathWorld
  • -
  • Triangular matrix in Wikipedia
  • +
  • Triangular matrix in MathWorld
  • +
  • Triangular matrix in Wikipedia

  • @@ -11710,6 +12208,53 @@


    + +vecnorm( X ) +
    vecnorm( X, p ) +
    vecnorm( X, p, dim ) +
      +
    • +Compute the p-norm of each column vector (dim = 0) or row vector (dim = 1) of matrix X +
    • +
      +
    • +p is an integer ≥ 1, or "-inf" (minimum quasi-norm), or "inf" (maximum norm) +
    • +
      +
    • +The arguments p and dim are optional; by default p = 2 and dim = 0 are used +
    • +
      +
    • +Caveat: to compute the matrix norm, use norm() instead +
    • +
      +
    • +Examples: +
        +
        +mat X(4, 5, fill::randu);
        +
        +rowvec r = vecnorm(X, 2);
        +
        +colvec c = vecnorm(X, "inf", 1);
        +
        +
      +
    • +
      +
    • +See also: + +
    • +
      +
    + +


    vectorise( X )
    vectorise( X, dim ) @@ -11754,6 +12299,7 @@ See also:
    @@ -12590,12 +13164,37 @@


    B = inv_sympd( A ) +
    B = inv_sympd( A, settings ) +

    inv_sympd( B, A ) +
    inv_sympd( B, A, settings ) +
    +
    inv_sympd( B, rcond, A )
    • Inverse of symmetric/hermitian positive definite matrix A

    • +
    • The settings argument is optional; it is one of the following: +
      +
      + + + + + + +
      inv_opts::no_ugly   do not provide inverses for poorly conditioned matrices (where rcond < A.n_rows · datum::eps)
      inv_opts::allow_approx   allow approximate inverses for rank deficient or poorly conditioned symmetric matrices
      inv_opts::tiny   use fast inverse algorithm for tiny matrices (with size ≤ 4x4); may produce lower quality inverses
      +
    • +
      +
    • +The reciprocal condition number is optionally calculated and stored in rcond +
        +
      • rcond close to 1 suggests that A is well-conditioned
      • +
      • rcond close to 0 suggests that A is badly conditioned
      • +
      +
    • +
    • If A is not square sized, a std::logic_error exception is thrown
    • @@ -12604,6 +13203,7 @@
      • B = inv_sympd(A) resets B and throws a std::runtime_error exception
      • inv_sympd(B,A) resets B and returns a bool set to false (exception is not thrown)
      • +
      • inv_sympd(B,rcond,A) resets B, sets rcond to zero, and returns a bool set to false (exception is not thrown)
      +shift-invert mode in ARPACK +
    • eigen decomposition in MathWorld
    • +
    • eigenvalues & eigenvectors in Wikipedia

    @@ -13690,6 +14319,11 @@
  • +NOTE: the implementation in Armadillo 12.6 is considerably faster than earlier versions; +further speedups can be obtained by enabling OpenMP in your compiler (eg. -fopenmp in GCC and clang) +
  • +
    +
  • Examples: +
  • +
    + + +


    + +vec s = svds( X, k ) +
    vec s = svds( X, k, tol ) +
    +
    svds( vec s, X, k ) +
    svds( vec s, X, k, tol ) +
    +
    svds( mat U, vec s, mat V, sp_mat X, k ) +
    svds( mat U, vec s, mat V, sp_mat X, k, tol ) +
    +
    svds( cx_mat U, vec s, cx_mat V, sp_cx_mat X, k ) +
    svds( cx_mat U, vec s, cx_mat V, sp_cx_mat X, k, tol ) +
      +
    • +Obtain a limited number of singular values and singular vectors (truncated SVD) of sparse matrix X +
    • +
      +
    • +The singular values and vectors are calculated via sparse eigen decomposition of: + + + + + + +
      ⎡ zeros(X.n_rows, X.n_rows)  X ⎤
      ⎣ X.t() zeros(X.n_cols, X.n_cols) ⎦
      +
      +
    • +
      +
    • +k specifies the number of singular values and singular vectors +
    • +
      +
    • +The singular values are in descending order +
    • +
      +
    • +The argument tol is optional; it specifies the tolerance for convergence; +it is passed as (tol ÷ √2) to eigs_sym() +
    • +
      +
    • +If the decomposition fails, the output objects are reset and: +
        +
      • s = svds(X,k) resets s and throws a std::runtime_error exception
      • +
      • svds(s,X,k) resets s and returns a bool set to false (exception is not thrown)
      • +
      • svds(U,s,V,X,k) resets U, s, V and returns a bool set to false (exception is not thrown)
      • +
      +
    • +
      +
    • +Caveats: +
        +
      • +svds() is intended only for finding a few singular values from a large sparse matrix; +to find all singular values, use svd() instead +
      • +
      • +depending on the given matrix, svds() may find fewer singular values than specified +
      • +
      +
    • +
      +
    • +Examples: +
        +
        +sp_mat X = sprandu<sp_mat>(100, 200, 0.1);
        +
        +mat U;
        +vec s;
        +mat V;
        +
        +svds(U, s, V, X, 10);
        +
        +
      +
    • +
      +
    • +See also: +

    • @@ -13754,10 +14481,10 @@ The solver argument is optional; solver is either "superlu" or "lapack"; by default "superlu" is used
      • -For "superlu", ARMA_USE_SUPERLU must be enabled in config.hpp +for "superlu", ARMA_USE_SUPERLU must be enabled in config.hpp
      • -For "lapack", sparse matrix A is converted to a dense matrix before using the LAPACK solver; this considerably increases memory usage +for "lapack", sparse matrix A is converted to a dense matrix before using the LAPACK solver; this considerably increases memory usage
      @@ -13765,8 +14492,9 @@
    • Notes:
        -
      • The SuperLU solver is mainly useful for very large and/or very sparse matrices
      • -
      • If there is sufficient amount of memory to store a dense version of matrix A, the LAPACK solver can be faster
      • +
      • the SuperLU solver is mainly useful for very large and/or very sparse matrices
      • +
      • to reuse the SuperLU factorisation of A for finding solutions where B is iteratively changed, see the spsolve_factoriser class
      • +
      • if there is sufficient amount of memory to store a dense version of matrix A, the LAPACK solver can be faster

    • @@ -13862,92 +14590,113 @@
    • See also:

    -


    - -vec s = svds( X, k ) -
    vec s = svds( X, k, tol ) -
    -
    svds( vec s, X, k ) -
    svds( vec s, X, k, tol ) -
    -
    svds( mat U, vec s, mat V, sp_mat X, k ) -
    svds( mat U, vec s, mat V, sp_mat X, k, tol ) -
    -
    svds( cx_mat U, vec s, cx_mat V, sp_cx_mat X, k ) -
    svds( cx_mat U, vec s, cx_mat V, sp_cx_mat X, k, tol ) -
      -
    • -Obtain a limited number of singular values and singular vectors (truncated SVD) of sparse matrix X -
    • -
      -
    • -The singular values and vectors are calculated via sparse eigen decomposition of: - - - - - - -
      ⎡ zeros(X.n_rows, X.n_rows)  X ⎤
      ⎣ X.t() zeros(X.n_cols, X.n_cols) ⎦
      -
      -
    • +


      + +spsolve_factoriser
      +
      • -k specifies the number of singular values and singular vectors +Class for factorisation of sparse matrix A for solving systems of linear equations in the form A*X = B

      • -The singular values are in descending order +Allows the SuperLU factorisation of A to be reused for finding solutions in cases where B is iteratively changed

      • -The argument tol is optional; it specifies the tolerance for convergence; -it is passed as (tol ÷ √2) to eigs_sym() -
      • +For an instance of spsolve_factoriser named as SF, the member functions are: +

        -
      • -If the decomposition fails, the output objects are reset and:
          -
        • s = svds(X,k) resets s and throws a std::runtime_error exception
        • -
        • svds(s,X,k) resets s and returns a bool set to false (exception is not thrown)
        • -
        • svds(U,s,V,X,k) resets U, s, V and returns a bool set to false (exception is not thrown)
        • -
        +SF.factorise(A) +
        +SF.factorise(A, opts) +
          +
        • +factorise square-sized sparse matrix A +
        • +
        • +optional settings are given in the opts argument as per the spsolve() function
        • +
        • if the factorisation fails, a bool set to false is returned
        • +

        +SF.solve(X, B) +
        • -Caveats: +using the given dense matrix B and the computed factorisation, +store in X the solution to A*X = B +
        • +
        • if computing the solution fails, X is reset and a bool set to false is returned
        • +
        +
        +SF.rcond()
        • -svds() is intended only for finding a few singular values from a large sparse matrix; -to find all singular values, use svd() instead +return the 1-norm estimate of the reciprocal condition number computed during the factorisation +
            +
          • + values close to 1 suggest that the factorised matrix is well-conditioned +
          • +
          • + values close to 0 suggest that the factorised matrix is badly conditioned +
          • +
        • +
        +
        +SF.reset() +
        • -depending on the given matrix, svds() may find fewer singular values than specified +reset the instance and release all memory related to the stored factorisation; +this is automatically done when the instance goes out of scope
        +
      +
      +
    • Notes: +
        +
      • if the factorisation of A does not need to be reused, use spsolve() instead
      • +
      • this class internally uses the SuperLU solver; ARMA_USE_SUPERLU must be enabled in config.hpp
      • +

    • Examples:
        -sp_mat X = sprandu<sp_mat>(100, 200, 0.1);
        +sp_mat A = sprandu<sp_mat>(1000, 1000, 0.1);
         
        -mat U;
        -vec s;
        -mat V;
        +spsolve_factoriser SF;
         
        -svds(U, s, V, X, 10);
        +bool status = SF.factorise(A);
        +
        +if(status == false) { cout << "factorisation failed" << endl; }
        +
        +double rcond_value = SF.rcond();
        +
        +vec B1(1000, fill::randu);
        +vec B2(1000, fill::randu);
        +
        +vec X1;
        +vec X2;
        +
        +bool solution1_ok = SF.solve(X1,B1);
        +bool solution2_ok = SF.solve(X2,B2);
        +
        +if(solution1_ok == false) { cout << "couldn't find X1" << endl; }
        +if(solution2_ok == false) { cout << "couldn't find X2" << endl; }
         
    • @@ -13955,11 +14704,9 @@
    • See also:

    • @@ -14031,9 +14778,9 @@
    • fft()
    • cor()
    • interp1()
    • -
    • Convolution in MathWorld
    • -
    • Convolution in Wikipedia
    • -
    • FIR filter in Wikipedia
    • +
    • Convolution in MathWorld
    • +
    • Convolution in Wikipedia
    • +
    • FIR filter in Wikipedia

    @@ -14062,7 +14809,7 @@
    -
  • The implementation of 2D convolution in this version is preliminary; it is not yet fully optimised
  • +
  • The implementation of 2D convolution in this version is preliminary

  • Examples: @@ -14085,9 +14832,9 @@
  • conv()
  • fft2()
  • interp2()
  • -
  • Convolution in MathWorld
  • -
  • Convolution in Wikipedia
  • -
  • Kernel (image processing) in Wikipedia
  • +
  • Convolution in MathWorld
  • +
  • Convolution in Wikipedia
  • +
  • Kernel (image processing) in Wikipedia

  • @@ -14121,7 +14868,23 @@
  • Caveat: the transform is fastest when the transform length is a power of 2, eg. 64, 128, 256, 512, 1024, ...

  • -
  • The implementation of the transform in this version is preliminary; it is not yet fully optimised
  • +
  • +By default, an internal FFT algorithm based on KISS FFT is used +
  • +
    +
  • +Since Armadillo 12.0, the FFTW3 library can be optionally used for faster execution, as follows: +
      +
    • ARMA_USE_FFTW3 must be defined before including the armadillo header: +
      + +#define ARMA_USE_FFTW3 +
      #include <armadillo> +
      +
    • +
    • you will also need to link with the FFTW3 runtime library (eg. -lfftw3)
    • +
    +

  • Examples: @@ -14140,8 +14903,8 @@
  • fft2()
  • conv()
  • real()
  • -
  • fast Fourier transform in MathWorld
  • -
  • fast Fourier transform in Wikipedia
  • +
  • fast Fourier transform in MathWorld
  • +
  • fast Fourier transform in Wikipedia

  • @@ -14166,7 +14929,7 @@
  • Caveat: the transform is fastest when both n_rows and n_cols are a power of 2, eg. 64, 128, 256, 512, 1024, ...

  • -
  • The implementation of the transform in this version is preliminary; it is not yet fully optimised
  • +
  • The implementation of the 2D transform in this version is preliminary

  • Examples: @@ -14186,8 +14949,8 @@
  • fft()
  • conv2()
  • real()
  • -
  • fast Fourier transform in MathWorld
  • -
  • fast Fourier transform in Wikipedia
  • +
  • fast Fourier transform in MathWorld
  • +
  • fast Fourier transform in Wikipedia

  • @@ -14417,7 +15180,7 @@
  • polynomial in Wikipedia
  • least squares in Wikipedia
  • curve fitting in Wikipedia
  • -
  • least squares fitting in MathWorld
  • +
  • least squares fitting in MathWorld

  • @@ -14692,9 +15455,21 @@
  • -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 +The norm_type argument is optional; by default norm_type = 0 is used +
  • +
    +
  • +the norm_type argument controls the type of normalisation used, with N denoting the number of observations: +
      +
    • +for norm_type = 0, normalisation is done using N-1, +providing the best unbiased estimation of the covariance matrix (if the observations are from a normal distribution) +
    • +
    • +for norm_type = 1, normalisation is done using N, +which provides the second moment matrix of the observations about their mean +
    • +

  • @@ -14716,7 +15491,7 @@
  • cor()
  • statistics functions
  • running_stat_vec
  • -
  • Covariance in MathWorld
  • +
  • Covariance in MathWorld

  • @@ -14753,8 +15528,15 @@
  • -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 norm_type argument is optional; by default norm_type = 0 is used +
  • +
    +
  • +the norm_type argument controls the type of normalisation used, with N denoting the number of observations: +
      +
    • for norm_type = 0, normalisation is done using N-1
    • +
    • for norm_type = 1, normalisation is done using N
    • +

  • @@ -14777,8 +15559,8 @@
  • conv()
  • statistics functions
  • running_stat_vec
  • -
  • Correlation in MathWorld
  • -
  • Autocorrelation in MathWorld
  • +
  • Correlation in MathWorld
  • +
  • Autocorrelation in MathWorld

  • @@ -14917,8 +15699,8 @@
    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 +The American Statistician, 50(4), 361-365, 1996. +DOI: 10.2307/2684934
  • @@ -15006,7 +15788,7 @@
  • eig_sym()
  • svd()
  • svd_econ()
  • -
  • principal components analysis in Wikipedia
  • +
  • principal components analysis in Wikipedia

  • @@ -15072,9 +15854,9 @@
    @@ -15150,7 +15932,7 @@
    @@ -15193,8 +15975,8 @@ @@ -15249,7 +16031,7 @@
  • See also:

  • @@ -15975,7 +16757,7 @@
  • -Internal implementation details are available in the following paper: +Mathematical implementation details are available in the following paper:

  • @@ -16612,7 +17394,7 @@


    -constants (pi, inf, speed of light, ...) +constants (pi, inf, eps, ...)
      @@ -16636,7 +17418,7 @@   @@ -16668,50 +17450,51 @@ - + @@ -17152,9 +17935,9 @@
    • The physical constants were mainly taken from -NIST 2018 CODATA values, +NIST 2018 CODATA values, and some from -WolframAlpha (as of 2009-06-23) +WolframAlpha (as of 2009-06-23)

    • @@ -17176,11 +17959,11 @@
    • @@ -17192,7 +17975,7 @@ wall_clock
      • -A simple timer class for measuring the number of elapsed seconds +Simple timer class for measuring the number of elapsed seconds

      • @@ -17253,93 +18036,35 @@


        -std::ostream& x = get_cout_stream() -
        std::ostream& x = get_cerr_stream() -
        -
        set_cout_stream( user_stream ) -
        set_cerr_stream( user_stream ) -
        -
          -
        • get_cout_stream(): -
            -
          • get a reference to the stream used for printing matrices and cubes with .print() and .raw_print()
          • -
          • by default this is std::cout
          • -
          -
          -
        • get_cerr_stream(): -
            -
          • 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( custom_stream ): -
            -
          • set the stream used for printing matrices and cubes
          • -
          • the stream can also be changed via the ARMA_COUT_STREAM define; see config.hpp
          • -
          -
        • -
          -
        • set_cerr_stream( custom_stream ): -
            -
          • change the stream for printing warnings and errors -
          • the stream can also be changed via the ARMA_CERR_STREAM define; see config.hpp
          • -
          -
        • -
          -
        • -Caveats: +output streams
          • -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
            • -
            +The default stream for printing matrices and cubes is std::cout +
            the stream can be changed via the ARMA_COUT_STREAM define; see config.hpp
          • +
          • -in Armadillo 10.3 and earlier versions: -
              -
            • 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> -
            +The default stream for printing warnings and errors is std::cerr +
            the stream can be changed via the ARMA_CERR_STREAM define; see config.hpp
          • +
          • -detailed information about errors is always reported via the base std::exception class -
          • -
          +The degree of printed warnings is controlled by the ARMA_WARN_LEVEL define; see config.hpp

        • -
        • See also:

        • @@ -17392,8 +18117,8 @@
        • See also: @@ -17425,8 +18150,8 @@
        • See also: @@ -18309,9 +19034,16 @@
          • -Armadillo can be configured via editing the file include/armadillo_bits/config.hpp. +Armadillo can be configured via editing the file include/armadillo_bits/config.hpp +
          • +
            +
          • Specific functionality can be enabled or disabled by uncommenting or commenting out a particular #define, listed below. +

          • +
          • +Some options can also be specified by explicitly defining them before including the armadillo header. +

      - τ, the ratio of any circle's circumference to its radius (replacement of 2π) + τ, the ratio of any circle's circumference to its radius (equivalent to 2π)
      - datum::e + datum::eps   - base of the natural logarithm + machine epsilon; approximately 2.2204e-16; difference between 1 and the next representable value +
      - datum::sqrt2 + datum::e   - square root of 2 + base of the natural logarithm
         
      @@ -18615,6 +19347,51 @@ + + + + + + + + + + + + + + + + + + + + @@ -19133,51 +19908,6 @@ - - - - - - - - - - - - - - - - - - - -
      +ARMA_USE_FFTW3 + +   + +Enable use of the FFTW3 library by fft() and ifft(); +you will need to link with the FFTW3 library (eg. -lfftw3) +
      +   + +   + +   +
      +ARMA_DONT_USE_FFTW3 + +   + +Disable the use of the FFTW3 library; overrides ARMA_USE_FFTW3 +
      +   + +   + +   +
      ARMA_DONT_USE_STD_MUTEX @@ -19015,12 +19792,10 @@   -Disable all run-time checks, such as bounds checking. -This will result in faster code, but you first need to make sure that your code runs correctly! -We strongly recommend to have the run-time checks enabled during development, -as this greatly aids in finding mistakes in your code, and hence speeds up development. -We recommend that run-time checks be disabled only for the shipped version of your program -(ie. final release build). +Disable all run-time checks, including size conformance and bounds checks. +NOT RECOMMENDED. +DO NOT USE UNLESS YOU KNOW WHAT YOU ARE DOING AND ARE WILLING TO RISK THE DOWNSIDES. +Keeping run-time checks enabled during development and deployment greatly aids in finding mistakes in your code.
      -ARMA_PRINT_ERRORS - -   - -Print errors and warnings encountered during program execution -
      -   - -   - -   -
      -ARMA_DONT_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 -
      -   - -   - -   -
      ARMA_WARN_LEVEL @@ -19185,19 +19915,23 @@ The level of warning messages printed to ARMA_CERR_STREAM. -
      Must be an integer ≥ 0. The default value is 2. +
      Must be an integer ≥ 0. By default defined to 2. - + - +
      0 = no warnings
      0 = no warnings; generally not recommended
      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
      3 = as per level 2, and warnings about failed decompositions, failed saving / loading, etc
      +
      +Example usage: +
      +#define ARMA_WARN_LEVEL 1
      +#include <armadillo>
      +
      - -
    • See also: @@ -19256,8 +19990,8 @@ See also:

    • @@ -19267,11 +20001,11 @@


      - + History of API Additions, Changes and Deprecations
        -
      • API Stability and Versioning: +
      • API Stability and Version Policy:

          @@ -19281,12 +20015,15 @@
        • Each release of Armadillo has its full version specified as A.B.C, where A is a major version number, B is a minor version number, and C is a patch level (indicating bug fixes). +The version specification has explicit meaning, similar to Semantic Versioning, as follows:

        • +
          • -Within a major version (eg. 7), each minor version has a public API that strongly strives to be backwards compatible (at the source level) with the public API of preceding minor versions. -For example, user code written for version 7.100 should work with version 7.200, 7.300, 7.400, etc. -However, as later minor versions may have more features (API extensions) than preceding minor versions, user code specifically written for version 7.400 may not work with 7.300. +Within a major version (eg. 10), each minor version (eg. 10.2) has a public API that strongly strives to be backwards compatible (at the source level) with the public API of preceding minor versions. +For example, user code written for version 10.0 should work with version 10.1, 10.2, etc. +However, later minor versions may have more features (API additions and extensions) than preceding minor versions. +As such, user code specifically written for version 10.2 may not work with 10.1.

          • @@ -19295,14 +20032,16 @@
          • We don't like changes to existing public API and strongly prefer not to break any user software. -However, to allow evolution, we reserve the right to alter the public API in future major versions of Armadillo while remaining backwards compatible in as many cases as possible -(eg. major version 8 may have slightly different public API than major version 7). +However, to allow evolution, the public API may be altered in future major versions while remaining backwards compatible in as many cases as possible +(eg. major version 11 may have slightly different public API than major version 10).
          • +

        • -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 be removed or changed without notice. -(In other words, don't use internal functionality). +Caveat: +the above policy applies only to the public API described in the documentation. +Any functionality within Armadillo which is not explicitly described in the public API documentation is considered as internal implementation details, +and may be changed or removed without notice.
      • @@ -19330,6 +20069,84 @@ + +
      • Version 12.6: + +
      • +
        + +
      • Version 12.4: +
          +
        • added norm2est() for finding fast estimates of matrix 2-norm (spectral norm)
        • +
        • added vecnorm() for obtaining the vector norm of each row or column of a matrix
        • +
        +
      • +
        + +
      • Version 12.2: +
          +
        • more efficient use of FFTW3 by fft() and ifft()
        • +
        • faster in-place element-wise multiplication of sparse matrices by dense matrices
        • +
        • added spsolve_factoriser class to allow reuse of sparse matrix factorisation for solving systems of linear equations
        • +
        +
      • +
        + +
      • Version 12.0: + +
      • +
        + +
      • Version 11.4: +
          +
        • extended pow() with various forms of element-wise power operations
        • +
        • added find_nan() to find indices of NaN elements
        • +
        • faster handling of compound expressions by sum()
        • +
        +
      • +
        + +
      • Version 11.2: +
          +
        • extended randu() and randn() to allow specification of distribution parameters
        • +
        • added inv_opts::no_ugly option to inv() and inv_sympd() to disallow inverses of poorly conditioned matrices
        • +
        • more efficient handling of rank-deficient matrices via inv_opts::allow_approx option in inv() and inv_sympd()
        • +
        • faster handling of sparse submatrix column views by norm(), accu(), nonzeros()
        • +
        • faster handling of symmetric and diagonal matrices by cond()
        • +
        • better detection of rank deficient matrices by solve()
        • +
        +
      • +
        + +
      • Version 11.0: +
          +
        • added variants of inv() and inv_sympd() that provide rcond (reciprocal condition number)
        • +
        • expanded inv() and inv_sympd() with options inv_opts::tiny and inv_opts::allow_approx
        • +
        • stricter handling of singular matrices by inv() and inv_sympd()
        • +
        • stricter handling of non-sympd matrices by inv_sympd()
        • +
        • stricter handling of non-finite matrices by pinv()
        • +
        • more robust handling of rank deficient matrices by solve()
        • +
        • faster handling of diagonal matrices by rcond()
        • +
        • changed eigs_sym() and eigs_gen() to use higher quality RNG
        • +
        • quantile() and median() will now throw an exception if given matrices/vectors have NaN elements
        • +
        +
      • +
      • Version 10.8:
          @@ -19355,7 +20172,7 @@
        • 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
        • +
        • added csv_opts::semicolon option to allow saving / loading of CSV files with semicolon (;) instead of comma (,) as the separator

      • @@ -19377,7 +20194,7 @@
      • 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
      • +
      • reduced the default degree of warning messages, so that failed decompositions, failed saving / loading, etc, no longer emit warnings

      @@ -19592,7 +20409,7 @@
    • faster loading of CSV files
    • expanded kron() to handle sparse matrices
    • expanded index_min() and index_max() to handle cubes
    • -
    • expanded randi(), randu(), randn(), randg() to output single scalars
    • +
    • expanded randi(), randu(), randn(), randg() to output single scalars
    • added submatrix & subcube iterators
    • added normcdf()
    • added mvnrnd()
    • @@ -19637,7 +20454,7 @@
    • Version 7.960:
    • @@ -20140,7 +20957,7 @@
    • expressions X=inv(A)*B and X=A.i()*B are automatically converted to X=solve(A,B)
    • better detection of vector expressions by sum(), cumsum(), prod(), min(), max(), mean(), median(), stddev(), var()
    • faster generation of random numbers -(eg. randu() and randn()), +(eg. randu() and randn()), via an algorithm that produces slightly different numbers than in 2.x
    • @@ -20252,8 +21069,8 @@

    • -rand() has been replaced by randu(); -this has been done to avoid confusion with std::rand(), +rand() has been replaced by randu(); +this has been done to avoid confusion with std::rand(), which generates random numbers in a different interval

    • diff -Nru armadillo-10.8.2+dfsg/examples/README.txt armadillo-12.6.1+dfsg/examples/README.txt --- armadillo-10.8.2+dfsg/examples/README.txt 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/examples/README.txt 2016-06-16 16:27:01.000000000 +0000 @@ -7,11 +7,11 @@ 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 + g++ example1.cpp -o example1 -std=c++11 -O2 -I /home/user/armadillo-12.2.0/include -DARMA_DONT_USE_WRAPPER -lopenblas -The above command assumes that the armadillo archive was unpacked into /home/blah/ -The command needs to be adjusted if the archive was unpacked into a different directory -and/or for each specific version of Armadillo (ie. "7.200.3" needs to be changed) +The above command assumes that the armadillo archive was unpacked into /home/user/ +The command needs to be adjusted if the archive was unpacked into a different directory, +and/or for each specific version of Armadillo (ie. "12.2.0" 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 diff -Nru armadillo-10.8.2+dfsg/include/armadillo armadillo-12.6.1+dfsg/include/armadillo --- armadillo-10.8.2+dfsg/include/armadillo 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo 2016-06-16 16:27:01.000000000 +0000 @@ -19,6 +19,10 @@ #ifndef ARMA_INCLUDES #define ARMA_INCLUDES +// NOTE: functions that are designed to be user accessible are described in the documentation (docs.html). +// NOTE: all other functions and classes (ie. not explicitly described in the documentation) +// NOTE: are considered as internal implementation details, and may be changed or removed without notice. + #include "armadillo_bits/config.hpp" #include "armadillo_bits/compiler_check.hpp" @@ -52,16 +56,39 @@ #include #endif -#if defined(ARMA_USE_TBB_ALLOC) - #include +// #if defined(ARMA_HAVE_CXX17) +// #include +// #include +// #endif + +#if ( defined(__unix__) || defined(__unix) || defined(_POSIX_C_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) ) && !defined(_WIN32) + #include #endif -#if defined(ARMA_USE_MKL_ALLOC) - #include +#if defined(ARMA_USE_TBB_ALLOC) + #if defined(__has_include) + #if __has_include() + #include + #else + #undef ARMA_USE_TBB_ALLOC + #pragma message ("WARNING: use of TBB alloc disabled; tbb/scalable_allocator.h header not found") + #endif + #else + #include + #endif #endif -#if ( defined(__unix__) || defined(__unix) || defined(_POSIX_C_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) ) && !defined(_WIN32) - #include +#if defined(ARMA_USE_MKL_ALLOC) + #if defined(__has_include) + #if __has_include() + #include + #else + #undef ARMA_USE_MKL_ALLOC + #pragma message ("WARNING: use of MKL alloc disabled; mkl_service.h header not found") + #endif + #else + #include + #endif #endif @@ -69,11 +96,19 @@ #if defined(ARMA_USE_OPENMP) - #include + #if defined(__has_include) + #if __has_include() + #include + #else + #undef ARMA_USE_OPENMP + #pragma message ("WARNING: use of OpenMP disabled; omp.h header not found") + #endif + #else + #include + #endif #endif -#include "armadillo_bits/include_atlas.hpp" #include "armadillo_bits/include_hdf5.hpp" #include "armadillo_bits/include_superlu.hpp" @@ -105,13 +140,12 @@ #include "armadillo_bits/arma_rel_comparators.hpp" #include "armadillo_bits/fill.hpp" - #ifdef ARMA_RNG_ALT + #if defined(ARMA_RNG_ALT) #include ARMA_INCFILE_WRAP(ARMA_RNG_ALT) #else - #include "armadillo_bits/arma_rng_cxx98.hpp" + #include "armadillo_bits/arma_rng_cxx03.hpp" #endif - #include "armadillo_bits/arma_rng_cxx11.hpp" #include "armadillo_bits/arma_rng.hpp" @@ -123,17 +157,18 @@ #include "armadillo_bits/SpBase_bones.hpp" #include "armadillo_bits/def_blas.hpp" - #include "armadillo_bits/def_lapack.hpp" #include "armadillo_bits/def_atlas.hpp" + #include "armadillo_bits/def_lapack.hpp" #include "armadillo_bits/def_arpack.hpp" #include "armadillo_bits/def_superlu.hpp" - #include "armadillo_bits/def_hdf5.hpp" + #include "armadillo_bits/def_fftw3.hpp" #include "armadillo_bits/translate_blas.hpp" - #include "armadillo_bits/translate_lapack.hpp" #include "armadillo_bits/translate_atlas.hpp" + #include "armadillo_bits/translate_lapack.hpp" #include "armadillo_bits/translate_arpack.hpp" #include "armadillo_bits/translate_superlu.hpp" + #include "armadillo_bits/translate_fftw3.hpp" #include "armadillo_bits/cond_rel_bones.hpp" #include "armadillo_bits/arrayops_bones.hpp" @@ -199,6 +234,7 @@ #include "armadillo_bits/mtGlue_bones.hpp" #include "armadillo_bits/SpGlue_bones.hpp" #include "armadillo_bits/mtSpGlue_bones.hpp" + #include "armadillo_bits/SpToDGlue_bones.hpp" #include "armadillo_bits/GlueCube_bones.hpp" #include "armadillo_bits/eGlueCube_bones.hpp" @@ -207,7 +243,6 @@ #include "armadillo_bits/eop_core_bones.hpp" #include "armadillo_bits/eglue_core_bones.hpp" - #include "armadillo_bits/GenSpecialiser.hpp" #include "armadillo_bits/Gen_bones.hpp" #include "armadillo_bits/GenCube_bones.hpp" @@ -216,7 +251,8 @@ #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_inv_gen_bones.hpp" + #include "armadillo_bits/op_inv_spd_bones.hpp" #include "armadillo_bits/op_htrans_bones.hpp" #include "armadillo_bits/op_max_bones.hpp" #include "armadillo_bits/op_min_bones.hpp" @@ -268,6 +304,8 @@ #include "armadillo_bits/op_nonzeros_bones.hpp" #include "armadillo_bits/op_diff_bones.hpp" #include "armadillo_bits/op_norm_bones.hpp" + #include "armadillo_bits/op_vecnorm_bones.hpp" + #include "armadillo_bits/op_norm2est_bones.hpp" #include "armadillo_bits/op_sqrtmat_bones.hpp" #include "armadillo_bits/op_logmat_bones.hpp" #include "armadillo_bits/op_range_bones.hpp" @@ -275,12 +313,16 @@ #include "armadillo_bits/op_wishrnd_bones.hpp" #include "armadillo_bits/op_roots_bones.hpp" #include "armadillo_bits/op_cond_bones.hpp" + #include "armadillo_bits/op_rcond_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/op_row_as_mat_bones.hpp" + #include "armadillo_bits/op_col_as_mat_bones.hpp" #include "armadillo_bits/glue_times_bones.hpp" + #include "armadillo_bits/glue_times_misc_bones.hpp" #include "armadillo_bits/glue_mixed_bones.hpp" #include "armadillo_bits/glue_cov_bones.hpp" #include "armadillo_bits/glue_cor_bones.hpp" @@ -304,6 +346,7 @@ #include "armadillo_bits/glue_affmul_bones.hpp" #include "armadillo_bits/glue_mvnrnd_bones.hpp" #include "armadillo_bits/glue_quantile_bones.hpp" + #include "armadillo_bits/glue_powext_bones.hpp" #include "armadillo_bits/gmm_misc_bones.hpp" #include "armadillo_bits/gmm_diag_bones.hpp" @@ -325,6 +368,7 @@ #include "armadillo_bits/spop_repmat_bones.hpp" #include "armadillo_bits/spop_vectorise_bones.hpp" #include "armadillo_bits/spop_norm_bones.hpp" + #include "armadillo_bits/spop_vecnorm_bones.hpp" #include "armadillo_bits/spglue_plus_bones.hpp" #include "armadillo_bits/spglue_minus_bones.hpp" @@ -337,6 +381,8 @@ #include "armadillo_bits/spglue_merge_bones.hpp" #include "armadillo_bits/spglue_relational_bones.hpp" + #include "armadillo_bits/spsolve_factoriser_bones.hpp" + #if defined(ARMA_USE_NEWARP) #include "armadillo_bits/newarp_EigsSelect.hpp" #include "armadillo_bits/newarp_DenseGenMatProd_bones.hpp" @@ -426,6 +472,7 @@ #include "armadillo_bits/fn_diagmat.hpp" #include "armadillo_bits/fn_diagvec.hpp" #include "armadillo_bits/fn_inv.hpp" + #include "armadillo_bits/fn_inv_sympd.hpp" #include "armadillo_bits/fn_trace.hpp" #include "armadillo_bits/fn_trans.hpp" #include "armadillo_bits/fn_det.hpp" @@ -445,6 +492,7 @@ #include "armadillo_bits/fn_elem.hpp" #include "armadillo_bits/fn_approx_equal.hpp" #include "armadillo_bits/fn_norm.hpp" + #include "armadillo_bits/fn_vecnorm.hpp" #include "armadillo_bits/fn_dot.hpp" #include "armadillo_bits/fn_randu.hpp" #include "armadillo_bits/fn_randn.hpp" @@ -503,7 +551,7 @@ #include "armadillo_bits/fn_inplace_trans.hpp" #include "armadillo_bits/fn_randi.hpp" #include "armadillo_bits/fn_randg.hpp" - #include "armadillo_bits/fn_cond.hpp" + #include "armadillo_bits/fn_cond_rcond.hpp" #include "armadillo_bits/fn_normalise.hpp" #include "armadillo_bits/fn_clamp.hpp" #include "armadillo_bits/fn_expmat.hpp" @@ -532,6 +580,8 @@ #include "armadillo_bits/fn_randperm.hpp" #include "armadillo_bits/fn_quantile.hpp" #include "armadillo_bits/fn_powmat.hpp" + #include "armadillo_bits/fn_powext.hpp" + #include "armadillo_bits/fn_diags_spdiags.hpp" #include "armadillo_bits/fn_speye.hpp" #include "armadillo_bits/fn_spones.hpp" @@ -546,9 +596,10 @@ // misc stuff #include "armadillo_bits/hdf5_misc.hpp" - #include "armadillo_bits/fft_engine.hpp" + #include "armadillo_bits/fft_engine_kissfft.hpp" + #include "armadillo_bits/fft_engine_fftw3.hpp" #include "armadillo_bits/band_helper.hpp" - #include "armadillo_bits/sympd_helper.hpp" + #include "armadillo_bits/sym_helper.hpp" #include "armadillo_bits/trimat_helper.hpp" // @@ -577,6 +628,7 @@ #include "armadillo_bits/GlueCube_meat.hpp" #include "armadillo_bits/SpGlue_meat.hpp" #include "armadillo_bits/mtSpGlue_meat.hpp" + #include "armadillo_bits/SpToDGlue_meat.hpp" #include "armadillo_bits/eOp_meat.hpp" #include "armadillo_bits/eOpCube_meat.hpp" @@ -646,7 +698,8 @@ #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_inv_gen_meat.hpp" + #include "armadillo_bits/op_inv_spd_meat.hpp" #include "armadillo_bits/op_htrans_meat.hpp" #include "armadillo_bits/op_max_meat.hpp" #include "armadillo_bits/op_index_max_meat.hpp" @@ -698,6 +751,8 @@ #include "armadillo_bits/op_nonzeros_meat.hpp" #include "armadillo_bits/op_diff_meat.hpp" #include "armadillo_bits/op_norm_meat.hpp" + #include "armadillo_bits/op_vecnorm_meat.hpp" + #include "armadillo_bits/op_norm2est_meat.hpp" #include "armadillo_bits/op_sqrtmat_meat.hpp" #include "armadillo_bits/op_logmat_meat.hpp" #include "armadillo_bits/op_range_meat.hpp" @@ -705,12 +760,16 @@ #include "armadillo_bits/op_wishrnd_meat.hpp" #include "armadillo_bits/op_roots_meat.hpp" #include "armadillo_bits/op_cond_meat.hpp" + #include "armadillo_bits/op_rcond_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/op_row_as_mat_meat.hpp" + #include "armadillo_bits/op_col_as_mat_meat.hpp" #include "armadillo_bits/glue_times_meat.hpp" + #include "armadillo_bits/glue_times_misc_meat.hpp" #include "armadillo_bits/glue_mixed_meat.hpp" #include "armadillo_bits/glue_cov_meat.hpp" #include "armadillo_bits/glue_cor_meat.hpp" @@ -734,6 +793,7 @@ #include "armadillo_bits/glue_affmul_meat.hpp" #include "armadillo_bits/glue_mvnrnd_meat.hpp" #include "armadillo_bits/glue_quantile_meat.hpp" + #include "armadillo_bits/glue_powext_meat.hpp" #include "armadillo_bits/gmm_misc_meat.hpp" #include "armadillo_bits/gmm_diag_meat.hpp" @@ -755,6 +815,7 @@ #include "armadillo_bits/spop_repmat_meat.hpp" #include "armadillo_bits/spop_vectorise_meat.hpp" #include "armadillo_bits/spop_norm_meat.hpp" + #include "armadillo_bits/spop_vecnorm_meat.hpp" #include "armadillo_bits/spglue_plus_meat.hpp" #include "armadillo_bits/spglue_minus_meat.hpp" @@ -767,6 +828,8 @@ #include "armadillo_bits/spglue_merge_meat.hpp" #include "armadillo_bits/spglue_relational_meat.hpp" + #include "armadillo_bits/spsolve_factoriser_meat.hpp" + #if defined(ARMA_USE_NEWARP) #include "armadillo_bits/newarp_cx_attrib.hpp" #include "armadillo_bits/newarp_SortEigenvalue.hpp" diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arma_config.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arma_config.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arma_config.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arma_config.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -44,10 +44,31 @@ #endif - #if defined(ARMA_USE_ATLAS) - static constexpr bool atlas = true; + #if defined(ARMA_OPTIMISE_BAND) + static constexpr bool optimise_band = true; #else - static constexpr bool atlas = false; + static constexpr bool optimise_band = false; + #endif + + + #if defined(ARMA_OPTIMISE_SYM) + static constexpr bool optimise_sym = true; + #else + static constexpr bool optimise_sym = false; + #endif + + + #if defined(ARMA_OPTIMISE_INVEXPR) + static constexpr bool optimise_invexpr = true; + #else + static constexpr bool optimise_invexpr = false; + #endif + + + #if defined(ARMA_CHECK_NONFINITE) + static constexpr bool check_nonfinite = true; + #else + static constexpr bool check_nonfinite = false; #endif @@ -65,6 +86,13 @@ #endif + #if defined(ARMA_USE_ATLAS) + static constexpr bool atlas = true; + #else + static constexpr bool atlas = false; + #endif + + #if defined(ARMA_USE_NEWARP) static constexpr bool newarp = true; #else @@ -146,6 +174,13 @@ #endif + #if defined(ARMA_HAVE_CXX20) + static constexpr bool cxx20 = true; + #else + static constexpr bool cxx20 = false; + #endif + + #if (!defined(ARMA_DONT_USE_STD_MUTEX)) static constexpr bool std_mutex = true; #else @@ -181,6 +216,27 @@ #endif + #if defined(ARMA_DONT_ZERO_INIT) + static constexpr bool zero_init = false; + #else + static constexpr bool zero_init = true; + #endif + + + #if defined(ARMA_FAST_MATH) + static constexpr bool fast_math = true; + #else + static constexpr bool fast_math = false; + #endif + + + #if defined(ARMA_FAST_MATH) && !defined(ARMA_DONT_PRINT_FAST_MATH_WARNING) + static constexpr bool fast_math_warn = true; + #else + static constexpr bool fast_math_warn = false; + #endif + + static constexpr uword warn_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : 0; }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arma_forward.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arma_forward.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arma_forward.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arma_forward.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -83,12 +83,18 @@ class op_strans; class op_htrans; class op_htrans2; -class op_inv; -class op_inv_sympd; +class op_inv_gen_default; +class op_inv_spd_default; +class op_inv_gen_full; +class op_inv_spd_full; class op_diagmat; class op_trimat; class op_vectorise_row; class op_vectorise_col; + +class op_row_as_mat; +class op_col_as_mat; + class glue_times; class glue_times_diag; @@ -115,8 +121,6 @@ class gen_eye; class gen_ones; class gen_zeros; -class gen_randu; -class gen_randn; @@ -241,9 +245,10 @@ template< typename T1, typename op_type> class CubeToMatOp; template class mtOp; -template< typename T1, typename T2, typename glue_type> class Glue; -template< typename T1, typename T2, typename eglue_type> class eGlue; -template class mtGlue; +template< typename T1, typename T2, typename glue_type> class Glue; +template< typename T1, typename T2, typename eglue_type> class eGlue; +template< typename T1, typename T2, typename glue_type> class SpToDGlue; +template class mtGlue; @@ -346,6 +351,7 @@ template struct injector_end_of_row {}; +// DEPRECATED: DO NOT USE IN NEW CODE static const injector_end_of_row<> endr = injector_end_of_row<>(); //!< endr indicates "end of row" when using the << operator; //!< similar conceptual meaning to std::endl diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arma_ostream_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arma_ostream_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arma_ostream_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arma_ostream_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -49,8 +49,7 @@ 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 raw_print_elem_zero(std::ostream& o); + template inline static void print_elem_zero(std::ostream& o, const bool modify); 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); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arma_ostream_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arma_ostream_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arma_ostream_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arma_ostream_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -425,7 +425,6 @@ //! Print a matrix to the specified stream template -arma_cold inline void arma_ostream::print(std::ostream& o, const Mat& m, const bool modify) @@ -495,7 +494,6 @@ //! Print a cube to the specified stream template -arma_cold inline void arma_ostream::print(std::ostream& o, const Cube& x, const bool modify) @@ -538,7 +536,6 @@ //! Print a field to the specified stream //! Assumes type oT can be printed, ie. oT has std::ostream& operator<< (std::ostream&, const oT&) template -arma_cold inline void arma_ostream::print(std::ostream& o, const field& x) @@ -612,7 +609,6 @@ //! Print a subfield to the specified stream //! Assumes type oT can be printed, ie. oT has std::ostream& operator<< (std::ostream&, const oT&) template -arma_cold inline void arma_ostream::print(std::ostream& o, const subview_field& x) @@ -683,7 +679,6 @@ template -arma_cold inline void arma_ostream::print_dense(std::ostream& o, const SpMat& m, const bool modify) @@ -766,7 +761,6 @@ template -arma_cold inline void arma_ostream::print(std::ostream& o, const SpMat& m, const bool modify) @@ -869,7 +863,6 @@ -arma_cold inline void arma_ostream::print(std::ostream& o, const SizeMat& S) @@ -891,7 +884,6 @@ -arma_cold inline void arma_ostream::print(std::ostream& o, const SizeCube& S) @@ -914,7 +906,6 @@ template -arma_cold inline void arma_ostream::brief_print(std::ostream& o, const Mat& m, const bool print_size) @@ -1073,7 +1064,6 @@ template -arma_cold inline void arma_ostream::brief_print(std::ostream& o, const Cube& x) @@ -1131,7 +1121,6 @@ template -arma_cold inline void arma_ostream::brief_print(std::ostream& o, const SpMat& m) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng_cxx03.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arma_rng_cxx03.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng_cxx03.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arma_rng_cxx03.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,185 @@ +// 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 arma_rng_cxx03 +//! @{ + + + +class arma_rng_cxx03 + { + public: + + typedef unsigned int seed_type; + + inline static void set_seed(const seed_type val); + + arma_inline static int randi_val(); + arma_inline static double randu_val(); + inline static double randn_val(); + + template + inline static void randn_dual_val(eT& out1, eT& out2); + + template + inline static void randi_fill(eT* mem, const uword N, const int a, const int b); + + inline static int randi_max_val(); + }; + + + +inline +void +arma_rng_cxx03::set_seed(const arma_rng_cxx03::seed_type val) + { + std::srand(val); + } + + + +arma_inline +int +arma_rng_cxx03::randi_val() + { + #if (RAND_MAX == 32767) + { + // NOTE: this is a better-than-nothing solution + // NOTE: see also arma_rng_cxx03::randi_max_val() + + u32 val1 = u32(std::rand()); + u32 val2 = u32(std::rand()); + + val1 <<= 15; + + return (val1 | val2); + } + #else + { + return std::rand(); + } + #endif + } + + + +arma_inline +double +arma_rng_cxx03::randu_val() + { + return double( double(randi_val()) * ( double(1) / double(randi_max_val()) ) ); + } + + + +inline +double +arma_rng_cxx03::randn_val() + { + // polar form of the Box-Muller transformation: + // http://en.wikipedia.org/wiki/Box-Muller_transformation + // http://en.wikipedia.org/wiki/Marsaglia_polar_method + + double tmp1 = double(0); + double tmp2 = double(0); + double w = double(0); + + do + { + tmp1 = double(2) * double(randi_val()) * (double(1) / double(randi_max_val())) - double(1); + tmp2 = double(2) * double(randi_val()) * (double(1) / double(randi_max_val())) - double(1); + + w = tmp1*tmp1 + tmp2*tmp2; + } + while( w >= double(1) ); + + return double( tmp1 * std::sqrt( (double(-2) * std::log(w)) / w) ); + } + + + +template +inline +void +arma_rng_cxx03::randn_dual_val(eT& out1, eT& out2) + { + // make sure we are internally using at least floats + typedef typename promote_type::result eTp; + + eTp tmp1 = eTp(0); + eTp tmp2 = eTp(0); + eTp w = eTp(0); + + do + { + tmp1 = eTp(2) * eTp(randi_val()) * (eTp(1) / eTp(randi_max_val())) - eTp(1); + tmp2 = eTp(2) * eTp(randi_val()) * (eTp(1) / eTp(randi_max_val())) - eTp(1); + + w = tmp1*tmp1 + tmp2*tmp2; + } + while( w >= eTp(1) ); + + const eTp k = std::sqrt( (eTp(-2) * std::log(w)) / w); + + out1 = eT(tmp1*k); + out2 = eT(tmp2*k); + } + + + +template +inline +void +arma_rng_cxx03::randi_fill(eT* mem, const uword N, const int a, const int b) + { + if( (a == 0) && (b == RAND_MAX) ) + { + for(uword i=0; i - arma_inline void randn_dual_val(eT& out1, eT& out2); - - template - inline void randi_fill(eT* mem, const uword N, const int a, const int b); - - inline static int randi_max_val(); - - template - inline void randg_fill_simple(eT* mem, const uword N, const double a, const double b); - - template - inline void randg_fill(eT* mem, const uword N, const double a, const double b); - - - private: - - arma_aligned std::mt19937_64 engine; // typedef for std::mersenne_twister_engine with preset parameters - - arma_aligned std::uniform_int_distribution i_distr; // by default uses a=0, b=std::numeric_limits::max() - - arma_aligned std::uniform_real_distribution u_distr; // by default uses [0,1) interval - - arma_aligned std::normal_distribution n_distr; // by default uses mean=0.0 and stddev=1.0 - }; - - - -inline -void -arma_rng_cxx11::set_seed(const arma_rng_cxx11::seed_type val) - { - engine.seed(val); - - i_distr.reset(); - u_distr.reset(); - n_distr.reset(); - } - - - -arma_inline -int -arma_rng_cxx11::randi_val() - { - return i_distr(engine); - } - - - -arma_inline -double -arma_rng_cxx11::randu_val() - { - return u_distr(engine); - } - - - -arma_inline -double -arma_rng_cxx11::randn_val() - { - return n_distr(engine); - } - - - -template -arma_inline -void -arma_rng_cxx11::randn_dual_val(eT& out1, eT& out2) - { - out1 = eT( n_distr(engine) ); - out2 = eT( n_distr(engine) ); - } - - - -template -inline -void -arma_rng_cxx11::randi_fill(eT* mem, const uword N, const int a, const int b) - { - std::uniform_int_distribution local_i_distr(a, b); - - for(uword i=0; i::max(); - } - - - -template -inline -void -arma_rng_cxx11::randg_fill_simple(eT* mem, const uword N, const double a, const double b) - { - std::gamma_distribution g_distr(a,b); - - for(uword i=0; i -inline -void -arma_rng_cxx11::randg_fill(eT* mem, const uword N, const double a, const double b) - { - #if defined(ARMA_USE_OPENMP) - { - if((N < 512) || omp_in_parallel()) { (*this).randg_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((*this).randi_val()) ); - - 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 - { - (*this).randg_fill_simple(mem, N, a, b); - } - #endif - } - - -//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng_cxx98.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arma_rng_cxx98.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arma_rng_cxx98.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arma_rng_cxx98.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,185 +0,0 @@ -// 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 arma_rng_cxx98 -//! @{ - - - -class arma_rng_cxx98 - { - public: - - typedef unsigned int seed_type; - - inline static void set_seed(const seed_type val); - - arma_inline static int randi_val(); - arma_inline static double randu_val(); - inline static double randn_val(); - - template - inline static void randn_dual_val(eT& out1, eT& out2); - - template - inline static void randi_fill(eT* mem, const uword N, const int a, const int b); - - inline static int randi_max_val(); - }; - - - -inline -void -arma_rng_cxx98::set_seed(const arma_rng_cxx98::seed_type val) - { - std::srand(val); - } - - - -arma_inline -int -arma_rng_cxx98::randi_val() - { - #if (RAND_MAX == 32767) - { - // NOTE: this is a better-than-nothing solution - // NOTE: see also arma_rng_cxx98::randi_max_val() - - u32 val1 = u32(std::rand()); - u32 val2 = u32(std::rand()); - - val1 <<= 15; - - return (val1 | val2); - } - #else - { - return std::rand(); - } - #endif - } - - - -arma_inline -double -arma_rng_cxx98::randu_val() - { - return double( double(randi_val()) * ( double(1) / double(randi_max_val()) ) ); - } - - - -inline -double -arma_rng_cxx98::randn_val() - { - // polar form of the Box-Muller transformation: - // http://en.wikipedia.org/wiki/Box-Muller_transformation - // http://en.wikipedia.org/wiki/Marsaglia_polar_method - - double tmp1 = double(0); - double tmp2 = double(0); - double w = double(0); - - do - { - tmp1 = double(2) * double(randi_val()) * (double(1) / double(randi_max_val())) - double(1); - tmp2 = double(2) * double(randi_val()) * (double(1) / double(randi_max_val())) - double(1); - - w = tmp1*tmp1 + tmp2*tmp2; - } - while( w >= double(1) ); - - return double( tmp1 * std::sqrt( (double(-2) * std::log(w)) / w) ); - } - - - -template -inline -void -arma_rng_cxx98::randn_dual_val(eT& out1, eT& out2) - { - // make sure we are internally using at least floats - typedef typename promote_type::result eTp; - - eTp tmp1 = eTp(0); - eTp tmp2 = eTp(0); - eTp w = eTp(0); - - do - { - tmp1 = eTp(2) * eTp(randi_val()) * (eTp(1) / eTp(randi_max_val())) - eTp(1); - tmp2 = eTp(2) * eTp(randi_val()) * (eTp(1) / eTp(randi_max_val())) - eTp(1); - - w = tmp1*tmp1 + tmp2*tmp2; - } - while( w >= eTp(1) ); - - const eTp k = std::sqrt( (eTp(-2) * std::log(w)) / w); - - out1 = eT(tmp1*k); - out2 = eT(tmp2*k); - } - - - -template -inline -void -arma_rng_cxx98::randi_fill(eT* mem, const uword N, const int a, const int b) - { - if( (a == 0) && (b == RAND_MAX) ) - { - for(uword i=0; i local_u_distr(a,b); + + for(uword i=0; i < N; ++i) { mem[i] = eT( local_u_distr(mt19937_64_instance) ); } + } + #else + { + if(N == uword(1)) { mem[0] = eT( arma_rng_cxx03::randu_val() * (b - a) + a ); return; } + + typedef typename std::mt19937_64::result_type local_seed_type; + + std::mt19937_64 local_engine; + std::uniform_real_distribution local_u_distr(a,b); + + local_engine.seed( local_seed_type(std::rand()) ); + + for(uword i=0; i < N; ++i) { mem[i] = eT( local_u_distr(local_engine) ); } + } + #endif + } }; @@ -373,8 +407,8 @@ } #else { - const T a = T( arma_rng_cxx98::randu_val() ); - const T b = T( arma_rng_cxx98::randu_val() ); + const T a = T( arma_rng_cxx03::randu_val() ); + const T b = T( arma_rng_cxx03::randu_val() ); return std::complex(a, b); } @@ -413,8 +447,8 @@ { if(N == uword(1)) { - const T a = T( arma_rng_cxx98::randu_val() ); - const T b = T( arma_rng_cxx98::randu_val() ); + const T a = T( arma_rng_cxx03::randu_val() ); + const T b = T( arma_rng_cxx03::randu_val() ); mem[0] = std::complex(a, b); @@ -438,6 +472,68 @@ } #endif } + + + inline + static + void + fill(std::complex* mem, const uword N, const double a, const double b) + { + #if defined(ARMA_RNG_ALT) + { + const double r = b - a; + + for(uword i=0; i < N; ++i) + { + const T tmp1 = T( arma_rng_alt::randu_val() * r + a ); + const T tmp2 = T( arma_rng_alt::randu_val() * r + a ); + + mem[i] = std::complex(tmp1, tmp2); + } + } + #elif defined(ARMA_USE_EXTERN_RNG) + { + std::uniform_real_distribution local_u_distr(a,b); + + for(uword i=0; i < N; ++i) + { + const T tmp1 = T( local_u_distr(mt19937_64_instance) ); + const T tmp2 = T( local_u_distr(mt19937_64_instance) ); + + mem[i] = std::complex(tmp1, tmp2); + } + } + #else + { + if(N == uword(1)) + { + const double r = b - a; + + const T tmp1 = T( arma_rng_cxx03::randu_val() * r + a); + const T tmp2 = T( arma_rng_cxx03::randu_val() * r + a); + + mem[0] = std::complex(tmp1, tmp2); + + return; + } + + typedef typename std::mt19937_64::result_type local_seed_type; + + std::mt19937_64 local_engine; + std::uniform_real_distribution local_u_distr(a,b); + + local_engine.seed( local_seed_type(std::rand()) ); + + for(uword i=0; i < N; ++i) + { + const T tmp1 = T( local_u_distr(local_engine) ); + const T tmp2 = T( local_u_distr(local_engine) ); + + mem[i] = std::complex(tmp1, tmp2); + } + } + #endif + } }; @@ -464,7 +560,7 @@ } #else { - return eT( arma_rng_cxx98::randn_val() ); + return eT( arma_rng_cxx03::randn_val() ); } #endif } @@ -488,7 +584,7 @@ } #else { - arma_rng_cxx98::randn_dual_val(out1, out2); + arma_rng_cxx03::randn_dual_val(out1, out2); } #endif } @@ -497,7 +593,7 @@ inline static void - fill_simple(eT* mem, const uword N) + fill(eT* mem, const uword N) { #if defined(ARMA_RNG_ALT) { @@ -517,7 +613,7 @@ } #else { - if(N == uword(1)) { mem[0] = eT( arma_rng_cxx98::randn_val() ); return; } + if(N == uword(1)) { mem[0] = eT( arma_rng_cxx03::randn_val() ); return; } typedef typename std::mt19937_64::result_type local_seed_type; @@ -535,52 +631,60 @@ inline static void - fill(eT* mem, const uword N) + fill(eT* mem, const uword N, const double mu, const double sd) { - #if defined(ARMA_USE_OPENMP) + #if defined(ARMA_RNG_ALT) { - if((N < 1024) || omp_in_parallel()) { arma_rng::randn::fill_simple(mem, N); return; } - - typedef typename std::mt19937_64::result_type local_seed_type; - - const uword n_threads = uword( mp_thread_limit::get() ); + // NOTE: old method to avoid regressions in user code that assumes specific sequence - std::vector< std::mt19937_64 > engine(n_threads); - std::vector< std::normal_distribution > distr(n_threads); + uword i, j; - for(uword t=0; t < n_threads; ++t) + for(i=0, j=1; j < N; i+=2, j+=2) { - std::mt19937_64& t_engine = engine[t]; + eT val_i = eT(0); + eT val_j = eT(0); - t_engine.seed( local_seed_type(t) + local_seed_type(arma_rng::randi()) ); + arma_rng_alt::randn_dual_val( val_i, val_j ); + + mem[i] = (val_i * sd) + mu; + mem[j] = (val_j * sd) + mu; } - const uword chunk_size = N / n_threads; + if(i < N) + { + const eT val_i = eT( arma_rng_alt::randn_val() ); + + mem[i] = (val_i * sd) + mu; + } + } + #elif defined(ARMA_USE_EXTERN_RNG) + { + std::normal_distribution local_n_distr(mu, sd); - #pragma omp parallel for schedule(static) num_threads(int(n_threads)) - for(uword t=0; t < n_threads; ++t) + for(uword i=0; i < N; ++i) { mem[i] = eT( local_n_distr(mt19937_64_instance) ); } + } + #else + { + if(N == uword(1)) { - const uword start = (t+0) * chunk_size; - const uword endp1 = (t+1) * chunk_size; + const eT val = eT( arma_rng_cxx03::randn_val() ); - std::mt19937_64& t_engine = engine[t]; - std::normal_distribution& t_distr = distr[t]; + mem[0] = (val * sd) + mu; - for(uword i=start; i < endp1; ++i) { mem[i] = eT( t_distr(t_engine)); } + return; } - std::mt19937_64& t0_engine = engine[0]; - std::normal_distribution& t0_distr = distr[0]; + typedef typename std::mt19937_64::result_type local_seed_type; - for(uword i=(n_threads*chunk_size); i < N; ++i) { mem[i] = eT( t0_distr(t0_engine)); } - } - #else - { - arma_rng::randn::fill_simple(mem, N); + std::mt19937_64 local_engine; + std::normal_distribution local_n_distr(mu, sd); + + local_engine.seed( local_seed_type(std::rand()) ); + + for(uword i=0; i < N; ++i) { mem[i] = eT( local_n_distr(local_engine) ); } } #endif } - }; @@ -631,7 +735,7 @@ inline static void - fill_simple(std::complex* mem, const uword N) + fill(std::complex* mem, const uword N) { #if defined(ARMA_RNG_ALT) { @@ -656,7 +760,7 @@ T a = T(0); T b = T(0); - arma_rng_cxx98::randn_dual_val(a,b); + arma_rng_cxx03::randn_dual_val(a,b); mem[0] = std::complex(a,b); @@ -685,62 +789,18 @@ inline static void - fill(std::complex* mem, const uword N) + fill(std::complex* mem, const uword N, const double mu, const double sd) { - #if defined(ARMA_USE_OPENMP) + arma_rng::randn< std::complex >::fill(mem, N); + + if( (mu == double(0)) && (sd == double(1)) ) { return; } + + for(uword i=0; i >::fill_simple(mem, N); return; } - - typedef typename std::mt19937_64::result_type local_seed_type; - - const uword n_threads = uword( mp_thread_limit::get() ); - - std::vector< std::mt19937_64 > engine(n_threads); - std::vector< std::normal_distribution > distr(n_threads); - - for(uword t=0; t < n_threads; ++t) - { - std::mt19937_64& t_engine = engine[t]; - - t_engine.seed( local_seed_type(t) + local_seed_type(arma_rng::randi()) ); - } - - 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; - - std::mt19937_64& t_engine = engine[t]; - std::normal_distribution& t_distr = distr[t]; - - for(uword i=start; i < endp1; ++i) - { - const T val1 = T( t_distr(t_engine) ); - const T val2 = T( t_distr(t_engine) ); - - mem[i] = std::complex(val1, val2); - } - } - - std::mt19937_64& t0_engine = engine[0]; - std::normal_distribution& t0_distr = distr[0]; + const std::complex& val = mem[i]; - for(uword i=(n_threads*chunk_size); i < N; ++i) - { - const T val1 = T( t0_distr(t0_engine) ); - const T val2 = T( t0_distr(t0_engine) ); - - mem[i] = std::complex(val1, val2); - } - } - #else - { - arma_rng::randn< std::complex >::fill_simple(mem, N); + mem[i] = std::complex( ((val.real() * sd) + mu), ((val.imag() * sd) + mu) ); } - #endif } }; @@ -756,7 +816,7 @@ inline static void - fill_simple(eT* mem, const uword N, const double a, const double b) + fill(eT* mem, const uword N, const double a, const double b) { #if defined(ARMA_USE_EXTERN_RNG) { @@ -777,64 +837,6 @@ } #endif } - - - inline - static - void - fill(eT* mem, const uword N, const double a, const double b) - { - #if defined(ARMA_USE_OPENMP) - { - if((N < 512) || omp_in_parallel()) { arma_rng::randg::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-10.8.2+dfsg/include/armadillo_bits/arma_str.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arma_str.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arma_str.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arma_str.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,24 +22,57 @@ namespace arma_str { - - class format + class char_buffer { public: - format(const char* in_fmt) - : A(in_fmt) + static constexpr uword n_chars_prealloc = 1024; + + char* mem = nullptr; + uword n_chars = 0; + + char local_mem[n_chars_prealloc]; + + inline + ~char_buffer() { + if(n_chars > n_chars_prealloc) { std::free(mem); } + + mem = nullptr; + n_chars = 0; } - format(const std::string& in_fmt) - : A(in_fmt) + inline + char_buffer() { + mem = &(local_mem[0]); + n_chars = n_chars_prealloc; + + if(n_chars > 0) { mem[0] = char(0); } } - // TODO: constructor to handle std::string&& ? + inline + void + set_size(const uword new_n_chars) + { + if(n_chars > n_chars_prealloc) { std::free(mem); } + + mem = (new_n_chars <= n_chars_prealloc) ? &(local_mem[0]) : (char*)std::malloc(new_n_chars); + n_chars = (new_n_chars <= n_chars_prealloc) ? n_chars_prealloc : new_n_chars; + + if(n_chars > 0) { mem[0] = char(0); } + } + }; + + + class format + { + public: + + const std::string fmt; - const std::string A; + inline format(const char* in_fmt) : fmt(in_fmt) { } + inline format(const std::string& in_fmt) : fmt(in_fmt) { } private: format(); @@ -52,15 +85,11 @@ { public: - basic_format(const T1& in_A, const T2& in_B) - : A(in_A) - , B(in_B) - { - } - const T1& A; const T2& B; + inline basic_format(const T1& in_A, const T2& in_B) : A(in_A) , B(in_B) { } + private: basic_format(); }; @@ -92,49 +121,30 @@ std::string str(const basic_format< format, T2>& X) { - char local_buffer[1024]; - char* buffer = local_buffer; - - int buffer_size = 1024; - int required_size = buffer_size; - - bool using_local_buffer = true; - std::string out; + char_buffer buf; + + bool status = false; - do + while(status == false) { - if(using_local_buffer == false) - { - buffer = new char[size_t(buffer_size)]; - } - - required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B); + int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.fmt.c_str(), X.B); if(required_size < 0) { break; } - if(required_size < buffer_size) + if(uword(required_size) >= buf.n_chars) { - if(required_size > 0) - { - out = buffer; - } + if(buf.n_chars > char_buffer::n_chars_prealloc) { break; } + + buf.set_size(1 + uword(required_size)); } else { - buffer_size *= 2; + status = true; } - if(using_local_buffer) - { - using_local_buffer = false; - } - else - { - delete[] buffer; - } - - } while( (required_size >= buffer_size) ); + if(status) { out = buf.mem; } + } return out; } @@ -146,49 +156,30 @@ std::string str(const basic_format< basic_format< format, T2>, T3>& X) { - char local_buffer[1024]; - char* buffer = local_buffer; - - int buffer_size = 1024; - int required_size = buffer_size; - - bool using_local_buffer = true; - + char_buffer buf; std::string out; - do + bool status = false; + + while(status == false) { - if(using_local_buffer == false) - { - buffer = new char[size_t(buffer_size)]; - } - - required_size = std::snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B); + int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.fmt.c_str(), X.A.B, X.B); if(required_size < 0) { break; } - if(required_size < buffer_size) + if(uword(required_size) >= buf.n_chars) { - if(required_size > 0) - { - out = buffer; - } + if(buf.n_chars > char_buffer::n_chars_prealloc) { break; } + + buf.set_size(1 + uword(required_size)); } else { - buffer_size *= 2; + status = true; } - if(using_local_buffer) - { - using_local_buffer = false; - } - else - { - delete[] buffer; - } - - } while( (required_size >= buffer_size) ); + if(status) { out = buf.mem; } + } return out; } @@ -200,49 +191,30 @@ std::string str(const basic_format< basic_format< basic_format< format, T2>, T3>, T4>& X) { - char local_buffer[1024]; - char* buffer = local_buffer; - - int buffer_size = 1024; - int required_size = buffer_size; - - bool using_local_buffer = true; - + char_buffer buf; std::string out; - do + bool status = false; + + while(status == false) { - if(using_local_buffer == false) - { - buffer = new char[size_t(buffer_size)]; - } - - 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); + int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.A.fmt.c_str(), X.A.A.B, X.A.B, X.B); if(required_size < 0) { break; } - if(required_size < buffer_size) - { - if(required_size > 0) - { - out = buffer; - } - } - else - { - buffer_size *= 2; - } - - if(using_local_buffer) + if(uword(required_size) >= buf.n_chars) { - using_local_buffer = false; + if(buf.n_chars > char_buffer::n_chars_prealloc) { break; } + + buf.set_size(1 + uword(required_size)); } else { - delete[] buffer; + status = true; } - } while( (required_size >= buffer_size) ); + if(status) { out = buf.mem; } + } return out; } @@ -254,49 +226,30 @@ std::string str(const basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>& X) { - char local_buffer[1024]; - char* buffer = local_buffer; - - int buffer_size = 1024; - int required_size = buffer_size; - - bool using_local_buffer = true; - + char_buffer buf; std::string out; - do + bool status = false; + + while(status == false) { - if(using_local_buffer == false) - { - buffer = new char[size_t(buffer_size)]; - } - - 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); + int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.A.A.fmt.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B); if(required_size < 0) { break; } - if(required_size < buffer_size) + if(uword(required_size) >= buf.n_chars) { - if(required_size > 0) - { - out = buffer; - } + if(buf.n_chars > char_buffer::n_chars_prealloc) { break; } + + buf.set_size(1 + uword(required_size)); } else { - buffer_size *= 2; + status = true; } - if(using_local_buffer) - { - using_local_buffer = false; - } - else - { - delete[] buffer; - } - - } while( (required_size >= buffer_size) ); + if(status) { out = buf.mem; } + } return out; } @@ -308,49 +261,30 @@ std::string str(const basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>& X) { - char local_buffer[1024]; - char* buffer = local_buffer; - - int buffer_size = 1024; - int required_size = buffer_size; - - bool using_local_buffer = true; - + char_buffer buf; std::string out; - do + bool status = false; + + while(status == false) { - if(using_local_buffer == false) - { - buffer = new char[size_t(buffer_size)]; - } - - 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); + int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.A.A.A.fmt.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; } - if(required_size < buffer_size) + if(uword(required_size) >= buf.n_chars) { - if(required_size > 0) - { - out = buffer; - } + if(buf.n_chars > char_buffer::n_chars_prealloc) { break; } + + buf.set_size(1 + uword(required_size)); } else { - buffer_size *= 2; + status = true; } - if(using_local_buffer) - { - using_local_buffer = false; - } - else - { - delete[] buffer; - } - - } while( (required_size >= buffer_size) ); + if(status) { out = buf.mem; } + } return out; } @@ -362,49 +296,30 @@ std::string str(const basic_format< basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>, T7>& X) { - char local_buffer[1024]; - char* buffer = local_buffer; - - int buffer_size = 1024; - int required_size = buffer_size; - - bool using_local_buffer = true; - + char_buffer buf; std::string out; - do + bool status = false; + + while(status == false) { - if(using_local_buffer == false) - { - buffer = new char[size_t(buffer_size)]; - } - - 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); + int required_size = (std::snprintf)(buf.mem, size_t(buf.n_chars), X.A.A.A.A.A.A.fmt.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; } - if(required_size < buffer_size) + if(uword(required_size) >= buf.n_chars) { - if(required_size > 0) - { - out = buffer; - } + if(buf.n_chars > char_buffer::n_chars_prealloc) { break; } + + buf.set_size(1 + uword(required_size)); } else { - buffer_size *= 2; + status = true; } - if(using_local_buffer) - { - using_local_buffer = false; - } - else - { - delete[] buffer; - } - - } while( (required_size >= buffer_size) ); + if(status) { out = buf.mem; } + } return out; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arma_version.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arma_version.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arma_version.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arma_version.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,10 +21,10 @@ -#define ARMA_VERSION_MAJOR 10 -#define ARMA_VERSION_MINOR 8 -#define ARMA_VERSION_PATCH 2 -#define ARMA_VERSION_NAME "Realm Raider" +#define ARMA_VERSION_MAJOR 12 +#define ARMA_VERSION_MINOR 6 +#define ARMA_VERSION_PATCH 1 +#define ARMA_VERSION_NAME "Cortisol Retox" diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arrayops_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arrayops_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arrayops_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arrayops_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -29,10 +29,6 @@ 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 inline static void fill_zeros(eT* dest, const uword n_elem); @@ -144,11 +140,6 @@ void inplace_set_base(eT* dest, const eT val, const uword n_elem); - template - arma_cold inline static - void - inplace_set_small(eT* dest, const eT val, const uword n_elem); - template arma_hot inline static void diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/arrayops_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/arrayops_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/arrayops_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/arrayops_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -28,53 +28,7 @@ { if( (dest == src) || (n_elem == 0) ) { return; } - if(is_cx::no) - { - if(n_elem <= 9) - { - arrayops::copy_small(dest, src, n_elem); - } - else - { - std::memcpy(dest, src, n_elem*sizeof(eT)); - } - } - else - { - std::memcpy(dest, src, n_elem*sizeof(eT)); - } - } - - - -template -arma_cold -inline -void -arrayops::copy_small(eT* dest, const eT* src, const uword n_elem) - { - switch(n_elem) - { - case 9: dest[ 8] = src[ 8]; - // fallthrough - case 8: dest[ 7] = src[ 7]; - // fallthrough - case 7: dest[ 6] = src[ 6]; - // fallthrough - case 6: dest[ 5] = src[ 5]; - // fallthrough - case 5: dest[ 4] = src[ 4]; - // fallthrough - case 4: dest[ 3] = src[ 3]; - // fallthrough - case 3: dest[ 2] = src[ 2]; - // fallthrough - case 2: dest[ 1] = src[ 1]; - // fallthrough - case 1: dest[ 0] = src[ 0]; - // fallthrough - default: ; - } + std::memcpy(dest, src, n_elem*sizeof(eT)); } @@ -101,7 +55,6 @@ template -arma_hot inline void arrayops::replace(eT* mem, const uword n_elem, const eT old_val, const eT new_val) @@ -129,7 +82,6 @@ template -arma_hot inline void arrayops::clean(eT* mem, const uword n_elem, const eT abs_limit, const typename arma_not_cx::result* junk) @@ -147,7 +99,6 @@ template -arma_hot inline void arrayops::clean(std::complex* mem, const uword n_elem, const T abs_limit) @@ -280,7 +231,6 @@ template -arma_hot inline void arrayops::convert(out_eT* dest, const in_eT* src, const uword n_elem) @@ -350,7 +300,6 @@ template -arma_hot inline void arrayops::convert_cx(out_eT* dest, const in_eT* src, const uword n_elem) @@ -372,7 +321,6 @@ template -arma_hot inline void arrayops::inplace_plus(eT* dest, const eT* src, const uword n_elem) @@ -410,7 +358,6 @@ template -arma_hot inline void arrayops::inplace_minus(eT* dest, const eT* src, const uword n_elem) @@ -448,7 +395,6 @@ template -arma_hot inline void arrayops::inplace_mul(eT* dest, const eT* src, const uword n_elem) @@ -486,7 +432,6 @@ template -arma_hot inline void arrayops::inplace_div(eT* dest, const eT* src, const uword n_elem) @@ -524,7 +469,6 @@ template -arma_hot inline void arrayops::inplace_plus_base(eT* dest, const eT* src, const uword n_elem) @@ -560,7 +504,6 @@ template -arma_hot inline void arrayops::inplace_minus_base(eT* dest, const eT* src, const uword n_elem) @@ -596,7 +539,6 @@ template -arma_hot inline void arrayops::inplace_mul_base(eT* dest, const eT* src, const uword n_elem) @@ -632,7 +574,6 @@ template -arma_hot inline void arrayops::inplace_div_base(eT* dest, const eT* src, const uword n_elem) @@ -668,7 +609,6 @@ template -arma_hot inline void arrayops::inplace_set(eT* dest, const eT val, const uword n_elem) @@ -679,21 +619,13 @@ } else { - if( (n_elem <= 9) && (is_cx::no) ) - { - arrayops::inplace_set_small(dest, val, n_elem); - } - else - { - arrayops::inplace_set_simple(dest, val, n_elem); - } + arrayops::inplace_set_simple(dest, val, n_elem); } } template -arma_hot inline void arrayops::inplace_set_simple(eT* dest, const eT val, const uword n_elem) @@ -713,7 +645,6 @@ template -arma_hot inline void arrayops::inplace_set_base(eT* dest, const eT val, const uword n_elem) @@ -745,40 +676,7 @@ -template -arma_cold -inline -void -arrayops::inplace_set_small(eT* dest, const eT val, const uword n_elem) - { - switch(n_elem) - { - case 9: dest[ 8] = val; - // fallthrough - case 8: dest[ 7] = val; - // fallthrough - case 7: dest[ 6] = val; - // fallthrough - case 6: dest[ 5] = val; - // fallthrough - case 5: dest[ 4] = val; - // fallthrough - case 4: dest[ 3] = val; - // fallthrough - case 3: dest[ 2] = val; - // fallthrough - case 2: dest[ 1] = val; - // fallthrough - case 1: dest[ 0] = val; - // fallthrough - default:; - } - } - - - template -arma_hot inline void arrayops::inplace_set_fixed(eT* dest, const eT val) @@ -792,7 +690,6 @@ template -arma_hot inline void arrayops::inplace_plus(eT* dest, const eT val, const uword n_elem) @@ -812,7 +709,6 @@ template -arma_hot inline void arrayops::inplace_minus(eT* dest, const eT val, const uword n_elem) @@ -832,7 +728,6 @@ template -arma_hot inline void arrayops::inplace_mul(eT* dest, const eT val, const uword n_elem) @@ -852,7 +747,6 @@ template -arma_hot inline void arrayops::inplace_div(eT* dest, const eT val, const uword n_elem) @@ -872,7 +766,6 @@ template -arma_hot inline void arrayops::inplace_plus_base(eT* dest, const eT val, const uword n_elem) @@ -905,7 +798,6 @@ template -arma_hot inline void arrayops::inplace_minus_base(eT* dest, const eT val, const uword n_elem) @@ -938,7 +830,6 @@ template -arma_hot inline void arrayops::inplace_mul_base(eT* dest, const eT val, const uword n_elem) @@ -971,7 +862,6 @@ template -arma_hot inline void arrayops::inplace_div_base(eT* dest, const eT val, const uword n_elem) @@ -1004,12 +894,11 @@ template -arma_hot inline eT arrayops::accumulate(const eT* src, const uword n_elem) { - #if defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ > 0) + #if defined(__FAST_MATH__) { eT acc = eT(0); @@ -1051,7 +940,6 @@ template -arma_hot inline eT arrayops::product(const eT* src, const uword n_elem) @@ -1078,7 +966,6 @@ 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) @@ -1108,7 +995,6 @@ template -arma_hot inline bool arrayops::is_zero(const std::complex* mem, const uword n_elem, const T abs_limit) @@ -1144,7 +1030,6 @@ template -arma_hot inline bool arrayops::is_finite(const eT* src, const uword n_elem) @@ -1156,18 +1041,13 @@ const eT val_i = (*src); src++; const eT val_j = (*src); src++; - if( (arma_isfinite(val_i) == false) || (arma_isfinite(val_j) == false) ) - { - return false; - } + if(arma_isfinite(val_i) == false) { return false; } + if(arma_isfinite(val_j) == false) { return false; } } if((j-1) < n_elem) { - if(arma_isfinite(*src) == false) - { - return false; - } + if(arma_isfinite(*src) == false) { return false; } } return true; @@ -1176,7 +1056,6 @@ template -arma_hot inline bool arrayops::has_inf(const eT* src, const uword n_elem) @@ -1202,7 +1081,6 @@ template -arma_hot inline bool arrayops::has_nan(const eT* src, const uword n_elem) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/auxlib_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/auxlib_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/auxlib_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/auxlib_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -20,7 +20,7 @@ //! @{ -//! interface functions for accessing decompositions in LAPACK and ATLAS +//! low-level interface functions for accessing LAPACK class auxlib { public: @@ -35,19 +35,25 @@ inline static bool inv(Mat& out, const Mat& X); template + inline static bool inv_rcond(Mat& A, typename get_pod_type::result& out_rcond); + + template inline static bool inv_tr(Mat& A, const uword layout); template - inline static bool inv_sympd(Mat& A); + inline static bool inv_tr_rcond(Mat& A, typename get_pod_type::result& out_rcond, const uword layout); + + template + inline static bool inv_sympd(Mat& A, bool& out_sympd_state); template inline static bool inv_sympd(Mat& out, const Mat& X); template - inline static bool inv_sympd_rcond(Mat& A, const eT rcond_threshold); + inline static bool inv_sympd_rcond(Mat& A, bool& out_sympd_state, eT& out_rcond); template - inline static bool inv_sympd_rcond(Mat< std::complex >& A, const T rcond_threshold); + inline static bool inv_sympd_rcond(Mat< std::complex >& A, bool& out_sympd_state, T& out_rcond); // @@ -250,19 +256,16 @@ // solve template - arma_cold inline static bool solve_square_tiny(Mat& out, const Mat& A, const Base& B_expr); - - template inline static bool solve_square_fast(Mat& out, Mat& A, const Base& B_expr); template - inline static bool solve_square_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool allow_ugly); + inline static bool solve_square_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr); template - inline static bool solve_square_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate, const bool allow_ugly); + inline static bool solve_square_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate); template - inline static bool solve_square_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate, const bool allow_ugly); + inline static bool solve_square_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate); // @@ -273,16 +276,16 @@ inline static bool solve_sympd_fast_common(Mat& out, Mat& A, const Base& B_expr); template - inline static bool solve_sympd_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool allow_ugly); + inline static bool solve_sympd_rcond(Mat& out, bool& out_sympd_state, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr); template - inline static bool solve_sympd_rcond(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base< std::complex,T1>& B_expr, const bool allow_ugly); + inline static bool solve_sympd_rcond(Mat< std::complex >& out, bool& out_sympd_state, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base< std::complex,T1>& B_expr); template - inline static bool solve_sympd_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate, const bool allow_ugly); + inline static bool solve_sympd_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate); template - inline static bool solve_sympd_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate, const bool allow_ugly); + inline static bool solve_sympd_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate); // @@ -290,7 +293,7 @@ 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); + inline static bool solve_rect_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr); // @@ -306,7 +309,7 @@ inline static bool solve_trimat_fast(Mat& out, const Mat& A, const Base& B_expr, const uword layout); template - inline static bool solve_trimat_rcond(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const Base& B_expr, const uword layout, const bool allow_ugly); + inline static bool solve_trimat_rcond(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const Base& B_expr, const uword layout); // @@ -320,19 +323,19 @@ inline static bool solve_band_fast_common(Mat& out, const Mat& A, const uword KL, const uword KU, const Base& B_expr); template - inline static bool solve_band_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool allow_ugly); + inline static bool solve_band_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr); template - inline static bool solve_band_rcond(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base< std::complex,T1>& B_expr, const bool allow_ugly); + inline static bool solve_band_rcond(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base< std::complex,T1>& B_expr); template - inline static bool solve_band_rcond_common(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool allow_ugly); + inline static bool solve_band_rcond_common(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const uword KL, const uword KU, const Base& B_expr); template - inline static bool solve_band_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool equilibrate, const bool allow_ugly); + inline static bool solve_band_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool equilibrate); template - inline static bool solve_band_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base,T1>& B_expr, const bool equilibrate, const bool allow_ugly); + inline static bool solve_band_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base,T1>& B_expr, const bool equilibrate); // @@ -425,9 +428,6 @@ template inline static bool crippled_lapack(const Base&); - template - inline static typename T1::pod_type epsilon_lapack(const Base&); - template inline static bool rudimentary_sym_check(const Mat& X); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/auxlib_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/auxlib_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/auxlib_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/auxlib_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -30,25 +30,7 @@ if(A.is_empty()) { return true; } - #if defined(ARMA_USE_ATLAS) - { - arma_debug_assert_atlas_size(A); - - podarray ipiv(A.n_rows); - - int info = 0; - - arma_extra_debug_print("atlas::clapack_getrf()"); - 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, A.n_rows, A.memptr(), A.n_rows, ipiv.memptr()); - - return (info == 0); - } - #elif defined(ARMA_USE_LAPACK) + #if defined(ARMA_USE_LAPACK) { arma_debug_assert_blas_size(A); @@ -59,10 +41,15 @@ podarray ipiv(A.n_rows); + arma_extra_debug_print("lapack::getrf()"); + lapack::getrf(&n, &n, A.memptr(), &lda, ipiv.memptr(), &info); + + if(info != 0) { return false; } + if(n > 16) { - eT work_query[2]; - blas_int lwork_query = -1; + eT work_query[2] = {}; + blas_int lwork_query = -1; arma_extra_debug_print("lapack::getri()"); lapack::getri(&n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info); @@ -76,11 +63,6 @@ podarray work( static_cast(lwork) ); - arma_extra_debug_print("lapack::getrf()"); - lapack::getrf(&n, &n, A.memptr(), &lda, ipiv.memptr(), &info); - - if(info != 0) { return false; } - arma_extra_debug_print("lapack::getri()"); lapack::getri(&n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info); @@ -89,7 +71,7 @@ #else { arma_ignore(A); - arma_stop_logic_error("inv(): use of ATLAS or LAPACK must be enabled"); + arma_stop_logic_error("inv(): use of LAPACK must be enabled"); return false; } #endif @@ -114,6 +96,76 @@ template inline bool +auxlib::inv_rcond(Mat& A, typename get_pod_type::result& out_rcond) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + out_rcond = T(0); + + if(A.is_empty()) { return true; } + + #if defined(ARMA_USE_LAPACK) + { + arma_debug_assert_blas_size(A); + + char norm_id = '1'; + 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; + T norm_val = T(0); + + podarray junk(1); + podarray ipiv(A.n_rows); + + arma_extra_debug_print("lapack::lange()"); + norm_val = lapack::lange(&norm_id, &n, &n, A.memptr(), &lda, junk.memptr()); + + arma_extra_debug_print("lapack::getrf()"); + lapack::getrf(&n, &n, A.memptr(), &lda, ipiv.memptr(), &info); + + if(info != 0) { return false; } + + out_rcond = auxlib::lu_rcond(A, norm_val); + + if(n > 16) + { + eT work_query[2] = {}; + blas_int lwork_query = -1; + + arma_extra_debug_print("lapack::getri()"); + lapack::getri(&n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info); + + if(info != 0) { return false; } + + blas_int lwork_proposed = static_cast( access::tmp_real(work_query[0]) ); + + lwork = (std::max)(lwork_proposed, lwork); + } + + podarray work( static_cast(lwork) ); + + arma_extra_debug_print("lapack::getri()"); + lapack::getri(&n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info); + + return (info == 0); + } + #else + { + arma_ignore(A); + arma_stop_logic_error("inv_rcond(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +template +inline +bool auxlib::inv_tr(Mat& A, const uword layout) { arma_extra_debug_sigprint(); @@ -121,7 +173,7 @@ #if defined(ARMA_USE_LAPACK) { if(A.is_empty()) { return true; } - + arma_debug_assert_blas_size(A); char uplo = (layout == 0) ? 'U' : 'L'; @@ -134,15 +186,6 @@ if(info != 0) { return false; } - if(layout == 0) - { - A = trimatu(A); // upper triangular - } - else - { - A = trimatl(A); // lower triangular - } - return true; } #else @@ -160,33 +203,57 @@ template inline bool -auxlib::inv_sympd(Mat& A) +auxlib::inv_tr_rcond(Mat& A, typename get_pod_type::result& out_rcond, const uword layout) { arma_extra_debug_sigprint(); - if(A.is_empty()) { return true; } - - #if defined(ARMA_USE_ATLAS) + #if defined(ARMA_USE_LAPACK) { - arma_debug_assert_atlas_size(A); + typedef typename get_pod_type::result T; - int info = 0; + if(A.is_empty()) { return true; } - arma_extra_debug_print("atlas::clapack_potrf()"); - info = atlas::clapack_potrf(atlas::CblasColMajor, atlas::CblasLower, A.n_rows, A.memptr(), A.n_rows); + out_rcond = auxlib::rcond_trimat(A, layout); - if(info != 0) { return false; } + arma_debug_assert_blas_size(A); - arma_extra_debug_print("atlas::clapack_potri()"); - info = atlas::clapack_potri(atlas::CblasColMajor, atlas::CblasLower, A.n_rows, A.memptr(), A.n_rows); + char uplo = (layout == 0) ? 'U' : 'L'; + char diag = 'N'; + blas_int n = blas_int(A.n_rows); + blas_int info = 0; - if(info != 0) { return false; } + arma_extra_debug_print("lapack::trtri()"); + lapack::trtri(&uplo, &diag, &n, A.memptr(), &n, &info); - A = symmatl(A); + if(info != 0) { out_rcond = T(0); return false; } return true; } - #elif defined(ARMA_USE_LAPACK) + #else + { + arma_ignore(A); + arma_ignore(out_rcond); + arma_ignore(layout); + arma_stop_logic_error("inv(): use of LAPACK must be enabled"); + return false; + } + #endif + } + + + +template +inline +bool +auxlib::inv_sympd(Mat& A, bool& out_sympd_state) + { + arma_extra_debug_sigprint(); + + out_sympd_state = false; + + if(A.is_empty()) { return true; } + + #if defined(ARMA_USE_LAPACK) { arma_debug_assert_blas_size(A); @@ -201,6 +268,8 @@ if(info != 0) { return false; } + out_sympd_state = true; + arma_extra_debug_print("lapack::potri()"); lapack::potri(&uplo, &n, A.memptr(), &n, &info); @@ -213,7 +282,8 @@ #else { arma_ignore(A); - arma_stop_logic_error("inv_sympd(): use of ATLAS or LAPACK must be enabled"); + arma_ignore(out_sympd_state); + arma_stop_logic_error("inv_sympd(): use of LAPACK must be enabled"); return false; } #endif @@ -230,7 +300,9 @@ out = X; - return auxlib::inv_sympd(out); + bool sympd_state_junk = false; + + return auxlib::inv_sympd(out, sympd_state_junk); } @@ -238,10 +310,12 @@ template inline bool -auxlib::inv_sympd_rcond(Mat& A, const eT rcond_threshold) +auxlib::inv_sympd_rcond(Mat& A, bool& out_sympd_state, eT& out_rcond) { arma_extra_debug_sigprint(); + out_sympd_state = false; + if(A.is_empty()) { return true; } #if defined(ARMA_USE_LAPACK) @@ -264,11 +338,13 @@ arma_extra_debug_print("lapack::potrf()"); lapack::potrf(&uplo, &n, A.memptr(), &n, &info); - if(info != 0) { return false; } + if(info != 0) { out_rcond = eT(0); return false; } + + out_sympd_state = true; - const T rcond = auxlib::lu_rcond_sympd(A, norm_val); + out_rcond = auxlib::lu_rcond_sympd(A, norm_val); - if(rcond < rcond_threshold) { return false; } + if(arma_isnan(out_rcond)) { return false; } arma_extra_debug_print("lapack::potri()"); lapack::potri(&uplo, &n, A.memptr(), &n, &info); @@ -282,7 +358,8 @@ #else { arma_ignore(A); - arma_ignore(rcond_threshold); + arma_ignore(out_sympd_state); + arma_ignore(out_rcond); arma_stop_logic_error("inv_sympd_rcond(): use LAPACK must be enabled"); return false; } @@ -294,16 +371,19 @@ template inline bool -auxlib::inv_sympd_rcond(Mat< std::complex >& A, const T rcond_threshold) +auxlib::inv_sympd_rcond(Mat< std::complex >& A, bool& out_sympd_state, T& out_rcond) { arma_extra_debug_sigprint(); + out_sympd_state = false; + if(A.is_empty()) { return true; } #if defined(ARMA_CRIPPLED_LAPACK) { arma_ignore(A); - arma_ignore(rcond_threshold); + arma_ignore(out_sympd_state); + arma_ignore(out_rcond); return false; } #elif defined(ARMA_USE_LAPACK) @@ -324,11 +404,13 @@ arma_extra_debug_print("lapack::potrf()"); lapack::potrf(&uplo, &n, A.memptr(), &n, &info); - if(info != 0) { return false; } + if(info != 0) { out_rcond = T(0); return false; } - const T rcond = auxlib::lu_rcond_sympd(A, norm_val); + out_sympd_state = true; - if(rcond < rcond_threshold) { return false; } + out_rcond = auxlib::lu_rcond_sympd(A, norm_val); + + if(arma_isnan(out_rcond)) { return false; } arma_extra_debug_print("lapack::potri()"); lapack::potri(&uplo, &n, A.memptr(), &n, &info); @@ -342,7 +424,8 @@ #else { arma_ignore(A); - arma_ignore(rcond_threshold); + arma_ignore(out_sympd_state); + arma_ignore(out_rcond); arma_stop_logic_error("inv_sympd_rcond(): use LAPACK must be enabled"); return false; } @@ -361,33 +444,7 @@ if(A.is_empty()) { out_val = eT(1); return true; } - #if defined(ARMA_USE_ATLAS) - { - arma_debug_assert_atlas_size(A); - - podarray ipiv(A.n_rows); - - arma_extra_debug_print("atlas::clapack_getrf()"); - 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 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 < A.n_rows; ++i) - { - // NOTE: no adjustment required, as the clapack version of getrf() assumes counting from 0 - if( int(i) != ipiv.mem[i] ) { sign *= -1; } - } - - out_val = (sign < 0) ? eT(-val) : eT(val); - - return true; - } - #elif defined(ARMA_USE_LAPACK) + #if defined(ARMA_USE_LAPACK) { arma_debug_assert_blas_size(A); @@ -421,7 +478,7 @@ { arma_ignore(out_val); arma_ignore(A); - arma_stop_logic_error("det(): use of ATLAS or LAPACK must be enabled"); + arma_stop_logic_error("det(): use of LAPACK must be enabled"); return false; } #endif @@ -439,51 +496,9 @@ typedef typename get_pod_type::result T; - if(A.is_empty()) - { - out_val = eT(0); - out_sign = T(1); - return true; - } - - #if defined(ARMA_USE_ATLAS) - { - arma_debug_assert_atlas_size(A); - - podarray ipiv(A.n_rows); - - arma_extra_debug_print("atlas::clapack_getrf()"); - 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 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( 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 < A.n_rows; ++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 < 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; - } - } - - out_val = val; - out_sign = T(sign); - - return true; - } - #elif defined(ARMA_USE_LAPACK) + if(A.is_empty()) { out_val = eT(0); out_sign = T(1); return true; } + + #if defined(ARMA_USE_LAPACK) { arma_debug_assert_blas_size(A); @@ -529,7 +544,7 @@ 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"); + arma_stop_logic_error("log_det(): use of LAPACK must be enabled"); return false; } #endif @@ -548,26 +563,7 @@ if(A.is_empty()) { out_val = T(0); return true; } - #if defined(ARMA_USE_ATLAS) - { - arma_debug_assert_atlas_size(A); - - int info = 0; - - 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) + #if defined(ARMA_USE_LAPACK) { arma_debug_assert_blas_size(A); @@ -580,9 +576,9 @@ if(info != 0) { return false; } - T val = std::log( access::tmp_real(A.at(0,0)) ); + T val = T(0); - for(uword i=1; i < A.n_rows; ++i) { val += std::log( access::tmp_real(A.at(i,i)) ); } + for(uword i=0; i < A.n_rows; ++i) { val += std::log( access::tmp_real(A.at(i,i)) ); } out_val = T(2) * val; @@ -592,7 +588,7 @@ { arma_ignore(out_val); arma_ignore(A); - arma_stop_logic_error("det(): use of ATLAS or LAPACK must be enabled"); + arma_stop_logic_error("log_det_sympd(): use of LAPACK must be enabled"); return false; } #endif @@ -613,47 +609,26 @@ const uword U_n_rows = U.n_rows; const uword U_n_cols = U.n_cols; - if(U.is_empty()) - { - L.set_size(U_n_rows, 0); - U.set_size(0, U_n_cols); - ipiv.reset(); - return true; - } + if(U.is_empty()) { L.set_size(U_n_rows, 0); U.set_size(0, U_n_cols); ipiv.reset(); return true; } - #if defined(ARMA_USE_ATLAS) || defined(ARMA_USE_LAPACK) + #if defined(ARMA_USE_LAPACK) { - #if defined(ARMA_USE_ATLAS) - { - arma_debug_assert_atlas_size(U); - - ipiv.set_size( (std::min)(U_n_rows, U_n_cols) ); - - arma_extra_debug_print("atlas::clapack_getrf()"); - int info = atlas::clapack_getrf(atlas::CblasColMajor, U_n_rows, U_n_cols, U.memptr(), U_n_rows, ipiv.memptr()); - - if(info < 0) { return false; } - } - #elif defined(ARMA_USE_LAPACK) - { - arma_debug_assert_blas_size(U); - - ipiv.set_size( (std::min)(U_n_rows, U_n_cols) ); - - blas_int info = 0; - - blas_int n_rows = blas_int(U_n_rows); - blas_int n_cols = blas_int(U_n_cols); - - arma_extra_debug_print("lapack::getrf()"); - lapack::getrf(&n_rows, &n_cols, U.memptr(), &n_rows, ipiv.memptr(), &info); - - if(info < 0) { return false; } - - // take into account that Fortran counts from 1 - arrayops::inplace_minus(ipiv.memptr(), blas_int(1), ipiv.n_elem); - } - #endif + arma_debug_assert_blas_size(U); + + ipiv.set_size( (std::min)(U_n_rows, U_n_cols) ); + + blas_int info = 0; + + blas_int n_rows = blas_int(U_n_rows); + blas_int n_cols = blas_int(U_n_cols); + + arma_extra_debug_print("lapack::getrf()"); + lapack::getrf(&n_rows, &n_cols, U.memptr(), &n_rows, ipiv.memptr(), &info); + + if(info < 0) { return false; } + + // take into account that Fortran counts from 1 + arrayops::inplace_minus(ipiv.memptr(), blas_int(1), ipiv.n_elem); L.copy_size(U); @@ -680,7 +655,7 @@ } #else { - arma_stop_logic_error("lu(): use of ATLAS or LAPACK must be enabled"); + arma_stop_logic_error("lu(): use of LAPACK must be enabled"); return false; } #endif @@ -833,14 +808,9 @@ arma_debug_assert_blas_size(X); - if(X.is_empty()) - { - vals.reset(); - vecs.reset(); - return true; - } + if(X.is_empty()) { vals.reset(); vecs.reset(); return true; } - if(X.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && X.internal_has_nonfinite()) { return false; } vals.set_size(X.n_rows, 1); @@ -946,14 +916,9 @@ arma_debug_assert_blas_size(X); - if(X.is_empty()) - { - vals.reset(); - vecs.reset(); - return true; - } + if(X.is_empty()) { vals.reset(); vecs.reset(); return true; } - if(X.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && X.internal_has_nonfinite()) { return false; } vals.set_size(X.n_rows, 1); @@ -1018,14 +983,9 @@ arma_debug_assert_blas_size(X); - if(X.is_empty()) - { - vals.reset(); - vecs.reset(); - return true; - } + if(X.is_empty()) { vals.reset(); vecs.reset(); return true; } - if(X.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && X.internal_has_nonfinite()) { return false; } vals.set_size(X.n_rows, 1); @@ -1147,14 +1107,9 @@ arma_debug_assert_blas_size(X); - if(X.is_empty()) - { - vals.reset(); - vecs.reset(); - return true; - } + if(X.is_empty()) { vals.reset(); vecs.reset(); return true; } - if(X.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && X.internal_has_nonfinite()) { return false; } vals.set_size(X.n_rows, 1); @@ -1228,15 +1183,9 @@ arma_debug_assert_blas_size(X); - if(X.is_empty()) - { - vals.reset(); - lvecs.reset(); - rvecs.reset(); - return true; - } + if(X.is_empty()) { vals.reset(); lvecs.reset(); rvecs.reset(); return true; } - if(X.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && X.internal_has_nonfinite()) { return false; } vals.set_size(X.n_rows, 1); @@ -1335,15 +1284,9 @@ arma_debug_assert_blas_size(X); - if(X.is_empty()) - { - vals.reset(); - lvecs.reset(); - rvecs.reset(); - return true; - } + if(X.is_empty()) { vals.reset(); lvecs.reset(); rvecs.reset(); return true; } - if(X.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && X.internal_has_nonfinite()) { return false; } vals.set_size(X.n_rows, 1); @@ -1405,15 +1348,9 @@ arma_debug_assert_blas_size(X); - if(X.is_empty()) - { - vals.reset(); - lvecs.reset(); - rvecs.reset(); - return true; - } + if(X.is_empty()) { vals.reset(); lvecs.reset(); rvecs.reset(); return true; } - if(X.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && X.internal_has_nonfinite()) { return false; } vals.set_size(X.n_rows, 1); @@ -1528,15 +1465,9 @@ arma_debug_assert_blas_size(X); - if(X.is_empty()) - { - vals.reset(); - lvecs.reset(); - rvecs.reset(); - return true; - } + if(X.is_empty()) { vals.reset(); lvecs.reset(); rvecs.reset(); return true; } - if(X.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && X.internal_has_nonfinite()) { return false; } vals.set_size(X.n_rows, 1); @@ -1612,15 +1543,10 @@ arma_debug_assert_blas_size(A); - if(A.is_empty()) - { - vals.reset(); - vecs.reset(); - return true; - } + if(A.is_empty()) { vals.reset(); vecs.reset(); return true; } - if(A.is_finite() == false) { return false; } - if(B.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + if(arma_config::check_nonfinite && B.internal_has_nonfinite()) { return false; } vals.set_size(A.n_rows, 1); @@ -1755,15 +1681,10 @@ arma_debug_assert_blas_size(A); - if(A.is_empty()) - { - vals.reset(); - vecs.reset(); - return true; - } + if(A.is_empty()) { vals.reset(); vecs.reset(); return true; } - if(A.is_finite() == false) { return false; } - if(B.is_finite() == false) { return false; } + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + if(arma_config::check_nonfinite && B.internal_has_nonfinite()) { return false; } vals.set_size(A.n_rows, 1); @@ -1857,16 +1778,10 @@ arma_debug_assert_blas_size(A); - if(A.is_empty()) - { - vals.reset(); - lvecs.reset(); - rvecs.reset(); - return true; - } + 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; } + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + if(arma_config::check_nonfinite && B.internal_has_nonfinite()) { return false; } vals.set_size(A.n_rows, 1); @@ -1994,16 +1909,10 @@ arma_debug_assert_blas_size(A); - if(A.is_empty()) - { - vals.reset(); - lvecs.reset(); - rvecs.reset(); - return true; - } + 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; } + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + if(arma_config::check_nonfinite && B.internal_has_nonfinite()) { return false; } vals.set_size(A.n_rows, 1); @@ -2079,17 +1988,13 @@ if(A.is_empty()) { eigval.reset(); return true; } - // if(auxlib::rudimentary_sym_check(A) == false) - // { - // 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_level(1, "eig_sym(): given matrix is not symmetric"); } + if(arma_config::check_nonfinite && trimat_helper::has_nonfinite_triu(A)) { return false; } + arma_debug_assert_blas_size(A); eigval.set_size(A.n_rows); @@ -2136,17 +2041,13 @@ if(A.is_empty()) { eigval.reset(); return true; } - // if(auxlib::rudimentary_sym_check(A) == false) - // { - // 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_level(1, "eig_sym(): given matrix is not hermitian"); } + if(arma_config::check_nonfinite && trimat_helper::has_nonfinite_triu(A)) { return false; } + arma_debug_assert_blas_size(A); eigval.set_size(A.n_rows); @@ -2190,14 +2091,11 @@ { arma_debug_check( (X.is_square() == false), "eig_sym(): given matrix must be square sized" ); + if(arma_config::check_nonfinite && trimat_helper::has_nonfinite_triu(X)) { return false; } + eigvec = X; - if(eigvec.is_empty()) - { - eigval.reset(); - eigvec.reset(); - return true; - } + if(eigvec.is_empty()) { eigval.reset(); eigvec.reset(); return true; } arma_debug_assert_blas_size(eigvec); @@ -2244,14 +2142,11 @@ arma_debug_check( (X.is_square() == false), "eig_sym(): given matrix must be square sized" ); + if(arma_config::check_nonfinite && trimat_helper::has_nonfinite_triu(X)) { return false; } + eigvec = X; - if(eigvec.is_empty()) - { - eigval.reset(); - eigvec.reset(); - return true; - } + if(eigvec.is_empty()) { eigval.reset(); eigvec.reset(); return true; } arma_debug_assert_blas_size(eigvec); @@ -2297,14 +2192,11 @@ { arma_debug_check( (X.is_square() == false), "eig_sym(): given matrix must be square sized" ); + if(arma_config::check_nonfinite && trimat_helper::has_nonfinite_triu(X)) { return false; } + eigvec = X; - if(eigvec.is_empty()) - { - eigval.reset(); - eigvec.reset(); - return true; - } + if(eigvec.is_empty()) { eigval.reset(); eigvec.reset(); return true; } arma_debug_assert_blas_size(eigvec); @@ -2323,8 +2215,8 @@ if(N >= 32) { - eT work_query[2]; - blas_int iwork_query[2]; + eT work_query[2] = {}; + blas_int iwork_query[2] = {}; blas_int lwork_query = -1; blas_int liwork_query = -1; @@ -2376,14 +2268,11 @@ arma_debug_check( (X.is_square() == false), "eig_sym(): given matrix must be square sized" ); - eigvec = X; + if(arma_config::check_nonfinite && trimat_helper::has_nonfinite_triu(X)) { return false; } - if(eigvec.is_empty()) - { - eigval.reset(); - eigvec.reset(); - return true; - } + eigvec = X; + + if(eigvec.is_empty()) { eigval.reset(); eigvec.reset(); return true; } arma_debug_assert_blas_size(eigvec); @@ -2404,9 +2293,9 @@ if(N >= 32) { - eT work_query[2]; - T rwork_query[2]; - blas_int iwork_query[2]; + eT work_query[2] = {}; + T rwork_query[2] = {}; + blas_int iwork_query[2] = {}; blas_int lwork_query = -1; blas_int lrwork_query = -1; @@ -2455,18 +2344,7 @@ { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_ATLAS) - { - arma_debug_assert_atlas_size(X); - - int info = 0; - - arma_extra_debug_print("atlas::clapack_potrf()"); - info = atlas::clapack_potrf(atlas::CblasColMajor, atlas::CblasUpper, X.n_rows, X.memptr(), X.n_rows); - - return (info == 0); - } - #elif defined(ARMA_USE_LAPACK) + #if defined(ARMA_USE_LAPACK) { arma_debug_assert_blas_size(X); @@ -2483,7 +2361,7 @@ { arma_ignore(X); - arma_stop_logic_error("chol(): use of ATLAS or LAPACK must be enabled"); + arma_stop_logic_error("chol(): use of LAPACK must be enabled"); return false; } #endif @@ -2498,22 +2376,7 @@ { arma_extra_debug_sigprint(); - #if defined(ARMA_USE_ATLAS) - { - arma_debug_assert_atlas_size(X); - - int info = 0; - - arma_extra_debug_print("atlas::clapack_potrf()"); - info = atlas::clapack_potrf(atlas::CblasColMajor, ((layout == 0) ? atlas::CblasUpper : atlas::CblasLower), X.n_rows, X.memptr(), X.n_rows); - - if(info != 0) { return false; } - - X = (layout == 0) ? trimatu(X) : trimatl(X); // trimatu() and trimatl() return the same type - - return true; - } - #elif defined(ARMA_USE_LAPACK) + #if defined(ARMA_USE_LAPACK) { arma_debug_assert_blas_size(X); @@ -2535,7 +2398,7 @@ arma_ignore(X); arma_ignore(layout); - arma_stop_logic_error("chol(): use of ATLAS or LAPACK must be enabled"); + arma_stop_logic_error("chol(): use of LAPACK must be enabled"); return false; } #endif @@ -2696,10 +2559,7 @@ arma_debug_check( (H.is_square() == false), "hess(): given matrix must be square sized" ); - if(H.is_empty()) - { - return true; - } + if(H.is_empty()) { return true; } arma_debug_assert_blas_size(H); @@ -2751,11 +2611,7 @@ 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); - return true; - } + if(R.is_empty()) { Q.eye(R_n_rows, R_n_rows); return true; } arma_debug_assert_blas_size(R); @@ -2767,8 +2623,8 @@ podarray tau( static_cast(k) ); - eT work_query[2]; - blas_int lwork_query = -1; + eT work_query[2] = {}; + blas_int lwork_query = -1; arma_extra_debug_print("lapack::geqrf()"); lapack::geqrf(&m, &n, R.memptr(), &m, tau.memptr(), &work_query[0], &lwork_query, &info); @@ -2842,10 +2698,7 @@ const unwrap tmp(X.get_ref()); const Mat& M = tmp.M; - if(M.n_rows < M.n_cols) - { - return auxlib::qr(Q, R, X); - } + if(M.n_rows < M.n_cols) { return auxlib::qr(Q, R, X); } } Q = X.get_ref(); @@ -2853,17 +2706,9 @@ 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_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; - } + 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); @@ -2875,8 +2720,8 @@ podarray tau( static_cast(k) ); - eT work_query[2]; - blas_int lwork_query = -1; + 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); @@ -2971,8 +2816,8 @@ jpvt.zeros(); - eT work_query[2]; - blas_int lwork_query = -1; + 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); @@ -3065,8 +2910,8 @@ jpvt.zeros(); - eT work_query[2]; - blas_int lwork_query = -1; + eT work_query[2] = {}; + blas_int lwork_query = -1; 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); @@ -3129,6 +2974,8 @@ { if(A.is_empty()) { S.reset(); return true; } + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + arma_debug_assert_blas_size(A); Mat U(1, 1, arma_nozeros_indicator()); @@ -3150,10 +2997,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 1024) { - eT work_query[2]; - blas_int lwork_query = -1; + 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); @@ -3197,6 +3044,8 @@ if(A.is_empty()) { S.reset(); return true; } + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + arma_debug_assert_blas_size(A); Mat U(1, 1, arma_nozeros_indicator()); @@ -3220,10 +3069,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 256) { - eT work_query[2]; - blas_int lwork_query = -1; // query to find optimum size of workspace + 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); @@ -3263,13 +3112,9 @@ #if defined(ARMA_USE_LAPACK) { - if(A.is_empty()) - { - U.eye(A.n_rows, A.n_rows); - S.reset(); - V.eye(A.n_cols, A.n_cols); - return true; - } + if(A.is_empty()) { U.eye(A.n_rows, A.n_rows); S.reset(); V.eye(A.n_cols, A.n_cols); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A); @@ -3292,11 +3137,11 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 1024) { // query to find optimum size of workspace - eT work_query[2]; - blas_int lwork_query = -1; + 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); @@ -3344,13 +3189,9 @@ { typedef std::complex eT; - if(A.is_empty()) - { - U.eye(A.n_rows, A.n_rows); - S.reset(); - V.eye(A.n_cols, A.n_cols); - return true; - } + if(A.is_empty()) { U.eye(A.n_rows, A.n_rows); S.reset(); V.eye(A.n_cols, A.n_cols); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A); @@ -3375,10 +3216,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 256) { - eT work_query[2]; - blas_int lwork_query = -1; // query to find optimum size of workspace + 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); @@ -3424,13 +3265,9 @@ #if defined(ARMA_USE_LAPACK) { - if(A.is_empty()) - { - U.eye(); - S.reset(); - V.eye(); - return true; - } + if(A.is_empty()) { U.eye(); S.reset(); V.eye(); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A); @@ -3489,10 +3326,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 1024) { - eT work_query[2]; - blas_int lwork_query = -1; // query to find optimum size of workspace + 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); @@ -3541,13 +3378,9 @@ { typedef std::complex eT; - if(A.is_empty()) - { - U.eye(); - S.reset(); - V.eye(); - return true; - } + if(A.is_empty()) { U.eye(); S.reset(); V.eye(); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A); @@ -3607,10 +3440,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 256) { - eT work_query[2]; - blas_int lwork_query = -1; // query to find optimum size of workspace + 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); @@ -3659,6 +3492,8 @@ { if(A.is_empty()) { S.reset(); return true; } + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + arma_debug_assert_blas_size(A); Mat U(1, 1, arma_nozeros_indicator()); @@ -3682,10 +3517,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 1024) { - eT work_query[2]; - blas_int lwork_query = blas_int(-1); + 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); @@ -3729,6 +3564,8 @@ if(A.is_empty()) { S.reset(); return true; } + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + arma_debug_assert_blas_size(A); Mat U(1, 1, arma_nozeros_indicator()); @@ -3753,10 +3590,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 256) { - eT work_query[2]; - blas_int lwork_query = blas_int(-1); + 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); @@ -3796,13 +3633,9 @@ #if defined(ARMA_USE_LAPACK) { - if(A.is_empty()) - { - U.eye(A.n_rows, A.n_rows); - S.reset(); - V.eye(A.n_cols, A.n_cols); - return true; - } + if(A.is_empty()) { U.eye(A.n_rows, A.n_rows); S.reset(); V.eye(A.n_cols, A.n_cols); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A); @@ -3829,10 +3662,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 1024) { - eT work_query[2]; - blas_int lwork_query = blas_int(-1); + 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); @@ -3880,13 +3713,9 @@ { typedef std::complex eT; - if(A.is_empty()) - { - U.eye(A.n_rows, A.n_rows); - S.reset(); - V.eye(A.n_cols, A.n_cols); - return true; - } + if(A.is_empty()) { U.eye(A.n_rows, A.n_rows); S.reset(); V.eye(A.n_cols, A.n_cols); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A); @@ -3913,10 +3742,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 256) { - eT work_query[2]; - blas_int lwork_query = blas_int(-1); + 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); @@ -3962,6 +3791,8 @@ #if defined(ARMA_USE_LAPACK) { + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + arma_debug_assert_blas_size(A); char jobz = 'S'; @@ -3996,10 +3827,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 1024) { - eT work_query[2]; - blas_int lwork_query = blas_int(-1); + 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); @@ -4047,6 +3878,8 @@ { typedef std::complex eT; + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + arma_debug_assert_blas_size(A); char jobz = 'S'; @@ -4081,10 +3914,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= 256) { - eT work_query[2]; - blas_int lwork_query = blas_int(-1); + 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); @@ -4121,61 +3954,6 @@ -//! solve a system of linear equations via explicit inverse (tiny matrices) -template -arma_cold -inline -bool -auxlib::solve_square_tiny(Mat& out, const Mat& A, const Base& B_expr) - { - arma_extra_debug_sigprint(); - - // 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, arma_nozeros_indicator()); - - const bool status = op_inv::apply_tiny_noalias(A_inv, A); - - if(status == false) { return false; } - - const quasi_unwrap UB(B_expr.get_ref()); - const Mat& B = UB.M; - - const uword B_n_rows = B.n_rows; - const uword B_n_cols = B.n_cols; - - 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; - } - - if(UB.is_alias(out)) - { - Mat tmp(A_n_rows, B_n_cols, arma_nozeros_indicator()); - - gemm_emul::apply(tmp, A_inv, B); - - out.steal_mem(tmp); - } - else - { - out.set_size(A_n_rows, B_n_cols); - - gemm_emul::apply(out, A_inv, B); - } - - return true; - } - - - //! solve a system of linear equations via LU decomposition template inline @@ -4184,52 +3962,28 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - - const uword A_n_rows = A.n_rows; - - if((A_n_rows <= 4) && is_cx::no) - { - const bool status = auxlib::solve_square_tiny(out, A, B_expr.get_ref()); - - if(status) { return true; } - } - out = B_expr.get_ref(); const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - - 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() || out.is_empty()) - { - out.zeros(A.n_cols, B_n_cols); - return true; - } - #if defined(ARMA_USE_ATLAS) + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); + + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; } + + #if defined(ARMA_USE_LAPACK) { - arma_debug_assert_atlas_size(A); - - podarray ipiv(A_n_rows + 2); // +2 for paranoia: old versions of Atlas might be trashing memory - - arma_extra_debug_print("atlas::clapack_gesv()"); - int info = atlas::clapack_gesv(atlas::CblasColMajor, A_n_rows, B_n_cols, A.memptr(), A_n_rows, ipiv.memptr(), out.memptr(), A_n_rows); + typedef typename T1::elem_type eT; - return (info == 0); - } - #elif defined(ARMA_USE_LAPACK) - { arma_debug_assert_blas_size(A); - blas_int n = blas_int(A_n_rows); // assuming A is square - blas_int lda = blas_int(A_n_rows); + blas_int n = blas_int(A.n_rows); // assuming A is square + blas_int lda = blas_int(A.n_rows); blas_int ldb = blas_int(B_n_rows); blas_int nrhs = blas_int(B_n_cols); blas_int info = blas_int(0); - podarray ipiv(A_n_rows + 2); // +2 for paranoia: some versions of Lapack might be trashing memory + podarray ipiv(A.n_rows + 2); // +2 for paranoia: some versions of Lapack might be trashing memory arma_extra_debug_print("lapack::gesv()"); lapack::gesv(&n, &nrhs, A.memptr(), &lda, ipiv.memptr(), out.memptr(), &ldb, &info); @@ -4238,7 +3992,7 @@ } #else { - arma_stop_logic_error("solve(): use of ATLAS or LAPACK must be enabled"); + arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } #endif @@ -4250,7 +4004,7 @@ template inline bool -auxlib::solve_square_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool allow_ugly) +auxlib::solve_square_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr) { arma_extra_debug_sigprint(); @@ -4265,14 +4019,10 @@ const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - - 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() || out.is_empty()) - { - out.zeros(A.n_cols, B_n_cols); - return true; - } + + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); + + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; } arma_debug_assert_blas_size(A); @@ -4303,8 +4053,6 @@ out_rcond = auxlib::lu_rcond(A, norm_val); - if( (allow_ugly == false) && (out_rcond < auxlib::epsilon_lapack(A)) ) { return false; } - return true; } #else @@ -4313,7 +4061,6 @@ 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; } @@ -4326,7 +4073,7 @@ template inline bool -auxlib::solve_square_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate, const bool allow_ugly) +auxlib::solve_square_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate) { arma_extra_debug_sigprint(); @@ -4346,13 +4093,9 @@ const Mat& B = (use_copy) ? B_tmp : UB_M_as_Mat; - arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_rows, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_rows, B.n_cols); return true; } arma_debug_assert_blas_size(A,B); @@ -4405,7 +4148,7 @@ out_rcond = rcond; - return (allow_ugly) ? ((info == 0) || (info == (n+1))) : (info == 0); + return ((info == 0) || (info == (n+1))); } #else { @@ -4414,7 +4157,6 @@ arma_ignore(A); arma_ignore(B_expr); arma_ignore(equilibrate); - arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -4427,7 +4169,7 @@ template inline bool -auxlib::solve_square_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate, const bool allow_ugly) +auxlib::solve_square_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate) { arma_extra_debug_sigprint(); @@ -4448,13 +4190,9 @@ const Mat& B = (use_copy) ? B_tmp : UB_M_as_Mat; - arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_rows, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_rows, B.n_cols); return true; } arma_debug_assert_blas_size(A,B); @@ -4507,7 +4245,7 @@ out_rcond = rcond; - return (allow_ugly) ? ((info == 0) || (info == (n+1))) : (info == 0); + return ((info == 0) || (info == (n+1))); } #else { @@ -4516,7 +4254,6 @@ arma_ignore(A); arma_ignore(B_expr); arma_ignore(equilibrate); - arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -4554,49 +4291,25 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - - const uword A_n_rows = A.n_rows; - - if((A_n_rows <= 4) && is_cx::no) - { - const bool status = auxlib::solve_square_tiny(out, A, B_expr.get_ref()); - - if(status) { return true; } - } - out = B_expr.get_ref(); const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - arma_debug_check( (A_n_rows != B_n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); - if(A.is_empty() || out.is_empty()) - { - out.zeros(A.n_cols, B_n_cols); - return true; - } + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; } - #if defined(ARMA_USE_ATLAS) + #if defined(ARMA_USE_LAPACK) { - arma_debug_assert_atlas_size(A, out); - - int info = 0; - - arma_extra_debug_print("atlas::clapack_posv()"); - info = atlas::clapack_posv(atlas::CblasColMajor, atlas::CblasLower, A_n_rows, B_n_cols, A.memptr(), A_n_rows, out.memptr(), B_n_rows); + typedef typename T1::elem_type eT; - return (info == 0); - } - #elif defined(ARMA_USE_LAPACK) - { arma_debug_assert_blas_size(A, out); char uplo = 'L'; - blas_int n = blas_int(A_n_rows); // assuming A is square + blas_int n = blas_int(A.n_rows); // assuming A is square blas_int nrhs = blas_int(B_n_cols); - blas_int lda = blas_int(A_n_rows); + blas_int lda = blas_int(A.n_rows); blas_int ldb = blas_int(B_n_rows); blas_int info = blas_int(0); @@ -4610,7 +4323,7 @@ arma_ignore(out); arma_ignore(A); arma_ignore(B_expr); - arma_stop_logic_error("solve(): use of ATLAS or LAPACK must be enabled"); + arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } #endif @@ -4622,7 +4335,7 @@ template inline bool -auxlib::solve_sympd_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool allow_ugly) +auxlib::solve_sympd_rcond(Mat& out, bool& out_sympd_state, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr) { arma_extra_debug_sigprint(); @@ -4631,20 +4344,17 @@ typedef typename T1::elem_type eT; typedef typename T1::pod_type T; - out_rcond = T(0); + out_sympd_state = false; + out_rcond = T(0); out = B_expr.get_ref(); const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); - if(A.is_empty() || out.is_empty()) - { - out.zeros(A.n_cols, B_n_cols); - return true; - } + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; } arma_debug_assert_blas_size(A, out); @@ -4665,6 +4375,8 @@ if(info != 0) { return false; } + out_sympd_state = true; + arma_extra_debug_print("lapack::potrs()"); lapack::potrs(&uplo, &n, &nrhs, A.memptr(), &n, out.memptr(), &n, &info); @@ -4672,17 +4384,15 @@ out_rcond = auxlib::lu_rcond_sympd(A, norm_val); - if( (allow_ugly == false) && (out_rcond < auxlib::epsilon_lapack(A)) ) { return false; } - return true; } #else { arma_ignore(out); + arma_ignore(out_sympd_state); 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; } @@ -4695,7 +4405,7 @@ template inline bool -auxlib::solve_sympd_rcond(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base< std::complex,T1>& B_expr, const bool allow_ugly) +auxlib::solve_sympd_rcond(Mat< std::complex >& out, bool& out_sympd_state, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base< std::complex,T1>& B_expr) { arma_extra_debug_sigprint(); @@ -4703,27 +4413,26 @@ { arma_extra_debug_print("auxlib::solve_sympd_rcond(): redirecting to auxlib::solve_square_rcond() due to crippled LAPACK"); - return auxlib::solve_square_rcond(out, out_rcond, A, B_expr, allow_ugly); + out_sympd_state = false; + + return auxlib::solve_square_rcond(out, out_rcond, A, B_expr); } #elif defined(ARMA_USE_LAPACK) { typedef typename T1::pod_type T; typedef typename std::complex eT; - out_rcond = T(0); + out_sympd_state = false; + out_rcond = T(0); out = B_expr.get_ref(); const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); - if(A.is_empty() || out.is_empty()) - { - out.zeros(A.n_cols, B_n_cols); - return true; - } + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; } arma_debug_assert_blas_size(A, out); @@ -4744,6 +4453,8 @@ if(info != 0) { return false; } + out_sympd_state = true; + arma_extra_debug_print("lapack::potrs()"); lapack::potrs(&uplo, &n, &nrhs, A.memptr(), &n, out.memptr(), &n, &info); @@ -4751,17 +4462,15 @@ out_rcond = auxlib::lu_rcond_sympd(A, norm_val); - if( (allow_ugly == false) && (out_rcond < auxlib::epsilon_lapack(A)) ) { return false; } - return true; } #else { arma_ignore(out); + arma_ignore(out_sympd_state); 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; } @@ -4774,7 +4483,7 @@ template inline bool -auxlib::solve_sympd_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate, const bool allow_ugly) +auxlib::solve_sympd_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr, const bool equilibrate) { arma_extra_debug_sigprint(); @@ -4794,13 +4503,9 @@ const Mat& B = (use_copy) ? B_tmp : UB_M_as_Mat; - arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_rows, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_rows, B.n_cols); return true; } arma_debug_assert_blas_size(A,B); @@ -4832,9 +4537,10 @@ // NOTE: using const_cast(B.memptr()) to allow B to be overwritten for equilibration; // NOTE: B is created as a copy of B_expr if equilibration is enabled; otherwise B is a reference to B_expr + // NOTE: lapack::posvx() sets rcond to zero if A is not sympd out_rcond = rcond; - return (allow_ugly) ? ((info == 0) || (info == (n+1))) : (info == 0); + return ((info == 0) || (info == (n+1))); } #else { @@ -4843,7 +4549,6 @@ arma_ignore(A); arma_ignore(B_expr); arma_ignore(equilibrate); - arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -4856,7 +4561,7 @@ template inline bool -auxlib::solve_sympd_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate, const bool allow_ugly) +auxlib::solve_sympd_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const Base,T1>& B_expr, const bool equilibrate) { arma_extra_debug_sigprint(); @@ -4864,7 +4569,7 @@ { arma_extra_debug_print("auxlib::solve_sympd_refine(): redirecting to auxlib::solve_square_refine() due to crippled LAPACK"); - return auxlib::solve_square_refine(out, out_rcond, A, B_expr, equilibrate, allow_ugly); + return auxlib::solve_square_refine(out, out_rcond, A, B_expr, equilibrate); } #elif defined(ARMA_USE_LAPACK) { @@ -4883,13 +4588,9 @@ const Mat& B = (use_copy) ? B_tmp : UB_M_as_Mat; - arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_rows, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_rows, B.n_cols); return true; } arma_debug_assert_blas_size(A,B); @@ -4921,9 +4622,10 @@ // NOTE: using const_cast(B.memptr()) to allow B to be overwritten for equilibration; // NOTE: B is created as a copy of B_expr if equilibration is enabled; otherwise B is a reference to B_expr + // NOTE: lapack::cx_posvx() sets rcond to zero if A is not sympd out_rcond = rcond; - return (allow_ugly) ? ((info == 0) || (info == (n+1))) : (info == 0); + return ((info == 0) || (info == (n+1))); } #else { @@ -4932,7 +4634,6 @@ arma_ignore(A); arma_ignore(B_expr); arma_ignore(equilibrate); - arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -4956,13 +4657,9 @@ 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" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_cols, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_cols, B.n_cols); return true; } arma_debug_assert_blas_size(A,B); @@ -4990,10 +4687,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= ((is_cx::yes) ? uword(256) : uword(1024))) { - eT work_query[2]; - blas_int lwork_query = -1; + 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 ); @@ -5040,7 +4737,7 @@ 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) +auxlib::solve_rect_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const Base& B_expr) { arma_extra_debug_sigprint(); @@ -5054,13 +4751,9 @@ 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" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_cols, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_cols, B.n_cols); return true; } arma_debug_assert_blas_size(A,B); @@ -5088,10 +4781,10 @@ blas_int lwork_proposed = 0; - if((m*n) >= 1024) + if(A.n_elem >= ((is_cx::yes) ? uword(256) : uword(1024))) { - eT work_query[2]; - blas_int lwork_query = -1; + 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 ); @@ -5129,8 +4822,6 @@ // 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) @@ -5152,8 +4843,6 @@ // 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) @@ -5173,7 +4862,6 @@ 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; } @@ -5196,13 +4884,12 @@ 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" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_cols, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_cols, B.n_cols); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + if(arma_config::check_nonfinite && B.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A,B); @@ -5224,7 +4911,8 @@ 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" + //eT rcond = eT(-1); // -1 means "use machine precision" + eT rcond = (std::max)(A.n_rows, A.n_cols) * std::numeric_limits::epsilon(); blas_int rank = blas_int(0); blas_int info = blas_int(0); @@ -5251,15 +4939,15 @@ 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) ) ); + blas_int nlvl = (std::max)( blas_int(0), blas_int(1) + blas_int( std::log2( double(min_mn)/double(smlsiz_p1) ) ) ); 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); + eT work_query[2] = {}; + blas_int lwork_query = blas_int(-1); arma_extra_debug_print("lapack::gelsd()"); lapack::gelsd(&m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, S.memptr(), &rcond, &rank, &work_query[0], &lwork_query, iwork.memptr(), &info); @@ -5317,13 +5005,12 @@ 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" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_cols, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_cols, B.n_cols); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + if(arma_config::check_nonfinite && B.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A,B); @@ -5345,7 +5032,8 @@ 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" + //T rcond = T(-1); // -1 means "use machine precision" + T rcond = (std::max)(A.n_rows, A.n_cols) * std::numeric_limits::epsilon(); blas_int rank = blas_int(0); blas_int info = blas_int(0); @@ -5369,7 +5057,7 @@ 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) ) ); + blas_int nlvl = (std::max)( blas_int(0), blas_int(1) + blas_int( std::log2( double(min_mn)/double(smlsiz_p1) ) ) ); blas_int lrwork = (m >= n) ? blas_int(10)*n + blas_int(2)*n*smlsiz + blas_int(8)*n*nlvl + blas_int(3)*smlsiz*nrhs + (std::max)( (smlsiz_p1)*(smlsiz_p1), n*(blas_int(1)+nrhs) + blas_int(2)*nrhs ) @@ -5382,8 +5070,8 @@ blas_int lwork_min = 2*min_mn + min_mn*nrhs; - eT work_query[2]; - blas_int lwork_query = blas_int(-1); + eT work_query[2] = {}; + blas_int lwork_query = blas_int(-1); arma_extra_debug_print("lapack::cx_gelsd()"); lapack::cx_gelsd(&m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, S.memptr(), &rcond, &rank, &work_query[0], &lwork_query, rwork.memptr(), iwork.memptr(), &info); @@ -5438,13 +5126,9 @@ const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); - if(A.is_empty() || out.is_empty()) - { - out.zeros(A.n_cols, B_n_cols); - return true; - } + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; } arma_debug_assert_blas_size(A,out); @@ -5477,7 +5161,7 @@ template inline bool -auxlib::solve_trimat_rcond(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const Base& B_expr, const uword layout, const bool allow_ugly) +auxlib::solve_trimat_rcond(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const Base& B_expr, const uword layout) { arma_extra_debug_sigprint(); @@ -5492,13 +5176,9 @@ const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); - if(A.is_empty() || out.is_empty()) - { - out.zeros(A.n_cols, B_n_cols); - return true; - } + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; } arma_debug_assert_blas_size(A,out); @@ -5517,8 +5197,6 @@ // determine quality of solution out_rcond = auxlib::rcond_trimat(A, layout); - if( (allow_ugly == false) && (out_rcond < auxlib::epsilon_lapack(A)) ) { return false; } - return true; } #else @@ -5528,7 +5206,6 @@ arma_ignore(A); arma_ignore(B_expr); arma_ignore(layout); - arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -5593,13 +5270,9 @@ const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); - if(A.is_empty() || out.is_empty()) - { - out.zeros(A.n_rows, B_n_cols); - return true; - } + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_rows, B_n_cols); return true; } // for gbsv, matrix AB size: 2*KL+KU+1 x N; band representation of A stored in rows KL+1 to 2*KL+KU+1 (note: fortran counts from 1) @@ -5646,11 +5319,11 @@ template inline bool -auxlib::solve_band_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool allow_ugly) +auxlib::solve_band_rcond(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr) { arma_extra_debug_sigprint(); - return auxlib::solve_band_rcond_common(out, out_rcond, A, KL, KU, B_expr, allow_ugly); + return auxlib::solve_band_rcond_common(out, out_rcond, A, KL, KU, B_expr); } @@ -5659,7 +5332,7 @@ template inline bool -auxlib::solve_band_rcond(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base< std::complex,T1>& B_expr, const bool allow_ugly) +auxlib::solve_band_rcond(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base< std::complex,T1>& B_expr) { arma_extra_debug_sigprint(); @@ -5670,11 +5343,11 @@ arma_ignore(KL); arma_ignore(KU); - return auxlib::solve_square_rcond(out, out_rcond, A, B_expr, allow_ugly); + return auxlib::solve_square_rcond(out, out_rcond, A, B_expr); } #else { - return auxlib::solve_band_rcond_common(out, out_rcond, A, KL, KU, B_expr, allow_ugly); + return auxlib::solve_band_rcond_common(out, out_rcond, A, KL, KU, B_expr); } #endif } @@ -5685,7 +5358,7 @@ template inline bool -auxlib::solve_band_rcond_common(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool allow_ugly) +auxlib::solve_band_rcond_common(Mat& out, typename T1::pod_type& out_rcond, const Mat& A, const uword KL, const uword KU, const Base& B_expr) { arma_extra_debug_sigprint(); @@ -5701,13 +5374,9 @@ const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); - if(A.is_empty() || out.is_empty()) - { - out.zeros(A.n_rows, B_n_cols); - return true; - } + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_rows, B_n_cols); return true; } // for gbtrf, matrix AB size: 2*KL+KU+1 x N; band representation of A stored in rows KL+1 to 2*KL+KU+1 (note: fortran counts from 1) @@ -5747,8 +5416,6 @@ out_rcond = auxlib::lu_rcond_band(AB, KL, KU, ipiv, norm_val); - if( (allow_ugly == false) && (out_rcond < auxlib::epsilon_lapack(AB)) ) { return false; } - return true; } #else @@ -5759,7 +5426,6 @@ arma_ignore(KL); arma_ignore(KU); arma_ignore(B_expr); - arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -5772,7 +5438,7 @@ template inline bool -auxlib::solve_band_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool equilibrate, const bool allow_ugly) +auxlib::solve_band_refine(Mat& out, typename T1::pod_type& out_rcond, Mat& A, const uword KL, const uword KU, const Base& B_expr, const bool equilibrate) { arma_extra_debug_sigprint(); @@ -5782,13 +5448,9 @@ Mat B = B_expr.get_ref(); // B is overwritten - arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_rows, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_rows, B.n_cols); return true; } // for gbsvx, matrix AB size: KL+KU+1 x N; band representation of A stored in rows 1 to KL+KU+1 (note: fortran counts from 1) @@ -5847,7 +5509,7 @@ out_rcond = rcond; - return (allow_ugly) ? ((info == 0) || (info == (n+1))) : (info == 0); + return ((info == 0) || (info == (n+1))); } #else { @@ -5858,7 +5520,6 @@ arma_ignore(KU); arma_ignore(B_expr); arma_ignore(equilibrate); - arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -5871,7 +5532,7 @@ template inline bool -auxlib::solve_band_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base,T1>& B_expr, const bool equilibrate, const bool allow_ugly) +auxlib::solve_band_refine(Mat< std::complex >& out, typename T1::pod_type& out_rcond, Mat< std::complex >& A, const uword KL, const uword KU, const Base,T1>& B_expr, const bool equilibrate) { arma_extra_debug_sigprint(); @@ -5882,7 +5543,7 @@ arma_ignore(KL); arma_ignore(KU); - return auxlib::solve_square_refine(out, out_rcond, A, B_expr, equilibrate, allow_ugly); + return auxlib::solve_square_refine(out, out_rcond, A, B_expr, equilibrate); } #elif defined(ARMA_USE_LAPACK) { @@ -5891,13 +5552,9 @@ Mat B = B_expr.get_ref(); // B is overwritten - arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); - if(A.is_empty() || B.is_empty()) - { - out.zeros(A.n_rows, B.n_cols); - return true; - } + if(A.is_empty() || B.is_empty()) { out.zeros(A.n_rows, B.n_cols); return true; } // for gbsvx, matrix AB size: KL+KU+1 x N; band representation of A stored in rows 1 to KL+KU+1 (note: fortran counts from 1) @@ -5956,7 +5613,7 @@ out_rcond = rcond; - return (allow_ugly) ? ((info == 0) || (info == (n+1))) : (info == 0); + return ((info == 0) || (info == (n+1))); } #else { @@ -5967,7 +5624,6 @@ arma_ignore(KU); arma_ignore(B_expr); arma_ignore(equilibrate); - arma_ignore(allow_ugly); arma_stop_logic_error("solve(): use of LAPACK must be enabled"); return false; } @@ -6029,13 +5685,9 @@ const uword B_n_rows = out.n_rows; const uword B_n_cols = out.n_cols; - arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in the given matrices must be the same" ); + arma_debug_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } ); - if(A.is_empty() || out.is_empty()) - { - out.zeros(A.n_rows, B_n_cols); - return true; - } + if(A.is_empty() || out.is_empty()) { out.zeros(A.n_rows, B_n_cols); return true; } Mat tridiag; band_helper::extract_tridiag(tridiag, A); @@ -6081,12 +5733,7 @@ arma_debug_check( (S.is_square() == false), "schur(): given matrix must be square sized" ); - if(S.is_empty()) - { - U.reset(); - S.reset(); - return true; - } + if(S.is_empty()) { U.reset(); S.reset(); return true; } arma_debug_assert_blas_size(S); @@ -6155,12 +5802,7 @@ { typedef std::complex eT; - if(S.is_empty()) - { - U.reset(); - S.reset(); - return true; - } + if(S.is_empty()) { U.reset(); S.reset(); return true; } arma_debug_assert_blas_size(S); @@ -6277,18 +5919,14 @@ A = X_expr.get_ref(); B = Y_expr.get_ref(); - arma_debug_check( ((A.is_square() == false) || (B.is_square() == false)), "qz(): given matrices must be square sized" ); + arma_debug_check( ((A.is_square() == false) || (B.is_square() == false)), "qz(): given matrices must be square sized", [&](){ A.soft_reset(); B.soft_reset(); } ); arma_debug_check( (A.n_rows != B.n_rows), "qz(): given matrices must have the same size" ); - if(A.is_empty()) - { - A.reset(); - B.reset(); - vsl.reset(); - vsr.reset(); - return true; - } + if(A.is_empty()) { A.reset(); B.reset(); vsl.reset(); vsr.reset(); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + if(arma_config::check_nonfinite && B.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A); @@ -6368,18 +6006,14 @@ A = X_expr.get_ref(); B = Y_expr.get_ref(); - arma_debug_check( ((A.is_square() == false) || (B.is_square() == false)), "qz(): given matrices must be square sized" ); + arma_debug_check( ((A.is_square() == false) || (B.is_square() == false)), "qz(): given matrices must be square sized", [&](){ A.soft_reset(); B.soft_reset(); } ); arma_debug_check( (A.n_rows != B.n_rows), "qz(): given matrices must have the same size" ); - if(A.is_empty()) - { - A.reset(); - B.reset(); - vsl.reset(); - vsr.reset(); - return true; - } + if(A.is_empty()) { A.reset(); B.reset(); vsl.reset(); vsr.reset(); return true; } + + if(arma_config::check_nonfinite && A.internal_has_nonfinite()) { return false; } + if(arma_config::check_nonfinite && B.internal_has_nonfinite()) { return false; } arma_debug_assert_blas_size(A); @@ -6985,58 +6619,6 @@ } - -template -inline -typename T1::pod_type -auxlib::epsilon_lapack(const Base&) - { - typedef typename T1::pod_type T; - - return T(0.5)*std::numeric_limits::epsilon(); - - // value reverse engineered from dgesvx.f and dlamch.f - // http://www.netlib.org/lapack/explore-html/da/d21/dgesvx_8f.html - // http://www.netlib.org/lapack/explore-html/d5/dd4/dlamch_8f.html - // - // Fortran epsilon(X) function: - // https://gcc.gnu.org/onlinedocs/gfortran/EPSILON.html - // "EPSILON(X) returns the smallest number E of the same kind as X such that 1 + E > 1" - // - // C++ std::numeric_limits::epsilon() function: - // https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon - // "the difference between 1.0 and the next value representable by the floating-point type T" - // - // extract from dgesvx.f: - // - // IF( rcond.LT.dlamch( 'Epsilon' ) ) - // info = n + 1 - // RETURN - // - // extract from dlamch.f: - // - // * rnd = 1.0 when rounding occurs in addition, 0.0 otherwise - // ... - // * Assume rounding, not chopping. Always - // - // rnd = one - // - // IF( one.EQ.rnd ) THEN - // eps = epsilon(zero) * 0.5 - // ELSE - // eps = epsilon(zero) - // END IF - // ... - // IF( lsame( cmach, 'E' ) ) THEN - // rmach = eps - // ... - // END IF - // ... - // dlamch = rmach - // RETURN - } - - template inline diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Base_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Base_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Base_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Base_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -24,10 +24,10 @@ template struct Base_extra_yes { - inline arma_warn_unused const Op i() const; //!< matrix inverse + arma_warn_unused inline 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; + arma_warn_unused inline bool is_sympd() const; + arma_warn_unused inline bool is_sympd(typename get_pod_type::result tol) const; }; @@ -51,14 +51,14 @@ template struct Base_eval_Mat { - arma_inline arma_warn_unused const derived& eval() const; + arma_warn_unused arma_inline const derived& eval() const; }; template struct Base_eval_expr { - inline arma_warn_unused Mat eval() const; //!< force the immediate evaluation of a delayed expression + arma_warn_unused inline Mat eval() const; //!< force the immediate evaluation of a delayed expression }; @@ -76,18 +76,18 @@ template struct Base_trans_cx { - 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 + arma_warn_unused arma_inline const Op t() const; + arma_warn_unused arma_inline const Op ht() const; + arma_warn_unused arma_inline const Op st() const; // simple transpose: no complex conjugates }; template struct Base_trans_default { - 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 + arma_warn_unused arma_inline const Op t() const; + arma_warn_unused arma_inline const Op ht() const; + arma_warn_unused arma_inline const Op st() const; // return op_htrans instead of op_strans, as it's handled better by matrix multiplication code }; @@ -124,8 +124,8 @@ 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; + arma_warn_unused inline elem_type min() const; + arma_warn_unused inline elem_type max() const; inline elem_type min(uword& index_of_min_val) const; inline elem_type max(uword& index_of_max_val) const; @@ -133,31 +133,33 @@ inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const; inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const; - inline arma_warn_unused uword index_min() const; - inline arma_warn_unused uword index_max() const; + arma_warn_unused inline uword index_min() const; + arma_warn_unused inline uword index_max() const; - inline arma_warn_unused bool is_symmetric() const; - inline arma_warn_unused bool is_symmetric(const typename get_pod_type::result tol) const; + arma_warn_unused inline bool is_symmetric() const; + arma_warn_unused inline bool is_symmetric(const typename get_pod_type::result tol) const; - inline arma_warn_unused bool is_hermitian() const; - inline arma_warn_unused bool is_hermitian(const typename get_pod_type::result tol) const; + arma_warn_unused inline bool is_hermitian() const; + arma_warn_unused inline 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; - inline arma_warn_unused bool is_empty() const; - inline arma_warn_unused bool is_square() const; - inline arma_warn_unused bool is_vec() const; - inline arma_warn_unused bool is_colvec() const; - inline arma_warn_unused bool is_rowvec() const; - inline arma_warn_unused bool is_finite() const; - inline arma_warn_unused bool has_inf() const; - inline arma_warn_unused bool has_nan() const; + arma_warn_unused inline bool is_zero(const typename get_pod_type::result tol = 0) const; + + arma_warn_unused inline bool is_trimatu() const; + arma_warn_unused inline bool is_trimatl() const; + arma_warn_unused inline bool is_diagmat() const; + arma_warn_unused inline bool is_empty() const; + arma_warn_unused inline bool is_square() const; + arma_warn_unused inline bool is_vec() const; + arma_warn_unused inline bool is_colvec() const; + arma_warn_unused inline bool is_rowvec() const; + arma_warn_unused inline bool is_finite() const; + + arma_warn_unused inline bool has_inf() const; + arma_warn_unused inline bool has_nan() const; + arma_warn_unused inline bool has_nonfinite() const; - inline arma_warn_unused const Op as_col() const; - inline arma_warn_unused const Op as_row() const; + arma_warn_unused inline const Op as_col() const; + arma_warn_unused inline const Op as_row() const; }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/BaseCube_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/BaseCube_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/BaseCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/BaseCube_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -24,14 +24,14 @@ template struct BaseCube_eval_Cube { - arma_inline arma_warn_unused const derived& eval() const; + arma_warn_unused arma_inline const derived& eval() const; }; template struct BaseCube_eval_expr { - inline arma_warn_unused Cube eval() const; //!< force the immediate evaluation of a delayed expression + arma_warn_unused inline Cube eval() const; //!< force the immediate evaluation of a delayed expression }; @@ -39,7 +39,7 @@ struct BaseCube_eval {}; template -struct BaseCube_eval { typedef BaseCube_eval_Cube result; }; +struct BaseCube_eval { typedef BaseCube_eval_Cube result; }; template struct BaseCube_eval { typedef BaseCube_eval_expr result; }; @@ -62,18 +62,23 @@ 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; + arma_warn_unused inline elem_type min() const; + arma_warn_unused inline elem_type max() const; - inline arma_warn_unused uword index_min() const; - inline arma_warn_unused uword index_max() const; + arma_warn_unused inline uword index_min() const; + arma_warn_unused inline uword index_max() const; - inline arma_warn_unused bool is_zero(const typename get_pod_type::result tol = 0) const; + arma_warn_unused inline 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; - inline arma_warn_unused bool has_nan() const; + arma_warn_unused inline bool is_empty() const; + arma_warn_unused inline bool is_finite() const; + + arma_warn_unused inline bool has_inf() const; + arma_warn_unused inline bool has_nan() const; + arma_warn_unused inline bool has_nonfinite() const; + + arma_warn_unused inline const CubeToMatOp row_as_mat(const uword in_row) const; + arma_warn_unused inline const CubeToMatOp col_as_mat(const uword in_col) const; }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/BaseCube_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/BaseCube_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/BaseCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/BaseCube_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -32,7 +32,6 @@ template -arma_cold inline void BaseCube::print(const std::string extra_text) const @@ -56,7 +55,6 @@ template -arma_cold inline void BaseCube::print(std::ostream& user_stream, const std::string extra_text) const @@ -80,7 +78,6 @@ template -arma_cold inline void BaseCube::raw_print(const std::string extra_text) const @@ -104,7 +101,6 @@ template -arma_cold inline void BaseCube::raw_print(std::ostream& user_stream, const std::string extra_text) const @@ -128,7 +124,6 @@ template -arma_cold inline void BaseCube::brief_print(const std::string extra_text) const @@ -152,7 +147,6 @@ template -arma_cold inline void BaseCube::brief_print(std::ostream& user_stream, const std::string extra_text) const @@ -177,7 +171,6 @@ template inline -arma_warn_unused elem_type BaseCube::min() const { @@ -188,7 +181,6 @@ template inline -arma_warn_unused elem_type BaseCube::max() const { @@ -199,7 +191,6 @@ template inline -arma_warn_unused uword BaseCube::index_min() const { @@ -223,7 +214,6 @@ template inline -arma_warn_unused uword BaseCube::index_max() const { @@ -247,7 +237,6 @@ template inline -arma_warn_unused bool BaseCube::is_zero(const typename get_pod_type::result tol) const { @@ -300,7 +289,6 @@ template inline -arma_warn_unused bool BaseCube::is_empty() const { @@ -315,30 +303,33 @@ template inline -arma_warn_unused bool BaseCube::is_finite() const { arma_extra_debug_sigprint(); - const ProxyCube P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "is_finite(): detection of non-finite values is not reliable in fast math mode"); } if(is_Cube::stored_type>::value) { - const unwrap_cube::stored_type> U(P.Q); + const unwrap_cube U( (*this).get_ref() ); return arrayops::is_finite( U.M.memptr(), U.M.n_elem ); } - - const uword n_r = P.get_n_rows(); - const uword n_c = P.get_n_cols(); - const uword n_s = P.get_n_slices(); - - for(uword s=0; s P( (*this).get_ref() ); + + const uword n_r = P.get_n_rows(); + const uword n_c = P.get_n_cols(); + const uword n_s = P.get_n_slices(); + + for(uword s=0; s inline -arma_warn_unused bool BaseCube::has_inf() const { arma_extra_debug_sigprint(); - const ProxyCube P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_inf(): detection of non-finite values is not reliable in fast math mode"); } if(is_Cube::stored_type>::value) { - const unwrap_cube::stored_type> U(P.Q); + const unwrap_cube U( (*this).get_ref() ); return arrayops::has_inf( U.M.memptr(), U.M.n_elem ); } - - const uword n_r = P.get_n_rows(); - const uword n_c = P.get_n_cols(); - const uword n_s = P.get_n_slices(); - - for(uword s=0; s P( (*this).get_ref() ); + + const uword n_r = P.get_n_rows(); + const uword n_c = P.get_n_cols(); + const uword n_s = P.get_n_slices(); + + for(uword s=0; s inline -arma_warn_unused bool BaseCube::has_nan() const { arma_extra_debug_sigprint(); - const ProxyCube P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nan(): detection of non-finite values is not reliable in fast math mode"); } if(is_Cube::stored_type>::value) { - const unwrap_cube::stored_type> U(P.Q); + const unwrap_cube U( (*this).get_ref() ); return arrayops::has_nan( U.M.memptr(), U.M.n_elem ); } + else + { + const ProxyCube P( (*this).get_ref() ); + + const uword n_r = P.get_n_rows(); + const uword n_c = P.get_n_cols(); + const uword n_s = P.get_n_slices(); + + for(uword s=0; s +inline +bool +BaseCube::has_nonfinite() const + { + arma_extra_debug_sigprint(); + + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nonfinite(): detection of non-finite values is not reliable in fast math mode"); } + + if(is_Cube::stored_type>::value) + { + const unwrap_cube U( (*this).get_ref() ); + + return (arrayops::is_finite( U.M.memptr(), U.M.n_elem ) == false); + } + else { - if(arma_isnan(P.at(r,c,s))) { return true; } + const ProxyCube P( (*this).get_ref() ); + + const uword n_r = P.get_n_rows(); + const uword n_c = P.get_n_cols(); + const uword n_s = P.get_n_slices(); + + for(uword s=0; s +inline +const CubeToMatOp +BaseCube::row_as_mat(const uword in_row) const + { + return CubeToMatOp( (*this).get_ref(), in_row ); + } + + + +template +inline +const CubeToMatOp +BaseCube::col_as_mat(const uword in_col) const + { + return CubeToMatOp( (*this).get_ref(), in_col ); + } + + + // // extra functions defined in BaseCube_eval_Cube template arma_inline -arma_warn_unused const derived& BaseCube_eval_Cube::eval() const { @@ -433,7 +485,6 @@ template inline -arma_warn_unused Cube BaseCube_eval_expr::eval() const { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Base_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Base_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Base_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Base_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -32,7 +32,6 @@ template -arma_cold inline void Base::print(const std::string extra_text) const @@ -56,7 +55,6 @@ template -arma_cold inline void Base::print(std::ostream& user_stream, const std::string extra_text) const @@ -80,7 +78,6 @@ template -arma_cold inline void Base::raw_print(const std::string extra_text) const @@ -104,7 +101,6 @@ template -arma_cold inline void Base::raw_print(std::ostream& user_stream, const std::string extra_text) const @@ -128,7 +124,6 @@ template -arma_cold inline void Base::brief_print(const std::string extra_text) const @@ -152,7 +147,6 @@ template -arma_cold inline void Base::brief_print(std::ostream& user_stream, const std::string extra_text) const @@ -177,7 +171,6 @@ template inline -arma_warn_unused elem_type Base::min() const { @@ -188,7 +181,6 @@ template inline -arma_warn_unused elem_type Base::max() const { @@ -265,7 +257,6 @@ template inline -arma_warn_unused uword Base::index_min() const { @@ -289,7 +280,6 @@ template inline -arma_warn_unused uword Base::index_max() const { @@ -313,7 +303,6 @@ template inline -arma_warn_unused bool Base::is_symmetric() const { @@ -354,7 +343,6 @@ template inline -arma_warn_unused bool Base::is_symmetric(const typename get_pod_type::result tol) const { @@ -386,7 +374,6 @@ template inline -arma_warn_unused bool Base::is_hermitian() const { @@ -439,7 +426,6 @@ template inline -arma_warn_unused bool Base::is_hermitian(const typename get_pod_type::result tol) const { @@ -471,7 +457,6 @@ template inline -arma_warn_unused bool Base::is_zero(const typename get_pod_type::result tol) const { @@ -524,7 +509,6 @@ template inline -arma_warn_unused bool Base::is_trimatu() const { @@ -543,7 +527,6 @@ template inline -arma_warn_unused bool Base::is_trimatl() const { @@ -562,7 +545,6 @@ template inline -arma_warn_unused bool Base::is_diagmat() const { @@ -602,7 +584,6 @@ template inline -arma_warn_unused bool Base::is_empty() const { @@ -617,7 +598,6 @@ template inline -arma_warn_unused bool Base::is_square() const { @@ -632,7 +612,6 @@ template inline -arma_warn_unused bool Base::is_vec() const { @@ -649,7 +628,6 @@ template inline -arma_warn_unused bool Base::is_colvec() const { @@ -666,7 +644,6 @@ template inline -arma_warn_unused bool Base::is_rowvec() const { @@ -683,41 +660,44 @@ template inline -arma_warn_unused bool Base::is_finite() const { arma_extra_debug_sigprint(); - const Proxy P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "is_finite(): detection of non-finite values is not reliable in fast math mode"); } if(is_Mat::stored_type>::value) { - const quasi_unwrap::stored_type> U(P.Q); + const quasi_unwrap U( (*this).get_ref() ); return arrayops::is_finite( U.M.memptr(), U.M.n_elem ); } - - if(Proxy::use_at == false) + else { - const typename Proxy::ea_type Pea = P.get_ea(); + const Proxy P( (*this).get_ref() ); - const uword n_elem = P.get_n_elem(); - - for(uword i=0; i::use_at == false) { - if(arma_isfinite(Pea[i]) == false) { return false; } + const typename Proxy::ea_type Pea = P.get_ea(); + + const uword n_elem = P.get_n_elem(); + + for(uword i=0; i inline -arma_warn_unused bool Base::has_inf() const { arma_extra_debug_sigprint(); - const Proxy P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_inf(): detection of non-finite values is not reliable in fast math mode"); } if(is_Mat::stored_type>::value) { - const quasi_unwrap::stored_type> U(P.Q); + const quasi_unwrap U( (*this).get_ref() ); return arrayops::has_inf( U.M.memptr(), U.M.n_elem ); } - - if(Proxy::use_at == false) + else { - const typename Proxy::ea_type Pea = P.get_ea(); + const Proxy P( (*this).get_ref() ); - const uword n_elem = P.get_n_elem(); - - for(uword i=0; i::use_at == false) { - if(arma_isinf(Pea[i])) { return true; } + const typename Proxy::ea_type Pea = P.get_ea(); + + const uword n_elem = P.get_n_elem(); + + for(uword i=0; i inline -arma_warn_unused bool Base::has_nan() const { arma_extra_debug_sigprint(); - const Proxy P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nan(): detection of non-finite values is not reliable in fast math mode"); } if(is_Mat::stored_type>::value) { - const quasi_unwrap::stored_type> U(P.Q); + const quasi_unwrap U( (*this).get_ref() ); return arrayops::has_nan( U.M.memptr(), U.M.n_elem ); } - - if(Proxy::use_at == false) + else { - const typename Proxy::ea_type Pea = P.get_ea(); + const Proxy P( (*this).get_ref() ); - const uword n_elem = P.get_n_elem(); - - for(uword i=0; i::use_at == false) + { + const typename Proxy::ea_type Pea = P.get_ea(); + + const uword n_elem = P.get_n_elem(); + + for(uword i=0; i +inline +bool +Base::has_nonfinite() const + { + arma_extra_debug_sigprint(); + + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nonfinite(): detection of non-finite values is not reliable in fast math mode"); } + + if(is_Mat::stored_type>::value) + { + const quasi_unwrap U( (*this).get_ref() ); + + return (arrayops::is_finite( U.M.memptr(), U.M.n_elem ) == false); + } else { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); + const Proxy P( (*this).get_ref() ); - for(uword col=0; col::use_at == false) { - if(arma_isnan(P.at(row,col))) { return true; } + const typename Proxy::ea_type Pea = P.get_ea(); + + const uword n_elem = P.get_n_elem(); + + for(uword i=0; i inline -arma_warn_unused const Op Base::as_col() const { @@ -829,7 +862,6 @@ template inline -arma_warn_unused const Op Base::as_row() const { @@ -843,18 +875,16 @@ template inline -arma_warn_unused -const Op +const Op Base_extra_yes::i() const { - return Op(static_cast(*this)); + return Op(static_cast(*this)); } template inline -arma_warn_unused bool Base_extra_yes::is_sympd() const { @@ -880,7 +910,6 @@ template inline -arma_warn_unused bool Base_extra_yes::is_sympd(typename get_pod_type::result tol) const { @@ -908,7 +937,6 @@ template arma_inline -arma_warn_unused const derived& Base_eval_Mat::eval() const { @@ -924,7 +952,6 @@ template inline -arma_warn_unused Mat Base_eval_expr::eval() const { @@ -940,7 +967,6 @@ template arma_inline -arma_warn_unused const Op Base_trans_cx::t() const { @@ -951,7 +977,6 @@ template arma_inline -arma_warn_unused const Op Base_trans_cx::ht() const { @@ -962,7 +987,6 @@ template arma_inline -arma_warn_unused const Op Base_trans_cx::st() const { @@ -976,7 +1000,6 @@ template arma_inline -arma_warn_unused const Op Base_trans_default::t() const { @@ -987,7 +1010,6 @@ template arma_inline -arma_warn_unused const Op Base_trans_default::ht() const { @@ -998,7 +1020,6 @@ template arma_inline -arma_warn_unused const Op Base_trans_default::st() const { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Col_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Col_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Col_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Col_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -67,6 +67,9 @@ inline Col(Col&& m); inline Col& operator=(Col&& m); + // inline Col(Mat&& m); + // inline Col& operator=(Mat&& m); + inline Col& operator=(const eT val); inline Col& operator=(const Col& m); @@ -88,13 +91,13 @@ inline Col(const subview_cube& X); inline Col& operator=(const subview_cube& X); - arma_cold inline mat_injector operator<<(const eT val); + arma_frown("use braced initialiser list instead") inline mat_injector operator<<(const eT val); - 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_warn_unused arma_inline const Op,op_htrans> t() const; + arma_warn_unused arma_inline const Op,op_htrans> ht() const; + arma_warn_unused arma_inline const Op,op_strans> st() const; - arma_inline arma_warn_unused const Op,op_strans> as_row() const; + arma_warn_unused arma_inline 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; @@ -138,15 +141,17 @@ template inline void shed_rows(const Base& indices); - inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero = true); + arma_deprecated inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero); + inline void insert_rows(const uword row_num, const uword N); + template inline void insert_rows(const uword row_num, const Base& X); - arma_inline arma_warn_unused eT& at(const uword i); - arma_inline arma_warn_unused const eT& at(const uword i) const; + arma_warn_unused arma_inline eT& at(const uword i); + arma_warn_unused arma_inline const eT& at(const uword i) const; - arma_inline arma_warn_unused eT& at(const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& at(const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline eT& at(const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& at(const uword in_row, const uword in_col) const; typedef eT* row_iterator; @@ -169,7 +174,7 @@ public: - #ifdef ARMA_EXTRA_COL_PROTO + #if defined(ARMA_EXTRA_COL_PROTO) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_COL_PROTO) #endif }; @@ -235,30 +240,30 @@ template inline Col& operator=(const eGlue& X); #endif - 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; - - arma_inline arma_warn_unused eT& operator[] (const uword i); - arma_inline arma_warn_unused const eT& operator[] (const uword i) const; - arma_inline arma_warn_unused eT& at (const uword i); - arma_inline arma_warn_unused const eT& at (const uword i) const; - arma_inline arma_warn_unused eT& operator() (const uword i); - arma_inline arma_warn_unused const eT& operator() (const uword i) const; - - arma_inline arma_warn_unused eT& at (const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& at (const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col) const; - - arma_inline arma_warn_unused eT* memptr(); - arma_inline arma_warn_unused const eT* memptr() const; - - arma_hot inline const Col& fill(const eT val); - arma_hot inline const Col& zeros(); - arma_hot inline const Col& ones(); + arma_warn_unused arma_inline const Op< Col_fixed_type, op_htrans > t() const; + arma_warn_unused arma_inline const Op< Col_fixed_type, op_htrans > ht() const; + arma_warn_unused arma_inline const Op< Col_fixed_type, op_strans > st() const; + + arma_warn_unused arma_inline const eT& at_alt (const uword i) const; + + arma_warn_unused arma_inline eT& operator[] (const uword i); + arma_warn_unused arma_inline const eT& operator[] (const uword i) const; + arma_warn_unused arma_inline eT& at (const uword i); + arma_warn_unused arma_inline const eT& at (const uword i) const; + arma_warn_unused arma_inline eT& operator() (const uword i); + arma_warn_unused arma_inline const eT& operator() (const uword i) const; + + arma_warn_unused arma_inline eT& at (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& at (const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const; + + arma_warn_unused arma_inline eT* memptr(); + arma_warn_unused arma_inline const eT* memptr() const; + + inline const Col& fill(const eT val); + inline const Col& zeros(); + inline const Col& ones(); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Col_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Col_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Col_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Col_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -51,12 +51,11 @@ { arma_extra_debug_sigprint(); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Col::constructor: zeroing memory"); arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); } - #endif } @@ -70,12 +69,11 @@ Mat::init_warm(in_n_rows, in_n_cols); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Col::constructor: zeroing memory"); arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); } - #endif } @@ -89,12 +87,11 @@ Mat::init_warm(s.n_rows, s.n_cols); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Col::constructor: zeroing memory"); arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); } - #endif } @@ -314,10 +311,9 @@ { arma_extra_debug_sigprint_this(this); - if(x.size() > 0) - { - arrayops::copy( Mat::memptr(), &(x[0]), uword(x.size()) ); - } + const uword N = uword(x.size()); + + if(N > 0) { arrayops::copy( Mat::memptr(), &(x[0]), N ); } } @@ -330,12 +326,11 @@ { arma_extra_debug_sigprint(); - Mat::init_warm(uword(x.size()), 1); + const uword N = uword(x.size()); - if(x.size() > 0) - { - arrayops::copy( Mat::memptr(), &(x[0]), uword(x.size()) ); - } + Mat::init_warm(N, 1); + + if(N > 0) { arrayops::copy( Mat::memptr(), &(x[0]), N ); } return *this; } @@ -345,11 +340,13 @@ template inline Col::Col(const std::initializer_list& list) - : Mat(arma_vec_indicator(), 1) + : Mat(arma_vec_indicator(), uword(list.size()), 1, 1) { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); - (*this).operator=(list); + const uword N = uword(list.size()); + + if(N > 0) { arrayops::copy( Mat::memptr(), list.begin(), N ); } } @@ -361,14 +358,11 @@ { arma_extra_debug_sigprint(); - Mat tmp(list); + const uword N = uword(list.size()); - arma_debug_check( ((tmp.n_elem > 0) && (tmp.is_vec() == false)), "Mat::init(): requested size is not compatible with column vector layout" ); + Mat::init_warm(N, 1); - access::rw(tmp.n_rows) = tmp.n_elem; - access::rw(tmp.n_cols) = 1; - - (*this).steal_mem(tmp); + if(N > 0) { arrayops::copy( Mat::memptr(), list.begin(), N ); } return *this; } @@ -424,21 +418,71 @@ { arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - (*this).steal_mem(X); - - if( (X.mem_state == 0) && (X.n_alloc <= 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) = nullptr; - } + (*this).steal_mem(X, true); return *this; } +// template +// inline +// Col::Col(Mat&& X) +// : Mat(arma_vec_indicator(), 1) +// { +// arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); +// +// if(X.n_cols != 1) { const Mat& XX = X; Mat::operator=(XX); return; } +// +// 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_elem) = 0; +// access::rw(X.n_alloc) = 0; +// access::rw(X.mem_state) = 0; +// access::rw(X.mem) = nullptr; +// } +// else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3) +// { +// (*this).init_cold(); +// +// arrayops::copy( (*this).memptr(), X.mem, X.n_elem ); +// +// if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) +// { +// access::rw(X.n_rows) = 0; +// access::rw(X.n_elem) = 0; +// access::rw(X.mem) = nullptr; +// } +// } +// } +// +// +// +// template +// inline +// Col& +// Col::operator=(Mat&& X) +// { +// arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); +// +// if(X.n_cols != 1) { const Mat& XX = X; Mat::operator=(XX); return *this; } +// +// (*this).steal_mem(X, true); +// +// return *this; +// } + + + template inline Col& @@ -625,7 +669,6 @@ template inline -arma_cold mat_injector< Col > Col::operator<<(const eT val) { @@ -636,7 +679,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> Col::t() const { @@ -647,7 +689,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> Col::ht() const { @@ -658,7 +699,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> Col::st() const { @@ -669,7 +709,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> Col::as_row() const { @@ -1068,8 +1107,6 @@ -//! insert N rows at the specified row position, -//! optionally setting the elements of the inserted rows to zero template inline void @@ -1077,6 +1114,20 @@ { arma_extra_debug_sigprint(); + arma_ignore(set_to_zero); + + (*this).insert_rows(row_num, N); + } + + + +template +inline +void +Col::insert_rows(const uword row_num, const uword N) + { + arma_extra_debug_sigprint(); + const uword t_n_rows = Mat::n_rows; const uword A_n_rows = row_num; @@ -1085,30 +1136,26 @@ // insertion at row_num == n_rows is in effect an append operation arma_debug_check_bounds( (row_num > t_n_rows), "Col::insert_rows(): index out of bounds" ); - if(N > 0) + if(N == 0) { return; } + + Col out(t_n_rows + N, arma_nozeros_indicator()); + + eT* out_mem = out.memptr(); + const eT* t_mem = (*this).memptr(); + + if(A_n_rows > 0) { - Col out(t_n_rows + N, arma_nozeros_indicator()); - - eT* out_mem = out.memptr(); - const eT* t_mem = (*this).memptr(); - - if(A_n_rows > 0) - { - arrayops::copy( out_mem, t_mem, A_n_rows ); - } - - if(B_n_rows > 0) - { - arrayops::copy( &(out_mem[row_num + N]), &(t_mem[row_num]), B_n_rows ); - } - - if(set_to_zero) - { - arrayops::inplace_set( &(out_mem[row_num]), eT(0), N ); - } - - Mat::steal_mem(out); + arrayops::copy( out_mem, t_mem, A_n_rows ); + } + + if(B_n_rows > 0) + { + arrayops::copy( &(out_mem[row_num + N]), &(t_mem[row_num]), B_n_rows ); } + + arrayops::fill_zeros( &(out_mem[row_num]), N ); + + Mat::steal_mem(out); } @@ -1130,7 +1177,6 @@ template arma_inline -arma_warn_unused eT& Col::at(const uword i) { @@ -1141,7 +1187,6 @@ template arma_inline -arma_warn_unused const eT& Col::at(const uword i) const { @@ -1152,7 +1197,6 @@ template arma_inline -arma_warn_unused eT& Col::at(const uword in_row, const uword) { @@ -1163,7 +1207,6 @@ template arma_inline -arma_warn_unused const eT& Col::at(const uword in_row, const uword) const { @@ -1236,7 +1279,7 @@ { arma_extra_debug_sigprint_this(this); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Col::fixed::constructor: zeroing memory"); @@ -1244,7 +1287,6 @@ arrayops::inplace_set_fixed( mem_use, eT(0) ); } - #endif } @@ -1585,7 +1627,6 @@ template template arma_inline -arma_warn_unused const Op< typename Col::template fixed::Col_fixed_type, op_htrans > Col::fixed::t() const { @@ -1597,7 +1638,6 @@ template template arma_inline -arma_warn_unused const Op< typename Col::template fixed::Col_fixed_type, op_htrans > Col::fixed::ht() const { @@ -1609,7 +1649,6 @@ template template arma_inline -arma_warn_unused const Op< typename Col::template fixed::Col_fixed_type, op_strans > Col::fixed::st() const { @@ -1621,7 +1660,6 @@ template template arma_inline -arma_warn_unused const eT& Col::fixed::at_alt(const uword ii) const { @@ -1643,7 +1681,6 @@ template template arma_inline -arma_warn_unused eT& Col::fixed::operator[] (const uword ii) { @@ -1655,7 +1692,6 @@ template template arma_inline -arma_warn_unused const eT& Col::fixed::operator[] (const uword ii) const { @@ -1667,7 +1703,6 @@ template template arma_inline -arma_warn_unused eT& Col::fixed::at(const uword ii) { @@ -1679,7 +1714,6 @@ template template arma_inline -arma_warn_unused const eT& Col::fixed::at(const uword ii) const { @@ -1691,7 +1725,6 @@ template template arma_inline -arma_warn_unused eT& Col::fixed::operator() (const uword ii) { @@ -1705,7 +1738,6 @@ template template arma_inline -arma_warn_unused const eT& Col::fixed::operator() (const uword ii) const { @@ -1719,7 +1751,6 @@ template template arma_inline -arma_warn_unused eT& Col::fixed::at(const uword in_row, const uword) { @@ -1731,7 +1762,6 @@ template template arma_inline -arma_warn_unused const eT& Col::fixed::at(const uword in_row, const uword) const { @@ -1743,7 +1773,6 @@ template template arma_inline -arma_warn_unused eT& Col::fixed::operator() (const uword in_row, const uword in_col) { @@ -1757,7 +1786,6 @@ template template arma_inline -arma_warn_unused const eT& Col::fixed::operator() (const uword in_row, const uword in_col) const { @@ -1771,7 +1799,6 @@ template template arma_inline -arma_warn_unused eT* Col::fixed::memptr() { @@ -1783,7 +1810,6 @@ template template arma_inline -arma_warn_unused const eT* Col::fixed::memptr() const { @@ -1794,7 +1820,6 @@ template template -arma_hot inline const Col& Col::fixed::fill(const eT val) @@ -1812,7 +1837,6 @@ template template -arma_hot inline const Col& Col::fixed::zeros() @@ -1830,7 +1854,6 @@ template template -arma_hot inline const Col& Col::fixed::ones() @@ -1856,7 +1879,7 @@ -#ifdef ARMA_EXTRA_COL_MEAT +#if defined(ARMA_EXTRA_COL_MEAT) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_COL_MEAT) #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_check.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/compiler_check.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_check.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/compiler_check.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -42,11 +42,11 @@ #if defined(_MSVC_LANG) #if (_MSVC_LANG >= 201402L) - #undef ARMA_HAVE_CXX11 - #undef ARMA_HAVE_CXX14 - - #define ARMA_HAVE_CXX11 - #define ARMA_HAVE_CXX14 + #undef ARMA_HAVE_CXX11 + #define ARMA_HAVE_CXX11 + + #undef ARMA_HAVE_CXX14 + #define ARMA_HAVE_CXX14 #endif #if (_MSVC_LANG >= 201703L) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_setup.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/compiler_setup.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/compiler_setup.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/compiler_setup.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -23,6 +23,7 @@ #undef arma_align_mem #undef arma_warn_unused #undef arma_deprecated +#undef arma_frown #undef arma_malloc #undef arma_inline #undef arma_noinline @@ -34,6 +35,7 @@ #define arma_align_mem #define arma_warn_unused #define arma_deprecated +#define arma_frown(msg) #define arma_malloc #define arma_inline inline #define arma_noinline @@ -138,11 +140,6 @@ #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 @@ -166,6 +163,10 @@ #error "*** newer compiler required; need gcc 4.8 or later ***" #endif + // #if (ARMA_GCC_VERSION < 60100) + // #pragma message ("WARNING: support for gcc versions older than 6.1 is deprecated") + // #endif + #define ARMA_GOOD_COMPILER #undef arma_hot @@ -174,19 +175,21 @@ #undef arma_align_mem #undef arma_warn_unused #undef arma_deprecated + #undef arma_frown #undef arma_malloc #undef arma_inline #undef arma_noinline - #define arma_hot __attribute__((__hot__)) - #define arma_cold __attribute__((__cold__)) - #define arma_aligned __attribute__((__aligned__)) - #define arma_align_mem __attribute__((__aligned__(16))) - #define arma_warn_unused __attribute__((__warn_unused_result__)) - #define arma_deprecated __attribute__((__deprecated__)) - #define arma_malloc __attribute__((__malloc__)) - #define arma_inline inline __attribute__((__always_inline__)) - #define arma_noinline __attribute__((__noinline__)) + #define arma_hot __attribute__((__hot__)) + #define arma_cold __attribute__((__cold__)) + #define arma_aligned __attribute__((__aligned__)) + #define arma_align_mem __attribute__((__aligned__(16))) + #define arma_warn_unused __attribute__((__warn_unused_result__)) + #define arma_deprecated __attribute__((__deprecated__)) + #define arma_frown(msg) __attribute__((__deprecated__(msg))) + #define arma_malloc __attribute__((__malloc__)) + #define arma_inline __attribute__((__always_inline__)) inline + #define arma_noinline __attribute__((__noinline__)) #undef ARMA_HAVE_ALIGNED_ATTRIBUTE #define ARMA_HAVE_ALIGNED_ATTRIBUTE @@ -204,6 +207,7 @@ #endif +// TODO: __INTEL_CLANG_COMPILER indicates the clang based intel compiler, distinct from the classic intel compiler #if !defined(ARMA_ALLOW_FAKE_CLANG) #if defined(__clang__) && (defined(__INTEL_COMPILER) || defined(__NVCC__) || defined(__CUDACC__) || defined(__PGI) || defined(__PATHSCALE__) || defined(__ARMCC_VERSION) || defined(__IBMCPP__)) #undef ARMA_DETECTED_FAKE_CLANG @@ -247,6 +251,11 @@ #define arma_deprecated __attribute__((__deprecated__)) #endif + #if __has_attribute(__deprecated__) + #undef arma_frown + #define arma_frown(msg) __attribute__((__deprecated__(msg))) + #endif + #if __has_attribute(__malloc__) #undef arma_malloc #define arma_malloc __attribute__((__malloc__)) @@ -254,7 +263,7 @@ #if __has_attribute(__always_inline__) #undef arma_inline - #define arma_inline inline __attribute__((__always_inline__)) + #define arma_inline __attribute__((__always_inline__)) inline #endif #if __has_attribute(__noinline__) @@ -267,12 +276,12 @@ #define arma_hot __attribute__((__hot__)) #endif - #if __has_attribute(__minsize__) - #undef arma_cold - #define arma_cold __attribute__((__minsize__)) - #elif __has_attribute(__cold__) + #if __has_attribute(__cold__) #undef arma_cold #define arma_cold __attribute__((__cold__)) + #elif __has_attribute(__minsize__) + #undef arma_cold + #define arma_cold __attribute__((__minsize__)) #endif #if defined(__has_builtin) && __has_builtin(__builtin_assume_aligned) @@ -309,7 +318,7 @@ #undef arma_deprecated #define arma_deprecated __declspec(deprecated) // #undef arma_inline - // #define arma_inline inline __forceinline + // #define arma_inline __forceinline inline #pragma warning(push) @@ -321,6 +330,7 @@ #pragma warning(disable: 4512) // assignment operator can't be generated #pragma warning(disable: 4513) // destructor can't be generated #pragma warning(disable: 4514) // unreferenced inline function has been removed + #pragma warning(disable: 4519) // default template args are only allowed on a class template (C++11) #pragma warning(disable: 4522) // multiple assignment operators specified #pragma warning(disable: 4623) // default constructor can't be generated #pragma warning(disable: 4624) // destructor can't be generated @@ -331,8 +341,13 @@ #pragma warning(disable: 4711) // call was inlined #pragma warning(disable: 4714) // __forceinline can't be inlined #pragma warning(disable: 4800) // value forced to bool - #pragma warning(disable: 4519) // C++11: default template args are only allowed on a class template + // NOTE: also possible to disable 4146 (unary minus operator applied to unsigned type, result still unsigned) + + #if defined(ARMA_HAVE_CXX17) + #pragma warning(disable: 26812) // unscoped enum + #pragma warning(disable: 26819) // unannotated fallthrough + #endif // #if (_MANAGED == 1) || (_M_CEE == 1) // @@ -371,8 +386,18 @@ #endif -#if defined(__CYGWIN__) && !defined(ARMA_DONT_PRINT_CXX11_WARNING) - #pragma message ("WARNING: Cygwin may have incomplete support for C++11 features.") +#if defined(ARMA_HAVE_CXX14) + #undef arma_deprecated + #define arma_deprecated [[deprecated]] + + #undef arma_frown + #define arma_frown(msg) [[deprecated(msg)]] +#endif + + +#if defined(ARMA_HAVE_CXX17) + #undef arma_warn_unused + #define arma_warn_unused [[nodiscard]] #endif @@ -397,7 +422,7 @@ #pragma message ("WARNING: use of OpenMP disabled; compiler support for OpenMP 3.1+ not detected") #if (defined(_OPENMP) && (_OPENMP < 201107)) - #pragma message ("NOTE: your compiler appears to have an ancient version of OpenMP") + #pragma message ("NOTE: your compiler has an outdated version of OpenMP") #pragma message ("NOTE: consider upgrading to a better compiler") #endif #endif @@ -406,7 +431,6 @@ #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") @@ -415,9 +439,22 @@ #endif -#if ( defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) ) - #undef ARMA_PRINT_EXCEPTIONS - #define ARMA_PRINT_EXCEPTIONS +#if (defined(__FAST_MATH__) || (defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ > 0)) || defined(_M_FP_FAST)) + #undef ARMA_FAST_MATH + #define ARMA_FAST_MATH +#endif + + +#if defined(ARMA_FAST_MATH) && !defined(ARMA_DONT_PRINT_FAST_MATH_WARNING) + #pragma message ("WARNING: compiler is in fast math mode; some functions may be unreliable.") + #pragma message ("WARNING: to suppress this warning and related warnings,") + #pragma message ("WARNING: #define ARMA_DONT_PRINT_FAST_MATH_WARNING before #include ") +#endif + + +#if ( (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)) && (!defined(__MINGW32__) && !defined(__MINGW64__)) ) + #undef ARMA_PRINT_EXCEPTIONS_INTERNAL + #define ARMA_PRINT_EXCEPTIONS_INTERNAL #endif @@ -436,28 +473,38 @@ +// undefine conflicting macros + #if defined(log2) #undef log2 - #pragma message ("WARNING: detected 'log2' macro and undefined it") + #pragma message ("WARNING: undefined conflicting 'log2' macro") #endif - - -// -// whoever defined macros with the names "min" and "max" should be permanently removed from the gene pool +#if defined(check) + #undef check + #pragma message ("WARNING: undefined conflicting 'check' macro") +#endif #if defined(min) || defined(max) #undef min #undef max - #pragma message ("WARNING: detected 'min' and/or 'max' macros and undefined them;") - #pragma message ("WARNING: you may wish to define NOMINMAX before including any windows header") + #pragma message ("WARNING: undefined conflicting 'min' and/or 'max' macros;") + #pragma message ("WARNING: suggest to define NOMINMAX before including any windows header") #endif - - -// -// handle more stupid macros // https://sourceware.org/bugzilla/show_bug.cgi?id=19239 - #undef minor #undef major + + +// optionally allow disabling of compile-time deprecation messages (not recommended) +// NOTE: option 'ARMA_IGNORE_DEPRECATED_MARKER' will be removed +// NOTE: disabling deprecation messages is counter-productive + +#if defined(ARMA_IGNORE_DEPRECATED_MARKER) && (!defined(ARMA_DONT_IGNORE_DEPRECATED_MARKER)) && (!defined(ARMA_EXTRA_DEBUG)) + #undef arma_deprecated + #define arma_deprecated + + #undef arma_frown + #define arma_frown(msg) +#endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/config.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/config.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/config.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/config.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,11 +22,16 @@ #endif //// The level of warning messages printed to ARMA_CERR_STREAM. //// Must be an integer >= 0. The default value is 2. -//// 0 = no warnings +//// 0 = no warnings; generally not recommended //// 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 +// #define ARMA_USE_WRAPPER +//// Comment out the above line if you prefer to directly link with BLAS, LAPACK, etc +//// instead of the Armadillo runtime library. +//// You will need to link your programs directly with -lopenblas -llapack instead of -larmadillo + #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, @@ -68,10 +73,27 @@ //// Make sure the directory has a trailing / #endif -// #define ARMA_USE_WRAPPER -//// Comment out the above line if you're getting linking errors when compiling your programs, -//// or if you prefer to directly link with LAPACK, BLAS + etc instead of the Armadillo runtime library. -//// You will then need to link your programs directly with -llapack -lblas instead of -larmadillo +#if !defined(ARMA_USE_ATLAS) +// #define ARMA_USE_ATLAS +//// NOTE: support for ATLAS is deprecated and will be removed. +#endif + +#if !defined(ARMA_USE_HDF5) +// #define ARMA_USE_HDF5 +//// Uncomment the above line to allow the ability to save and load matrices stored in HDF5 format; +//// the hdf5.h header file must be available on your system, +//// and you will need to link with the hdf5 library (eg. -lhdf5) +#endif + +#if !defined(ARMA_USE_FFTW3) +// #define ARMA_USE_FFTW3 +//// Uncomment the above line to allow the use of the FFTW3 library by fft() and ifft() functions; +//// you will need to link with the FFTW3 library (eg. -lfftw3) +#endif + +#if defined(ARMA_USE_FFTW) + #error "use ARMA_USE_FFTW3 instead of ARMA_USE_FFTW" +#endif // #define ARMA_BLAS_CAPITALS //// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names @@ -100,23 +122,17 @@ //// These "hidden" arguments are typically tacked onto the end of function definitions. // #define ARMA_USE_TBB_ALLOC -//// Uncomment the above line if you want to use Intel TBB scalable_malloc() and scalable_free() instead of standard malloc() and free() +//// Uncomment the above line to use Intel TBB scalable_malloc() and scalable_free() instead of standard malloc() and free() // #define ARMA_USE_MKL_ALLOC -//// Uncomment the above line if you want to use Intel MKL mkl_malloc() and mkl_free() instead of standard malloc() and free() +//// Uncomment the above line to use Intel MKL mkl_malloc() and mkl_free() instead of standard malloc() and free() // #define ARMA_USE_MKL_TYPES -//// Uncomment the above line if you want to use Intel MKL types for complex numbers. +//// Uncomment the above line to use Intel MKL types for complex numbers. //// You will need to include appropriate MKL headers before the Armadillo header. //// You may also need to enable or disable the following options: //// ARMA_BLAS_LONG, ARMA_BLAS_LONG_LONG, ARMA_USE_FORTRAN_HIDDEN_ARGS -// #define ARMA_USE_ATLAS -// #define ARMA_ATLAS_INCLUDE_DIR /usr/include/ -//// If you're using ATLAS and the compiler can't find cblas.h and/or clapack.h -//// uncomment the above define and specify the appropriate include directory. -//// Make sure the directory has a trailing / - #if !defined(ARMA_USE_OPENMP) // #define ARMA_USE_OPENMP //// Uncomment the above line to forcefully enable use of OpenMP for parallelisation. @@ -129,32 +145,28 @@ //// 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) -// #define ARMA_USE_HDF5 -//// Uncomment the above line to allow the ability to save and load matrices stored in HDF5 format; -//// the hdf5.h header file must be available on your system, -//// and you will need to link with the hdf5 library (eg. -lhdf5) -#endif - #if !defined(ARMA_OPTIMISE_BAND) #define ARMA_OPTIMISE_BAND - //// Comment out the above line if you don't want automatically optimised handling + //// Comment out the above line to disable optimised handling //// of band matrices by solve() and chol() #endif -#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 -#if defined(ARMA_USE_HDF5_ALT) && defined(ARMA_USE_WRAPPER) - #undef ARMA_USE_HDF5 - #define ARMA_USE_HDF5 - - // #define ARMA_HDF5_INCLUDE_DIR /usr/include/ +#if !defined(ARMA_OPTIMISE_SYM) + #define ARMA_OPTIMISE_SYM + //// Comment out the above line to disable optimised handling + //// of symmetric/hermitian matrices by various functions: + //// solve(), inv(), pinv(), expmat(), logmat(), sqrtmat(), rcond(), rank() +#endif + +#if !defined(ARMA_OPTIMISE_INVEXPR) + #define ARMA_OPTIMISE_INVEXPR + //// Comment out the above line to disable optimised handling + //// of inv() and inv_sympd() within compound expressions +#endif + +#if !defined(ARMA_CHECK_NONFINITE) + #define ARMA_CHECK_NONFINITE + //// Comment out the above line to disable checking for nonfinite matrices #endif #if !defined(ARMA_MAT_PREALLOC) @@ -178,17 +190,22 @@ //// it must be an integer that is at least 1. // #define ARMA_NO_DEBUG -//// Uncomment the above line if you want to disable all run-time checks. -//// This will result in faster code, but you first need to make sure that your code runs correctly! -//// We strongly recommend to have the run-time checks enabled during development, -//// as this greatly aids in finding mistakes in your code, and hence speeds up development. -//// We recommend that run-time checks be disabled _only_ for the shipped version of your program. +//// Uncomment the above line to disable all run-time checks. NOT RECOMMENDED. +//// It is strongly recommended that run-time checks are enabled during development, +//// as this greatly aids in finding mistakes in your code. // #define ARMA_EXTRA_DEBUG -//// Uncomment the above line if you want to see the function traces of how Armadillo evaluates expressions. +//// Uncomment the above line to see the function traces of how Armadillo evaluates expressions. //// This is mainly useful for debugging of the library. +#if defined(ARMA_EXTRA_DEBUG) + #undef ARMA_NO_DEBUG + #undef ARMA_WARN_LEVEL + #define ARMA_WARN_LEVEL 3 +#endif + + #if defined(ARMA_DEFAULT_OSTREAM) #pragma message ("WARNING: support for ARMA_DEFAULT_OSTREAM is deprecated and will be removed;") #pragma message ("WARNING: use ARMA_COUT_STREAM and ARMA_CERR_STREAM instead") @@ -214,18 +231,12 @@ #endif -#if !defined(ARMA_PRINT_ERRORS) -#define ARMA_PRINT_ERRORS -//// 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 + // #define ARMA_PRINT_EXCEPTIONS + #if defined(ARMA_PRINT_EXCEPTIONS_INTERNAL) + #undef ARMA_PRINT_EXCEPTIONS + #define ARMA_PRINT_EXCEPTIONS + #endif #endif #if defined(ARMA_DONT_USE_LAPACK) @@ -251,12 +262,18 @@ #if defined(ARMA_DONT_USE_ATLAS) #undef ARMA_USE_ATLAS - #undef ARMA_ATLAS_INCLUDE_DIR +#endif + +#if defined(ARMA_DONT_USE_HDF5) + #undef ARMA_USE_HDF5 +#endif + +#if defined(ARMA_DONT_USE_FFTW3) + #undef ARMA_USE_FFTW3 #endif #if defined(ARMA_DONT_USE_WRAPPER) #undef ARMA_USE_WRAPPER - #undef ARMA_USE_HDF5_ALT #endif #if defined(ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS) @@ -301,21 +318,32 @@ #undef ARMA_64BIT_WORD #endif -#if defined(ARMA_DONT_USE_HDF5) - #undef ARMA_USE_HDF5 - #undef ARMA_USE_HDF5_ALT -#endif - #if defined(ARMA_DONT_OPTIMISE_BAND) || defined(ARMA_DONT_OPTIMISE_SOLVE_BAND) #undef ARMA_OPTIMISE_BAND #endif -#if defined(ARMA_DONT_OPTIMISE_SYMPD) || defined(ARMA_DONT_OPTIMISE_SOLVE_SYMPD) - #undef ARMA_OPTIMISE_SYMPD +#if defined(ARMA_DONT_OPTIMISE_SYM) || defined(ARMA_DONT_OPTIMISE_SYMPD) || defined(ARMA_DONT_OPTIMISE_SOLVE_SYMPD) + #undef ARMA_OPTIMISE_SYM +#endif + +#if defined(ARMA_DONT_OPTIMISE_INVEXPR) + #undef ARMA_OPTIMISE_INVEXPR +#endif + +#if defined(ARMA_DONT_CHECK_NONFINITE) + #undef ARMA_CHECK_NONFINITE #endif #if defined(ARMA_DONT_PRINT_ERRORS) - #undef ARMA_PRINT_ERRORS + #pragma message ("INFO: support for ARMA_DONT_PRINT_ERRORS option has been removed") + + #if defined(ARMA_PRINT_EXCEPTIONS) + #pragma message ("INFO: suggest to use ARMA_WARN_LEVEL and ARMA_DONT_PRINT_EXCEPTIONS options instead") + #else + #pragma message ("INFO: suggest to use ARMA_WARN_LEVEL option instead") + #endif + + #pragma message ("INFO: see the documentation for details") #endif #if defined(ARMA_DONT_PRINT_EXCEPTIONS) @@ -327,10 +355,6 @@ //// 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 diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/config.hpp.cmake armadillo-12.6.1+dfsg/include/armadillo_bits/config.hpp.cmake --- armadillo-10.8.2+dfsg/include/armadillo_bits/config.hpp.cmake 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/config.hpp.cmake 2016-06-16 16:27:01.000000000 +0000 @@ -22,11 +22,16 @@ #endif //// The level of warning messages printed to ARMA_CERR_STREAM. //// Must be an integer >= 0. The default value is 2. -//// 0 = no warnings +//// 0 = no warnings; generally not recommended //// 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 +#cmakedefine ARMA_USE_WRAPPER +//// Comment out the above line if you prefer to directly link with BLAS, LAPACK, etc +//// instead of the Armadillo runtime library. +//// You will need to link your programs directly with -lopenblas -llapack instead of -larmadillo + #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, @@ -68,10 +73,27 @@ //// Make sure the directory has a trailing / #endif -#cmakedefine ARMA_USE_WRAPPER -//// Comment out the above line if you're getting linking errors when compiling your programs, -//// or if you prefer to directly link with LAPACK, BLAS + etc instead of the Armadillo runtime library. -//// You will then need to link your programs directly with -llapack -lblas instead of -larmadillo +#if !defined(ARMA_USE_ATLAS) +#cmakedefine ARMA_USE_ATLAS +//// NOTE: support for ATLAS is deprecated and will be removed. +#endif + +#if !defined(ARMA_USE_HDF5) +// #define ARMA_USE_HDF5 +//// Uncomment the above line to allow the ability to save and load matrices stored in HDF5 format; +//// the hdf5.h header file must be available on your system, +//// and you will need to link with the hdf5 library (eg. -lhdf5) +#endif + +#if !defined(ARMA_USE_FFTW3) +// #define ARMA_USE_FFTW3 +//// Uncomment the above line to allow the use of the FFTW3 library by fft() and ifft() functions; +//// you will need to link with the FFTW3 library (eg. -lfftw3) +#endif + +#if defined(ARMA_USE_FFTW) + #error "use ARMA_USE_FFTW3 instead of ARMA_USE_FFTW" +#endif // #define ARMA_BLAS_CAPITALS //// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names @@ -100,23 +122,17 @@ //// These "hidden" arguments are typically tacked onto the end of function definitions. // #define ARMA_USE_TBB_ALLOC -//// Uncomment the above line if you want to use Intel TBB scalable_malloc() and scalable_free() instead of standard malloc() and free() +//// Uncomment the above line to use Intel TBB scalable_malloc() and scalable_free() instead of standard malloc() and free() // #define ARMA_USE_MKL_ALLOC -//// Uncomment the above line if you want to use Intel MKL mkl_malloc() and mkl_free() instead of standard malloc() and free() +//// Uncomment the above line to use Intel MKL mkl_malloc() and mkl_free() instead of standard malloc() and free() // #define ARMA_USE_MKL_TYPES -//// Uncomment the above line if you want to use Intel MKL types for complex numbers. +//// Uncomment the above line to use Intel MKL types for complex numbers. //// You will need to include appropriate MKL headers before the Armadillo header. //// You may also need to enable or disable the following options: //// ARMA_BLAS_LONG, ARMA_BLAS_LONG_LONG, ARMA_USE_FORTRAN_HIDDEN_ARGS -#cmakedefine ARMA_USE_ATLAS -#define ARMA_ATLAS_INCLUDE_DIR ${ARMA_ATLAS_INCLUDE_DIR}/ -//// If you're using ATLAS and the compiler can't find cblas.h and/or clapack.h -//// uncomment the above define and specify the appropriate include directory. -//// Make sure the directory has a trailing / - #if !defined(ARMA_USE_OPENMP) // #define ARMA_USE_OPENMP //// Uncomment the above line to forcefully enable use of OpenMP for parallelisation. @@ -129,32 +145,28 @@ //// 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) -// #define ARMA_USE_HDF5 -//// Uncomment the above line to allow the ability to save and load matrices stored in HDF5 format; -//// the hdf5.h header file must be available on your system, -//// and you will need to link with the hdf5 library (eg. -lhdf5) -#endif - #if !defined(ARMA_OPTIMISE_BAND) #define ARMA_OPTIMISE_BAND - //// Comment out the above line if you don't want automatically optimised handling + //// Comment out the above line to disable optimised handling //// of band matrices by solve() and chol() #endif -#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 -#if defined(ARMA_USE_HDF5_ALT) && defined(ARMA_USE_WRAPPER) - #undef ARMA_USE_HDF5 - #define ARMA_USE_HDF5 - - #define ARMA_HDF5_INCLUDE_DIR ${ARMA_HDF5_INCLUDE_DIR}/ +#if !defined(ARMA_OPTIMISE_SYM) + #define ARMA_OPTIMISE_SYM + //// Comment out the above line to disable optimised handling + //// of symmetric/hermitian matrices by various functions: + //// solve(), inv(), pinv(), expmat(), logmat(), sqrtmat(), rcond(), rank() +#endif + +#if !defined(ARMA_OPTIMISE_INVEXPR) + #define ARMA_OPTIMISE_INVEXPR + //// Comment out the above line to disable optimised handling + //// of inv() and inv_sympd() within compound expressions +#endif + +#if !defined(ARMA_CHECK_NONFINITE) + #define ARMA_CHECK_NONFINITE + //// Comment out the above line to disable checking for nonfinite matrices #endif #if !defined(ARMA_MAT_PREALLOC) @@ -178,17 +190,22 @@ //// it must be an integer that is at least 1. // #define ARMA_NO_DEBUG -//// Uncomment the above line if you want to disable all run-time checks. -//// This will result in faster code, but you first need to make sure that your code runs correctly! -//// We strongly recommend to have the run-time checks enabled during development, -//// as this greatly aids in finding mistakes in your code, and hence speeds up development. -//// We recommend that run-time checks be disabled _only_ for the shipped version of your program. +//// Uncomment the above line to disable all run-time checks. NOT RECOMMENDED. +//// It is strongly recommended that run-time checks are enabled during development, +//// as this greatly aids in finding mistakes in your code. // #define ARMA_EXTRA_DEBUG -//// Uncomment the above line if you want to see the function traces of how Armadillo evaluates expressions. +//// Uncomment the above line to see the function traces of how Armadillo evaluates expressions. //// This is mainly useful for debugging of the library. +#if defined(ARMA_EXTRA_DEBUG) + #undef ARMA_NO_DEBUG + #undef ARMA_WARN_LEVEL + #define ARMA_WARN_LEVEL 3 +#endif + + #if defined(ARMA_DEFAULT_OSTREAM) #pragma message ("WARNING: support for ARMA_DEFAULT_OSTREAM is deprecated and will be removed;") #pragma message ("WARNING: use ARMA_COUT_STREAM and ARMA_CERR_STREAM instead") @@ -214,18 +231,12 @@ #endif -#if !defined(ARMA_PRINT_ERRORS) -#define ARMA_PRINT_ERRORS -//// 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 + // #define ARMA_PRINT_EXCEPTIONS + #if defined(ARMA_PRINT_EXCEPTIONS_INTERNAL) + #undef ARMA_PRINT_EXCEPTIONS + #define ARMA_PRINT_EXCEPTIONS + #endif #endif #if defined(ARMA_DONT_USE_LAPACK) @@ -251,12 +262,18 @@ #if defined(ARMA_DONT_USE_ATLAS) #undef ARMA_USE_ATLAS - #undef ARMA_ATLAS_INCLUDE_DIR +#endif + +#if defined(ARMA_DONT_USE_HDF5) + #undef ARMA_USE_HDF5 +#endif + +#if defined(ARMA_DONT_USE_FFTW3) + #undef ARMA_USE_FFTW3 #endif #if defined(ARMA_DONT_USE_WRAPPER) #undef ARMA_USE_WRAPPER - #undef ARMA_USE_HDF5_ALT #endif #if defined(ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS) @@ -301,21 +318,32 @@ #undef ARMA_64BIT_WORD #endif -#if defined(ARMA_DONT_USE_HDF5) - #undef ARMA_USE_HDF5 - #undef ARMA_USE_HDF5_ALT -#endif - #if defined(ARMA_DONT_OPTIMISE_BAND) || defined(ARMA_DONT_OPTIMISE_SOLVE_BAND) #undef ARMA_OPTIMISE_BAND #endif -#if defined(ARMA_DONT_OPTIMISE_SYMPD) || defined(ARMA_DONT_OPTIMISE_SOLVE_SYMPD) - #undef ARMA_OPTIMISE_SYMPD +#if defined(ARMA_DONT_OPTIMISE_SYM) || defined(ARMA_DONT_OPTIMISE_SYMPD) || defined(ARMA_DONT_OPTIMISE_SOLVE_SYMPD) + #undef ARMA_OPTIMISE_SYM +#endif + +#if defined(ARMA_DONT_OPTIMISE_INVEXPR) + #undef ARMA_OPTIMISE_INVEXPR +#endif + +#if defined(ARMA_DONT_CHECK_NONFINITE) + #undef ARMA_CHECK_NONFINITE #endif #if defined(ARMA_DONT_PRINT_ERRORS) - #undef ARMA_PRINT_ERRORS + #pragma message ("INFO: support for ARMA_DONT_PRINT_ERRORS option has been removed") + + #if defined(ARMA_PRINT_EXCEPTIONS) + #pragma message ("INFO: suggest to use ARMA_WARN_LEVEL and ARMA_DONT_PRINT_EXCEPTIONS options instead") + #else + #pragma message ("INFO: suggest to use ARMA_WARN_LEVEL option instead") + #endif + + #pragma message ("INFO: see the documentation for details") #endif #if defined(ARMA_DONT_PRINT_EXCEPTIONS) @@ -327,10 +355,6 @@ //// 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 diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/constants.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/constants.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/constants.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/constants.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -33,14 +33,7 @@ { arma_ignore(junk); - if(std::numeric_limits::has_quiet_NaN) - { - return std::numeric_limits::quiet_NaN(); - } - else - { - return eT(0); - } + return (std::numeric_limits::has_quiet_NaN) ? eT(std::numeric_limits::quiet_NaN()) : eT(0); } @@ -75,14 +68,7 @@ { 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) ? eT(std::numeric_limits::infinity()) : eT(std::numeric_limits::max()); } @@ -98,7 +84,7 @@ return eT( Datum_helper::inf(), Datum_helper::inf() ); } - + template static typename arma_integral_only::result @@ -108,7 +94,6 @@ return std::numeric_limits::max(); } - }; } @@ -223,8 +208,8 @@ -typedef Datum fdatum; -typedef Datum datum; +typedef Datum fdatum; +typedef Datum datum; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/constants_old.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/constants_old.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/constants_old.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/constants_old.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -30,137 +30,54 @@ { public: - // 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 - - //! ratio of any circle's circumference to its diameter - 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(Datum::e); } // use datum::e instead - - //! Euler's constant, aka Euler-Mascheroni constant - arma_deprecated static eT euler() { return eT(Datum::euler); } // use datum::euler instead - - //! golden ratio - arma_deprecated static eT gratio() { return eT(Datum::gratio); } // use datum::gratio instead - - //! square root of 2 - 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 eT(Datum::eps); } // use datum::eps instead - - //! log of the minimum representable value - 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() { return eT(Datum::log_max); } // use datum::log_max instead - - //! "not a number" - arma_deprecated static eT nan() { return eT(Datum::nan); } // use datum::nan instead - - //! infinity - arma_deprecated static eT inf() { return eT(Datum::inf); } // use datum::inf instead + arma_frown("use datum::pi instead") static eT pi() { return eT(Datum::pi); } + arma_frown("use datum::e instead") static eT e() { return eT(Datum::e); } + arma_frown("use datum::euler instead") static eT euler() { return eT(Datum::euler); } + arma_frown("use datum::gratio instead") static eT gratio() { return eT(Datum::gratio); } + arma_frown("use datum::sqrt2 instead") static eT sqrt2() { return eT(Datum::sqrt2); } + arma_frown("use datum::eps instead") static eT eps() { return eT(Datum::eps); } + arma_frown("use datum::log_min instead") static eT log_min() { return eT(Datum::log_min); } + arma_frown("use datum::log_max instead") static eT log_max() { return eT(Datum::log_max); } + arma_frown("use datum::nan instead") static eT nan() { return eT(Datum::nan); } + arma_frown("use datum::inf instead") static eT inf() { return eT(Datum::inf); } }; -//! Physical constants taken from NIST 2010 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 template class Phy { public: - //! atomic mass constant (in kg) - arma_deprecated static eT m_u() { return eT(Datum::m_u); } - - //! Avogadro constant - arma_deprecated static eT N_A() { return eT(Datum::N_A); } - - //! Boltzmann constant (in joules per kelvin) - arma_deprecated static eT k() { return eT(Datum::k); } - - //! Boltzmann constant (in eV/K) - arma_deprecated static eT k_evk() { return eT(Datum::k_evk); } - - //! Bohr radius (in meters) - arma_deprecated static eT a_0() { return eT(Datum::a_0); } - - //! Bohr magneton - 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(Datum::Z_0); } - - //! conductance quantum (in siemens) - 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(Datum::k_e); } - - //! electric constant (in farads per meter) - arma_deprecated static eT eps_0() { return eT(Datum::eps_0); } - - //! electron mass (in kg) - arma_deprecated static eT m_e() { return eT(Datum::m_e); } - - //! electron volt (in joules) - arma_deprecated static eT eV() { return eT(Datum::eV); } - - //! elementary charge (in coulombs) - arma_deprecated static eT e() { return eT(Datum::ec); } - - //! Faraday constant (in coulombs) - arma_deprecated static eT F() { return eT(Datum::F); } - - //! fine-structure constant - arma_deprecated static eT alpha() { return eT(Datum::alpha); } - - //! inverse fine-structure constant + arma_deprecated static eT m_u() { return eT(Datum::m_u); } + arma_deprecated static eT N_A() { return eT(Datum::N_A); } + arma_deprecated static eT k() { return eT(Datum::k); } + arma_deprecated static eT k_evk() { return eT(Datum::k_evk); } + arma_deprecated static eT a_0() { return eT(Datum::a_0); } + arma_deprecated static eT mu_B() { return eT(Datum::mu_B); } + arma_deprecated static eT Z_0() { return eT(Datum::Z_0); } + arma_deprecated static eT G_0() { return eT(Datum::G_0); } + arma_deprecated static eT k_e() { return eT(Datum::k_e); } + arma_deprecated static eT eps_0() { return eT(Datum::eps_0); } + arma_deprecated static eT m_e() { return eT(Datum::m_e); } + arma_deprecated static eT eV() { return eT(Datum::eV); } + arma_deprecated static eT e() { return eT(Datum::ec); } + arma_deprecated static eT F() { return eT(Datum::F); } + arma_deprecated static eT alpha() { return eT(Datum::alpha); } arma_deprecated static eT alpha_inv() { return eT(Datum::alpha_inv); } - - //! Josephson constant - 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(Datum::mu_0); } - - //! magnetic flux quantum (in webers) - 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(Datum::R); } - - //! Newtonian constant of gravitation (in newton square meters per kilogram squared) - arma_deprecated static eT G() { return eT(Datum::G); } - - //! Planck constant (in joule seconds) - 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(Datum::h_bar); } - - //! proton mass (in kg) - arma_deprecated static eT m_p() { return eT(Datum::m_p); } - - //! Rydberg constant (in reciprocal meters) - 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(Datum::c_0); } - - //! Stefan-Boltzmann constant - arma_deprecated static eT sigma() { return eT(Datum::sigma); } - - //! von Klitzing constant (in ohms) - arma_deprecated static eT R_k() { return eT(Datum::R_k); } - - //! Wien wavelength displacement law constant - arma_deprecated static eT b() { return eT(Datum::b); } + arma_deprecated static eT K_J() { return eT(Datum::K_J); } + arma_deprecated static eT mu_0() { return eT(Datum::mu_0); } + arma_deprecated static eT phi_0() { return eT(Datum::phi_0); } + arma_deprecated static eT R() { return eT(Datum::R); } + arma_deprecated static eT G() { return eT(Datum::G); } + arma_deprecated static eT h() { return eT(Datum::h); } + arma_deprecated static eT h_bar() { return eT(Datum::h_bar); } + arma_deprecated static eT m_p() { return eT(Datum::m_p); } + arma_deprecated static eT R_inf() { return eT(Datum::R_inf); } + arma_deprecated static eT c_0() { return eT(Datum::c_0); } + arma_deprecated static eT sigma() { return eT(Datum::sigma); } + arma_deprecated static eT R_k() { return eT(Datum::R_k); } + arma_deprecated static eT b() { return eT(Datum::b); } }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/csv_name.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/csv_name.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/csv_name.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/csv_name.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -28,12 +28,13 @@ { const flag_type flags; - inline explicit opts(const flag_type in_flags); + inline constexpr explicit opts(const flag_type in_flags); inline const opts operator+(const opts& rhs) const; }; inline + constexpr opts::opts(const flag_type in_flags) : flags(in_flags) {} @@ -50,23 +51,26 @@ // 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; + static constexpr flag_type flag_none = flag_type(0 ); + static constexpr flag_type flag_trans = flag_type(1u << 0); + static constexpr flag_type flag_no_header = flag_type(1u << 1); + static constexpr flag_type flag_with_header = flag_type(1u << 2); + static constexpr flag_type flag_semicolon = flag_type(1u << 3); + static constexpr flag_type flag_strict = flag_type(1u << 4); + + struct opts_none : public opts { inline constexpr opts_none() : opts(flag_none ) {} }; + struct opts_trans : public opts { inline constexpr opts_trans() : opts(flag_trans ) {} }; + struct opts_no_header : public opts { inline constexpr opts_no_header() : opts(flag_no_header ) {} }; + struct opts_with_header : public opts { inline constexpr opts_with_header() : opts(flag_with_header) {} }; + struct opts_semicolon : public opts { inline constexpr opts_semicolon() : opts(flag_semicolon ) {} }; + struct opts_strict : public opts { inline constexpr opts_strict() : opts(flag_strict ) {} }; + + static constexpr opts_none none; + static constexpr opts_trans trans; + static constexpr opts_no_header no_header; + static constexpr opts_with_header with_header; + static constexpr opts_semicolon semicolon; + static constexpr opts_strict strict; } @@ -82,11 +86,19 @@ 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) + csv_name(const std::string& in_filename) + : filename (in_filename ) + , opts (csv_opts::no_header) + , header_ro(header_junk ) + , header_rw(header_junk ) + {} + + inline + csv_name(const std::string& in_filename, const csv_opts::opts& in_opts) + : filename (in_filename ) + , opts (csv_opts::no_header + in_opts) + , header_ro(header_junk ) + , header_rw(header_junk ) {} inline diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Cube_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Cube_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Cube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Cube_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -39,13 +39,13 @@ typedef eT elem_type; //!< the type of elements stored in the cube 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 in each slice (read-only) - const uword n_cols; //!< number of columns in each slice (read-only) - 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; + const uword n_rows; //!< number of rows in each slice (read-only) + const uword n_cols; //!< number of columns in each slice (read-only) + 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 // mem_state = 1: use auxiliary memory until a size change @@ -57,10 +57,27 @@ protected: - arma_aligned const Mat** const mat_ptrs; + using mat_type = Mat; - arma_align_mem Mat* mat_ptrs_local[ Cube_prealloc::mat_ptrs_size ]; - arma_align_mem eT mem_local[ Cube_prealloc::mem_n_elem ]; // local storage, for small cubes + #if defined(ARMA_USE_OPENMP) + using raw_mat_ptr_type = mat_type*; + using atomic_mat_ptr_type = mat_type*; + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + using raw_mat_ptr_type = mat_type*; + using atomic_mat_ptr_type = std::atomic; + #else + using raw_mat_ptr_type = mat_type*; + using atomic_mat_ptr_type = mat_type*; + #endif + + atomic_mat_ptr_type* mat_ptrs = nullptr; + + #if (!defined(ARMA_DONT_USE_STD_MUTEX)) + mutable std::mutex mat_mutex; // required for slice() + #endif + + arma_aligned atomic_mat_ptr_type mat_ptrs_local[ Cube_prealloc::mat_ptrs_size ]; + arma_align_mem eT mem_local[ Cube_prealloc::mem_n_elem ]; // local storage, for small cubes public: @@ -124,7 +141,7 @@ inline Mat& slice(const uword in_slice); inline const Mat& slice(const uword in_slice) const; - + arma_inline subview_cube rows(const uword in_row1, const uword in_row2); arma_inline const subview_cube rows(const uword in_row1, const uword in_row2) const; @@ -180,10 +197,10 @@ template inline subview_cube_each2 each_slice(const Base& indices); template inline const subview_cube_each2 each_slice(const Base& indices) const; - inline const Cube& each_slice(const std::function< void( Mat&) >& F); + inline 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 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; @@ -201,13 +218,18 @@ template inline void shed_slices(const Base& indices); - inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero = true); - inline void insert_cols(const uword row_num, const uword N, const bool set_to_zero = true); - inline void insert_slices(const uword slice_num, const uword N, const bool set_to_zero = true); + arma_deprecated inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero); + arma_deprecated inline void insert_cols(const uword row_num, const uword N, const bool set_to_zero); + arma_deprecated inline void insert_slices(const uword slice_num, const uword N, const bool set_to_zero); + + inline void insert_rows(const uword row_num, const uword N); + inline void insert_cols(const uword row_num, const uword N); + inline void insert_slices(const uword slice_num, const uword N); template inline void insert_rows(const uword row_num, const BaseCube& X); template inline void insert_cols(const uword col_num, const BaseCube& X); template inline void insert_slices(const uword slice_num, const BaseCube& X); + template inline void insert_slices(const uword slice_num, const Base& X); template inline Cube(const GenCube& X); @@ -260,22 +282,27 @@ template inline Cube& operator/=(const mtGlueCube& X); - arma_inline arma_warn_unused const eT& at_alt (const uword i) const; + arma_warn_unused arma_inline const eT& at_alt (const uword i) const; + + arma_warn_unused arma_inline eT& operator[] (const uword i); + arma_warn_unused arma_inline const eT& operator[] (const uword i) const; - arma_inline arma_warn_unused eT& operator[] (const uword i); - arma_inline arma_warn_unused const eT& operator[] (const uword i) const; + arma_warn_unused arma_inline eT& at(const uword i); + arma_warn_unused arma_inline const eT& at(const uword i) const; - arma_inline arma_warn_unused eT& at(const uword i); - arma_inline arma_warn_unused const eT& at(const uword i) const; + arma_warn_unused arma_inline eT& operator() (const uword i); + arma_warn_unused arma_inline const eT& operator() (const uword i) const; - arma_inline arma_warn_unused eT& operator() (const uword i); - arma_inline arma_warn_unused const eT& operator() (const uword i) const; + #if defined(__cpp_multidimensional_subscript) + arma_warn_unused arma_inline eT& operator[] (const uword in_row, const uword in_col, const uword in_slice); + arma_warn_unused arma_inline const eT& operator[] (const uword in_row, const uword in_col, const uword in_slice) const; + #endif - arma_inline arma_warn_unused eT& at (const uword in_row, const uword in_col, const uword in_slice); - arma_inline arma_warn_unused const eT& at (const uword in_row, const uword in_col, const uword in_slice) const; + arma_warn_unused arma_inline eT& at (const uword in_row, const uword in_col, const uword in_slice); + arma_warn_unused arma_inline const eT& at (const uword in_row, const uword in_col, const uword in_slice) const; - arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col, const uword in_slice); - arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col, const uword in_slice) const; + arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col, const uword in_slice); + arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col, const uword in_slice) const; arma_inline const Cube& operator++(); arma_inline void operator++(int); @@ -283,70 +310,71 @@ arma_inline const Cube& operator--(); arma_inline void operator--(int); - inline arma_warn_unused bool is_finite() const; - arma_inline arma_warn_unused bool is_empty() const; + arma_warn_unused arma_inline bool is_empty() const; - inline arma_warn_unused bool has_inf() const; - inline arma_warn_unused bool has_nan() const; + arma_warn_unused inline bool internal_is_finite() const; + arma_warn_unused inline bool internal_has_inf() const; + arma_warn_unused inline bool internal_has_nan() const; + arma_warn_unused inline bool internal_has_nonfinite() const; - arma_inline arma_warn_unused bool in_range(const uword i) const; - arma_inline arma_warn_unused bool in_range(const span& x) const; + arma_warn_unused arma_inline bool in_range(const uword i) const; + arma_warn_unused arma_inline bool in_range(const span& x) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const uword in_slice) const; - inline arma_warn_unused bool in_range(const span& row_span, const span& col_span, const span& slice_span) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const uword in_col, const uword in_slice) const; + arma_warn_unused inline bool in_range(const span& row_span, const span& col_span, const span& slice_span) const; - inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const uword in_slice, const SizeCube& s) const; + arma_warn_unused inline bool in_range(const uword in_row, const uword in_col, const uword in_slice, const SizeCube& s) const; - arma_inline arma_warn_unused eT* memptr(); - arma_inline arma_warn_unused const eT* memptr() const; + arma_warn_unused arma_inline eT* memptr(); + arma_warn_unused arma_inline const eT* memptr() const; - arma_inline arma_warn_unused eT* slice_memptr(const uword slice); - arma_inline arma_warn_unused const eT* slice_memptr(const uword slice) const; + arma_warn_unused arma_inline eT* slice_memptr(const uword slice); + arma_warn_unused arma_inline const eT* slice_memptr(const uword slice) const; - 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_warn_unused arma_inline eT* slice_colptr(const uword in_slice, const uword in_col); + arma_warn_unused arma_inline const eT* slice_colptr(const uword in_slice, const uword in_col) const; - 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 Cube& set_size(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + inline Cube& set_size(const SizeCube& s); - 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 Cube& reshape(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + inline Cube& reshape(const SizeCube& s); - inline void resize(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); - inline void resize(const SizeCube& s); + inline Cube& resize(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + inline Cube& resize(const SizeCube& s); - template inline void copy_size(const Cube& m); + template inline Cube& copy_size(const Cube& m); - template inline const Cube& for_each(functor F); + template inline Cube& for_each(functor F); template inline const Cube& for_each(functor F) const; - template inline const Cube& transform(functor F); - template inline const Cube& imbue(functor F); + template inline Cube& transform(functor F); + template inline Cube& imbue(functor F); - inline const Cube& replace(const eT old_val, const eT new_val); + inline Cube& replace(const eT old_val, const eT new_val); - inline const Cube& clean(const pod_type threshold); + inline Cube& clean(const pod_type threshold); - inline const Cube& clamp(const eT min_val, const eT max_val); + inline Cube& clamp(const eT min_val, const eT max_val); - inline const Cube& fill(const eT val); + inline Cube& fill(const eT val); - inline const Cube& zeros(); - 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 Cube& zeros(); + inline Cube& zeros(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + inline Cube& zeros(const SizeCube& s); - inline const Cube& ones(); - 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 Cube& ones(); + inline Cube& ones(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + inline Cube& ones(const SizeCube& s); - inline const Cube& randu(); - 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 Cube& randu(); + inline Cube& randu(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + inline Cube& randu(const SizeCube& s); - inline const Cube& randn(); - 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 Cube& randn(); + inline Cube& randn(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices); + inline Cube& randn(const SizeCube& s); inline void reset(); inline void soft_reset(); @@ -356,8 +384,8 @@ template inline void set_imag(const BaseCube& X); - inline arma_warn_unused eT min() const; - inline arma_warn_unused eT max() const; + arma_warn_unused inline eT min() const; + arma_warn_unused inline eT max() const; inline eT min(uword& index_of_min_val) const; inline eT max(uword& index_of_max_val) const; @@ -366,21 +394,21 @@ 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; - 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; - 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( std::istream& is, const file_type type = auto_detect); + arma_cold inline bool save(const std::string name, const file_type type = arma_binary) const; + arma_cold inline bool save(const hdf5_name& spec, const file_type type = hdf5_binary) const; + arma_cold inline bool save( std::ostream& os, const file_type type = arma_binary) const; + + arma_cold inline bool load(const std::string name, const file_type type = auto_detect); + arma_cold inline bool load(const hdf5_name& spec, const file_type type = hdf5_binary); + arma_cold inline bool load( std::istream& is, const file_type type = auto_detect); + + arma_deprecated inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; + arma_deprecated inline bool quiet_save(const hdf5_name& spec, const file_type type = hdf5_binary) const; + arma_deprecated inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; + + arma_deprecated inline bool quiet_load(const std::string name, const file_type type = auto_detect); + arma_deprecated inline bool quiet_load(const hdf5_name& spec, const file_type type = hdf5_binary); + arma_deprecated inline bool quiet_load( std::istream& is, const file_type type = auto_detect); // iterators @@ -409,15 +437,16 @@ inline bool empty() const; inline uword size() const; - inline arma_warn_unused eT& front(); - inline arma_warn_unused const eT& front() const; + arma_warn_unused inline eT& front(); + arma_warn_unused inline const eT& front() const; - inline arma_warn_unused eT& back(); - inline arma_warn_unused const eT& back() const; + arma_warn_unused inline eT& back(); + arma_warn_unused inline 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 + inline void steal_mem(Cube& X); //!< don't use this unless you're writing code internal to Armadillo + inline void steal_mem(Cube& X, const bool is_move); //!< don't use this unless you're writing code internal to Armadillo template class fixed; @@ -433,6 +462,9 @@ inline void delete_mat(); inline void create_mat(); + inline Mat* create_mat_ptr(const uword in_slice) const; + inline Mat* get_mat_ptr(const uword in_slice) const; + friend class glue_join; friend class op_reshape; friend class op_resize; @@ -441,7 +473,7 @@ public: - #ifdef ARMA_EXTRA_CUBE_PROTO + #if defined(ARMA_EXTRA_CUBE_PROTO) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_PROTO) #endif }; @@ -459,8 +491,8 @@ 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 ]; + arma_aligned atomic_mat_ptr_type 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 ]; arma_inline void mem_setup(); @@ -481,20 +513,25 @@ inline Cube& operator=(const fixed& X); - arma_inline arma_warn_unused eT& operator[] (const uword i); - arma_inline arma_warn_unused const eT& operator[] (const uword i) const; + arma_warn_unused arma_inline eT& operator[] (const uword i); + arma_warn_unused arma_inline const eT& operator[] (const uword i) const; + + arma_warn_unused arma_inline eT& at (const uword i); + arma_warn_unused arma_inline const eT& at (const uword i) const; - arma_inline arma_warn_unused eT& at (const uword i); - arma_inline arma_warn_unused const eT& at (const uword i) const; + arma_warn_unused arma_inline eT& operator() (const uword i); + arma_warn_unused arma_inline const eT& operator() (const uword i) const; - arma_inline arma_warn_unused eT& operator() (const uword i); - arma_inline arma_warn_unused const eT& operator() (const uword i) const; + #if defined(__cpp_multidimensional_subscript) + arma_warn_unused arma_inline eT& operator[] (const uword in_row, const uword in_col, const uword in_slice); + arma_warn_unused arma_inline const eT& operator[] (const uword in_row, const uword in_col, const uword in_slice) const; + #endif - arma_inline arma_warn_unused eT& at (const uword in_row, const uword in_col, const uword in_slice); - arma_inline arma_warn_unused const eT& at (const uword in_row, const uword in_col, const uword in_slice) const; + arma_warn_unused arma_inline eT& at (const uword in_row, const uword in_col, const uword in_slice); + arma_warn_unused arma_inline const eT& at (const uword in_row, const uword in_col, const uword in_slice) const; - arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col, const uword in_slice); - arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col, const uword in_slice) const; + arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col, const uword in_slice); + arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col, const uword in_slice) const; }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Cube_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Cube_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Cube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Cube_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -35,11 +35,7 @@ } // try to expose buggy user code that accesses deleted objects - if(arma_config::debug) - { - access::rw(mem) = nullptr; - access::rw(mat_ptrs) = nullptr; - } + if(arma_config::debug) { access::rw(mem) = nullptr; } arma_type_check(( is_supported_elem_type::value == false )); } @@ -57,7 +53,6 @@ , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); } @@ -76,18 +71,16 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); init_cold(); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Cube::constructor: zeroing memory"); arrayops::fill_zeros(memptr(), n_elem); } - #endif } @@ -103,18 +96,16 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); init_cold(); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Cube::constructor: zeroing memory"); arrayops::fill_zeros(memptr(), n_elem); } - #endif } @@ -132,7 +123,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -160,7 +150,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -188,7 +177,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -216,7 +204,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -244,7 +231,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -266,7 +252,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -288,12 +273,10 @@ , 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); - (*this).steal_mem(in_cube); + (*this).steal_mem(in_cube, true); } @@ -305,7 +288,7 @@ { arma_extra_debug_sigprint(arma_str::format("this = %x in_cube = %x") % this % &in_cube); - (*this).steal_mem(in_cube); + (*this).steal_mem(in_cube, true); return *this; } @@ -317,7 +300,7 @@ void Cube::init_cold() { - arma_extra_debug_sigprint( arma_str::format("n_rows = %d, n_cols = %d, n_slices = %d") % n_rows % n_cols % n_slices ); + arma_extra_debug_sigprint( arma_str::format("n_rows = %u, n_cols = %u, n_slices = %u") % n_rows % n_cols % n_slices ); #if defined(ARMA_64BIT_WORD) const char* error_message = "Cube::init(): requested size is too large"; @@ -361,7 +344,7 @@ void Cube::init_warm(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) { - arma_extra_debug_sigprint( arma_str::format("in_n_rows = %d, in_n_cols = %d, in_n_slices = %d") % in_n_rows % in_n_cols % in_n_slices ); + arma_extra_debug_sigprint( arma_str::format("in_n_rows = %u, in_n_cols = %u, in_n_slices = %u") % in_n_rows % in_n_cols % in_n_slices ); if( (n_rows == in_n_rows) && (n_cols == in_n_cols) && (n_slices == in_n_slices) ) { return; } @@ -370,12 +353,14 @@ bool err_state = false; 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" ); + const char* error_message_1 = "Cube::init(): size is fixed and hence cannot be changed"; + + arma_debug_set_error( err_state, err_msg, (t_mem_state == 3), error_message_1 ); #if defined(ARMA_64BIT_WORD) - const char* error_message = "Cube::init(): requested size is too large"; + const char* error_message_2 = "Cube::init(): requested size is too large"; #else - const char* error_message = "Cube::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; + const char* error_message_2 = "Cube::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_set_error @@ -387,7 +372,7 @@ ? ( (double(in_n_rows) * double(in_n_cols) * double(in_n_slices)) > double(ARMA_MAX_UWORD) ) : false ), - error_message + error_message_2 ); arma_debug_check(err_state, err_msg); @@ -542,14 +527,23 @@ if((n_slices > 0) && (mat_ptrs != nullptr)) { - for(uword uslice = 0; uslice < n_slices; ++uslice) + for(uword s=0; s < n_slices; ++s) { - if(mat_ptrs[uslice] != nullptr) { delete access::rw(mat_ptrs[uslice]); } + raw_mat_ptr_type mat_ptr = raw_mat_ptr_type(mat_ptrs[s]); // explicit cast to indicate load from std::atomic*> + + if(mat_ptr != nullptr) + { + arma_extra_debug_print( arma_str::format("Cube::delete_mat(): destroying matrix %u") % s ); + delete mat_ptr; + mat_ptrs[s] = nullptr; + } } if( (mem_state <= 2) && (n_slices > Cube_prealloc::mat_ptrs_size) ) { + arma_extra_debug_print("Cube::delete_mat(): freeing mat_ptrs array"); delete [] mat_ptrs; + mat_ptrs = nullptr; } } } @@ -563,31 +557,110 @@ { arma_extra_debug_sigprint(); - if(n_slices == 0) + if(n_slices == 0) { mat_ptrs = nullptr; return; } + + if(mem_state <= 2) { - access::rw(mat_ptrs) = nullptr; + if(n_slices <= Cube_prealloc::mat_ptrs_size) + { + arma_extra_debug_print("Cube::create_mat(): using local memory for mat_ptrs array"); + + mat_ptrs = mat_ptrs_local; + } + else + { + arma_extra_debug_print("Cube::create_mat(): allocating mat_ptrs array"); + + mat_ptrs = new(std::nothrow) atomic_mat_ptr_type[n_slices]; + + arma_check_bad_alloc( (mat_ptrs == nullptr), "Cube::create_mat(): out of memory" ); + } } - else + + for(uword s=0; s < n_slices; ++s) { mat_ptrs[s] = nullptr; } + } + + + +template +inline +Mat* +Cube::create_mat_ptr(const uword in_slice) const + { + arma_extra_debug_sigprint(); + + arma_extra_debug_print( arma_str::format("Cube::create_mat_ptr(): creating matrix %u") % in_slice ); + + const eT* mat_mem = (n_elem_slice > 0) ? slice_memptr(in_slice) : nullptr; + + Mat* mat_ptr = new(std::nothrow) Mat('j', mat_mem, n_rows, n_cols); + + return mat_ptr; + } + + + +template +inline +Mat* +Cube::get_mat_ptr(const uword in_slice) const + { + arma_extra_debug_sigprint(); + + raw_mat_ptr_type mat_ptr = nullptr; + + #if defined(ARMA_USE_OPENMP) { - if(mem_state <= 2) + #pragma omp atomic read + mat_ptr = mat_ptrs[in_slice]; + } + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + { + mat_ptr = mat_ptrs[in_slice].load(); + } + #else + { + mat_ptr = mat_ptrs[in_slice]; + } + #endif + + if(mat_ptr == nullptr) + { + #if defined(ARMA_USE_OPENMP) { - if(n_slices <= Cube_prealloc::mat_ptrs_size) + #pragma omp critical (arma_Cube_mat_ptrs) { - access::rw(mat_ptrs) = const_cast< const Mat** >(mat_ptrs_local); - } - else - { - access::rw(mat_ptrs) = new(std::nothrow) const Mat*[n_slices]; + #pragma omp atomic read + mat_ptr = mat_ptrs[in_slice]; + + if(mat_ptr == nullptr) { mat_ptr = create_mat_ptr(in_slice); } - arma_check_bad_alloc( (mat_ptrs == nullptr), "Cube::create_mat(): out of memory" ); + #pragma omp atomic write + mat_ptrs[in_slice] = mat_ptr; } } - - for(uword uslice = 0; uslice < n_slices; ++uslice) + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + { + const std::lock_guard lock(mat_mutex); + + mat_ptr = mat_ptrs[in_slice].load(); + + if(mat_ptr == nullptr) { mat_ptr = create_mat_ptr(in_slice); } + + mat_ptrs[in_slice].store(mat_ptr); + } + #else { - mat_ptrs[uslice] = nullptr; + mat_ptr = create_mat_ptr(in_slice); + + mat_ptrs[in_slice] = mat_ptr; } + #endif + + arma_check_bad_alloc( (mat_ptr == nullptr), "Cube::get_mat_ptr(): out of memory" ); } + + return mat_ptr; } @@ -682,7 +755,6 @@ , n_alloc() , 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 % &x); @@ -728,11 +800,10 @@ , n_alloc ( 0 ) , mem_state ( copy_aux_mem ? 0 : (strict ? 2 : 1) ) , mem ( copy_aux_mem ? nullptr : aux_mem ) - , mat_ptrs ( nullptr ) { arma_extra_debug_sigprint_this(this); - if(prealloc_mat) { arma_debug_warn_level(3, "Cube::Cube(): parameter 'prealloc_mat' ignored as it's no longer used"); } + arma_ignore(prealloc_mat); // kept only for compatibility with old user code if(copy_aux_mem) { @@ -761,7 +832,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -857,7 +927,6 @@ , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -878,7 +947,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -989,7 +1057,6 @@ , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -1154,14 +1221,7 @@ arma_debug_check_bounds( (in_slice >= n_slices), "Cube::slice(): index out of bounds" ); - if(mat_ptrs[in_slice] == nullptr) - { - const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : nullptr; - - mat_ptrs[in_slice] = new Mat('j', ptr, n_rows, n_cols); - } - - return const_cast< Mat& >( *(mat_ptrs[in_slice]) ); + return *(get_mat_ptr(in_slice)); } @@ -1176,14 +1236,7 @@ arma_debug_check_bounds( (in_slice >= n_slices), "Cube::slice(): index out of bounds" ); - if(mat_ptrs[in_slice] == nullptr) - { - const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : nullptr; - - mat_ptrs[in_slice] = new Mat('j', ptr, n_rows, n_cols); - } - - return *(mat_ptrs[in_slice]); + return *(get_mat_ptr(in_slice)); } @@ -1917,7 +1970,7 @@ //! apply a lambda function to each slice, where each slice is interpreted as a matrix template inline -const Cube& +Cube& Cube::each_slice(const std::function< void(Mat&) >& F) { arma_extra_debug_sigprint(); @@ -1955,7 +2008,7 @@ template inline -const Cube& +Cube& Cube::each_slice(const std::function< void(Mat&) >& F, const bool use_mp) { arma_extra_debug_sigprint(); @@ -2267,6 +2320,20 @@ { arma_extra_debug_sigprint(); + arma_ignore(set_to_zero); + + (*this).insert_rows(row_num, N); + } + + + +template +inline +void +Cube::insert_rows(const uword row_num, const uword N) + { + arma_extra_debug_sigprint(); + const uword t_n_rows = n_rows; const uword A_n_rows = row_num; @@ -2275,27 +2342,23 @@ // insertion at row_num == n_rows is in effect an append operation arma_debug_check_bounds( (row_num > t_n_rows), "Cube::insert_rows(): index out of bounds" ); - if(N > 0) + if(N == 0) { return; } + + Cube out(t_n_rows + N, n_cols, n_slices, arma_nozeros_indicator()); + + if(A_n_rows > 0) { - Cube out(t_n_rows + N, n_cols, n_slices, arma_nozeros_indicator()); - - if(A_n_rows > 0) - { - out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1); - } - - if(B_n_rows > 0) - { - out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1); - } - - if(set_to_zero) - { - out.rows(row_num, row_num + N - 1).zeros(); - } - - steal_mem(out); + out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1); } + + if(B_n_rows > 0) + { + out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1); + } + + out.rows(row_num, row_num + N - 1).zeros(); + + steal_mem(out); } @@ -2307,6 +2370,20 @@ { arma_extra_debug_sigprint(); + arma_ignore(set_to_zero); + + (*this).insert_cols(col_num, N); + } + + + +template +inline +void +Cube::insert_cols(const uword col_num, const uword N) + { + arma_extra_debug_sigprint(); + const uword t_n_cols = n_cols; const uword A_n_cols = col_num; @@ -2315,33 +2392,27 @@ // insertion at col_num == n_cols is in effect an append operation arma_debug_check_bounds( (col_num > t_n_cols), "Cube::insert_cols(): index out of bounds" ); - if(N > 0) + if(N == 0) { return; } + + Cube out(n_rows, t_n_cols + N, n_slices, arma_nozeros_indicator()); + + if(A_n_cols > 0) { - Cube out(n_rows, t_n_cols + N, n_slices, arma_nozeros_indicator()); - - if(A_n_cols > 0) - { - out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1); - } - - if(B_n_cols > 0) - { - out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1); - } - - if(set_to_zero) - { - out.cols(col_num, col_num + N - 1).zeros(); - } - - steal_mem(out); + out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1); + } + + if(B_n_cols > 0) + { + out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1); } + + out.cols(col_num, col_num + N - 1).zeros(); + + steal_mem(out); } -//! insert N slices at the specified slice position, -//! optionally setting the elements of the inserted slices to zero template inline void @@ -2349,6 +2420,20 @@ { arma_extra_debug_sigprint(); + arma_ignore(set_to_zero); + + (*this).insert_slices(slice_num, N); + } + + + +template +inline +void +Cube::insert_slices(const uword slice_num, const uword N) + { + arma_extra_debug_sigprint(); + const uword t_n_slices = n_slices; const uword A_n_slices = slice_num; @@ -2357,32 +2442,28 @@ // insertion at slice_num == n_slices is in effect an append operation arma_debug_check_bounds( (slice_num > t_n_slices), "Cube::insert_slices(): index out of bounds" ); - if(N > 0) + if(N == 0) { return; } + + Cube out(n_rows, n_cols, t_n_slices + N, arma_nozeros_indicator()); + + if(A_n_slices > 0) { - Cube out(n_rows, n_cols, t_n_slices + N, arma_nozeros_indicator()); - - if(A_n_slices > 0) - { - out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1); - } - - if(B_n_slices > 0) - { - out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices-1); - } - - if(set_to_zero) - { - //out.slices(slice_num, slice_num + N - 1).zeros(); - - for(uword i=slice_num; i < (slice_num + N); ++i) - { - arrayops::fill_zeros(out.slice_memptr(i), out.n_elem_slice); - } - } - - steal_mem(out); + out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1); + } + + if(B_n_slices > 0) + { + out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices-1); + } + + //out.slices(slice_num, slice_num + N - 1).zeros(); + + for(uword i=slice_num; i < (slice_num + N); ++i) + { + arrayops::fill_zeros(out.slice_memptr(i), out.n_elem_slice); } + + steal_mem(out); } @@ -2414,24 +2495,23 @@ "Cube::insert_rows(): given object has incompatible dimensions" ); - if(N > 0) + if(N == 0) { return; } + + Cube out(t_n_rows + N, n_cols, n_slices, arma_nozeros_indicator()); + + if(A_n_rows > 0) { - Cube out(t_n_rows + N, n_cols, n_slices, arma_nozeros_indicator()); - - if(A_n_rows > 0) - { - out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1); - } - - if(B_n_rows > 0) - { - out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows - 1); - } - - out.rows(row_num, row_num + N - 1) = C; - - steal_mem(out); + out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1); + } + + if(B_n_rows > 0) + { + out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows - 1); } + + out.rows(row_num, row_num + N - 1) = C; + + steal_mem(out); } @@ -2463,24 +2543,23 @@ "Cube::insert_cols(): given object has incompatible dimensions" ); - if(N > 0) + if(N == 0) { return; } + + Cube out(n_rows, t_n_cols + N, n_slices, arma_nozeros_indicator()); + + if(A_n_cols > 0) { - Cube out(n_rows, t_n_cols + N, n_slices, arma_nozeros_indicator()); - - if(A_n_cols > 0) - { - out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1); - } - - if(B_n_cols > 0) - { - out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols - 1); - } - - out.cols(col_num, col_num + N - 1) = C; - - steal_mem(out); + out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1); } + + if(B_n_cols > 0) + { + out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols - 1); + } + + out.cols(col_num, col_num + N - 1) = C; + + steal_mem(out); } @@ -2514,24 +2593,40 @@ "Cube::insert_slices(): given object has incompatible dimensions" ); - if(N > 0) + if(N == 0) { return; } + + Cube out(n_rows, n_cols, t_n_slices + N, arma_nozeros_indicator()); + + if(A_n_slices > 0) { - Cube out(n_rows, n_cols, t_n_slices + N, arma_nozeros_indicator()); - - if(A_n_slices > 0) - { - out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1); - } - - if(B_n_slices > 0) - { - out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices - 1); - } - - out.slices(slice_num, slice_num + N - 1) = C; - - steal_mem(out); + out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1); } + + if(B_n_slices > 0) + { + out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices - 1); + } + + out.slices(slice_num, slice_num + N - 1) = C; + + steal_mem(out); + } + + + +template +template +inline +void +Cube::insert_slices(const uword slice_num, const Base& X) + { + arma_extra_debug_sigprint(); + + const quasi_unwrap U(X.get_ref()); + + const Cube C(const_cast(U.M.memptr()), U.M.n_rows, U.M.n_cols, uword(1), false, true); + + (*this).insert_slices(slice_num, C); } @@ -2549,7 +2644,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2650,7 +2744,6 @@ , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2764,7 +2857,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2790,18 +2882,11 @@ const bool bad_alias = ( X.P.has_subview && X.P.is_alias(*this) ); - if(bad_alias == false) - { - init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); - - eop_type::apply(*this, X); - } - else - { - Cube tmp(X); - - steal_mem(tmp); - } + if(bad_alias) { Cube tmp(X); steal_mem(tmp); return *this; } + + init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); + + eop_type::apply(*this, X); return *this; } @@ -2819,6 +2904,10 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + const bool bad_alias = ( X.P.has_subview && X.P.is_alias(*this) ); + + if(bad_alias) { const Cube tmp(X); return (*this).operator+=(tmp); } + eop_type::apply_inplace_plus(*this, X); return *this; @@ -2837,6 +2926,10 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + const bool bad_alias = ( X.P.has_subview && X.P.is_alias(*this) ); + + if(bad_alias) { const Cube tmp(X); return (*this).operator-=(tmp); } + eop_type::apply_inplace_minus(*this, X); return *this; @@ -2854,7 +2947,11 @@ arma_extra_debug_sigprint(); arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); - + + const bool bad_alias = ( X.P.has_subview && X.P.is_alias(*this) ); + + if(bad_alias) { const Cube tmp(X); return (*this).operator%=(tmp); } + eop_type::apply_inplace_schur(*this, X); return *this; @@ -2872,7 +2969,11 @@ arma_extra_debug_sigprint(); arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); - + + const bool bad_alias = ( X.P.has_subview && X.P.is_alias(*this) ); + + if(bad_alias) { const Cube tmp(X); return (*this).operator/=(tmp); } + eop_type::apply_inplace_div(*this, X); return *this; @@ -2892,7 +2993,6 @@ , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -2989,7 +3089,6 @@ , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -3105,7 +3204,6 @@ , n_alloc() , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -3133,18 +3231,11 @@ const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || (X.P2.has_subview && X.P2.is_alias(*this)) ); - if(bad_alias == false) - { - init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); - - eglue_type::apply(*this, X); - } - else - { - Cube tmp(X); - - steal_mem(tmp); - } + if(bad_alias) { Cube tmp(X); steal_mem(tmp); return *this; } + + init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); + + eglue_type::apply(*this, X); return *this; } @@ -3163,6 +3254,10 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || (X.P2.has_subview && X.P2.is_alias(*this)) ); + + if(bad_alias) { const Cube tmp(X); return (*this).operator+=(tmp); } + eglue_type::apply_inplace_plus(*this, X); return *this; @@ -3182,6 +3277,10 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || (X.P2.has_subview && X.P2.is_alias(*this)) ); + + if(bad_alias) { const Cube tmp(X); return (*this).operator-=(tmp); } + eglue_type::apply_inplace_minus(*this, X); return *this; @@ -3201,6 +3300,10 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || (X.P2.has_subview && X.P2.is_alias(*this)) ); + + if(bad_alias) { const Cube tmp(X); return (*this).operator%=(tmp); } + eglue_type::apply_inplace_schur(*this, X); return *this; @@ -3220,6 +3323,10 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || (X.P2.has_subview && X.P2.is_alias(*this)) ); + + if(bad_alias) { const Cube tmp(X); return (*this).operator/=(tmp); } + eglue_type::apply_inplace_div(*this, X); return *this; @@ -3239,7 +3346,6 @@ , n_alloc(0) , mem_state(0) , mem() - , mat_ptrs(nullptr) { arma_extra_debug_sigprint_this(this); @@ -3326,7 +3432,6 @@ //! linear element accessor (treats the cube as a vector); no bounds check; assumes memory is aligned template arma_inline -arma_warn_unused const eT& Cube::at_alt(const uword i) const { @@ -3342,7 +3447,6 @@ //! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline -arma_warn_unused eT& Cube::operator() (const uword i) { @@ -3356,7 +3460,6 @@ //! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline -arma_warn_unused const eT& Cube::operator() (const uword i) const { @@ -3369,7 +3472,6 @@ //! linear element accessor (treats the cube as a vector); no bounds check. template arma_inline -arma_warn_unused eT& Cube::operator[] (const uword i) { @@ -3381,7 +3483,6 @@ //! linear element accessor (treats the cube as a vector); no bounds check template arma_inline -arma_warn_unused const eT& Cube::operator[] (const uword i) const { @@ -3393,7 +3494,6 @@ //! linear element accessor (treats the cube as a vector); no bounds check. template arma_inline -arma_warn_unused eT& Cube::at(const uword i) { @@ -3405,7 +3505,6 @@ //! linear element accessor (treats the cube as a vector); no bounds check template arma_inline -arma_warn_unused const eT& Cube::at(const uword i) const { @@ -3417,7 +3516,6 @@ //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline -arma_warn_unused eT& Cube::operator() (const uword in_row, const uword in_col, const uword in_slice) { @@ -3438,7 +3536,6 @@ //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline -arma_warn_unused const eT& Cube::operator() (const uword in_row, const uword in_col, const uword in_slice) const { @@ -3456,10 +3553,35 @@ +#if defined(__cpp_multidimensional_subscript) + + //! element accessor; no bounds check + template + arma_inline + eT& + Cube::operator[] (const uword in_row, const uword in_col, const uword in_slice) + { + return access::rw( mem[in_slice*n_elem_slice + in_col*n_rows + in_row] ); + } + + + + //! element accessor; no bounds check + template + arma_inline + const eT& + Cube::operator[] (const uword in_row, const uword in_col, const uword in_slice) const + { + return mem[in_slice*n_elem_slice + in_col*n_rows + in_row]; + } + +#endif + + + //! element accessor; no bounds check template arma_inline -arma_warn_unused eT& Cube::at(const uword in_row, const uword in_col, const uword in_slice) { @@ -3471,7 +3593,6 @@ //! element accessor; no bounds check template arma_inline -arma_warn_unused const eT& Cube::at(const uword in_row, const uword in_col, const uword in_slice) const { @@ -3527,54 +3648,61 @@ -//! returns true if all of the elements are finite +//! returns true if the cube has no elements +template +arma_inline +bool +Cube::is_empty() const + { + return (n_elem == 0); + } + + + template inline -arma_warn_unused bool -Cube::is_finite() const +Cube::internal_is_finite() const { arma_extra_debug_sigprint(); - return arrayops::is_finite( memptr(), n_elem ); + return arrayops::is_finite(memptr(), n_elem); } -//! returns true if the cube has no elements template -arma_inline -arma_warn_unused +inline bool -Cube::is_empty() const +Cube::internal_has_inf() const { - return (n_elem == 0); + arma_extra_debug_sigprint(); + + return arrayops::has_inf(memptr(), n_elem); } template inline -arma_warn_unused bool -Cube::has_inf() const +Cube::internal_has_nan() const { arma_extra_debug_sigprint(); - return arrayops::has_inf( memptr(), n_elem ); + return arrayops::has_nan(memptr(), n_elem); } template inline -arma_warn_unused bool -Cube::has_nan() const +Cube::internal_has_nonfinite() const { arma_extra_debug_sigprint(); - return arrayops::has_nan( memptr(), n_elem ); + return (arrayops::is_finite(memptr(), n_elem) == false); } @@ -3582,7 +3710,6 @@ //! returns true if the given index is currently in range template arma_inline -arma_warn_unused bool Cube::in_range(const uword i) const { @@ -3594,7 +3721,6 @@ //! returns true if the given start and end indices are currently in range template arma_inline -arma_warn_unused bool Cube::in_range(const span& x) const { @@ -3618,7 +3744,6 @@ //! returns true if the given location is currently in range template arma_inline -arma_warn_unused bool Cube::in_range(const uword in_row, const uword in_col, const uword in_slice) const { @@ -3629,7 +3754,6 @@ template inline -arma_warn_unused bool Cube::in_range(const span& row_span, const span& col_span, const span& slice_span) const { @@ -3657,7 +3781,6 @@ template inline -arma_warn_unused bool Cube::in_range(const uword in_row, const uword in_col, const uword in_slice, const SizeCube& s) const { @@ -3683,7 +3806,6 @@ //! returns a pointer to array of eTs used by the cube template arma_inline -arma_warn_unused eT* Cube::memptr() { @@ -3695,7 +3817,6 @@ //! returns a pointer to array of eTs used by the cube template arma_inline -arma_warn_unused const eT* Cube::memptr() const { @@ -3707,7 +3828,6 @@ //! returns a pointer to array of eTs used by the specified slice in the cube template arma_inline -arma_warn_unused eT* Cube::slice_memptr(const uword uslice) { @@ -3719,7 +3839,6 @@ //! returns a pointer to array of eTs used by the specified slice in the cube template arma_inline -arma_warn_unused const eT* Cube::slice_memptr(const uword uslice) const { @@ -3731,7 +3850,6 @@ //! returns a pointer to array of eTs used by the specified slice in the cube template arma_inline -arma_warn_unused eT* Cube::slice_colptr(const uword uslice, const uword col) { @@ -3743,7 +3861,6 @@ //! returns a pointer to array of eTs used by the specified slice in the cube template arma_inline -arma_warn_unused const eT* Cube::slice_colptr(const uword uslice, const uword col) const { @@ -3755,12 +3872,14 @@ //! change the cube to have user specified dimensions (data is not preserved) template inline -void +Cube& Cube::set_size(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); init_warm(new_n_rows, new_n_cols, new_n_slices); + + return *this; } @@ -3768,12 +3887,14 @@ //! change the cube to have user specified dimensions (data is preserved) template inline -void +Cube& Cube::reshape(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); op_reshape::apply_cube_inplace((*this), new_n_rows, new_n_cols, new_n_slices); + + return *this; } @@ -3781,48 +3902,56 @@ //! change the cube to have user specified dimensions (data is preserved) template inline -void +Cube& Cube::resize(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); op_resize::apply_cube_inplace((*this), new_n_rows, new_n_cols, new_n_slices); + + return *this; } template inline -void +Cube& Cube::set_size(const SizeCube& s) { arma_extra_debug_sigprint(); init_warm(s.n_rows, s.n_cols, s.n_slices); + + return *this; } template inline -void +Cube& Cube::reshape(const SizeCube& s) { arma_extra_debug_sigprint(); op_reshape::apply_cube_inplace((*this), s.n_rows, s.n_cols, s.n_slices); + + return *this; } template inline -void +Cube& Cube::resize(const SizeCube& s) { arma_extra_debug_sigprint(); op_resize::apply_cube_inplace((*this), s.n_rows, s.n_cols, s.n_slices); + + return *this; } @@ -3831,12 +3960,14 @@ template template inline -void +Cube& Cube::copy_size(const Cube& m) { arma_extra_debug_sigprint(); init_warm(m.n_rows, m.n_cols, m.n_slices); + + return *this; } @@ -3845,7 +3976,7 @@ template template inline -const Cube& +Cube& Cube::for_each(functor F) { arma_extra_debug_sigprint(); @@ -3906,7 +4037,7 @@ template template inline -const Cube& +Cube& Cube::transform(functor F) { arma_extra_debug_sigprint(); @@ -3943,7 +4074,7 @@ template template inline -const Cube& +Cube& Cube::imbue(functor F) { arma_extra_debug_sigprint(); @@ -3975,7 +4106,7 @@ template inline -const Cube& +Cube& Cube::replace(const eT old_val, const eT new_val) { arma_extra_debug_sigprint(); @@ -3989,7 +4120,7 @@ template inline -const Cube& +Cube& Cube::clean(const typename get_pod_type::result threshold) { arma_extra_debug_sigprint(); @@ -4003,7 +4134,7 @@ template inline -const Cube& +Cube& Cube::clamp(const eT min_val, const eT max_val) { arma_extra_debug_sigprint(); @@ -4028,7 +4159,7 @@ //! fill the cube with the specified value template inline -const Cube& +Cube& Cube::fill(const eT val) { arma_extra_debug_sigprint(); @@ -4042,7 +4173,7 @@ template inline -const Cube& +Cube& Cube::zeros() { arma_extra_debug_sigprint(); @@ -4056,7 +4187,7 @@ template inline -const Cube& +Cube& Cube::zeros(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); @@ -4070,7 +4201,7 @@ template inline -const Cube& +Cube& Cube::zeros(const SizeCube& s) { arma_extra_debug_sigprint(); @@ -4082,7 +4213,7 @@ template inline -const Cube& +Cube& Cube::ones() { arma_extra_debug_sigprint(); @@ -4094,7 +4225,7 @@ template inline -const Cube& +Cube& Cube::ones(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); @@ -4108,7 +4239,7 @@ template inline -const Cube& +Cube& Cube::ones(const SizeCube& s) { arma_extra_debug_sigprint(); @@ -4120,7 +4251,7 @@ template inline -const Cube& +Cube& Cube::randu() { arma_extra_debug_sigprint(); @@ -4134,7 +4265,7 @@ template inline -const Cube& +Cube& Cube::randu(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); @@ -4148,7 +4279,7 @@ template inline -const Cube& +Cube& Cube::randu(const SizeCube& s) { arma_extra_debug_sigprint(); @@ -4160,7 +4291,7 @@ template inline -const Cube& +Cube& Cube::randn() { arma_extra_debug_sigprint(); @@ -4174,7 +4305,7 @@ template inline -const Cube& +Cube& Cube::randn(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices) { arma_extra_debug_sigprint(); @@ -4188,7 +4319,7 @@ template inline -const Cube& +Cube& Cube::randn(const SizeCube& s) { arma_extra_debug_sigprint(); @@ -4258,7 +4389,6 @@ template inline -arma_warn_unused eT Cube::min() const { @@ -4278,7 +4408,6 @@ template inline -arma_warn_unused eT Cube::max() const { @@ -4411,7 +4540,6 @@ //! save the cube to a file template inline -arma_cold bool Cube::save(const std::string name, const file_type type) const { @@ -4454,7 +4582,7 @@ save_okay = false; } - if(save_okay == false) { arma_debug_warn_level(3, "Cube::save(): couldn't write; file: ", name); } + if(save_okay == false) { arma_debug_warn_level(3, "Cube::save(): write failed; file: ", name); } return save_okay; } @@ -4463,7 +4591,6 @@ template inline -arma_cold bool Cube::save(const hdf5_name& spec, const file_type type) const { @@ -4511,7 +4638,7 @@ } else { - arma_debug_warn_level(3, "Cube::save(): couldn't write; file: ", spec.filename); + arma_debug_warn_level(3, "Cube::save(): write failed; file: ", spec.filename); } } @@ -4523,7 +4650,6 @@ //! save the cube to a stream template inline -arma_cold bool Cube::save(std::ostream& os, const file_type type) const { @@ -4558,7 +4684,7 @@ save_okay = false; } - if(save_okay == false) { arma_debug_warn_level(3, "Cube::save(): couldn't write to stream"); } + if(save_okay == false) { arma_debug_warn_level(3, "Cube::save(): stream write failed"); } return save_okay; } @@ -4568,7 +4694,6 @@ //! load a cube from a file template inline -arma_cold bool Cube::load(const std::string name, const file_type type) { @@ -4626,7 +4751,7 @@ } else { - arma_debug_warn_level(3, "Cube::load(): couldn't read; file: ", name); + arma_debug_warn_level(3, "Cube::load(): read failed; file: ", name); } } @@ -4637,7 +4762,6 @@ template inline -arma_cold bool Cube::load(const hdf5_name& spec, const file_type type) { @@ -4678,7 +4802,7 @@ } else { - arma_debug_warn_level(3, "Cube::load(): couldn't read; file: ", spec.filename); + arma_debug_warn_level(3, "Cube::load(): read failed; file: ", spec.filename); } } @@ -4690,7 +4814,6 @@ //! load a cube from a stream template inline -arma_cold bool Cube::load(std::istream& is, const file_type type) { @@ -4740,7 +4863,7 @@ } else { - arma_debug_warn_level(3, "Cube::load(): couldn't load from stream"); + arma_debug_warn_level(3, "Cube::load(): stream read failed"); } } @@ -4751,7 +4874,6 @@ template inline -arma_cold bool Cube::quiet_save(const std::string name, const file_type type) const { @@ -4764,7 +4886,6 @@ template inline -arma_cold bool Cube::quiet_save(const hdf5_name& spec, const file_type type) const { @@ -4777,7 +4898,6 @@ template inline -arma_cold bool Cube::quiet_save(std::ostream& os, const file_type type) const { @@ -4790,7 +4910,6 @@ template inline -arma_cold bool Cube::quiet_load(const std::string name, const file_type type) { @@ -4803,7 +4922,6 @@ template inline -arma_cold bool Cube::quiet_load(const hdf5_name& spec, const file_type type) { @@ -4816,7 +4934,6 @@ template inline -arma_cold bool Cube::quiet_load(std::istream& is, const file_type type) { @@ -4990,7 +5107,6 @@ template inline -arma_warn_unused eT& Cube::front() { @@ -5003,7 +5119,6 @@ template inline -arma_warn_unused const eT& Cube::front() const { @@ -5016,7 +5131,6 @@ template inline -arma_warn_unused eT& Cube::back() { @@ -5029,7 +5143,6 @@ template inline -arma_warn_unused const eT& Cube::back() const { @@ -5118,10 +5231,24 @@ { arma_extra_debug_sigprint(); + (*this).steal_mem(x, false); + } + + + +template +inline +void +Cube::steal_mem(Cube& x, const bool is_move) + { + arma_extra_debug_sigprint(); + if(this == &x) { return; } - if( (mem_state <= 1) && ( (x.n_alloc > 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) || (is_move && (x.mem_state == 2)) ) ) { + arma_extra_debug_print("Cube::steal_mem(): stealing memory"); + reset(); const uword x_n_slices = x.n_slices; @@ -5137,16 +5264,20 @@ if(x_n_slices > Cube_prealloc::mat_ptrs_size) { - access::rw( mat_ptrs) = x.mat_ptrs; - access::rw(x.mat_ptrs) = nullptr; + arma_extra_debug_print("Cube::steal_mem(): stealing mat_ptrs array"); + + mat_ptrs = x.mat_ptrs; + x.mat_ptrs = nullptr; } else { - access::rw(mat_ptrs) = const_cast< const Mat** >(mat_ptrs_local); + arma_extra_debug_print("Cube::steal_mem(): copying mat_ptrs array"); + + mat_ptrs = mat_ptrs_local; for(uword i=0; i < x_n_slices; ++i) { - mat_ptrs[i] = x.mat_ptrs[i]; + mat_ptrs[i] = raw_mat_ptr_type(x.mat_ptrs[i]); // cast required by std::atomic x.mat_ptrs[i] = nullptr; } } @@ -5162,7 +5293,14 @@ } else { + arma_extra_debug_print("Cube::steal_mem(): copying memory"); + (*this).operator=(x); + + if( (is_move) && (x.mem_state == 0) && (x.n_alloc <= Cube_prealloc::mem_n_elem) ) + { + x.reset(); + } } } @@ -5191,8 +5329,7 @@ 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** >( \ - (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local ); + Cube::mat_ptrs = (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local; create_mat(); } @@ -5206,7 +5343,7 @@ access::rw(Cube::n_alloc) = 0; access::rw(Cube::mem_state) = 3; access::rw(Cube::mem) = nullptr; - access::rw(Cube::mat_ptrs) = nullptr; + Cube::mat_ptrs = nullptr; } } @@ -5221,7 +5358,7 @@ mem_setup(); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Cube::fixed::constructor: zeroing memory"); @@ -5229,7 +5366,6 @@ arrayops::fill_zeros(mem_use, fixed_n_elem); } - #endif } @@ -5336,7 +5472,6 @@ template template arma_inline -arma_warn_unused eT& Cube::fixed::operator[] (const uword i) { @@ -5348,7 +5483,6 @@ template template arma_inline -arma_warn_unused const eT& Cube::fixed::operator[] (const uword i) const { @@ -5360,7 +5494,6 @@ template template arma_inline -arma_warn_unused eT& Cube::fixed::at(const uword i) { @@ -5372,7 +5505,6 @@ template template arma_inline -arma_warn_unused const eT& Cube::fixed::at(const uword i) const { @@ -5384,7 +5516,6 @@ template template arma_inline -arma_warn_unused eT& Cube::fixed::operator() (const uword i) { @@ -5398,7 +5529,6 @@ template template arma_inline -arma_warn_unused const eT& Cube::fixed::operator() (const uword i) const { @@ -5409,10 +5539,39 @@ +#if defined(__cpp_multidimensional_subscript) + + template + template + arma_inline + eT& + Cube::fixed::operator[] (const uword in_row, const uword in_col, const uword in_slice) + { + const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row; + + return (use_extra) ? mem_local_extra[i] : mem_local[i]; + } + + + + template + template + arma_inline + const eT& + Cube::fixed::operator[] (const uword in_row, const uword in_col, const uword in_slice) const + { + const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row; + + return (use_extra) ? mem_local_extra[i] : mem_local[i]; + } + +#endif + + + template template arma_inline -arma_warn_unused eT& Cube::fixed::at(const uword in_row, const uword in_col, const uword in_slice) { @@ -5426,7 +5585,6 @@ template template arma_inline -arma_warn_unused const eT& Cube::fixed::at(const uword in_row, const uword in_col, const uword in_slice) const { @@ -5440,7 +5598,6 @@ template template arma_inline -arma_warn_unused eT& Cube::fixed::operator() (const uword in_row, const uword in_col, const uword in_slice) { @@ -5463,7 +5620,6 @@ template template arma_inline -arma_warn_unused const eT& Cube::fixed::operator() (const uword in_row, const uword in_col, const uword in_slice) const { @@ -5691,11 +5847,7 @@ const uword N = out.n_elem; - for(uword i=0; i( A[i], out_mem[i].imag() ); - } + for(uword i=0; i( P.at(row,col,slice), (*out_mem).imag() ); + (*out_mem).real(P.at(row,col,slice)); out_mem++; } } @@ -5743,11 +5895,7 @@ const uword N = out.n_elem; - for(uword i=0; i( out_mem[i].real(), A[i] ); - } + for(uword i=0; i( (*out_mem).real(), P.at(row,col,slice) ); + (*out_mem).imag(P.at(row,col,slice)); out_mem++; } } @@ -5763,7 +5911,7 @@ -#ifdef ARMA_EXTRA_CUBE_MEAT +#if defined(ARMA_EXTRA_CUBE_MEAT) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_MEAT) #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/CubeToMatOp_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/CubeToMatOp_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/CubeToMatOp_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/CubeToMatOp_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -30,11 +30,11 @@ typedef typename get_pod_type::result pod_type; inline explicit CubeToMatOp(const T1& in_m); - inline CubeToMatOp(const T1& in_m, const elem_type in_aux); + inline CubeToMatOp(const T1& in_m, const uword in_aux_uword); inline ~CubeToMatOp(); - 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 + arma_aligned const T1& m; //!< the operand; must be derived from BaseCube + arma_aligned uword aux_uword; //!< auxiliary data, uword format static constexpr bool is_row = op_type::template traits::is_row; static constexpr bool is_col = op_type::template traits::is_col; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/CubeToMatOp_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/CubeToMatOp_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/CubeToMatOp_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/CubeToMatOp_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -33,9 +33,9 @@ template inline -CubeToMatOp::CubeToMatOp(const T1& in_m, const typename T1::elem_type in_aux) +CubeToMatOp::CubeToMatOp(const T1& in_m, const uword in_aux_uword) : m(in_m) - , aux(in_aux) + , aux_uword(in_aux_uword) { arma_extra_debug_sigprint(); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/debug.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/debug.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/debug.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/debug.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,110 +21,98 @@ -template inline std::ostream& -arma_cout_stream(std::ostream* user_stream) +get_cout_stream() { - static std::ostream* cout_stream = &(ARMA_COUT_STREAM); - - if(user_stream != nullptr) { cout_stream = user_stream; } - - return (*cout_stream); + return (ARMA_COUT_STREAM); } -template inline std::ostream& -arma_cerr_stream(std::ostream* user_stream) +get_cerr_stream() { - static std::ostream* cerr_stream = &(ARMA_CERR_STREAM); - - if(user_stream != nullptr) { cerr_stream = user_stream; } - - return (*cerr_stream); + return (ARMA_CERR_STREAM); } +arma_deprecated inline -void -set_cout_stream(std::ostream& user_stream) +std::ostream& +get_stream_err1() { - arma_cout_stream(&user_stream); + return get_cerr_stream(); } +arma_deprecated inline -void -set_cerr_stream(std::ostream& user_stream) +std::ostream& +get_stream_err2() { - arma_cerr_stream(&user_stream); + return get_cerr_stream(); } +arma_frown("this function does nothing; instead use ARMA_COUT_STREAM or ARMA_WARN_LEVEL; see documentation") inline -std::ostream& -get_cout_stream() +void +set_cout_stream(const std::ostream&) { - return arma_cout_stream(nullptr); } +arma_frown("this function does nothing; instead use ARMA_CERR_STREAM or ARMA_WARN_LEVEL; see documentation") inline -std::ostream& -get_cerr_stream() +void +set_cerr_stream(const std::ostream&) { - return arma_cerr_stream(nullptr); } -//! do not use this function - it's deprecated and will be removed +arma_frown("this function does nothing; instead use ARMA_CERR_STREAM or ARMA_WARN_LEVEL; see documentation") inline -arma_deprecated void -set_stream_err1(std::ostream& user_stream) +set_stream_err1(const std::ostream&) { - set_cerr_stream(user_stream); } -//! do not use this function - it's deprecated and will be removed +arma_frown("this function does nothing; instead use ARMA_CERR_STREAM or ARMA_WARN_LEVEL; see documentation") inline -arma_deprecated void -set_stream_err2(std::ostream& user_stream) +set_stream_err2(const std::ostream&) { - set_cerr_stream(user_stream); } -//! do not use this function - it's deprecated and will be removed +template +arma_frown("this function does nothing; instead use ARMA_COUT_STREAM or ARMA_WARN_LEVEL; see documentation") inline -arma_deprecated std::ostream& -get_stream_err1() +arma_cout_stream(std::ostream*) { - return get_cerr_stream(); + return (ARMA_COUT_STREAM); } -//! do not use this function - it's deprecated and will be removed +template +arma_frown("this function does nothing; instead use ARMA_CERR_STREAM or ARMA_WARN_LEVEL; see documentation") inline -arma_deprecated std::ostream& -get_stream_err2() +arma_cerr_stream(std::ostream*) { - return get_cerr_stream(); + return (ARMA_CERR_STREAM); } @@ -137,7 +125,7 @@ void arma_stop_logic_error(const T1& x) { - #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS)) + #if defined(ARMA_PRINT_EXCEPTIONS) { get_cerr_stream() << "\nerror: " << x << std::endl; } @@ -159,7 +147,7 @@ -//! print a message to get_cerr_stream() and throw logic_error exception +//! print a message to get_cerr_stream() and throw out_of_range exception template arma_cold arma_noinline @@ -167,7 +155,7 @@ void arma_stop_bounds_error(const T1& x) { - #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS)) + #if defined(ARMA_PRINT_EXCEPTIONS) { get_cerr_stream() << "\nerror: " << x << std::endl; } @@ -186,7 +174,7 @@ void arma_stop_bad_alloc(const T1& x) { - #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS)) + #if defined(ARMA_PRINT_EXCEPTIONS) { get_cerr_stream() << "\nerror: " << x << std::endl; } @@ -209,7 +197,7 @@ void arma_stop_runtime_error(const T1& x) { - #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS)) + #if defined(ARMA_PRINT_EXCEPTIONS) { get_cerr_stream() << "\nerror: " << x << std::endl; } @@ -275,7 +263,7 @@ // // arma_sigprint -//! print a message the the log stream with a preceding @ character. +//! print a message to the log stream with a preceding @ character. //! by default the log stream is cout. //! used for printing the signature of a function //! (see the arma_extra_debug_sigprint macro) @@ -347,15 +335,7 @@ void arma_warn(const T1& arg1) { - #if defined(ARMA_PRINT_ERRORS) - { - get_cerr_stream() << "\nwarning: " << arg1 << '\n'; - } - #else - { - arma_ignore(arg1); - } - #endif + get_cerr_stream() << "\nwarning: " << arg1 << std::endl; } @@ -366,16 +346,7 @@ void arma_warn(const T1& arg1, const T2& arg2) { - #if defined(ARMA_PRINT_ERRORS) - { - get_cerr_stream() << "\nwarning: " << arg1 << arg2 << '\n'; - } - #else - { - arma_ignore(arg1); - arma_ignore(arg2); - } - #endif + get_cerr_stream() << "\nwarning: " << arg1 << arg2 << std::endl; } @@ -386,17 +357,7 @@ void arma_warn(const T1& arg1, const T2& arg2, const T3& arg3) { - #if defined(ARMA_PRINT_ERRORS) - { - get_cerr_stream() << "\nwarning: " << arg1 << arg2 << arg3 << '\n'; - } - #else - { - arma_ignore(arg1); - arma_ignore(arg2); - arma_ignore(arg3); - } - #endif + get_cerr_stream() << "\nwarning: " << arg1 << arg2 << arg3 << std::endl; } @@ -407,18 +368,7 @@ 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 + get_cerr_stream() << "\nwarning: " << arg1 << arg2 << arg3 << arg4 << std::endl; } @@ -486,6 +436,16 @@ } +template +arma_hot +inline +void +arma_check(const bool state, const char* x, const Functor& fn) + { + if(state) { fn(); arma_stop_logic_error(x); } + } + + arma_hot inline void @@ -495,6 +455,16 @@ } +template +arma_hot +inline +void +arma_check(const bool state, const char* x, const char* y, const Functor& fn) + { + if(state) { fn(); arma_stop_logic_error(x,y); } + } + + template arma_hot inline @@ -597,8 +567,8 @@ -arma_inline arma_hot +arma_inline void arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x) { @@ -1313,6 +1283,7 @@ +// TODO: remove support for ATLAS in next major version template arma_hot inline @@ -1335,6 +1306,7 @@ +// TODO: remove support for ATLAS in next major version template arma_hot inline @@ -1404,19 +1376,16 @@ #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 - + #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 - + #endif @@ -1451,25 +1420,32 @@ << arma_version::major << '.' << arma_version::minor << '.' << arma_version::patch << " (" << nickname << ")\n"; - out << "@ arma_config::wrapper = " << arma_config::wrapper << '\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'; - out << "@ arma_config::blas = " << arma_config::blas << '\n'; - out << "@ arma_config::newarp = " << arma_config::newarp << '\n'; - out << "@ arma_config::arpack = " << arma_config::arpack << '\n'; - out << "@ arma_config::superlu = " << arma_config::superlu << '\n'; - out << "@ arma_config::atlas = " << arma_config::atlas << '\n'; - out << "@ arma_config::hdf5 = " << arma_config::hdf5 << '\n'; - out << "@ arma_config::good_comp = " << arma_config::good_comp << '\n'; - out << "@ arma_config::extra_code = " << arma_config::extra_code << '\n'; - out << "@ arma_config::hidden_args = " << arma_config::hidden_args << '\n'; - out << "@ arma_config::mat_prealloc = " << arma_config::mat_prealloc << '\n'; - out << "@ arma_config::mp_threshold = " << arma_config::mp_threshold << '\n'; - out << "@ arma_config::mp_threads = " << arma_config::mp_threads << '\n'; + out << "@ arma_config::wrapper = " << arma_config::wrapper << '\n'; + out << "@ arma_config::cxx14 = " << arma_config::cxx14 << '\n'; + out << "@ arma_config::cxx17 = " << arma_config::cxx17 << '\n'; + out << "@ arma_config::cxx20 = " << arma_config::cxx20 << '\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'; + out << "@ arma_config::blas = " << arma_config::blas << '\n'; + out << "@ arma_config::newarp = " << arma_config::newarp << '\n'; + out << "@ arma_config::arpack = " << arma_config::arpack << '\n'; + out << "@ arma_config::superlu = " << arma_config::superlu << '\n'; + out << "@ arma_config::atlas = " << arma_config::atlas << '\n'; + out << "@ arma_config::hdf5 = " << arma_config::hdf5 << '\n'; + out << "@ arma_config::good_comp = " << arma_config::good_comp << '\n'; + out << "@ arma_config::extra_code = " << arma_config::extra_code << '\n'; + out << "@ arma_config::hidden_args = " << arma_config::hidden_args << '\n'; + out << "@ arma_config::mat_prealloc = " << arma_config::mat_prealloc << '\n'; + out << "@ arma_config::mp_threshold = " << arma_config::mp_threshold << '\n'; + out << "@ arma_config::mp_threads = " << arma_config::mp_threads << '\n'; + out << "@ arma_config::optimise_band = " << arma_config::optimise_band << '\n'; + out << "@ arma_config::optimise_sym = " << arma_config::optimise_sym << '\n'; + out << "@ arma_config::optimise_invexpr = " << arma_config::optimise_invexpr << '\n'; + out << "@ arma_config::check_nonfinite = " << arma_config::check_nonfinite << '\n'; + out << "@ arma_config::zero_init = " << arma_config::zero_init << '\n'; + out << "@ arma_config::fast_math = " << arma_config::fast_math << '\n'; out << "@ sizeof(void*) = " << sizeof(void*) << '\n'; out << "@ sizeof(int) = " << sizeof(int) << '\n'; out << "@ sizeof(long) = " << sizeof(long) << '\n'; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/def_arpack.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/def_arpack.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/def_arpack.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/def_arpack.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -16,7 +16,7 @@ // ------------------------------------------------------------------------ -#ifdef ARMA_USE_ARPACK +#if defined(ARMA_USE_ARPACK) // I'm not sure this is necessary. #if !defined(ARMA_BLAS_CAPITALS) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/def_atlas.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/def_atlas.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/def_atlas.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/def_atlas.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -16,120 +16,63 @@ // ------------------------------------------------------------------------ -#ifdef ARMA_USE_ATLAS +// TODO: remove support for ATLAS in next major version +#if defined(ARMA_USE_ATLAS) -//! \namespace atlas namespace for ATLAS functions (imported from the global namespace) -namespace atlas + +typedef enum + { + atlas_CblasRowMajor = 101, + atlas_CblasColMajor = 102 + } + atlas_CBLAS_LAYOUT; + +typedef enum + { + atlas_CblasNoTrans = 111, + atlas_CblasTrans = 112, + atlas_CblasConjTrans = 113 + } + atlas_CBLAS_TRANS; + +typedef enum + { + atlas_CblasUpper = 121, + atlas_CblasLower = 122 + } + atlas_CBLAS_UPLO; + + +extern "C" { - using ::CblasColMajor; - using ::CblasNoTrans; - using ::CblasTrans; - using ::CblasConjTrans; - using ::CblasLower; - using ::CblasUpper; - - #if defined(ARMA_USE_WRAPPER) - extern "C" - { - float wrapper_cblas_sasum(const int N, const float *X, const int incX); - double wrapper_cblas_dasum(const int N, const double *X, const int incX); - - float wrapper_cblas_snrm2(const int N, const float *X, const int incX); - double wrapper_cblas_dnrm2(const int N, const double *X, const int incX); - - float wrapper_cblas_sdot(const int N, const float *X, const int incX, const float *Y, const int incY); - double wrapper_cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY); - - void wrapper_cblas_cdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu); - void wrapper_cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu); - - - void wrapper_cblas_sgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const float alpha, - const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY); - - void wrapper_cblas_dgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha, - const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY); - - void wrapper_cblas_cgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha, - const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); - - void wrapper_cblas_zgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha, - const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); - - - - void wrapper_cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, - const int M, const int N, const int K, const float alpha, - const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc); - - void wrapper_cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, - const int M, const int N, const int K, const double alpha, - const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); - - void wrapper_cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, - const int M, const int N, const int K, const void *alpha, - const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); - - void wrapper_cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, - const int M, const int N, const int K, const void *alpha, - const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); - - - - void wrapper_cblas_ssyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, - const int N, const int K, const float alpha, - const float *A, const int lda, const float beta, float *C, const int ldc); - - void wrapper_cblas_dsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, - const int N, const int K, const double alpha, - const double *A, const int lda, const double beta, double *C, const int ldc); - - - - void wrapper_cblas_cherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, - const int N, const int K, const float alpha, - const void *A, const int lda, const float beta, void *C, const int ldc); - - void wrapper_cblas_zherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, - const int N, const int K, const double alpha, - const void *A, const int lda, const double beta, void *C, const int ldc); - - - - int wrapper_clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N, float *A, const int lda, int *ipiv); - int wrapper_clapack_dgetrf(const enum CBLAS_ORDER Order, const int M, const int N, double *A, const int lda, int *ipiv); - int wrapper_clapack_cgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void *A, const int lda, int *ipiv); - int wrapper_clapack_zgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void *A, const int lda, int *ipiv); - - int wrapper_clapack_sgetri(const enum CBLAS_ORDER Order, const int N, float *A, const int lda, const int *ipiv); - int wrapper_clapack_dgetri(const enum CBLAS_ORDER Order, const int N, double *A, const int lda, const int *ipiv); - int wrapper_clapack_cgetri(const enum CBLAS_ORDER Order, const int N, void *A, const int lda, const int *ipiv); - int wrapper_clapack_zgetri(const enum CBLAS_ORDER Order, const int N, void *A, const int lda, const int *ipiv); - - int wrapper_clapack_sgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, float *A, const int lda, int *ipiv, float *B, const int ldb); - int wrapper_clapack_dgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, double *A, const int lda, int *ipiv, double *B, const int ldb); - int wrapper_clapack_cgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void *A, const int lda, int *ipiv, void *B, const int ldb); - int wrapper_clapack_zgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void *A, const int lda, int *ipiv, void *B, const int ldb); - - - - int wrapper_clapack_spotrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, float *A, const int lda); - int wrapper_clapack_dpotrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, double *A, const int lda); - int wrapper_clapack_cpotrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, void *A, const int lda); - int wrapper_clapack_zpotrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, void *A, const int lda); - - int wrapper_clapack_spotri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, float *A, const int lda); - int wrapper_clapack_dpotri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, double *A, const int lda); - int wrapper_clapack_cpotri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, void *A, const int lda); - int wrapper_clapack_zpotri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, void *A, const int lda); - - int wrapper_clapack_sposv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, float *A, const int lda, float *B, const int ldb); - int wrapper_clapack_dposv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, double *A, const int lda, double *B, const int ldb); - int wrapper_clapack_cposv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, void *A, const int lda, void *B, const int ldb); - int wrapper_clapack_zposv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, void *A, const int lda, void *B, const int ldb); - } - #endif + float arma_wrapper(cblas_sasum)(const int N, const float *X, const int incX); + double arma_wrapper(cblas_dasum)(const int N, const double *X, const int incX); + + float arma_wrapper(cblas_snrm2)(const int N, const float *X, const int incX); + double arma_wrapper(cblas_dnrm2)(const int N, const double *X, const int incX); + + float arma_wrapper(cblas_sdot)(const int N, const float *X, const int incX, const float *Y, const int incY); + double arma_wrapper(cblas_ddot)(const int N, const double *X, const int incX, const double *Y, const int incY); + + void arma_wrapper(cblas_cdotu_sub)(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu); + void arma_wrapper(cblas_zdotu_sub)(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu); + + void arma_wrapper(cblas_sgemv)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY); + void arma_wrapper(cblas_dgemv)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY); + void arma_wrapper(cblas_cgemv)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); + void arma_wrapper(cblas_zgemv)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); + + void arma_wrapper(cblas_sgemm)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc); + void arma_wrapper(cblas_dgemm)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); + void arma_wrapper(cblas_cgemm)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); + void arma_wrapper(cblas_zgemm)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); + + void arma_wrapper(cblas_ssyrk)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const float alpha, const float *A, const int lda, const float beta, float *C, const int ldc); + void arma_wrapper(cblas_dsyrk)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double beta, double *C, const int ldc); + + void arma_wrapper(cblas_cherk)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const float alpha, const void *A, const int lda, const float beta, void *C, const int ldc); + void arma_wrapper(cblas_zherk)(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const double alpha, const void *A, const int lda, const double beta, void *C, const int ldc); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/def_blas.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/def_blas.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/def_blas.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/def_blas.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -17,7 +17,7 @@ -#ifdef ARMA_USE_BLAS +#if defined(ARMA_USE_BLAS) #if defined(dgemm) || defined(DGEMM) #pragma message ("WARNING: detected possible interference with definitions of BLAS functions;") diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/def_fftw3.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/def_fftw3.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/def_fftw3.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/def_fftw3.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,49 @@ +// 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. +// ------------------------------------------------------------------------ + + +#if defined(ARMA_USE_FFTW3) + + +extern "C" + { + // function prefix for single precision: fftwf_ + // function prefix for double precision: fftw_ + + + // single precision (float) + + void_ptr fftwf_plan_dft_1d(int N, void* input, void* output, int fftw3_sign, unsigned int fftw3_flags); + + void fftwf_execute(void_ptr plan); + void fftwf_destroy_plan(void_ptr plan); + + void fftwf_cleanup(); + + + // double precision (double) + + void_ptr fftw_plan_dft_1d(int N, void* input, void* output, int fftw3_sign, unsigned int fftw3_flags); + + void fftw_execute(void_ptr plan); + void fftw_destroy_plan(void_ptr plan); + + void fftw_cleanup(); + } + + +#endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/def_hdf5.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/def_hdf5.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/def_hdf5.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/def_hdf5.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -// 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. -// ------------------------------------------------------------------------ - - -#if defined(ARMA_USE_HDF5) - -#if !defined(ARMA_USE_HDF5_ALT) - - // macros needed if the wrapper run-time library is not being used - - #define arma_H5Tcopy H5Tcopy - #define arma_H5Tcreate H5Tcreate - #define arma_H5Tinsert H5Tinsert - #define arma_H5Tequal H5Tequal - #define arma_H5Tclose H5Tclose - - #define arma_H5Dopen H5Dopen - #define arma_H5Dget_type H5Dget_type - #define arma_H5Dclose H5Dclose - #define arma_H5Dwrite H5Dwrite - #define arma_H5Dget_space H5Dget_space - #define arma_H5Dread H5Dread - #define arma_H5Dcreate H5Dcreate - - #define arma_H5Sget_simple_extent_ndims H5Sget_simple_extent_ndims - #define arma_H5Sget_simple_extent_dims H5Sget_simple_extent_dims - #define arma_H5Sclose H5Sclose - #define arma_H5Screate_simple H5Screate_simple - - #define arma_H5Ovisit H5Ovisit - - #define arma_H5Eset_auto H5Eset_auto - #define arma_H5Eget_auto H5Eget_auto - - #define arma_H5Fopen H5Fopen - #define arma_H5Fcreate H5Fcreate - #define arma_H5Fclose H5Fclose - #define arma_H5Fis_hdf5 H5Fis_hdf5 - - #define arma_H5Gcreate H5Gcreate - #define arma_H5Gopen H5Gopen - #define arma_H5Gclose H5Gclose - - #define arma_H5Lexists H5Lexists - #define arma_H5Ldelete H5Ldelete - - #define arma_H5T_NATIVE_UCHAR H5T_NATIVE_UCHAR - #define arma_H5T_NATIVE_CHAR H5T_NATIVE_CHAR - #define arma_H5T_NATIVE_SHORT H5T_NATIVE_SHORT - #define arma_H5T_NATIVE_USHORT H5T_NATIVE_USHORT - #define arma_H5T_NATIVE_INT H5T_NATIVE_INT - #define arma_H5T_NATIVE_UINT H5T_NATIVE_UINT - #define arma_H5T_NATIVE_LONG H5T_NATIVE_LONG - #define arma_H5T_NATIVE_ULONG H5T_NATIVE_ULONG - #define arma_H5T_NATIVE_LLONG H5T_NATIVE_LLONG - #define arma_H5T_NATIVE_ULLONG H5T_NATIVE_ULLONG - #define arma_H5T_NATIVE_FLOAT H5T_NATIVE_FLOAT - #define arma_H5T_NATIVE_DOUBLE H5T_NATIVE_DOUBLE - -#else - -// prototypes for the wrapper functions defined in the wrapper run-time library (src/wrapper.cpp) - -extern "C" - { - // Wrapper functions for H5* functions. - hid_t arma_H5Tcopy(hid_t dtype_id); - hid_t arma_H5Tcreate(H5T_class_t cl, size_t size); - herr_t arma_H5Tinsert(hid_t dtype_id, const char* name, size_t offset, hid_t field_id); - htri_t arma_H5Tequal(hid_t dtype_id1, hid_t dtype_id2); - herr_t arma_H5Tclose(hid_t dtype_id); - - hid_t arma_H5Dopen(hid_t loc_id, const char* name, hid_t dapl_id); - hid_t arma_H5Dget_type(hid_t dataset_id); - herr_t arma_H5Dclose(hid_t dataset_id); - hid_t arma_H5Dcreate(hid_t loc_id, const char* name, hid_t dtype_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id); - herr_t arma_H5Dwrite(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, const void* buf); - hid_t arma_H5Dget_space(hid_t dataset_id); - herr_t arma_H5Dread(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, void* buf); - - int arma_H5Sget_simple_extent_ndims(hid_t space_id); - int arma_H5Sget_simple_extent_dims(hid_t space_id, hsize_t* dims, hsize_t* maxdims); - herr_t arma_H5Sclose(hid_t space_id); - hid_t arma_H5Screate_simple(int rank, const hsize_t* current_dims, const hsize_t* maximum_dims); - - herr_t arma_H5Ovisit(hid_t object_id, H5_index_t index_type, H5_iter_order_t order, H5O_iterate_t op, void* op_data); - - herr_t arma_H5Eset_auto(hid_t estack_id, H5E_auto_t func, void* client_data); - herr_t arma_H5Eget_auto(hid_t estack_id, H5E_auto_t* func, void** client_data); - - hid_t arma_H5Fopen(const char* name, unsigned flags, hid_t fapl_id); - hid_t arma_H5Fcreate(const char* name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); - herr_t arma_H5Fclose(hid_t file_id); - htri_t arma_H5Fis_hdf5(const char* name); - - hid_t arma_H5Gcreate(hid_t loc_id, const char* name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id); - hid_t arma_H5Gopen(hid_t loc_id, const char* name, hid_t gapl_id); - herr_t arma_H5Gclose(hid_t group_id); - - htri_t arma_H5Lexists(hid_t loc_id, const char* name, hid_t lapl_id); - herr_t arma_H5Ldelete(hid_t loc_id, const char* name, hid_t lapl_id); - - // Wrapper variables that represent the hid_t values for the H5T_NATIVE_* - // types. Note that H5T_NATIVE_UCHAR itself is a macro that resolves to about - // forty other macros, and we definitely don't want to hijack those, - // so this is the best way to go about wrapping these... - extern hid_t arma_H5T_NATIVE_UCHAR; - extern hid_t arma_H5T_NATIVE_CHAR; - extern hid_t arma_H5T_NATIVE_SHORT; - extern hid_t arma_H5T_NATIVE_USHORT; - extern hid_t arma_H5T_NATIVE_INT; - extern hid_t arma_H5T_NATIVE_UINT; - extern hid_t arma_H5T_NATIVE_LONG; - extern hid_t arma_H5T_NATIVE_ULONG; - extern hid_t arma_H5T_NATIVE_LLONG; - extern hid_t arma_H5T_NATIVE_ULLONG; - extern hid_t arma_H5T_NATIVE_FLOAT; - extern hid_t arma_H5T_NATIVE_DOUBLE; - - } - - // Lastly, we have to hijack H5open() and H5check_version(), which are called - // by some expanded macros of the other H5* functions. This means we can't - // create arma_H5open(), because we can't modify those macros. Instead, we'll - // create arma::H5open() and arma::H5check_version(), and then issue a using - // directive so that arma::H5open() and arma::H5check_version() are always - // called. - // - // There is potential danger in the use of a using directive like this, but in - // this case, I can't think of a better way to solve the problem, and I doubt - // this will cause problems in any situations that aren't truly bizarre. And - // if it does cause problems, the user can #define ARMA_DONT_USE_WRAPPER or - // #undef ARMA_USE_WRAPPER in their Armadillo configuration. - herr_t H5open(); - herr_t H5check_version(unsigned majnum, unsigned minnum, unsigned relnum); - - using arma::H5open; - using arma::H5check_version; - -#endif - -#endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/def_lapack.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/def_lapack.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/def_lapack.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/def_lapack.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -17,7 +17,7 @@ -#ifdef ARMA_USE_LAPACK +#if defined(ARMA_USE_LAPACK) #if defined(dgetrf) || defined(DGETRF) #pragma message ("WARNING: detected possible interference with definitions of LAPACK functions;") @@ -259,9 +259,6 @@ #define arma_strevc strevc #define arma_dtrevc dtrevc - #define arma_slarnv slarnv - #define arma_dlarnv dlarnv - #define arma_sgehrd sgehrd #define arma_dgehrd dgehrd #define arma_cgehrd cgehrd @@ -498,9 +495,6 @@ #define arma_strevc STREVC #define arma_dtrevc DTREVC - #define arma_slarnv SLARNV - #define arma_dlarnv DLARNV - #define arma_sgehrd SGEHRD #define arma_dgehrd DGEHRD #define arma_cgehrd CGEHRD @@ -840,10 +834,6 @@ 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) 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) 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; @@ -1168,10 +1158,6 @@ 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) 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) 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; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/diskio_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/diskio_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/diskio_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/diskio_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -25,7 +25,7 @@ { public: - inline arma_deprecated static file_type guess_file_type(std::istream& f); + arma_deprecated inline static file_type guess_file_type(std::istream& f); private: @@ -40,23 +40,27 @@ 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&); + template arma_cold inline static std::string gen_txt_header(const Mat&); + template arma_cold inline static std::string gen_bin_header(const Mat&); - template inline arma_cold static std::string gen_bin_header(const SpMat&); + template arma_cold inline static std::string gen_bin_header(const SpMat&); - template inline arma_cold static std::string gen_txt_header(const Cube&); - template inline arma_cold static std::string gen_bin_header(const Cube&); + template arma_cold inline static std::string gen_txt_header(const Cube&); + template arma_cold inline static std::string gen_bin_header(const Cube&); - inline arma_cold static file_type guess_file_type_internal(std::istream& f); + arma_cold inline static file_type guess_file_type_internal(std::istream& f); - inline arma_cold static std::string gen_tmp_name(const std::string& x); + arma_cold inline static std::string gen_tmp_name(const std::string& x); - inline arma_cold static bool safe_rename(const std::string& old_name, const std::string& new_name); + arma_cold inline static bool safe_rename(const std::string& old_name, const std::string& new_name); + + arma_cold inline static bool is_readable(const std::string& name); 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 inline static bool convert_token_strict(eT& val, const std::string& token); + template inline static std::streamsize prepare_stream(std::ostream& f); @@ -91,7 +95,7 @@ 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, field& header, const bool with_header, const char separator); + 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, const bool strict); 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); @@ -102,8 +106,8 @@ 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, 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_csv_ascii (Mat& x, std::istream& f, std::string& err_msg, const char separator, const bool strict); + template inline static bool load_csv_ascii (Mat< std::complex >& x, std::istream& f, std::string& err_msg, const char separator, const bool strict); 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); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/diskio_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/diskio_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/diskio_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/diskio_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -27,7 +27,6 @@ //! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline -arma_cold std::string diskio::gen_txt_header(const Mat&) { @@ -77,7 +76,6 @@ //! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline -arma_cold std::string diskio::gen_bin_header(const Mat&) { @@ -127,7 +125,6 @@ //! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline -arma_cold std::string diskio::gen_bin_header(const SpMat&) { @@ -176,7 +173,6 @@ //! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline -arma_cold std::string diskio::gen_txt_header(const Cube&) { @@ -226,7 +222,6 @@ //! XYZ specifies the width of each element in terms of bytes, eg. "008" indicates eight bytes. template inline -arma_cold std::string diskio::gen_bin_header(const Cube&) { @@ -270,7 +265,6 @@ inline -arma_deprecated file_type diskio::guess_file_type(std::istream& f) { @@ -282,7 +276,6 @@ inline -arma_cold file_type diskio::guess_file_type_internal(std::istream& f) { @@ -343,7 +336,7 @@ // 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) + // the semicolon may be used to allow the comma character to represent the decimal seperator (eg. 1,2345 vs 1.2345) if(has_semicolon && (has_bracket == false)) { return ssv_ascii; } @@ -357,7 +350,6 @@ //! Append a quasi-random string to the given filename. //! Avoiding use of rand() to preserve its state. inline -arma_cold std::string diskio::gen_tmp_name(const std::string& x) { @@ -394,7 +386,6 @@ //! (i) overwriting files that are write protected, //! (ii) overwriting directories. inline -arma_cold bool diskio::safe_rename(const std::string& old_name, const std::string& new_name) { @@ -413,6 +404,21 @@ +inline +bool +diskio::is_readable(const std::string& name) + { + std::ifstream f; + + f.open(name, std::fstream::binary); + + // std::ifstream destructor will close the file + + return (f.is_open()); + } + + + template inline bool @@ -450,6 +456,34 @@ } } + // #if (defined(ARMA_HAVE_CXX17) && (__cpp_lib_to_chars >= 201611L)) + // { + // // std::from_chars() doesn't handle leading whitespace + // // std::from_chars() doesn't handle leading + sign + // // std::from_chars() handles only the decimal point (.) as the decimal seperator + // + // const char str0 = str[0]; + // const bool start_ok = ((str0 != ' ') && (str0 != '\t') && (str0 != '+')); + // + // bool has_comma = false; + // for(uword i=0; i inline +bool +diskio::convert_token_strict(eT& val, const std::string& token) + { + const size_t N = size_t(token.length()); + + const bool status = (N > 0) ? diskio::convert_token(val, token) : false; + + if(status == false) { val = Datum::nan; } + + return status; + } + + + +template +inline std::streamsize diskio::prepare_stream(std::ostream& f) { @@ -614,7 +664,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::fstream f(tmp_name.c_str(), std::fstream::out); + std::fstream f(tmp_name, std::fstream::out); bool save_okay = f.is_open(); @@ -679,7 +729,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str(), std::fstream::binary); + std::ofstream f(tmp_name, std::fstream::binary); bool save_okay = f.is_open(); @@ -723,7 +773,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str()); + std::ofstream f(tmp_name); bool save_okay = f.is_open(); @@ -791,7 +841,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str()); + std::ofstream f(tmp_name); bool save_okay = f.is_open(); @@ -918,7 +968,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str()); + std::ofstream f(tmp_name); bool save_okay = f.is_open(); @@ -1038,7 +1088,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str(), std::fstream::binary); + std::ofstream f(tmp_name, std::fstream::binary); bool save_okay = f.is_open(); @@ -1086,7 +1136,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::fstream f(tmp_name.c_str(), std::fstream::out | std::fstream::binary); + std::fstream f(tmp_name, std::fstream::out | std::fstream::binary); bool save_okay = f.is_open(); @@ -1188,12 +1238,12 @@ const bool append = bool(spec.opts.flags & hdf5_opts::flag_append); const bool replace = bool(spec.opts.flags & hdf5_opts::flag_replace); - const bool use_existing_file = ((append || replace) && (arma_H5Fis_hdf5(spec.filename.c_str()) > 0)); + const bool use_existing_file = ((append || replace) && (H5Fis_hdf5(spec.filename.c_str()) > 0)); const std::string tmp_name = (use_existing_file) ? std::string() : diskio::gen_tmp_name(spec.filename); // Set up the file according to HDF5's preferences - hid_t file = (use_existing_file) ? arma_H5Fopen(spec.filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT) : arma_H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t file = (use_existing_file) ? H5Fopen(spec.filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT) : H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if(file < 0) { return false; } @@ -1202,7 +1252,7 @@ dims[1] = x.n_rows; dims[0] = x.n_cols; - hid_t dataspace = arma_H5Screate_simple(2, dims, NULL); // treat the matrix as a 2d array dataspace + hid_t dataspace = H5Screate_simple(2, dims, NULL); // treat the matrix as a 2d array dataspace hid_t datatype = hdf5_misc::get_hdf5_type(); // If this returned something invalid, well, it's time to crash. @@ -1220,11 +1270,11 @@ // Create another group... 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); + hid_t gid = H5Gcreate((groups.size() == 0) ? file : groups[groups.size() - 1], full_name.substr(0, loc).c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if((gid < 0) && use_existing_file) { - gid = arma_H5Gopen((groups.size() == 0) ? file : groups[groups.size() - 1], full_name.substr(0, loc).c_str(), H5P_DEFAULT); + gid = H5Gopen((groups.size() == 0) ? file : groups[groups.size() - 1], full_name.substr(0, loc).c_str(), H5P_DEFAULT); } groups.push_back(gid); @@ -1239,32 +1289,32 @@ if(use_existing_file && replace) { - arma_H5Ldelete(last_group, dataset_name.c_str(), H5P_DEFAULT); + H5Ldelete(last_group, dataset_name.c_str(), H5P_DEFAULT); // NOTE: H5Ldelete() in HDF5 v1.8 doesn't reclaim the deleted space; use h5repack to reclaim space: h5repack oldfile.h5 newfile.h5 // NOTE: has this behaviour changed in HDF5 1.10 ? // NOTE: https://lists.hdfgroup.org/pipermail/hdf-forum_lists.hdfgroup.org/2017-August/010482.html // NOTE: https://lists.hdfgroup.org/pipermail/hdf-forum_lists.hdfgroup.org/2017-August/010486.html } - hid_t dataset = arma_H5Dcreate(last_group, dataset_name.c_str(), datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + hid_t dataset = H5Dcreate(last_group, dataset_name.c_str(), datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if(dataset < 0) { save_okay = false; - err_msg = "couldn't create dataset"; + err_msg = "failed to create dataset"; } else { - save_okay = (arma_H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, x.mem) >= 0); + save_okay = (H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, x.mem) >= 0); - arma_H5Dclose(dataset); + H5Dclose(dataset); } - arma_H5Tclose(datatype); - arma_H5Sclose(dataspace); - for(size_t i = 0; i < groups.size(); ++i) { arma_H5Gclose(groups[i]); } - arma_H5Fclose(file); + H5Tclose(datatype); + H5Sclose(dataspace); + for(size_t i = 0; i < groups.size(); ++i) { H5Gclose(groups[i]); } + H5Fclose(file); if((use_existing_file == false) && (save_okay == true)) { save_okay = diskio::safe_rename(tmp_name, spec.filename); } @@ -1296,7 +1346,7 @@ arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in); + f.open(name, std::fstream::in); bool load_okay = f.is_open(); @@ -1386,7 +1436,7 @@ if(diskio::convert_token(x.at(row,col), token) == false) { load_okay = false; - err_msg = "couldn't interpret data"; + err_msg = "data interpretation failure"; } } } @@ -1411,7 +1461,7 @@ arma_extra_debug_sigprint(); std::ifstream f; - f.open(name.c_str(), std::fstream::binary); + f.open(name, std::fstream::binary); bool load_okay = f.is_open(); @@ -1467,7 +1517,7 @@ { arma_extra_debug_sigprint(); - std::ifstream f(name.c_str()); + std::ifstream f(name); bool load_okay = f.is_open(); @@ -1566,12 +1616,12 @@ template inline bool -diskio::load_csv_ascii(Mat& x, const std::string& name, std::string& err_msg, field& header, const bool with_header, const char separator) +diskio::load_csv_ascii(Mat& x, const std::string& name, std::string& err_msg, field& header, const bool with_header, const char separator, const bool strict) { arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in); + f.open(name, std::fstream::in); bool load_okay = f.is_open(); @@ -1620,7 +1670,7 @@ if(load_okay) { - load_okay = diskio::load_csv_ascii(x, f, err_msg, separator); + load_okay = diskio::load_csv_ascii(x, f, err_msg, separator, strict); } f.close(); @@ -1634,7 +1684,7 @@ template inline bool -diskio::load_csv_ascii(Mat& x, std::istream& f, std::string& err_msg, const char separator) +diskio::load_csv_ascii(Mat& x, std::istream& f, std::string& err_msg, const char separator, const bool strict) { arma_extra_debug_sigprint(); @@ -1683,6 +1733,8 @@ try { x.zeros(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } + if(strict) { x.fill(Datum::nan); } // take into account that each row may have a unique number of columns + const bool use_mp = (arma_config::openmp) && (f_n_rows >= 2) && (f_n_cols >= 64); field token_array; @@ -1736,7 +1788,9 @@ #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) ); + eT& out_val = x.at(row,col); + + (strict) ? diskio::convert_token_strict( out_val, token_array(col) ) : diskio::convert_token( out_val, token_array(col) ); } ++row; @@ -1763,7 +1817,9 @@ { std::getline(line_stream, token, separator); - diskio::convert_token( x.at(row,col), token ); + eT& out_val = x.at(row,col); + + (strict) ? diskio::convert_token_strict( out_val, token ) : diskio::convert_token( out_val, token ); ++col; } @@ -1781,7 +1837,7 @@ template inline bool -diskio::load_csv_ascii(Mat< std::complex >& x, std::istream& f, std::string& err_msg, const char separator) +diskio::load_csv_ascii(Mat< std::complex >& x, std::istream& f, std::string& err_msg, const char separator, const bool strict) { arma_extra_debug_sigprint(); @@ -1830,6 +1886,8 @@ try { x.zeros(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } + if(strict) { x.fill(Datum< std::complex >::nan); } // take into account that each row may have a unique number of columns + uword row = 0; std::string str_real; @@ -1899,7 +1957,9 @@ if(found_val_real) { - x.at(row,col) = std::complex(val_real, T(0)); + const T val_imag = (strict) ? T(Datum::nan) : T(0); + + x.at(row,col) = std::complex(val_real, val_imag); col++; continue; // get next token } @@ -2003,8 +2063,8 @@ T val_real = T(0); T val_imag = T(0); - diskio::convert_token(val_real, str_real); - diskio::convert_token(val_imag, str_imag); + (strict) ? diskio::convert_token_strict(val_real, str_real) : diskio::convert_token(val_real, str_real); + (strict) ? diskio::convert_token_strict(val_imag, str_imag) : diskio::convert_token(val_imag, str_imag); x.at(row,col) = std::complex(val_real, val_imag); @@ -2027,7 +2087,7 @@ arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in); + f.open(name, std::fstream::in); bool load_okay = f.is_open(); @@ -2269,7 +2329,7 @@ arma_extra_debug_sigprint(); std::ifstream f; - f.open(name.c_str(), std::fstream::binary); + f.open(name, std::fstream::binary); bool load_okay = f.is_open(); @@ -2383,7 +2443,7 @@ arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in | std::fstream::binary); + f.open(name, std::fstream::in | std::fstream::binary); bool load_okay = f.is_open(); @@ -2532,11 +2592,13 @@ #if defined(ARMA_USE_HDF5) { + if(diskio::is_readable(spec.filename) == false) { return false; } + 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); + hid_t fid = H5Fopen(spec.filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); if(fid >= 0) { @@ -2563,22 +2625,22 @@ if(dataset >= 0) { - hid_t filespace = arma_H5Dget_space(dataset); + hid_t filespace = H5Dget_space(dataset); // This must be <= 2 due to our search rules. - const int ndims = arma_H5Sget_simple_extent_ndims(filespace); + const int ndims = H5Sget_simple_extent_ndims(filespace); hsize_t dims[2]; - const herr_t query_status = arma_H5Sget_simple_extent_dims(filespace, dims, NULL); + const herr_t query_status = H5Sget_simple_extent_dims(filespace, dims, NULL); // 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"; - arma_H5Sclose(filespace); - arma_H5Dclose(dataset); - arma_H5Fclose(fid); + H5Sclose(filespace); + H5Dclose(dataset); + H5Fclose(fid); return false; } @@ -2588,14 +2650,14 @@ 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); + hid_t datatype = 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) + if(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())); + hid_t read_status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(x.memptr())); if(read_status >= 0) { load_okay = true; } } @@ -2608,14 +2670,14 @@ } // Now clean up. - arma_H5Tclose(datatype); - arma_H5Tclose(mat_type); - arma_H5Sclose(filespace); + H5Tclose(datatype); + H5Tclose(mat_type); + H5Sclose(filespace); } - arma_H5Dclose(dataset); + H5Dclose(dataset); - arma_H5Fclose(fid); + H5Fclose(fid); if(load_okay == false) { @@ -2652,13 +2714,15 @@ { arma_extra_debug_sigprint(); + if(diskio::is_readable(name) == false) { return false; } + #if defined(ARMA_USE_HDF5) // 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); } + if( 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); + f.open(name, std::fstream::in | std::fstream::binary); bool load_okay = f.is_open(); @@ -2722,11 +2786,11 @@ switch(ft) { case csv_ascii: - return load_csv_ascii(x, f, err_msg, char(',')); + return load_csv_ascii(x, f, err_msg, char(','), false); break; case ssv_ascii: - return load_csv_ascii(x, f, err_msg, char(';')); + return load_csv_ascii(x, f, err_msg, char(';'), false); break; case raw_binary: @@ -2764,7 +2828,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str()); + std::ofstream f(tmp_name); bool save_okay = f.is_open(); @@ -2867,7 +2931,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str()); + std::ofstream f(tmp_name); bool save_okay = f.is_open(); @@ -2986,7 +3050,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str(), std::fstream::binary); + std::ofstream f(tmp_name, std::fstream::binary); bool save_okay = f.is_open(); @@ -3034,7 +3098,7 @@ arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in); + f.open(name, std::fstream::in); bool load_okay = f.is_open(); @@ -3216,7 +3280,7 @@ arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in | std::fstream::binary); + f.open(name, std::fstream::in | std::fstream::binary); bool load_okay = f.is_open(); @@ -3454,7 +3518,7 @@ arma_extra_debug_sigprint(); std::ifstream f; - f.open(name.c_str(), std::fstream::binary); + f.open(name, std::fstream::binary); bool load_okay = f.is_open(); @@ -3580,7 +3644,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::fstream f(tmp_name.c_str(), std::fstream::out); + std::fstream f(tmp_name, std::fstream::out); bool save_okay = f.is_open(); @@ -3647,7 +3711,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str(), std::fstream::binary); + std::ofstream f(tmp_name, std::fstream::binary); bool save_okay = f.is_open(); @@ -3691,7 +3755,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str()); + std::ofstream f(tmp_name); bool save_okay = f.is_open(); @@ -3763,7 +3827,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f(tmp_name.c_str(), std::fstream::binary); + std::ofstream f(tmp_name, std::fstream::binary); bool save_okay = f.is_open(); @@ -3818,12 +3882,12 @@ const bool append = bool(spec.opts.flags & hdf5_opts::flag_append); const bool replace = bool(spec.opts.flags & hdf5_opts::flag_replace); - const bool use_existing_file = ((append || replace) && (arma_H5Fis_hdf5(spec.filename.c_str()) > 0)); + const bool use_existing_file = ((append || replace) && (H5Fis_hdf5(spec.filename.c_str()) > 0)); const std::string tmp_name = (use_existing_file) ? std::string() : diskio::gen_tmp_name(spec.filename); // Set up the file according to HDF5's preferences - hid_t file = (use_existing_file) ? arma_H5Fopen(spec.filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT) : arma_H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t file = (use_existing_file) ? H5Fopen(spec.filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT) : H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if(file < 0) { return false; } @@ -3833,7 +3897,7 @@ dims[1] = x.n_cols; dims[0] = x.n_slices; - hid_t dataspace = arma_H5Screate_simple(3, dims, NULL); // treat the cube as a 3d array dataspace + hid_t dataspace = H5Screate_simple(3, dims, NULL); // treat the cube as a 3d array dataspace hid_t datatype = hdf5_misc::get_hdf5_type(); // If this returned something invalid, well, it's time to crash. @@ -3851,11 +3915,11 @@ // Create another group... 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); + hid_t gid = H5Gcreate((groups.size() == 0) ? file : groups[groups.size() - 1], full_name.substr(0, loc).c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if((gid < 0) && use_existing_file) { - gid = arma_H5Gopen((groups.size() == 0) ? file : groups[groups.size() - 1], full_name.substr(0, loc).c_str(), H5P_DEFAULT); + gid = H5Gopen((groups.size() == 0) ? file : groups[groups.size() - 1], full_name.substr(0, loc).c_str(), H5P_DEFAULT); } groups.push_back(gid); @@ -3870,32 +3934,32 @@ if(use_existing_file && replace) { - arma_H5Ldelete(last_group, dataset_name.c_str(), H5P_DEFAULT); + H5Ldelete(last_group, dataset_name.c_str(), H5P_DEFAULT); // NOTE: H5Ldelete() in HDF5 v1.8 doesn't reclaim the deleted space; use h5repack to reclaim space: h5repack oldfile.h5 newfile.h5 // NOTE: has this behaviour changed in HDF5 1.10 ? // NOTE: https://lists.hdfgroup.org/pipermail/hdf-forum_lists.hdfgroup.org/2017-August/010482.html // NOTE: https://lists.hdfgroup.org/pipermail/hdf-forum_lists.hdfgroup.org/2017-August/010486.html } - hid_t dataset = arma_H5Dcreate(last_group, dataset_name.c_str(), datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + hid_t dataset = H5Dcreate(last_group, dataset_name.c_str(), datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if(dataset < 0) { save_okay = false; - err_msg = "couldn't create dataset"; + err_msg = "failed to create dataset"; } else { - save_okay = (arma_H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, x.mem) >= 0); + save_okay = (H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, x.mem) >= 0); - arma_H5Dclose(dataset); + H5Dclose(dataset); } - arma_H5Tclose(datatype); - arma_H5Sclose(dataspace); - for(size_t i = 0; i < groups.size(); ++i) { arma_H5Gclose(groups[i]); } - arma_H5Fclose(file); + H5Tclose(datatype); + H5Sclose(dataspace); + for(size_t i = 0; i < groups.size(); ++i) { H5Gclose(groups[i]); } + H5Fclose(file); if((use_existing_file == false) && (save_okay == true)) { save_okay = diskio::safe_rename(tmp_name, spec.filename); } @@ -3988,7 +4052,7 @@ arma_extra_debug_sigprint(); std::ifstream f; - f.open(name.c_str(), std::fstream::binary); + f.open(name, std::fstream::binary); bool load_okay = f.is_open(); @@ -4044,7 +4108,7 @@ { arma_extra_debug_sigprint(); - std::ifstream f(name.c_str()); + std::ifstream f(name); bool load_okay = f.is_open(); @@ -4148,7 +4212,7 @@ arma_extra_debug_sigprint(); std::ifstream f; - f.open(name.c_str(), std::fstream::binary); + f.open(name, std::fstream::binary); bool load_okay = f.is_open(); @@ -4248,11 +4312,13 @@ #if defined(ARMA_USE_HDF5) { + if(diskio::is_readable(spec.filename) == false) { return false; } + 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); + hid_t fid = H5Fopen(spec.filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); if(fid >= 0) { @@ -4279,22 +4345,22 @@ if(dataset >= 0) { - hid_t filespace = arma_H5Dget_space(dataset); + hid_t filespace = H5Dget_space(dataset); // This must be <= 3 due to our search rules. - const int ndims = arma_H5Sget_simple_extent_ndims(filespace); + const int ndims = H5Sget_simple_extent_ndims(filespace); hsize_t dims[3]; - const herr_t query_status = arma_H5Sget_simple_extent_dims(filespace, dims, NULL); + const herr_t query_status = 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"; - arma_H5Sclose(filespace); - arma_H5Dclose(dataset); - arma_H5Fclose(fid); + H5Sclose(filespace); + H5Dclose(dataset); + H5Fclose(fid); return false; } @@ -4305,14 +4371,14 @@ 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 datatype = 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) + if(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())); + hid_t read_status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(x.memptr())); if(read_status >= 0) { load_okay = true; } } @@ -4325,14 +4391,14 @@ } // Now clean up. - arma_H5Tclose(datatype); - arma_H5Tclose(mat_type); - arma_H5Sclose(filespace); + H5Tclose(datatype); + H5Tclose(mat_type); + H5Sclose(filespace); } - arma_H5Dclose(dataset); + H5Dclose(dataset); - arma_H5Fclose(fid); + H5Fclose(fid); if(load_okay == false) { @@ -4369,13 +4435,15 @@ { arma_extra_debug_sigprint(); + if(diskio::is_readable(name) == false) { return false; } + #if defined(ARMA_USE_HDF5) // 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); } + if( 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); + f.open(name, std::fstream::in | std::fstream::binary); bool load_okay = f.is_open(); @@ -4476,7 +4544,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f( tmp_name.c_str(), std::fstream::binary ); + std::ofstream f( tmp_name, std::fstream::binary ); bool save_okay = f.is_open(); @@ -4539,7 +4607,7 @@ { arma_extra_debug_sigprint(); - std::ifstream f( name.c_str(), std::fstream::binary ); + std::ifstream f( name, std::fstream::binary ); bool load_okay = f.is_open(); @@ -4628,7 +4696,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f( tmp_name.c_str(), std::fstream::binary ); + std::ofstream f( tmp_name, std::fstream::binary ); bool save_okay = f.is_open(); @@ -4679,7 +4747,7 @@ { arma_extra_debug_sigprint(); - std::ifstream f( name.c_str() ); + std::ifstream f(name); bool load_okay = f.is_open(); @@ -4773,7 +4841,7 @@ arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in | std::fstream::binary); + f.open(name, std::fstream::in | std::fstream::binary); bool load_okay = f.is_open(); @@ -4850,7 +4918,7 @@ arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in | std::fstream::binary); + f.open(name, std::fstream::in | std::fstream::binary); bool load_okay = f.is_open(); @@ -4967,7 +5035,7 @@ const std::string tmp_name = diskio::gen_tmp_name(final_name); - std::ofstream f( tmp_name.c_str(), std::fstream::binary ); + std::ofstream f( tmp_name, std::fstream::binary ); bool save_okay = f.is_open(); @@ -5036,7 +5104,7 @@ arma_extra_debug_sigprint(); std::fstream f; - f.open(name.c_str(), std::fstream::in | std::fstream::binary); + f.open(name, std::fstream::in | std::fstream::binary); bool load_okay = f.is_open(); @@ -5166,7 +5234,7 @@ 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 ); + std::ofstream f( tmp_name, std::fstream::binary ); bool save_okay = f.is_open(); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/distr_param.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/distr_param.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/distr_param.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/distr_param.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -26,41 +26,64 @@ { public: - uword state; + const uword state; - union - { - int a_int; - double a_double; - }; + private: - union - { - int b_int; - double b_double; - }; + int a_int; + int b_int; + + double a_double; + double b_double; + public: inline distr_param() - : state(0) + : state (0) + , a_int (0) + , b_int (0) + , a_double(0) + , b_double(0) { } inline explicit distr_param(const int a, const int b) - : state(1) - , a_int(a) - , b_int(b) + : state (1) + , a_int (a) + , b_int (b) + , a_double(double(a)) + , b_double(double(b)) { } inline explicit distr_param(const double a, const double b) - : state(2) + : state (2) + , a_int (int(a)) + , b_int (int(b)) , a_double(a) , b_double(b) { } + + + inline void get_int_vals(int& out_a, int& out_b) const + { + if(state == 0) { return; } + + out_a = a_int; + out_b = b_int; + } + + + inline void get_double_vals(double& out_a, double& out_b) const + { + if(state == 0) { return; } + + out_a = a_double; + out_b = b_double; + } }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/eglue_core_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/eglue_core_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/eglue_core_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/eglue_core_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -255,7 +255,6 @@ template template -arma_hot inline void eglue_core::apply(outT& out, const eGlue& x) @@ -264,8 +263,8 @@ 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::openmp); + constexpr bool use_at = (Proxy::use_at || Proxy::use_at); + constexpr 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=() @@ -355,7 +354,6 @@ template template -arma_hot inline void eglue_core::apply_inplace_plus(Mat& out, const eGlue& x) @@ -371,8 +369,8 @@ 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::openmp); + constexpr bool use_at = (Proxy::use_at || Proxy::use_at); + constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -453,7 +451,6 @@ template template -arma_hot inline void eglue_core::apply_inplace_minus(Mat& out, const eGlue& x) @@ -469,8 +466,8 @@ 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::openmp); + constexpr bool use_at = (Proxy::use_at || Proxy::use_at); + constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -551,7 +548,6 @@ template template -arma_hot inline void eglue_core::apply_inplace_schur(Mat& out, const eGlue& x) @@ -567,8 +563,8 @@ 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::openmp); + constexpr bool use_at = (Proxy::use_at || Proxy::use_at); + constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -649,7 +645,6 @@ template template -arma_hot inline void eglue_core::apply_inplace_div(Mat& out, const eGlue& x) @@ -665,8 +660,8 @@ 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::openmp); + constexpr bool use_at = (Proxy::use_at || Proxy::use_at); + constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -752,7 +747,6 @@ template template -arma_hot inline void eglue_core::apply(Cube& out, const eGlueCube& x) @@ -761,8 +755,8 @@ 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::openmp); + constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); + constexpr 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=() @@ -853,7 +847,6 @@ template template -arma_hot inline void eglue_core::apply_inplace_plus(Cube& out, const eGlueCube& x) @@ -870,8 +863,8 @@ 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::openmp); + constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); + constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -952,7 +945,6 @@ template template -arma_hot inline void eglue_core::apply_inplace_minus(Cube& out, const eGlueCube& x) @@ -969,8 +961,8 @@ 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::openmp); + constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); + constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -1051,7 +1043,6 @@ template template -arma_hot inline void eglue_core::apply_inplace_schur(Cube& out, const eGlueCube& x) @@ -1068,8 +1059,8 @@ 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::openmp); + constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); + constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); if(use_at == false) { @@ -1150,7 +1141,6 @@ template template -arma_hot inline void eglue_core::apply_inplace_div(Cube& out, const eGlueCube& x) @@ -1167,8 +1157,8 @@ 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::openmp); + constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); + constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); if(use_at == false) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/eop_aux.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/eop_aux.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/eop_aux.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/eop_aux.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -92,7 +92,7 @@ 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()) ); } - 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_integral_only::result log2 (const eT x) { return eT( std::log2(double(x)) ); } 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); } @@ -100,7 +100,7 @@ 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); } - 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_integral_only::result exp2 (const eT x) { return eT( std::exp2(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); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/eop_core_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/eop_core_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/eop_core_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/eop_core_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -241,7 +241,6 @@ template template -arma_hot inline void eop_core::apply(outT& out, const eOp& x) @@ -317,7 +316,6 @@ template template -arma_hot inline void eop_core::apply_inplace_plus(Mat& out, const eOp& x) @@ -392,7 +390,7 @@ template template -arma_hot + inline void eop_core::apply_inplace_minus(Mat& out, const eOp& x) @@ -467,7 +465,7 @@ template template -arma_hot + inline void eop_core::apply_inplace_schur(Mat& out, const eOp& x) @@ -542,7 +540,7 @@ template template -arma_hot + inline void eop_core::apply_inplace_div(Mat& out, const eOp& x) @@ -622,7 +620,7 @@ template template -arma_hot + inline void eop_core::apply(Cube& out, const eOpCube& x) @@ -699,7 +697,7 @@ template template -arma_hot + inline void eop_core::apply_inplace_plus(Cube& out, const eOpCube& x) @@ -775,7 +773,7 @@ template template -arma_hot + inline void eop_core::apply_inplace_minus(Cube& out, const eOpCube& x) @@ -851,7 +849,7 @@ template template -arma_hot + inline void eop_core::apply_inplace_schur(Cube& out, const eOpCube& x) @@ -927,7 +925,7 @@ template template -arma_hot + inline void eop_core::apply_inplace_div(Cube& out, const eOpCube& x) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fft_engine_fftw3.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fft_engine_fftw3.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fft_engine_fftw3.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fft_engine_fftw3.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,104 @@ +// 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 fft_engine_fftw3 +//! @{ + + +#if defined(ARMA_USE_FFTW3) + +template +class fft_engine_fftw3 + { + public: + + constexpr static int fftw3_sign_forward = -1; + constexpr static int fftw3_sign_backward = +1; + + constexpr static unsigned int fftw3_flag_destroy = (1u << 0); + constexpr static unsigned int fftw3_flag_preserve = (1u << 4); + constexpr static unsigned int fftw3_flag_estimate = (1u << 6); + + const uword N; + + void_ptr fftw3_plan; + + podarray X_work; // for storing copy of input (can be overwritten by FFTW3) + podarray Y_work; // for storing output + + inline + ~fft_engine_fftw3() + { + arma_extra_debug_sigprint(); + + if(fftw3_plan != nullptr) { fftw3::destroy_plan(fftw3_plan); } + + // fftw3::cleanup(); // NOTE: this also removes any wisdom acquired by FFTW3 + } + + inline + fft_engine_fftw3(const uword in_N) + : N (in_N ) + , fftw3_plan(nullptr) + { + arma_extra_debug_sigprint(); + + if(N == 0) { return; } + + if(N > uword(std::numeric_limits::max())) + { + arma_stop_runtime_error("integer overflow: FFT size too large for integer type used by FFTW3"); + } + + arma_extra_debug_print("fft_engine_fftw3::constructor: allocating work arrays"); + X_work.set_size(N); + Y_work.set_size(N); + + const int fftw3_sign = (inverse) ? fftw3_sign_backward : fftw3_sign_forward; + const int fftw3_flags = fftw3_flag_destroy | fftw3_flag_estimate; + + arma_extra_debug_print("fft_engine_fftw3::constructor: generating 1D plan"); + fftw3_plan = fftw3::plan_dft_1d(N, X_work.memptr(), Y_work.memptr(), fftw3_sign, fftw3_flags); + + if(fftw3_plan == nullptr) { arma_stop_runtime_error("fft_engine_fftw3::constructor: failed to create plan"); } + } + + inline + void + run(cx_type* Y, const cx_type* X) + { + arma_extra_debug_sigprint(); + + if(fftw3_plan == nullptr) { return; } + + arma_extra_debug_print("fft_engine_fftw3::run(): copying input array"); + arrayops::copy(X_work.memptr(), X, N); + + arma_extra_debug_print("fft_engine_fftw3::run(): executing plan"); + fftw3::execute(fftw3_plan); + + arma_extra_debug_print("fft_engine_fftw3::run(): copying output array"); + arrayops::copy(Y, Y_work.memptr(), N); + } + }; + +#endif + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fft_engine.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fft_engine.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fft_engine.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fft_engine.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,424 +0,0 @@ -// 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) -// -// 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. -// -// ------------------------------------------------------------------------ -// -// This file includes portions of Kiss FFT software, -// 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, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the author nor the names of any contributors may be used to -// endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ------------------------------------------------------------------------ - - -//! \addtogroup fft_engine -//! @{ - - -template struct fft_store {}; - -template -struct fft_store - { - static constexpr uword N = fixed_N; - - arma_aligned cx_type coeffs_array[fixed_N]; - - inline fft_store() {} - inline fft_store(uword) {} - - arma_inline cx_type* coeffs_ptr() { return &coeffs_array[0]; } - arma_inline const cx_type* coeffs_ptr() const { return &coeffs_array[0]; } - }; - - - -template -struct fft_store - { - const uword N; - - podarray coeffs_array; - - inline fft_store() : N(0) {} - inline fft_store(uword in_N) : N(in_N) { coeffs_array.set_size(N); } - - arma_inline cx_type* coeffs_ptr() { return coeffs_array.memptr(); } - arma_inline const cx_type* coeffs_ptr() const { return coeffs_array.memptr(); } - }; - - - -template -class fft_engine : public fft_store 0)> - { - public: - - typedef typename get_pod_type::result T; - - using fft_store 0)>::N; - using fft_store 0)>::coeffs_ptr; - - podarray residue; - podarray radix; - - podarray tmp_array; - - - template - inline - uword - calc_radix() - { - uword i = 0; - - for(uword n = N, r=4; n >= 2; ++i) - { - while( (n % r) > 0 ) - { - switch(r) - { - case 2: r = 3; break; - case 4: r = 2; break; - default: r += 2; break; - } - - if(r*r > n) { r = n; } - } - - n /= r; - - if(fill) - { - residue[i] = n; - radix[i] = r; - } - } - - return i; - } - - - - inline - fft_engine(const uword in_N) - : fft_store< cx_type, fixed_N, (fixed_N > 0) >(in_N) - { - arma_extra_debug_sigprint(); - - const uword len = calc_radix(); - - residue.set_size(len); - radix.set_size(len); - - calc_radix(); - - - // calculate the constant coefficients - - cx_type* coeffs = coeffs_ptr(); - - const T k = T( (inverse) ? +2 : -2 ) * std::acos( T(-1) ) / T(N); - - for(uword i=0; i < N; ++i) { coeffs[i] = std::exp( cx_type(T(0), i*k) ); } - } - - - - arma_hot - inline - void - butterfly_2(cx_type* Y, const uword stride, const uword m) - { - arma_extra_debug_sigprint(); - - const cx_type* coeffs = coeffs_ptr(); - - for(uword i=0; i < m; ++i) - { - const cx_type t = Y[i+m] * coeffs[i*stride]; - - Y[i+m] = Y[i] - t; - Y[i ] += t; - } - } - - - - arma_hot - inline - void - butterfly_3(cx_type* Y, const uword stride, const uword m) - { - arma_extra_debug_sigprint(); - - arma_aligned cx_type tmp[5]; - - cx_type* coeffs1 = coeffs_ptr(); - cx_type* coeffs2 = coeffs1; - - const T coeff_sm_imag = coeffs1[stride*m].imag(); - - const uword n = m*2; - - // TODO: rearrange the indices within tmp[] into a more sane order - - for(uword i = m; i > 0; --i) - { - tmp[1] = Y[m] * (*coeffs1); - tmp[2] = Y[n] * (*coeffs2); - - tmp[0] = tmp[1] - tmp[2]; - tmp[0] *= coeff_sm_imag; - - tmp[3] = tmp[1] + tmp[2]; - - Y[m] = cx_type( (Y[0].real() - (T(0.5)*tmp[3].real())), (Y[0].imag() - (T(0.5)*tmp[3].imag())) ); - - Y[0] += tmp[3]; - - - Y[n] = cx_type( (Y[m].real() + tmp[0].imag()), (Y[m].imag() - tmp[0].real()) ); - - Y[m] += cx_type( -tmp[0].imag(), tmp[0].real() ); - - Y++; - - coeffs1 += stride; - coeffs2 += stride*2; - } - } - - - - arma_hot - inline - void - butterfly_4(cx_type* Y, const uword stride, const uword m) - { - arma_extra_debug_sigprint(); - - arma_aligned cx_type tmp[7]; - - const cx_type* coeffs = coeffs_ptr(); - - const uword m2 = m*2; - const uword m3 = m*3; - - // TODO: rearrange the indices within tmp[] into a more sane order - - for(uword i=0; i < m; ++i) - { - tmp[0] = Y[i + m ] * coeffs[i*stride ]; - tmp[2] = Y[i + m3] * coeffs[i*stride*3]; - tmp[3] = tmp[0] + tmp[2]; - - //tmp[4] = tmp[0] - tmp[2]; - //tmp[4] = (inverse) ? cx_type( -(tmp[4].imag()), tmp[4].real() ) : cx_type( tmp[4].imag(), -tmp[4].real() ); - - tmp[4] = (inverse) - ? cx_type( (tmp[2].imag() - tmp[0].imag()), (tmp[0].real() - tmp[2].real()) ) - : cx_type( (tmp[0].imag() - tmp[2].imag()), (tmp[2].real() - tmp[0].real()) ); - - tmp[1] = Y[i + m2] * coeffs[i*stride*2]; - tmp[5] = Y[i] - tmp[1]; - - - Y[i ] += tmp[1]; - Y[i + m2] = Y[i] - tmp[3]; - Y[i ] += tmp[3]; - Y[i + m ] = tmp[5] + tmp[4]; - Y[i + m3] = tmp[5] - tmp[4]; - } - } - - - - inline - arma_hot - void - butterfly_5(cx_type* Y, const uword stride, const uword m) - { - arma_extra_debug_sigprint(); - - arma_aligned cx_type tmp[13]; - - const cx_type* coeffs = coeffs_ptr(); - - const T a_real = coeffs[stride*1*m].real(); - const T a_imag = coeffs[stride*1*m].imag(); - - const T b_real = coeffs[stride*2*m].real(); - const T b_imag = coeffs[stride*2*m].imag(); - - cx_type* Y0 = Y; - cx_type* Y1 = Y + 1*m; - cx_type* Y2 = Y + 2*m; - cx_type* Y3 = Y + 3*m; - cx_type* Y4 = Y + 4*m; - - for(uword i=0; i < m; ++i) - { - tmp[0] = (*Y0); - - tmp[1] = (*Y1) * coeffs[stride*1*i]; - tmp[2] = (*Y2) * coeffs[stride*2*i]; - tmp[3] = (*Y3) * coeffs[stride*3*i]; - tmp[4] = (*Y4) * coeffs[stride*4*i]; - - tmp[7] = tmp[1] + tmp[4]; - tmp[8] = tmp[2] + tmp[3]; - tmp[9] = tmp[2] - tmp[3]; - tmp[10] = tmp[1] - tmp[4]; - - (*Y0) += tmp[7]; - (*Y0) += tmp[8]; - - tmp[5] = tmp[0] + cx_type( ( (tmp[7].real() * a_real) + (tmp[8].real() * b_real) ), ( (tmp[7].imag() * a_real) + (tmp[8].imag() * b_real) ) ); - - tmp[6] = cx_type( ( (tmp[10].imag() * a_imag) + (tmp[9].imag() * b_imag) ), ( -(tmp[10].real() * a_imag) - (tmp[9].real() * b_imag) ) ); - - (*Y1) = tmp[5] - tmp[6]; - (*Y4) = tmp[5] + tmp[6]; - - tmp[11] = tmp[0] + cx_type( ( (tmp[7].real() * b_real) + (tmp[8].real() * a_real) ), ( (tmp[7].imag() * b_real) + (tmp[8].imag() * a_real) ) ); - - tmp[12] = cx_type( ( -(tmp[10].imag() * b_imag) + (tmp[9].imag() * a_imag) ), ( (tmp[10].real() * b_imag) - (tmp[9].real() * a_imag) ) ); - - (*Y2) = tmp[11] + tmp[12]; - (*Y3) = tmp[11] - tmp[12]; - - Y0++; - Y1++; - Y2++; - Y3++; - Y4++; - } - } - - - - arma_hot - inline - void - butterfly_N(cx_type* Y, const uword stride, const uword m, const uword r) - { - arma_extra_debug_sigprint(); - - const cx_type* coeffs = coeffs_ptr(); - - tmp_array.set_min_size(r); - cx_type* tmp = tmp_array.memptr(); - - for(uword u=0; u < m; ++u) - { - uword k = u; - - for(uword v=0; v < r; ++v) - { - tmp[v] = Y[k]; - k += m; - } - - k = u; - - for(uword v=0; v < r; ++v) - { - Y[k] = tmp[0]; - - uword j = 0; - - for(uword w=1; w < r; ++w) - { - j += stride * k; - - if(j >= N) { j -= N; } - - Y[k] += tmp[w] * coeffs[j]; - } - - k += m; - } - } - } - - - - inline - void - run(cx_type* Y, const cx_type* X, const uword stage = 0, const uword stride = 1) - { - arma_extra_debug_sigprint(); - - const uword m = residue[stage]; - const uword r = radix[stage]; - - const cx_type *Y_end = Y + r*m; - - if(m == 1) - { - for(cx_type* Yi = Y; Yi != Y_end; Yi++, X += stride) { (*Yi) = (*X); } - } - else - { - const uword next_stage = stage + 1; - const uword next_stride = stride * r; - - for(cx_type* Yi = Y; Yi != Y_end; Yi += m, X += stride) { run(Yi, X, next_stage, next_stride); } - } - - switch(r) - { - case 2: butterfly_2(Y, stride, m ); break; - case 3: butterfly_3(Y, stride, m ); break; - case 4: butterfly_4(Y, stride, m ); break; - case 5: butterfly_5(Y, stride, m ); break; - default: butterfly_N(Y, stride, m, r); break; - } - } - - - }; - - -//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fft_engine_kissfft.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fft_engine_kissfft.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fft_engine_kissfft.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fft_engine_kissfft.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,392 @@ +// 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) +// +// 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. +// +// ------------------------------------------------------------------------ +// +// This file includes portions of Kiss FFT software, +// 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, +// are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the author nor the names of any contributors may be used to +// endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ------------------------------------------------------------------------ + + +//! \addtogroup fft_engine_kissfft +//! @{ + + +template +class fft_engine_kissfft + { + public: + + typedef typename get_pod_type::result T; + + const uword N; + + podarray coeffs_array; + podarray tmp_array; + + podarray residue; + podarray radix; + + + template + inline + uword + calc_radix() + { + uword i = 0; + + for(uword n = N, r=4; n >= 2; ++i) + { + while( (n % r) > 0 ) + { + switch(r) + { + case 2: r = 3; break; + case 4: r = 2; break; + default: r += 2; break; + } + + if(r*r > n) { r = n; } + } + + n /= r; + + if(fill) + { + residue[i] = n; + radix[i] = r; + } + } + + return i; + } + + + + inline + fft_engine_kissfft(const uword in_N) + : N(in_N) + { + arma_extra_debug_sigprint(); + + const uword len = calc_radix(); + + residue.set_size(len); + radix.set_size(len); + + calc_radix(); + + + // calculate the constant coefficients + + coeffs_array.set_size(N); + + cx_type* coeffs = coeffs_array.memptr(); + + const T k = T( (inverse) ? +2 : -2 ) * std::acos( T(-1) ) / T(N); + + for(uword i=0; i < N; ++i) { coeffs[i] = std::exp( cx_type(T(0), i*k) ); } + } + + + + arma_hot + inline + void + butterfly_2(cx_type* Y, const uword stride, const uword m) const + { + // arma_extra_debug_sigprint(); + + const cx_type* coeffs = coeffs_array.memptr(); + + for(uword i=0; i < m; ++i) + { + const cx_type t = Y[i+m] * coeffs[i*stride]; + + Y[i+m] = Y[i] - t; + Y[i ] += t; + } + } + + + + arma_hot + inline + void + butterfly_3(cx_type* Y, const uword stride, const uword m) const + { + // arma_extra_debug_sigprint(); + + arma_aligned cx_type tmp[5]; + + const cx_type* coeffs1 = coeffs_array.memptr(); + const cx_type* coeffs2 = coeffs1; + + const T coeff_sm_imag = coeffs1[stride*m].imag(); + + const uword n = m*2; + + // TODO: rearrange the indices within tmp[] into a more sane order + + for(uword i = m; i > 0; --i) + { + tmp[1] = Y[m] * (*coeffs1); + tmp[2] = Y[n] * (*coeffs2); + + tmp[0] = tmp[1] - tmp[2]; + tmp[0] *= coeff_sm_imag; + + tmp[3] = tmp[1] + tmp[2]; + + Y[m] = cx_type( (Y[0].real() - (T(0.5)*tmp[3].real())), (Y[0].imag() - (T(0.5)*tmp[3].imag())) ); + + Y[0] += tmp[3]; + + + Y[n] = cx_type( (Y[m].real() + tmp[0].imag()), (Y[m].imag() - tmp[0].real()) ); + + Y[m] += cx_type( -tmp[0].imag(), tmp[0].real() ); + + Y++; + + coeffs1 += stride; + coeffs2 += stride*2; + } + } + + + + arma_hot + inline + void + butterfly_4(cx_type* Y, const uword stride, const uword m) const + { + // arma_extra_debug_sigprint(); + + arma_aligned cx_type tmp[7]; + + const cx_type* coeffs = coeffs_array.memptr(); + + const uword m2 = m*2; + const uword m3 = m*3; + + // TODO: rearrange the indices within tmp[] into a more sane order + + for(uword i=0; i < m; ++i) + { + tmp[0] = Y[i + m ] * coeffs[i*stride ]; + tmp[2] = Y[i + m3] * coeffs[i*stride*3]; + tmp[3] = tmp[0] + tmp[2]; + + //tmp[4] = tmp[0] - tmp[2]; + //tmp[4] = (inverse) ? cx_type( -(tmp[4].imag()), tmp[4].real() ) : cx_type( tmp[4].imag(), -tmp[4].real() ); + + tmp[4] = (inverse) + ? cx_type( (tmp[2].imag() - tmp[0].imag()), (tmp[0].real() - tmp[2].real()) ) + : cx_type( (tmp[0].imag() - tmp[2].imag()), (tmp[2].real() - tmp[0].real()) ); + + tmp[1] = Y[i + m2] * coeffs[i*stride*2]; + tmp[5] = Y[i] - tmp[1]; + + + Y[i ] += tmp[1]; + Y[i + m2] = Y[i] - tmp[3]; + Y[i ] += tmp[3]; + Y[i + m ] = tmp[5] + tmp[4]; + Y[i + m3] = tmp[5] - tmp[4]; + } + } + + + + arma_hot + inline + void + butterfly_5(cx_type* Y, const uword stride, const uword m) const + { + // arma_extra_debug_sigprint(); + + arma_aligned cx_type tmp[13]; + + const cx_type* coeffs = coeffs_array.memptr(); + + const T a_real = coeffs[stride*1*m].real(); + const T a_imag = coeffs[stride*1*m].imag(); + + const T b_real = coeffs[stride*2*m].real(); + const T b_imag = coeffs[stride*2*m].imag(); + + cx_type* Y0 = Y; + cx_type* Y1 = Y + 1*m; + cx_type* Y2 = Y + 2*m; + cx_type* Y3 = Y + 3*m; + cx_type* Y4 = Y + 4*m; + + for(uword i=0; i < m; ++i) + { + tmp[0] = (*Y0); + + tmp[1] = (*Y1) * coeffs[stride*1*i]; + tmp[2] = (*Y2) * coeffs[stride*2*i]; + tmp[3] = (*Y3) * coeffs[stride*3*i]; + tmp[4] = (*Y4) * coeffs[stride*4*i]; + + tmp[7] = tmp[1] + tmp[4]; + tmp[8] = tmp[2] + tmp[3]; + tmp[9] = tmp[2] - tmp[3]; + tmp[10] = tmp[1] - tmp[4]; + + (*Y0) += tmp[7]; + (*Y0) += tmp[8]; + + tmp[5] = tmp[0] + cx_type( ( (tmp[7].real() * a_real) + (tmp[8].real() * b_real) ), ( (tmp[7].imag() * a_real) + (tmp[8].imag() * b_real) ) ); + + tmp[6] = cx_type( ( (tmp[10].imag() * a_imag) + (tmp[9].imag() * b_imag) ), ( -(tmp[10].real() * a_imag) - (tmp[9].real() * b_imag) ) ); + + (*Y1) = tmp[5] - tmp[6]; + (*Y4) = tmp[5] + tmp[6]; + + tmp[11] = tmp[0] + cx_type( ( (tmp[7].real() * b_real) + (tmp[8].real() * a_real) ), ( (tmp[7].imag() * b_real) + (tmp[8].imag() * a_real) ) ); + + tmp[12] = cx_type( ( -(tmp[10].imag() * b_imag) + (tmp[9].imag() * a_imag) ), ( (tmp[10].real() * b_imag) - (tmp[9].real() * a_imag) ) ); + + (*Y2) = tmp[11] + tmp[12]; + (*Y3) = tmp[11] - tmp[12]; + + Y0++; + Y1++; + Y2++; + Y3++; + Y4++; + } + } + + + + arma_hot + inline + void + butterfly_N(cx_type* Y, const uword stride, const uword m, const uword r) + { + // arma_extra_debug_sigprint(); + + const cx_type* coeffs = coeffs_array.memptr(); + + tmp_array.set_min_size(r); + cx_type* tmp = tmp_array.memptr(); + + for(uword u=0; u < m; ++u) + { + uword k = u; + + for(uword v=0; v < r; ++v) + { + tmp[v] = Y[k]; + k += m; + } + + k = u; + + for(uword v=0; v < r; ++v) + { + Y[k] = tmp[0]; + + uword j = 0; + + for(uword w=1; w < r; ++w) + { + j += stride * k; + + if(j >= N) { j -= N; } + + Y[k] += tmp[w] * coeffs[j]; + } + + k += m; + } + } + } + + + + inline + void + run(cx_type* Y, const cx_type* X, const uword stage = 0, const uword stride = 1) + { + arma_extra_debug_sigprint(); + + const uword m = residue[stage]; + const uword r = radix[stage]; + + const cx_type *Y_end = Y + r*m; + + if(m == 1) + { + for(cx_type* Yi = Y; Yi != Y_end; Yi++, X += stride) { (*Yi) = (*X); } + } + else + { + const uword next_stage = stage + 1; + const uword next_stride = stride * r; + + for(cx_type* Yi = Y; Yi != Y_end; Yi += m, X += stride) { run(Yi, X, next_stage, next_stride); } + } + + switch(r) + { + case 2: butterfly_2(Y, stride, m ); break; + case 3: butterfly_3(Y, stride, m ); break; + case 4: butterfly_4(Y, stride, m ); break; + case 5: butterfly_5(Y, stride, m ); break; + default: butterfly_N(Y, stride, m, r); break; + } + } + + + }; + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/field_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/field_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/field_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/field_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -67,11 +67,11 @@ inline explicit field(const SizeMat& s); inline explicit field(const SizeCube& s); - inline void set_size(const uword n_obj_in); - inline void set_size(const uword n_rows_in, const uword n_cols_in); - inline void set_size(const uword n_rows_in, const uword n_cols_in, const uword n_slices_in); - inline void set_size(const SizeMat& s); - inline void set_size(const SizeCube& s); + inline field& set_size(const uword n_obj_in); + inline field& set_size(const uword n_rows_in, const uword n_cols_in); + inline field& set_size(const uword n_rows_in, const uword n_cols_in, const uword n_slices_in); + inline field& set_size(const SizeMat& s); + inline field& set_size(const SizeCube& s); inline field(const std::vector& x); inline field& operator=(const std::vector& x); @@ -86,39 +86,49 @@ inline field& operator=(field&& X); template - inline void copy_size(const field& x); + inline field& copy_size(const field& x); - arma_inline arma_warn_unused oT& operator[](const uword i); - arma_inline arma_warn_unused const oT& operator[](const uword i) const; + arma_warn_unused arma_inline oT& operator[](const uword i); + arma_warn_unused arma_inline const oT& operator[](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_warn_unused arma_inline oT& at(const uword i); + arma_warn_unused arma_inline const oT& at(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_warn_unused arma_inline oT& operator()(const uword i); + arma_warn_unused arma_inline const oT& operator()(const uword i) 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 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; + #if defined(__cpp_multidimensional_subscript) + arma_warn_unused arma_inline oT& operator[](const uword row, const uword col); + arma_warn_unused arma_inline const oT& operator[](const uword row, const uword col) const; + #endif + + arma_warn_unused arma_inline oT& at(const uword row, const uword col); + arma_warn_unused arma_inline const oT& at(const uword row, const uword col) const; + + #if defined(__cpp_multidimensional_subscript) + arma_warn_unused arma_inline oT& operator[](const uword row, const uword col, const uword slice); + arma_warn_unused arma_inline const oT& operator[](const uword row, const uword col, const uword slice) const; + #endif + + arma_warn_unused arma_inline oT& at(const uword row, const uword col, const uword slice); + arma_warn_unused arma_inline const oT& at(const uword row, const uword col, const uword slice) 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_warn_unused arma_inline oT& operator()(const uword row, const uword col); + arma_warn_unused 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, const uword slice); - arma_inline arma_warn_unused const oT& operator()(const uword row, const uword col, const uword slice) const; + arma_warn_unused arma_inline oT& operator()(const uword row, const uword col, const uword slice); + arma_warn_unused arma_inline 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_warn_unused arma_inline oT& front(); + arma_warn_unused arma_inline const oT& front() const; - arma_inline arma_warn_unused oT& back(); - arma_inline arma_warn_unused const oT& back() const; + arma_warn_unused arma_inline oT& back(); + arma_warn_unused arma_inline const oT& back() const; - arma_cold inline field_injector operator<<(const oT& val); - arma_cold inline field_injector operator<<(const injector_end_of_row<>& x); + arma_frown("use braced initialiser list instead") inline field_injector operator<<(const oT& val); + arma_frown("use braced initialiser list instead") inline field_injector operator<<(const injector_end_of_row<>& x); inline subview_field row(const uword row_num); @@ -173,10 +183,10 @@ 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; - inline const field& for_each(const std::function< void( oT&) >& F); + inline field& for_each(const std::function< void( oT&) >& F); inline const field& for_each(const std::function< void(const oT&) >& F) const; - inline const field& fill(const oT& x); + inline field& fill(const oT& x); inline void reset(); inline void reset_objects(); @@ -184,34 +194,34 @@ arma_inline bool is_empty() const; - arma_inline arma_warn_unused bool in_range(const uword i) const; - arma_inline arma_warn_unused bool in_range(const span& x) const; + arma_warn_unused arma_inline bool in_range(const uword i) const; + arma_warn_unused arma_inline bool in_range(const span& x) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused bool in_range(const span& row_span, const uword in_col) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const span& col_span) const; - arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline bool in_range(const span& row_span, const uword in_col) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const span& col_span) const; + arma_warn_unused arma_inline bool in_range(const span& row_span, const span& col_span) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const uword in_slice) const; - arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span, const span& slice_span) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const uword in_col, const uword in_slice) const; + arma_warn_unused arma_inline bool in_range(const span& row_span, const span& col_span, const span& slice_span) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const uword in_slice, const SizeCube& s) const; + arma_warn_unused arma_inline 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; - inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary) const; + arma_cold inline bool save(const std::string name, const file_type type = arma_binary) const; + arma_cold inline 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( std::istream& is, const file_type type = auto_detect); + arma_cold inline bool load(const std::string name, const file_type type = auto_detect); + arma_cold inline 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( std::ostream& os, const file_type type = arma_binary) const; + arma_deprecated inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; + arma_deprecated inline 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( std::istream& is, const file_type type = auto_detect); + arma_deprecated inline bool quiet_load(const std::string name, const file_type type = auto_detect); + arma_deprecated inline bool quiet_load( std::istream& is, const file_type type = auto_detect); // for container-like functionality @@ -292,7 +302,7 @@ public: - #ifdef ARMA_EXTRA_FIELD_PROTO + #if defined(ARMA_EXTRA_FIELD_PROTO) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_FIELD_PROTO) #endif }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/field_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/field_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/field_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/field_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -202,12 +202,14 @@ //! assuming a column-major layout (data is not preserved) template inline -void +field& field::set_size(const uword n_elem_in) { - arma_extra_debug_sigprint(arma_str::format("n_elem_in = %d") % n_elem_in); + arma_extra_debug_sigprint(arma_str::format("n_elem_in = %u") % n_elem_in); init(n_elem_in, 1); + + return *this; } @@ -215,12 +217,14 @@ //! change the field to have the specified dimensions (data is not preserved) template inline -void +field& field::set_size(const uword n_rows_in, const uword n_cols_in) { - arma_extra_debug_sigprint(arma_str::format("n_rows_in = %d, n_cols_in = %d") % n_rows_in % n_cols_in); + arma_extra_debug_sigprint(arma_str::format("n_rows_in = %u, n_cols_in = %u") % n_rows_in % n_cols_in); init(n_rows_in, n_cols_in); + + return *this; } @@ -228,32 +232,42 @@ //! change the field to have the specified dimensions (data is not preserved) template inline -void +field& field::set_size(const uword n_rows_in, const uword n_cols_in, const uword n_slices_in) { - 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); + arma_extra_debug_sigprint(arma_str::format("n_rows_in = %u, n_cols_in = %u, n_slices_in = %u") % n_rows_in % n_cols_in % n_slices_in); init(n_rows_in, n_cols_in, n_slices_in); + + return *this; } template inline -void +field& field::set_size(const SizeMat& s) { + arma_extra_debug_sigprint(); + init(s.n_rows, s.n_cols); + + return *this; } template inline -void +field& field::set_size(const SizeCube& s) { + arma_extra_debug_sigprint(); + init(s.n_rows, s.n_cols, s.n_slices); + + return *this; } @@ -427,6 +441,8 @@ { arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); + if(this == &X) { return *this; } + reset(); access::rw(n_rows ) = X.n_rows; @@ -459,12 +475,14 @@ template template inline -void +field& field::copy_size(const field& x) { arma_extra_debug_sigprint(); init(x.n_rows, x.n_cols, x.n_slices); + + return *this; } @@ -472,7 +490,6 @@ //! linear element accessor (treats the field as a vector); no bounds check template arma_inline -arma_warn_unused oT& field::operator[] (const uword i) { @@ -484,7 +501,6 @@ //! 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 { @@ -496,7 +512,6 @@ //! linear element accessor (treats the field as a vector); no bounds check template arma_inline -arma_warn_unused oT& field::at(const uword i) { @@ -508,7 +523,6 @@ //! 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 { @@ -520,7 +534,6 @@ //! 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) { @@ -534,7 +547,6 @@ //! 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 { @@ -548,7 +560,6 @@ //! 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) { @@ -562,7 +573,6 @@ //! 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 { @@ -576,7 +586,6 @@ //! 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) { @@ -590,7 +599,6 @@ //! 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 { @@ -601,10 +609,35 @@ +#if defined(__cpp_multidimensional_subscript) + + //! element accessor; no bounds check + template + arma_inline + oT& + field::operator[] (const uword in_row, const uword in_col) + { + return (*mem[in_row + in_col*n_rows]); + } + + + + //! element accessor; no bounds check + template + arma_inline + const oT& + field::operator[] (const uword in_row, const uword in_col) const + { + return (*mem[in_row + in_col*n_rows]); + } + +#endif + + + //! element accessor; no bounds check template arma_inline -arma_warn_unused oT& field::at(const uword in_row, const uword in_col) { @@ -616,7 +649,6 @@ //! element accessor; no bounds check template arma_inline -arma_warn_unused const oT& field::at(const uword in_row, const uword in_col) const { @@ -625,10 +657,35 @@ +#if defined(__cpp_multidimensional_subscript) + + //! element accessor; no bounds check + template + arma_inline + oT& + field::operator[] (const uword in_row, const uword in_col, const uword in_slice) + { + return (*mem[in_row + in_col*n_rows + in_slice*(n_rows*n_cols)]); + } + + + + //! element accessor; no bounds check + template + arma_inline + const oT& + field::operator[] (const uword in_row, const uword in_col, const uword in_slice) const + { + return (*mem[in_row + in_col*n_rows + in_slice*(n_rows*n_cols)]); + } + +#endif + + + //! 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) { @@ -640,7 +697,6 @@ //! 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 { @@ -651,7 +707,6 @@ template arma_inline -arma_warn_unused oT& field::front() { @@ -664,7 +719,6 @@ template arma_inline -arma_warn_unused const oT& field::front() const { @@ -677,7 +731,6 @@ template arma_inline -arma_warn_unused oT& field::back() { @@ -690,7 +743,6 @@ template arma_inline -arma_warn_unused const oT& field::back() const { @@ -702,7 +754,6 @@ template -arma_cold inline field_injector< field > field::operator<<(const oT& val) @@ -713,7 +764,6 @@ template -arma_cold inline field_injector< field > field::operator<<(const injector_end_of_row<>& x) @@ -1427,7 +1477,6 @@ //! has been defined. template -arma_cold inline void field::print(const std::string extra_text) const @@ -1458,7 +1507,6 @@ //! has been defined. template -arma_cold inline void field::print(std::ostream& user_stream, const std::string extra_text) const @@ -1482,7 +1530,7 @@ //! apply a lambda function to each object template inline -const field& +field& field::for_each(const std::function< void(oT&) >& F) { arma_extra_debug_sigprint(); @@ -1511,7 +1559,7 @@ //! fill the field with an object template inline -const field& +field& field::fill(const oT& x) { arma_extra_debug_sigprint(); @@ -1565,7 +1613,6 @@ //! returns true if the given index is currently in range template arma_inline -arma_warn_unused bool field::in_range(const uword i) const { @@ -1577,7 +1624,6 @@ //! returns true if the given start and end indices are currently in range template arma_inline -arma_warn_unused bool field::in_range(const span& x) const { @@ -1601,7 +1647,6 @@ //! returns true if the given location is currently in range template arma_inline -arma_warn_unused bool field::in_range(const uword in_row, const uword in_col) const { @@ -1612,7 +1657,6 @@ template arma_inline -arma_warn_unused bool field::in_range(const span& row_span, const uword in_col) const { @@ -1635,7 +1679,6 @@ template arma_inline -arma_warn_unused bool field::in_range(const uword in_row, const span& col_span) const { @@ -1658,7 +1701,6 @@ template arma_inline -arma_warn_unused bool field::in_range(const span& row_span, const span& col_span) const { @@ -1680,7 +1722,6 @@ template arma_inline -arma_warn_unused bool field::in_range(const uword in_row, const uword in_col, const SizeMat& s) const { @@ -1701,7 +1742,6 @@ template arma_inline -arma_warn_unused bool field::in_range(const uword in_row, const uword in_col, const uword in_slice) const { @@ -1712,7 +1752,6 @@ template arma_inline -arma_warn_unused bool field::in_range(const span& row_span, const span& col_span, const span& slice_span) const { @@ -1738,7 +1777,6 @@ template arma_inline -arma_warn_unused bool field::in_range(const uword in_row, const uword in_col, const uword in_slice, const SizeCube& s) const { @@ -1760,7 +1798,6 @@ template inline -arma_cold bool field::save(const std::string name, const file_type type) const { @@ -1778,7 +1815,7 @@ } else { - arma_debug_warn_level(3, "field::save(): couldn't write; file: ", name); + arma_debug_warn_level(3, "field::save(): write failed; file: ", name); } } @@ -1789,7 +1826,6 @@ template inline -arma_cold bool field::save(std::ostream& os, const file_type type) const { @@ -1807,7 +1843,7 @@ } else { - arma_debug_warn_level(3, "field::save(): couldn't write to stream"); + arma_debug_warn_level(3, "field::save(): stream write failed"); } } @@ -1818,7 +1854,6 @@ template inline -arma_cold bool field::load(const std::string name, const file_type type) { @@ -1836,7 +1871,7 @@ } else { - arma_debug_warn_level(3, "field::load(): couldn't read; file: ", name); + arma_debug_warn_level(3, "field::load(): read failed; file: ", name); } } @@ -1849,7 +1884,6 @@ template inline -arma_cold bool field::load(std::istream& is, const file_type type) { @@ -1866,7 +1900,7 @@ } else { - arma_debug_warn_level(3, "field::load(): couldn't read from stream"); + arma_debug_warn_level(3, "field::load(): stream read failed"); } } @@ -1879,7 +1913,6 @@ template inline -arma_cold bool field::quiet_save(const std::string name, const file_type type) const { @@ -1892,7 +1925,6 @@ template inline -arma_cold bool field::quiet_save(std::ostream& os, const file_type type) const { @@ -1905,7 +1937,6 @@ template inline -arma_cold bool field::quiet_load(const std::string name, const file_type type) { @@ -1918,7 +1949,6 @@ template inline -arma_cold bool field::quiet_load(std::istream& is, const file_type type) { @@ -1984,7 +2014,7 @@ void field::init(const uword n_rows_in, const uword n_cols_in, const uword n_slices_in) { - 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 ); + arma_extra_debug_sigprint( arma_str::format("n_rows_in = %u, n_cols_in = %u, n_slices_in = %u") % n_rows_in % n_cols_in % n_slices_in ); #if defined(ARMA_64BIT_WORD) const char* error_message = "field::init(): requested size is too large"; @@ -2045,7 +2075,7 @@ void field::delete_objects() { - arma_extra_debug_sigprint( arma_str::format("n_elem = %d") % n_elem ); + arma_extra_debug_sigprint( arma_str::format("n_elem = %u") % n_elem ); for(uword i=0; i::create_objects() { - arma_extra_debug_sigprint( arma_str::format("n_elem = %d") % n_elem ); + arma_extra_debug_sigprint( arma_str::format("n_elem = %u") % n_elem ); for(uword i=0; i - struct fill_class { inline fill_class() {} }; + struct fill_class { inline constexpr 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; + static constexpr fill_class none; + static constexpr fill_class zeros; + static constexpr fill_class ones; + static constexpr fill_class eye; + static constexpr fill_class randu; + static constexpr fill_class randn; // diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_accu.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_accu.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_accu.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_accu.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -70,7 +70,7 @@ } else { - #if defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ > 0) + #if defined(__FAST_MATH__) { if(P.is_aligned()) { @@ -643,7 +643,7 @@ } else { - #if defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ > 0) + #if defined(__FAST_MATH__) { if(P.is_aligned()) { @@ -845,23 +845,36 @@ const SpProxy P(expr.get_ref()); + const uword N = P.get_n_nonzero(); + + if(N == 0) { return eT(0); } + if(SpProxy::use_iterator == false) { // direct counting - return arrayops::accumulate(P.get_values(), P.get_n_nonzero()); + return arrayops::accumulate(P.get_values(), N); } - else + + if(is_SpSubview::stored_type>::value) { - typename SpProxy::const_iterator_type it = P.begin(); + const SpSubview& sv = reinterpret_cast< const SpSubview& >(P.Q); - const uword P_n_nz = P.get_n_nonzero(); - - eT val = eT(0); - - for(uword i=0; i < P_n_nz; ++i) { val += (*it); ++it; } - - return val; + if(sv.n_rows == sv.m.n_rows) + { + const SpMat& m = sv.m; + const uword col = sv.aux_col1; + + return arrayops::accumulate(&(m.values[ m.col_ptrs[col] ]), N); + } } + + typename SpProxy::const_iterator_type it = P.begin(); + + eT val = eT(0); + + for(uword i=0; i < N; ++i) { val += (*it); ++it; } + + return val; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_as_scalar.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_as_scalar.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_as_scalar.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_as_scalar.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -140,7 +140,7 @@ const strip_inv strip1(X.A.B); const strip_diagmat strip2(strip1.M); - const bool tmp2_do_inv = strip1.do_inv; + const bool tmp2_do_inv_gen = strip1.do_inv_gen && arma_config::optimise_invexpr; const bool tmp2_do_diagmat = strip2.do_diagmat; if(tmp2_do_diagmat == false) @@ -187,7 +187,7 @@ if(B_is_vec) { - if(tmp2_do_inv) + if(tmp2_do_inv_gen) { return val * op_dotext::direct_rowvec_invdiagvec_colvec(A.mem, B, C.mem); } @@ -198,7 +198,7 @@ } else { - if(tmp2_do_inv) + if(tmp2_do_inv_gen) { return val * op_dotext::direct_rowvec_invdiagmat_colvec(A.mem, B, C.mem); } @@ -332,40 +332,6 @@ arma_warn_unused inline typename T1::elem_type -as_scalar(const Gen& X) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - 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()); - } - - - -template -arma_warn_unused -inline -typename T1::elem_type -as_scalar(const Gen& X) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - 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()); - } - - - -template -arma_warn_unused -inline -typename T1::elem_type as_scalar(const BaseCube& X) { arma_extra_debug_sigprint(); @@ -396,6 +362,8 @@ typename T1::elem_type as_scalar(const SpBase& X) { + arma_extra_debug_sigprint(); + typedef typename T1::elem_type eT; const unwrap_spmat tmp(X.get_ref()); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_chol.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_chol.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_chol.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_chol.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -95,7 +95,7 @@ out = X.get_ref(); - arma_debug_check( (out.is_square() == false), "chol(): given matrix must be square sized" ); + arma_debug_check( (out.is_square() == false), "chol(): given matrix must be square sized", [&](){ out.soft_reset(); } ); if(out.is_empty()) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cond.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_cond.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cond.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_cond.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -// 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_cond -//! @{ - - - -template -arma_warn_unused -inline -typename enable_if2::value, typename T1::pod_type>::result -cond(const Base& X) - { - arma_extra_debug_sigprint(); - - return op_cond::cond(X.get_ref()); - } - - - -template -arma_warn_unused -inline -typename enable_if2::value, typename T1::pod_type>::result -rcond(const Base& X) - { - arma_extra_debug_sigprint(); - - return op_cond::rcond(X.get_ref()); - } - - - -// 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-10.8.2+dfsg/include/armadillo_bits/fn_cond_rcond.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_cond_rcond.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_cond_rcond.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_cond_rcond.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,63 @@ +// 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_cond +//! @{ + + + +template +arma_warn_unused +inline +typename enable_if2::value, typename T1::pod_type>::result +cond(const Base& X) + { + arma_extra_debug_sigprint(); + + return op_cond::apply(X.get_ref()); + } + + + +template +arma_warn_unused +inline +typename enable_if2::value, typename T1::pod_type>::result +rcond(const Base& X) + { + arma_extra_debug_sigprint(); + + return op_rcond::apply(X.get_ref()); + } + + + +// 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-10.8.2+dfsg/include/armadillo_bits/fn_conv_to.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_conv_to.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_conv_to.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_conv_to.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -57,7 +57,7 @@ const Proxy P(in.get_ref()); - arma_debug_check( (P.get_n_elem() != 1), "conv_to(): given object doesn't have exactly one element" ); + arma_debug_check( (P.get_n_elem() != 1), "conv_to(): given object does not have exactly one element" ); return out_eT(Proxy::use_at ? P.at(0,0) : P[0]); } @@ -78,7 +78,7 @@ const Proxy P(in.get_ref()); - arma_debug_check( (P.get_n_elem() != 1), "conv_to(): given object doesn't have exactly one element" ); + arma_debug_check( (P.get_n_elem() != 1), "conv_to(): given object does not have exactly one element" ); out_eT out; @@ -103,7 +103,7 @@ const ProxyCube P(in.get_ref()); - arma_debug_check( (P.get_n_elem() != 1), "conv_to(): given object doesn't have exactly one element" ); + arma_debug_check( (P.get_n_elem() != 1), "conv_to(): given object does not have exactly one element" ); return out_eT(ProxyCube::use_at ? P.at(0,0,0) : P[0]); } @@ -124,7 +124,7 @@ const ProxyCube P(in.get_ref()); - arma_debug_check( (P.get_n_elem() != 1), "conv_to(): given object doesn't have exactly one element" ); + arma_debug_check( (P.get_n_elem() != 1), "conv_to(): given object does not have exactly one element" ); out_eT out; @@ -303,7 +303,7 @@ const quasi_unwrap tmp(in.get_ref()); const Mat& X = tmp.M; - arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); + arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); Row out(X.n_elem, arma_nozeros_indicator()); @@ -327,7 +327,7 @@ const quasi_unwrap tmp(in.get_ref()); const Mat& X = tmp.M; - arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); + arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); Row out(X.n_rows, X.n_cols, arma_nozeros_indicator()); @@ -422,7 +422,7 @@ const quasi_unwrap tmp(in.get_ref()); const Mat& X = tmp.M; - arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); + arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); Col out(X.n_elem, arma_nozeros_indicator()); @@ -446,7 +446,7 @@ const quasi_unwrap tmp(in.get_ref()); const Mat& X = tmp.M; - arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); + arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); Col out(X.n_rows, X.n_cols, arma_nozeros_indicator()); @@ -672,7 +672,7 @@ const quasi_unwrap tmp(in.get_ref()); const Mat& X = tmp.M; - arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); + arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); const uword N = X.n_elem; @@ -701,7 +701,7 @@ const quasi_unwrap tmp(in.get_ref()); const Mat& X = tmp.M; - arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" ); + arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); const uword N = X.n_elem; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_diags_spdiags.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_diags_spdiags.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_diags_spdiags.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_diags_spdiags.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,134 @@ +// 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_diags_spdiags +//! @{ + + + +template +inline +Mat +diags(const Base& V_expr, const Base& D_expr, const uword n_rows, const uword n_cols) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const quasi_unwrap UV(V_expr.get_ref()); + const Mat& V = UV.M; + + const quasi_unwrap UD(D_expr.get_ref()); + const Mat& D = UD.M; + + arma_debug_check( ((D.is_vec() == false) && (D.is_empty() == false)), "D must be a vector" ); + + arma_debug_check( (V.n_cols != D.n_elem), "number of colums in matrix V must match the length of vector D" ); + + Mat out(n_rows, n_cols, fill::zeros); + + for(uword i=0; i < D.n_elem; ++i) + { + const sword diag_id = D[i]; + + const uword row_offset = (diag_id < 0) ? uword(-diag_id) : 0; + const uword col_offset = (diag_id > 0) ? uword( diag_id) : 0; + + arma_debug_check_bounds + ( + ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), + "diags(): requested diagonal out of bounds" + ); + + const uword diag_len = (std::min)(n_rows - row_offset, n_cols - col_offset); + + const uword V_start = (diag_id < 0) ? uword(0) : uword(diag_id); + + const eT* V_colmem = V.colptr(i); + + for(uword j=0; j < diag_len; ++j) + { + const uword V_index = V_start + j; + + if(V_index >= V.n_rows) { break; } + + out.at(j + row_offset, j + col_offset) = V_colmem[V_index]; + } + } + + return out; + } + + + +template +inline +SpMat +spdiags(const Base& V_expr, const Base& D_expr, const uword n_rows, const uword n_cols) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const quasi_unwrap UV(V_expr.get_ref()); + const Mat& V = UV.M; + + const quasi_unwrap UD(D_expr.get_ref()); + const Mat& D = UD.M; + + arma_debug_check( ((D.is_vec() == false) && (D.is_empty() == false)), "D must be a vector" ); + + arma_debug_check( (V.n_cols != D.n_elem), "number of colums in matrix V must match the length of vector D" ); + + MapMat tmp(n_rows, n_cols); + + for(uword i=0; i < D.n_elem; ++i) + { + const sword diag_id = D[i]; + + const uword row_offset = (diag_id < 0) ? uword(-diag_id) : 0; + const uword col_offset = (diag_id > 0) ? uword( diag_id) : 0; + + arma_debug_check_bounds + ( + ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), + "diags(): requested diagonal out of bounds" + ); + + const uword diag_len = (std::min)(n_rows - row_offset, n_cols - col_offset); + + const uword V_start = (diag_id < 0) ? uword(0) : uword(diag_id); + + const eT* V_colmem = V.colptr(i); + + for(uword j=0; j < diag_len; ++j) + { + const uword V_index = V_start + j; + + if(V_index >= V.n_rows) { break; } + + tmp.at(j + row_offset, j + col_offset) = V_colmem[V_index]; + } + } + + return SpMat(tmp); + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eig_sym.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_eig_sym.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eig_sym.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_eig_sym.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -95,13 +95,6 @@ { arma_extra_debug_sigprint(); - // if(auxlib::rudimentary_sym_check(X) == false) - // { - // 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_level(1, caller_sig, ": given matrix is not symmetric"); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eye.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_eye.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_eye.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_eye.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -54,15 +54,8 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - if(is_Col::value) - { - arma_debug_check( (n_cols != 1), "eye(): incompatible size" ); - } - else - if(is_Row::value) - { - arma_debug_check( (n_rows != 1), "eye(): incompatible size" ); - } + if(is_Col::value) { arma_debug_check( (n_cols != 1), "eye(): incompatible size" ); } + if(is_Row::value) { arma_debug_check( (n_rows != 1), "eye(): incompatible size" ); } return Gen(n_rows, n_cols); } @@ -92,15 +85,8 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - if(is_SpCol::value) - { - arma_debug_check( (n_cols != 1), "eye(): incompatible size" ); - } - else - if(is_SpRow::value) - { - arma_debug_check( (n_rows != 1), "eye(): incompatible size" ); - } + if(is_SpCol::value) { arma_debug_check( (n_cols != 1), "eye(): incompatible size" ); } + if(is_SpRow::value) { arma_debug_check( (n_rows != 1), "eye(): incompatible size" ); } obj_type out; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_find.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_find.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_find.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_find.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -251,6 +251,24 @@ +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_type::value, + const mtOp + >::result +find_nan(const T1& X) + { + arma_extra_debug_sigprint(); + + return mtOp(X); + } + + + // @@ -293,6 +311,25 @@ +template +arma_warn_unused +inline +uvec +find_nan(const BaseCube& X) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_cube tmp(X.get_ref()); + + const Mat R( const_cast< eT* >(tmp.M.memptr()), tmp.M.n_elem, 1, false ); + + return find_nan(R); + } + + + // @@ -368,6 +405,50 @@ { const uword index = it.row() + it.col()*n_rows; + tmp_mem[count] = index; + + ++count; + } + + ++it; + } + + Col out; + + if(count > 0) { out.steal_mem_col(tmp, count); } + + return out; + } + + + +template +arma_warn_unused +inline +Col +find_nan(const SpBase& X) + { + arma_extra_debug_sigprint(); + + const SpProxy P(X.get_ref()); + + const uword n_rows = P.get_n_rows(); + const uword n_nz = P.get_n_nonzero(); + + Mat tmp(n_nz, 1, arma_nozeros_indicator()); + + uword* tmp_mem = tmp.memptr(); + + typename SpProxy::const_iterator_type it = P.begin(); + + uword count = 0; + + for(uword i=0; i::nan; + } + else { // XG and XI are guaranteed to be sorted in ascending manner, // so start searching XG from last known optimum position @@ -114,6 +119,11 @@ YI_mem[i] = extrap_val; } else + if(arma_isnan(XI_val)) + { + YI_mem[i] = Datum::nan; + } + else { // XG and XI are guaranteed to be sorted in ascending manner, // so start searching XG from last known optimum position @@ -223,11 +233,11 @@ Mat XI_tmp; uvec XI_indices; - const bool XI_is_sorted = XI.is_sorted(); + const bool XI_is_sorted = XI.is_sorted(); // NOTE: .is_sorted() currently doesn't detect NaN if(XI_is_sorted == false) { - XI_indices = sort_index(XI); + XI_indices = sort_index(XI); // NOTE: sort_index() will throw if XI has NaN const uword N = XI.n_elem; @@ -246,6 +256,8 @@ const Mat& XI_sorted = (XI_is_sorted) ? XI : XI_tmp; + // NOTE: XI_sorted may have NaN + if(sig == 10) { interp1_helper_nearest(X_sanitised, Y_sanitised, XI_sorted, YI, extrap_val); } else if(sig == 20) { interp1_helper_linear (X_sanitised, Y_sanitised, XI_sorted, YI, extrap_val); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inv.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_inv.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inv.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_inv.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -24,7 +24,7 @@ template arma_warn_unused arma_inline -typename enable_if2< is_supported_blas_type::value, const Op >::result +typename enable_if2< is_supported_blas_type::value, const Op >::result inv ( const Base& X @@ -32,7 +32,7 @@ { arma_extra_debug_sigprint(); - return Op(X.get_ref()); + return Op(X.get_ref()); } @@ -48,7 +48,7 @@ { arma_extra_debug_sigprint(); - const bool status = op_inv::apply_direct(out, X.get_ref(), "inv()"); + const bool status = op_inv_gen_default::apply_direct(out, X.get_ref(), "inv()"); if(status == false) { @@ -64,15 +64,16 @@ template arma_warn_unused arma_inline -typename enable_if2< is_supported_blas_type::value, const Op >::result -inv_sympd +typename enable_if2< is_supported_blas_type::value, const Op >::result +inv ( - const Base& X + const Base& X, + const inv_opts::opts& opts ) { arma_extra_debug_sigprint(); - return Op(X.get_ref()); + return Op(X.get_ref(), opts.flags, uword(0)); } @@ -80,20 +81,53 @@ template inline typename enable_if2< is_supported_blas_type::value, bool >::result -inv_sympd +inv ( Mat& out, - const Base& X + const Base& X, + const inv_opts::opts& opts ) { arma_extra_debug_sigprint(); - const bool status = op_inv_sympd::apply_direct(out, X.get_ref()); + const bool status = op_inv_gen_full::apply_direct(out, X.get_ref(), "inv()", opts.flags); if(status == false) { out.soft_reset(); - arma_debug_warn_level(3, "inv_sympd(): matrix is singular or not positive definite"); + arma_debug_warn_level(3, "inv(): matrix is singular"); + } + + return status; + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +inv + ( + Mat& out_inv, + typename T1::pod_type& out_rcond, + const Base& X + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + op_inv_gen_state inv_state; + + const bool status = op_inv_gen_rcond::apply_direct(out_inv, inv_state, X.get_ref()); + + out_rcond = inv_state.rcond; + + if(status == false) + { + out_rcond = T(0); + out_inv.soft_reset(); + arma_debug_warn_level(3, "inv(): matrix is singular"); } return status; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inv_sympd.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_inv_sympd.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_inv_sympd.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_inv_sympd.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,138 @@ +// 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_inv_sympd +//! @{ + + + +template +arma_warn_unused +arma_inline +typename enable_if2< is_supported_blas_type::value, const Op >::result +inv_sympd + ( + const Base& X + ) + { + arma_extra_debug_sigprint(); + + return Op(X.get_ref()); + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +inv_sympd + ( + Mat& out, + const Base& X + ) + { + arma_extra_debug_sigprint(); + + const bool status = op_inv_spd_default::apply_direct(out, X.get_ref()); + + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "inv_sympd(): matrix is singular or not positive definite"); + } + + return status; + } + + + +template +arma_warn_unused +arma_inline +typename enable_if2< is_supported_blas_type::value, const Op >::result +inv_sympd + ( + const Base& X, + const inv_opts::opts& opts + ) + { + arma_extra_debug_sigprint(); + + return Op(X.get_ref(), opts.flags, uword(0)); + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +inv_sympd + ( + Mat& out, + const Base& X, + const inv_opts::opts& opts + ) + { + arma_extra_debug_sigprint(); + + const bool status = op_inv_spd_full::apply_direct(out, X.get_ref(), opts.flags); + + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "inv_sympd(): matrix is singular or not positive definite"); + } + + return status; + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +inv_sympd + ( + Mat& out_inv, + typename T1::pod_type& out_rcond, + const Base& X + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + op_inv_spd_state inv_state; + + const bool status = op_inv_spd_rcond::apply_direct(out_inv, inv_state, X.get_ref()); + + out_rcond = inv_state.rcond; + + if(status == false) + { + out_rcond = T(0); + out_inv.soft_reset(); + arma_debug_warn_level(3, "inv_sympd(): matrix is singular or not positive definite"); + } + + return status; + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_log_det.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_log_det.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_log_det.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_log_det.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -55,8 +55,8 @@ template -inline arma_warn_unused +inline std::complex log_det ( @@ -124,8 +124,8 @@ template -inline arma_warn_unused +inline typename T1::pod_type log_det_sympd ( diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_log_normpdf.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_log_normpdf.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_log_normpdf.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_log_normpdf.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -92,8 +92,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), eT >::result log_normpdf(const eT x) { @@ -105,8 +105,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), eT >::result log_normpdf(const eT x, const eT mu, const eT sigma) { @@ -120,8 +120,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result log_normpdf(const eT x, const Base& M_expr, const Base& S_expr) { @@ -140,8 +140,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result log_normpdf(const Base& X_expr) { @@ -162,8 +162,8 @@ template -inline arma_warn_unused +inline 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) { @@ -184,8 +184,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result log_normpdf(const Base& X_expr, const Base& M_expr, const Base& S_expr) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normcdf.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_normcdf.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normcdf.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_normcdf.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -88,8 +88,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), eT >::result normcdf(const eT x) { @@ -101,8 +101,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), eT >::result normcdf(const eT x, const eT mu, const eT sigma) { @@ -116,8 +116,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result normcdf(const eT x, const Base& M_expr, const Base& S_expr) { @@ -136,8 +136,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result normcdf(const Base& X_expr) { @@ -158,8 +158,8 @@ template -inline arma_warn_unused +inline 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) { @@ -180,8 +180,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result normcdf(const Base& X_expr, const Base& M_expr, const Base& S_expr) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_norm.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_norm.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_norm.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_norm.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,8 +22,8 @@ template -inline arma_warn_unused +inline typename enable_if2< is_arma_type::value, typename T1::pod_type >::result norm ( @@ -48,7 +48,7 @@ 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" ); + arma_debug_check( (k == 0), "norm(): unsupported vector norm type" ); return op_norm::vec_norm_k(P, int(k)); } @@ -68,8 +68,8 @@ template -inline arma_warn_unused +inline typename enable_if2< is_arma_type::value, typename T1::pod_type >::result norm ( @@ -121,8 +121,8 @@ template -inline arma_warn_unused +inline typename enable_if2< is_arma_type::value, double >::result norm ( @@ -143,8 +143,8 @@ template -inline arma_warn_unused +inline typename enable_if2< is_arma_type::value, double >::result norm ( @@ -169,8 +169,8 @@ template -inline arma_warn_unused +inline typename enable_if2< is_arma_sparse_type::value, typename T1::pod_type >::result norm ( @@ -185,6 +185,20 @@ typedef typename T1::elem_type eT; typedef typename T1::pod_type T; + if(is_SpSubview_col::value) + { + const SpSubview_col& sv = reinterpret_cast< const SpSubview_col& >(expr); + + if(sv.n_rows == sv.m.n_rows) + { + const SpMat& m = sv.m; + const uword col = sv.aux_col1; + const eT* mem = &(m.values[ m.col_ptrs[col] ]); + + return spop_norm::vec_norm_k(mem, sv.n_nonzero, k); + } + } + const unwrap_spmat U(expr); const SpMat& X = U.M; @@ -194,17 +208,7 @@ if(is_vec) { - // create a fake dense vector to allow reuse of code for dense vectors - Col fake_vector( access::rwp(X.values), X.n_nonzero, false ); - - const Proxy< Col > P_fake_vector(fake_vector); - - 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)); + return spop_norm::vec_norm_k(X.values, X.n_nonzero, k); } else { @@ -220,8 +224,8 @@ template -inline arma_warn_unused +inline typename enable_if2< is_arma_sparse_type::value, typename T1::pod_type >::result norm ( @@ -290,5 +294,49 @@ } + +// +// approximate norms + + +template +arma_warn_unused +inline +typename T1::pod_type +norm2est + ( + const Base& X, + const typename T1::pod_type tolerance = 0, + const uword max_iter = 100, + const typename arma_real_or_cx_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + return op_norm2est::norm2est(X.get_ref(), tolerance, max_iter); + } + + + +template +arma_warn_unused +inline +typename T1::pod_type +norm2est + ( + const SpBase& X, + const typename T1::pod_type tolerance = 0, + const uword max_iter = 100, + const typename arma_real_or_cx_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + return op_norm2est::norm2est(X.get_ref(), tolerance, max_iter); + } + + //! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normpdf.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_normpdf.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_normpdf.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_normpdf.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -92,8 +92,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), eT >::result normpdf(const eT x) { @@ -105,8 +105,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), eT >::result normpdf(const eT x, const eT mu, const eT sigma) { @@ -120,8 +120,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result normpdf(const eT x, const Base& M_expr, const Base& S_expr) { @@ -140,8 +140,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result normpdf(const Base& X_expr) { @@ -162,8 +162,8 @@ template -inline arma_warn_unused +inline 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) { @@ -184,8 +184,8 @@ template -inline arma_warn_unused +inline typename enable_if2< (is_real::value), Mat >::result normpdf(const Base& X_expr, const Base& M_expr, const Base& S_expr) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_ones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_ones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_ones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_ones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -43,14 +43,10 @@ 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); } @@ -88,15 +84,8 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - if(is_Col::value) - { - arma_debug_check( (n_cols != 1), "ones(): incompatible size" ); - } - else - if(is_Row::value) - { - arma_debug_check( (n_rows != 1), "ones(): incompatible size" ); - } + if(is_Col::value) { arma_debug_check( (n_cols != 1), "ones(): incompatible size" ); } + if(is_Row::value) { arma_debug_check( (n_rows != 1), "ones(): incompatible size" ); } return Gen(n_rows, n_cols); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_pinv.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_pinv.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_pinv.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_pinv.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -24,11 +24,27 @@ template arma_warn_unused inline +typename enable_if2< is_real::value, const Op >::result +pinv + ( + const Base& X + ) + { + arma_extra_debug_sigprint(); + + return Op(X.get_ref()); + } + + + +template +arma_warn_unused +inline typename enable_if2< is_real::value, const Op >::result pinv ( const Base& X, - const typename T1::pod_type tol = 0.0, + const typename T1::pod_type tol, const char* method = nullptr ) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_powext.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_powext.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_powext.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_powext.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,179 @@ +// 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_powext +//! @{ + + + +template +arma_warn_unused +arma_inline +typename +enable_if2 + < + is_arma_type::value, + const Glue + >::result +pow + ( + const T1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + return Glue(X, Y.get_ref()); + } + + + +template +arma_warn_unused +inline +Mat +pow + ( + const subview_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + return glue_powext::apply(X,Y); + } + + + +template +arma_warn_unused +arma_inline +const GlueCube +pow + ( + const BaseCube& X, + const BaseCube& Y + ) + { + arma_extra_debug_sigprint(); + + return GlueCube(X.get_ref(), Y.get_ref()); + } + + + +template +arma_warn_unused +inline +Cube +pow + ( + const subview_cube_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + return glue_powext::apply(X,Y); + } + + + +// + + + +template +arma_warn_unused +arma_inline +typename +enable_if2 + < + ( is_arma_type::value && is_cx::yes ), + const mtGlue + >::result +pow + ( + const T1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + return mtGlue(X, Y.get_ref()); + } + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_cx::yes, + Mat + >::result +pow + ( + const subview_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + return glue_powext_cx::apply(X,Y); + } + + + +template +arma_warn_unused +arma_inline +const mtGlueCube +pow + ( + const BaseCube< std::complex, T1>& X, + const BaseCube< typename T1::pod_type , T2>& Y + ) + { + arma_extra_debug_sigprint(); + + return mtGlueCube(X.get_ref(), Y.get_ref()); + } + + + +template +arma_warn_unused +inline +Cube< std::complex > +pow + ( + const subview_cube_each1< std::complex >& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + return glue_powext_cx::apply(X,Y); + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randg.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randg.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randg.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randg.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -42,29 +42,14 @@ arma_debug_check( (n_rows != 1), "randg(): incompatible size" ); } - obj_type out(n_rows, n_cols, arma_nozeros_indicator()); + double a = double(1); + double b = double(1); - double a; - double b; + param.get_double_vals(a,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(): incorrect distribution parameters; a and b must be greater than zero" ); - arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): a and b must be greater than zero" ); + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); arma_rng::randg::fill(out.memptr(), out.n_elem, a, b); @@ -148,7 +133,18 @@ { arma_extra_debug_sigprint(); - return as_scalar( randg(uword(1), uword(1), param) ); + double a = double(1); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); + + double out_val = double(0); + + arma_rng::randg::fill(&out_val, uword(1), a, b); + + return out_val; } @@ -159,7 +155,20 @@ typename arma_real_or_cx_only::result randg(const distr_param& param = distr_param()) { - return eT( as_scalar( randg< Col >(uword(1), uword(1), param) ) ); + arma_extra_debug_sigprint(); + + double a = double(1); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); + + eT out_val = eT(0); + + arma_rng::randg::fill(&out_val, uword(1), a, b); + + return out_val; } @@ -175,29 +184,14 @@ typedef typename cube_type::elem_type eT; - cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); + double a = double(1); + double b = double(1); - double a; - double b; + param.get_double_vals(a,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(): incorrect distribution parameters; a and b must be greater than zero" ); - arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): a and b must be greater than zero" ); + cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); arma_rng::randg::fill(out.memptr(), out.n_elem, a, b); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randi.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randi.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randi.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randi.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -42,29 +42,14 @@ arma_debug_check( (n_rows != 1), "randi(): incompatible size" ); } - obj_type out(n_rows, n_cols, arma_nozeros_indicator()); + int a = 0; + int b = arma_rng::randi::max_val(); - int a; - int b; + param.get_int_vals(a,b); - if(param.state == 0) - { - a = 0; - b = arma_rng::randi::max_val(); - } - else - if(param.state == 1) - { - a = param.a_int; - b = param.b_int; - } - else - { - a = int(param.a_double); - b = int(param.b_double); - } + arma_debug_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" ); - arma_debug_check( (a > b), "randi(): incorrect distribution parameters: a must be less than b" ); + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); arma_rng::randi::fill(out.memptr(), out.n_elem, a, b); @@ -150,7 +135,20 @@ sword randi(const distr_param& param) { - return as_scalar( randi(uword(1), uword(1), param) ); + arma_extra_debug_sigprint(); + + int a = 0; + int b = arma_rng::randi::max_val(); + + param.get_int_vals(a,b); + + arma_debug_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" ); + + sword out_val = sword(0); + + arma_rng::randi::fill(&out_val, uword(1), a, b); + + return out_val; } @@ -161,7 +159,20 @@ typename arma_scalar_only::result randi(const distr_param& param) { - return eT( as_scalar( randi< Col >(uword(1), uword(1), param) ) ); + arma_extra_debug_sigprint(); + + int a = 0; + int b = arma_rng::randi::max_val(); + + param.get_int_vals(a,b); + + arma_debug_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" ); + + eT out_val = eT(0); + + arma_rng::randi::fill(&out_val, uword(1), a, b); + + return out_val; } @@ -171,6 +182,8 @@ sword randi() { + arma_extra_debug_sigprint(); + return sword( arma_rng::randi() ); } @@ -182,6 +195,8 @@ typename arma_scalar_only::result randi() { + arma_extra_debug_sigprint(); + return eT( arma_rng::randi() ); } @@ -198,29 +213,14 @@ typedef typename cube_type::elem_type eT; - cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); + int a = 0; + int b = arma_rng::randi::max_val(); - int a; - int b; + param.get_int_vals(a,b); - if(param.state == 0) - { - a = 0; - b = arma_rng::randi::max_val(); - } - else - if(param.state == 1) - { - a = param.a_int; - b = param.b_int; - } - else - { - a = int(param.a_double); - b = int(param.b_double); - } + arma_debug_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" ); - arma_debug_check( (a > b), "randi(): incorrect distribution parameters: a must be less than b" ); + cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); arma_rng::randi::fill(out.memptr(), out.n_elem, a, b); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randn.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randn.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randn.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randn.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,11 +21,15 @@ +// scalars + arma_warn_unused inline double randn() { + arma_extra_debug_sigprint(); + return double(arma_rng::randn()); } @@ -37,153 +41,315 @@ typename arma_real_or_cx_only::result randn() { + arma_extra_debug_sigprint(); + return eT(arma_rng::randn()); } -//! Generate a vector with all elements set to random values with a gaussian distribution (zero mean, unit variance) arma_warn_unused -arma_inline -const Gen -randn(const uword n_elem) +inline +double +randn(const distr_param& param) { arma_extra_debug_sigprint(); - return Gen(n_elem, 1); + if(param.state == 0) { return double(arma_rng::randn()); } + + double mu = double(0); + double sd = double(1); + + param.get_double_vals(mu,sd); + + arma_debug_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + + const double val = double(arma_rng::randn()); + + return ((val * sd) + mu); + } + + + +template +arma_warn_unused +inline +typename arma_real_or_cx_only::result +randn(const distr_param& param) + { + arma_extra_debug_sigprint(); + + if(param.state == 0) { return eT(arma_rng::randn()); } + + double mu = double(0); + double sd = double(1); + + param.get_double_vals(mu,sd); + + arma_debug_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + + eT val = eT(0); + + arma_rng::randn::fill(&val, 1, mu, sd); // using fill() as eT can be complex + + return val; + } + + + +// vectors + +arma_warn_unused +inline +vec +randn(const uword n_elem, const distr_param& param = distr_param()) + { + arma_extra_debug_sigprint(); + + vec out(n_elem, arma_nozeros_indicator()); + + if(param.state == 0) + { + arma_rng::randn::fill(out.memptr(), n_elem); + } + else + { + double mu = double(0); + double sd = double(1); + + param.get_double_vals(mu,sd); + + arma_debug_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + + arma_rng::randn::fill(out.memptr(), n_elem, mu, sd); + } + + return out; } template 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 = nullptr) +inline +obj_type +randn(const uword n_elem, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); - arma_ignore(junk1); - arma_ignore(junk2); + arma_ignore(junk); + + typedef typename obj_type::elem_type eT; 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); + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); + + if(param.state == 0) + { + arma_rng::randn::fill(out.memptr(), out.n_elem); + } + else + { + double mu = double(0); + double sd = double(1); + + param.get_double_vals(mu,sd); + + arma_debug_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + + arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); + } + + return out; } -//! Generate a dense matrix with all elements set to random values with a gaussian distribution (zero mean, unit variance) +// matrices + arma_warn_unused -arma_inline -const Gen -randn(const uword n_rows, const uword n_cols) +inline +mat +randn(const uword n_rows, const uword n_cols, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return Gen(n_rows, n_cols); + mat out(n_rows, n_cols, arma_nozeros_indicator()); + + if(param.state == 0) + { + arma_rng::randn::fill(out.memptr(), out.n_elem); + } + else + { + double mu = double(0); + double sd = double(1); + + param.get_double_vals(mu,sd); + + arma_debug_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + + arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); + } + + return out; } arma_warn_unused -arma_inline -const Gen -randn(const SizeMat& s) +inline +mat +randn(const SizeMat& s, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return Gen(s.n_rows, s.n_cols); + return randn(s.n_rows, s.n_cols, param); } template 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 = nullptr) +inline +obj_type +randn(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(is_Col::value) + typedef typename obj_type::elem_type eT; + + if(is_Col::value) { arma_debug_check( (n_cols != 1), "randn(): incompatible size" ); } + if(is_Row::value) { arma_debug_check( (n_rows != 1), "randn(): incompatible size" ); } + + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); + + if(param.state == 0) { - arma_debug_check( (n_cols != 1), "randn(): incompatible size" ); + arma_rng::randn::fill(out.memptr(), out.n_elem); } else - if(is_Row::value) { - arma_debug_check( (n_rows != 1), "randn(): incompatible size" ); + double mu = double(0); + double sd = double(1); + + param.get_double_vals(mu,sd); + + arma_debug_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + + arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); } - return Gen(n_rows, n_cols); + return out; } template arma_warn_unused -arma_inline -const Gen -randn(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = nullptr) +inline +obj_type +randn(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); - return randn(s.n_rows, s.n_cols); + return randn(s.n_rows, s.n_cols, param); } +// cubes + + arma_warn_unused -arma_inline -const GenCube -randn(const uword n_rows, const uword n_cols, const uword n_slices) +inline +cube +randn(const uword n_rows, const uword n_cols, const uword n_slices, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return GenCube(n_rows, n_cols, n_slices); + cube out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); + + if(param.state == 0) + { + arma_rng::randn::fill(out.memptr(), out.n_elem); + } + else + { + double mu = double(0); + double sd = double(1); + + param.get_double_vals(mu,sd); + + arma_debug_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + + arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); + } + + return out; } arma_warn_unused -arma_inline -const GenCube -randn(const SizeCube& s) +inline +cube +randn(const SizeCube& s, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return GenCube(s.n_rows, s.n_cols, s.n_slices); + return randn(s.n_rows, s.n_cols, s.n_slices, param); } template 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 = nullptr) +inline +cube_type +randn(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_extra_debug_sigprint(); arma_ignore(junk); - return GenCube(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()); + + if(param.state == 0) + { + arma_rng::randn::fill(out.memptr(), out.n_elem); + } + else + { + double mu = double(0); + double sd = double(1); + + param.get_double_vals(mu,sd); + + arma_debug_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + + arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); + } + + return out; } template arma_warn_unused -arma_inline -const GenCube -randn(const SizeCube& s, const typename arma_Cube_only::result* junk = nullptr) +inline +cube_type +randn(const SizeCube& s, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = nullptr) { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint(); arma_ignore(junk); - return GenCube(s.n_rows, s.n_cols, s.n_slices); + return randn(s.n_rows, s.n_cols, s.n_slices, param); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randperm.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randperm.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randperm.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randperm.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -31,6 +31,7 @@ typedef typename obj_type::elem_type eT; // see op_sort_index_bones.hpp for the definition of arma_sort_index_packet + // and the associated comparison functor typedef arma_sort_index_packet packet; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randu.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randu.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_randu.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_randu.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,11 +21,15 @@ +// scalars + arma_warn_unused inline double randu() { + arma_extra_debug_sigprint(); + return double(arma_rng::randu()); } @@ -37,153 +41,315 @@ typename arma_real_or_cx_only::result randu() { + arma_extra_debug_sigprint(); + return eT(arma_rng::randu()); } -//! Generate a vector with all elements set to random values in the [0,1] interval (uniform distribution) arma_warn_unused -arma_inline -const Gen -randu(const uword n_elem) +inline +double +randu(const distr_param& param) + { + arma_extra_debug_sigprint(); + + if(param.state == 0) { return double(arma_rng::randu()); } + + double a = double(0); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + + const double val = double(arma_rng::randu()); + + return ((val * (b - a)) + a); + } + + + +template +arma_warn_unused +inline +typename arma_real_or_cx_only::result +randu(const distr_param& param) + { + arma_extra_debug_sigprint(); + + if(param.state == 0) { return eT(arma_rng::randu()); } + + double a = double(0); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + + eT val = eT(0); + + arma_rng::randu::fill(&val, 1, a, b); // using fill() as eT can be complex + + return val; + } + + + +// vectors + +arma_warn_unused +inline +vec +randu(const uword n_elem, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return Gen(n_elem, 1); + vec out(n_elem, arma_nozeros_indicator()); + + if(param.state == 0) + { + arma_rng::randu::fill(out.memptr(), n_elem); + } + else + { + double a = double(0); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + + arma_rng::randu::fill(out.memptr(), n_elem, a, b); + } + + return out; } template 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 = nullptr) +inline +obj_type +randu(const uword n_elem, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only::result* junk = nullptr) { arma_extra_debug_sigprint(); - arma_ignore(junk1); - arma_ignore(junk2); + arma_ignore(junk); + + typedef typename obj_type::elem_type eT; 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); + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); + + if(param.state == 0) + { + arma_rng::randu::fill(out.memptr(), out.n_elem); + } + else + { + double a = double(0); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + + arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); + } + + return out; } -//! Generate a dense matrix with all elements set to random values in the [0,1] interval (uniform distribution) +// matrices + arma_warn_unused -arma_inline -const Gen -randu(const uword n_rows, const uword n_cols) +inline +mat +randu(const uword n_rows, const uword n_cols, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return Gen(n_rows, n_cols); + mat out(n_rows, n_cols, arma_nozeros_indicator()); + + if(param.state == 0) + { + arma_rng::randu::fill(out.memptr(), out.n_elem); + } + else + { + double a = double(0); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + + arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); + } + + return out; } arma_warn_unused -arma_inline -const Gen -randu(const SizeMat& s) +inline +mat +randu(const SizeMat& s, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return Gen(s.n_rows, s.n_cols); + return randu(s.n_rows, s.n_cols, param); } template 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 = nullptr) +inline +obj_type +randu(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(is_Col::value) + typedef typename obj_type::elem_type eT; + + if(is_Col::value) { arma_debug_check( (n_cols != 1), "randu(): incompatible size" ); } + if(is_Row::value) { arma_debug_check( (n_rows != 1), "randu(): incompatible size" ); } + + obj_type out(n_rows, n_cols, arma_nozeros_indicator()); + + if(param.state == 0) { - arma_debug_check( (n_cols != 1), "randu(): incompatible size" ); + arma_rng::randu::fill(out.memptr(), out.n_elem); } else - if(is_Row::value) { - arma_debug_check( (n_rows != 1), "randu(): incompatible size" ); + double a = double(0); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + + arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); } - return Gen(n_rows, n_cols); + return out; } template arma_warn_unused -arma_inline -const Gen -randu(const SizeMat& s, const typename arma_Mat_Col_Row_only::result* junk = nullptr) +inline +obj_type +randu(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); - return randu(s.n_rows, s.n_cols); + return randu(s.n_rows, s.n_cols, param); } +// cubes + + arma_warn_unused -arma_inline -const GenCube -randu(const uword n_rows, const uword n_cols, const uword n_slices) +inline +cube +randu(const uword n_rows, const uword n_cols, const uword n_slices, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return GenCube(n_rows, n_cols, n_slices); + cube out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); + + if(param.state == 0) + { + arma_rng::randu::fill(out.memptr(), out.n_elem); + } + else + { + double a = double(0); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + + arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); + } + + return out; } arma_warn_unused -arma_inline -const GenCube -randu(const SizeCube& s) +inline +cube +randu(const SizeCube& s, const distr_param& param = distr_param()) { arma_extra_debug_sigprint(); - return GenCube(s.n_rows, s.n_cols, s.n_slices); + return randu(s.n_rows, s.n_cols, s.n_slices, param); } template 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 = nullptr) +inline +cube_type +randu(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); - return GenCube(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()); + + if(param.state == 0) + { + arma_rng::randu::fill(out.memptr(), out.n_elem); + } + else + { + double a = double(0); + double b = double(1); + + param.get_double_vals(a,b); + + arma_debug_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + + arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); + } + + return out; } template arma_warn_unused -arma_inline -const GenCube -randu(const SizeCube& s, const typename arma_Cube_only::result* junk = nullptr) +inline +cube_type +randu(const SizeCube& s, const distr_param& param = distr_param(), const typename arma_Cube_only::result* junk = nullptr) { arma_extra_debug_sigprint(); arma_ignore(junk); - return GenCube(s.n_rows, s.n_cols, s.n_slices); + return randu(s.n_rows, s.n_cols, s.n_slices, param); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_reshape.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_reshape.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_reshape.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_reshape.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -47,20 +47,38 @@ -//! NOTE: don't use this form: it will be removed template -arma_deprecated +arma_frown("don't use this form: it will be removed") inline -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 +Mat +reshape(const Base& X, const uword new_n_rows, const uword new_n_cols, const uword dim) { arma_extra_debug_sigprint(); - // arma_debug_warn_level(1, "this form of reshape() is deprecated and will be removed"); + typedef typename T1::elem_type eT; arma_debug_check( (dim > 1), "reshape(): parameter 'dim' must be 0 or 1" ); - return Op(X.get_ref(), new_n_rows, new_n_cols, dim, 'j'); + const quasi_unwrap U(X.get_ref()); + const Mat& A = U.M; + + Mat out; + + if(dim == 0) + { + op_reshape::apply_mat_noalias(out, A, new_n_rows, new_n_cols); + } + else + if(dim == 1) + { + Mat tmp; + + op_strans::apply_mat_noalias(tmp, A); + + op_reshape::apply_mat_noalias(out, tmp, new_n_rows, new_n_cols); + } + + return out; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_shift.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_shift.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_shift.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_shift.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -41,19 +41,19 @@ const uword len = (N < 0) ? uword(-N) : uword(N); const uword neg = (N < 0) ? uword( 1) : uword(0); - return Op(X, len, neg, uword(0), 'j'); + return Op(X, len, neg); } template arma_warn_unused -arma_inline +inline typename enable_if2 < is_arma_type::value && resolves_to_vector::no, - const Op + Mat >::result shift ( @@ -63,22 +63,30 @@ { arma_extra_debug_sigprint(); + typedef typename T1::elem_type eT; + const uword len = (N < 0) ? uword(-N) : uword(N); const uword neg = (N < 0) ? uword( 1) : uword(0); - return Op(X, len, neg, uword(0), 'j'); + quasi_unwrap U(X); + + Mat out; + + op_shift::apply_noalias(out, U.M, len, neg, 0); + + return out; } template arma_warn_unused -arma_inline +inline typename enable_if2 < (is_arma_type::value), - const Op + Mat >::result shift ( @@ -89,10 +97,20 @@ { arma_extra_debug_sigprint(); + typedef typename T1::elem_type eT; + + arma_debug_check( (dim > 1), "shift(): parameter 'dim' must be 0 or 1" ); + const uword len = (N < 0) ? uword(-N) : uword(N); const uword neg = (N < 0) ? uword( 1) : uword(0); - return Op(X, len, neg, dim, 'j'); + quasi_unwrap U(X); + + Mat out; + + op_shift::apply_noalias(out, U.M, len, neg, dim); + + return out; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_solve.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_solve.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_solve.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_solve.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -28,17 +28,59 @@ template arma_warn_unused inline -typename enable_if2< is_supported_blas_type::value, const Glue >::result +typename enable_if2< is_supported_blas_type::value, const Glue >::result +solve + ( + const Base& A, + const Base& B + ) + { + arma_extra_debug_sigprint(); + + return Glue(A.get_ref(), B.get_ref()); + } + + + +template +inline +typename enable_if2< is_supported_blas_type::value, bool >::result +solve + ( + Mat& out, + const Base& A, + const Base& B + ) + { + arma_extra_debug_sigprint(); + + const bool status = glue_solve_gen_default::apply(out, A.get_ref(), B.get_ref()); + + if(status == false) + { + out.soft_reset(); + arma_debug_warn_level(3, "solve(): solution not found"); + } + + return status; + } + + + +template +arma_warn_unused +inline +typename enable_if2< is_supported_blas_type::value, const Glue >::result solve ( const Base& A, const Base& B, - const solve_opts::opts& opts = solve_opts::none + const solve_opts::opts& opts ) { arma_extra_debug_sigprint(); - return Glue(A.get_ref(), B.get_ref(), opts.flags); + return Glue(A.get_ref(), B.get_ref(), opts.flags); } @@ -51,12 +93,12 @@ Mat& out, const Base& A, const Base& B, - const solve_opts::opts& opts = solve_opts::none + const solve_opts::opts& opts ) { arma_extra_debug_sigprint(); - const bool status = glue_solve_gen::apply(out, A.get_ref(), B.get_ref(), opts.flags); + const bool status = glue_solve_gen_full::apply(out, A.get_ref(), B.get_ref(), opts.flags); if(status == false) { @@ -98,7 +140,7 @@ template arma_warn_unused inline -typename enable_if2< is_supported_blas_type::value, const Glue >::result +typename enable_if2< is_supported_blas_type::value, const Glue >::result solve ( const Op& A, @@ -113,7 +155,7 @@ 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); + return Glue(A.m, B.get_ref(), flags); } @@ -166,7 +208,7 @@ if(A.aux_uword_a == 0) { flags |= solve_opts::flag_triu; } if(A.aux_uword_a == 1) { flags |= solve_opts::flag_tril; } - const bool status = glue_solve_tri::apply(out, A.m, B.get_ref(), flags); + const bool status = glue_solve_tri_full::apply(out, A.m, B.get_ref(), flags); if(status == false) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_speye.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_speye.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_speye.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_speye.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -31,15 +31,8 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - if(is_SpCol::value) - { - arma_debug_check( (n_cols != 1), "speye(): incompatible size" ); - } - else - if(is_SpRow::value) - { - arma_debug_check( (n_rows != 1), "speye(): incompatible size" ); - } + if(is_SpCol::value) { arma_debug_check( (n_cols != 1), "speye(): incompatible size" ); } + if(is_SpRow::value) { arma_debug_check( (n_rows != 1), "speye(): incompatible size" ); } obj_type out; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_spsolve.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_spsolve.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_spsolve.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_spsolve.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -19,8 +19,7 @@ //! \addtogroup fn_spsolve //! @{ -//! 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 inline @@ -30,8 +29,8 @@ Mat& out, const SpBase& A, const Base& B, - const char* solver, - const spsolve_opts_base& settings, + const char* solver, + const spsolve_opts_base& settings, const typename arma_blas_type_only::result* junk = nullptr ) { @@ -104,7 +103,7 @@ if(opts.equilibrate == true ) { flags |= solve_opts::flag_equilibrate; } if(opts.allow_ugly == true ) { flags |= solve_opts::flag_allow_ugly; } - status = glue_solve_gen::apply(out, AA, B.get_ref(), flags); + status = glue_solve_gen_full::apply(out, AA, B.get_ref(), flags); } } @@ -114,7 +113,7 @@ arma_debug_warn_level(2, "spsolve(): system is singular (rcond: ", rcond, ")"); } - if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(out)) ) + if( (status == true) && (rcond > T(0)) && (rcond < std::numeric_limits::epsilon()) ) { arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); } @@ -124,6 +123,10 @@ +// + + + template inline bool @@ -132,8 +135,8 @@ Mat& out, const SpBase& A, const Base& B, - const char* solver = "superlu", - const spsolve_opts_base& settings = spsolve_opts_none(), + const char* solver = "superlu", + const spsolve_opts_base& settings = spsolve_opts_none(), const typename arma_blas_type_only::result* junk = nullptr ) { @@ -161,8 +164,8 @@ ( const SpBase& A, const Base& B, - const char* solver = "superlu", - const spsolve_opts_base& settings = spsolve_opts_none(), + const char* solver = "superlu", + const spsolve_opts_base& settings = spsolve_opts_none(), const typename arma_blas_type_only::result* junk = nullptr ) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_stddev.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_stddev.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_stddev.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_stddev.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -33,7 +33,7 @@ stddev(const T1& X, const uword norm_type = 0) { arma_extra_debug_sigprint(); - + return std::sqrt( op_var::var_vec(X, norm_type) ); } @@ -51,7 +51,7 @@ stddev(const T1& X, const uword norm_type = 0) { arma_extra_debug_sigprint(); - + return mtOp(X, norm_type, 0); } @@ -69,7 +69,7 @@ stddev(const T1& X, const uword norm_type, const uword dim) { arma_extra_debug_sigprint(); - + return mtOp(X, norm_type, dim); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trace.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_trace.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_trace.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_trace.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -102,10 +102,7 @@ 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) ) - { - return eT(0); - } + if( (A.n_elem == 0) || (B.n_elem == 0) ) { return eT(0); } const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; @@ -224,10 +221,7 @@ 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) ) - { - return eT(0); - } + if( (A.n_elem == 0) || (B.n_elem == 0) ) { return eT(0); } const uword A_n_rows = A.n_rows; const uword A_n_cols = A.n_cols; @@ -516,10 +510,7 @@ arma_debug_assert_mul_size(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); - if( (A.n_nonzero == 0) || (B.n_nonzero == 0) ) - { - return eT(0); - } + if( (A.n_nonzero == 0) || (B.n_nonzero == 0) ) { return eT(0); } const uword N = (std::min)(A.n_rows, B.n_cols); @@ -576,10 +567,7 @@ // NOTE: deliberately swapped A.n_rows and A.n_cols to take into account the requested transpose operation arma_debug_assert_mul_size(A.n_cols, A.n_rows, B.n_rows, B.n_cols, "matrix multiplication"); - if( (A.n_nonzero == 0) || (B.n_nonzero == 0) ) - { - return eT(0); - } + if( (A.n_nonzero == 0) || (B.n_nonzero == 0) ) { return eT(0); } const uword N = (std::min)(A.n_cols, B.n_cols); @@ -635,10 +623,7 @@ // NOTE: deliberately swapped A.n_rows and A.n_cols to take into account the requested transpose operation arma_debug_assert_mul_size(A.n_cols, A.n_rows, B.n_rows, B.n_cols, "matrix multiplication"); - if( (A.n_nonzero == 0) || (B.n_nonzero == 0) ) - { - return eT(0); - } + if( (A.n_nonzero == 0) || (B.n_nonzero == 0) ) { return eT(0); } const uword N = (std::min)(A.n_cols, B.n_cols); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_var.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_var.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_var.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_var.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -33,7 +33,7 @@ var(const T1& X, const uword norm_type = 0) { arma_extra_debug_sigprint(); - + return op_var::var_vec(X, norm_type); } @@ -51,7 +51,7 @@ var(const T1& X, const uword norm_type = 0) { arma_extra_debug_sigprint(); - + return mtOp(X, norm_type, 0); } @@ -69,7 +69,7 @@ var(const T1& X, const uword norm_type, const uword dim) { arma_extra_debug_sigprint(); - + return mtOp(X, norm_type, dim); } @@ -98,7 +98,7 @@ var(const T1& X, const uword norm_type = 0) { arma_extra_debug_sigprint(); - + return spop_var::var_vec(X, norm_type); } @@ -116,7 +116,7 @@ var(const T1& X, const uword norm_type = 0) { arma_extra_debug_sigprint(); - + return mtSpOp(X, norm_type, 0); } @@ -134,7 +134,7 @@ var(const T1& X, const uword norm_type, const uword dim) { arma_extra_debug_sigprint(); - + return mtSpOp(X, norm_type, dim); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_vecnorm.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_vecnorm.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_vecnorm.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_vecnorm.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,385 @@ +// 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_vecnorm +//! @{ + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_type::value && resolves_to_vector::yes, + typename T1::pod_type + >::result +vecnorm + ( + const T1& X, + const uword k = uword(2), + const arma_empty_class junk1 = arma_empty_class(), + const typename arma_real_or_cx_only::result* junk2 = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + typedef typename T1::pod_type T; + + const Proxy P(X); + + if(P.get_n_elem() == 0) { return T(0); } + + 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), "vecnorm(): unsupported vector norm type" ); + + return op_norm::vec_norm_k(P, int(k)); + } + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_type::value && resolves_to_vector::no, + const mtOp + >::result +vecnorm + ( + const T1& X, + const uword k = uword(2), + const arma_empty_class junk1 = arma_empty_class(), + const typename arma_real_or_cx_only::result* junk2 = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + const uword dim = 0; + + return mtOp(X, k, dim); + } + + + +template +arma_warn_unused +inline +const mtOp +vecnorm + ( + const Base& X, + const uword k, + const uword dim, + const typename arma_real_or_cx_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + return mtOp(X.get_ref(), k, dim); + } + + + +// + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_type::value && resolves_to_vector::yes, + typename T1::pod_type + >::result +vecnorm + ( + const T1& X, + const char* method, + const arma_empty_class junk1 = arma_empty_class(), + const typename arma_real_or_cx_only::result* junk2 = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + typedef typename T1::pod_type T; + + const Proxy P(X); + + if(P.get_n_elem() == 0) { return T(0); } + + const char sig = (method != nullptr) ? method[0] : char(0); + + if( (sig == 'i') || (sig == 'I') || (sig == '+') ) { return op_norm::vec_norm_max(P); } + if( (sig == '-') ) { return op_norm::vec_norm_min(P); } + + arma_stop_logic_error("vecnorm(): unsupported vector norm type"); + + return T(0); + } + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_type::value && resolves_to_vector::no, + const mtOp + >::result +vecnorm + ( + const T1& X, + const char* method, + const arma_empty_class junk1 = arma_empty_class(), + const typename arma_real_or_cx_only::result* junk2 = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + const char sig = (method != nullptr) ? method[0] : char(0); + + uword method_id = 0; + + if( (sig == 'i') || (sig == 'I') || (sig == '+') ) { method_id = 1; } + if( (sig == '-') ) { method_id = 2; } + + const uword dim = 0; + + return mtOp(X, method_id, dim); + } + + + +template +arma_warn_unused +inline +const mtOp +vecnorm + ( + const Base& X, + const char* method, + const uword dim, + const typename arma_real_or_cx_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + const char sig = (method != nullptr) ? method[0] : char(0); + + uword method_id = 0; + + if( (sig == 'i') || (sig == 'I') || (sig == '+') ) { method_id = 1; } + if( (sig == '-') ) { method_id = 2; } + + return mtOp(X.get_ref(), method_id, dim); + } + + + +// +// norms for sparse matrices + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_sparse_type::value && resolves_to_sparse_vector::yes, + typename T1::pod_type + >::result +vecnorm + ( + const T1& X, + const uword k = uword(2), + const arma_empty_class junk1 = arma_empty_class(), + const typename arma_real_or_cx_only::result* junk2 = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + return arma::norm(X, k); + } + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_sparse_type::value && resolves_to_sparse_vector::no, + const mtSpOp + >::result +vecnorm + ( + const T1& X, + const uword k = uword(2), + const arma_empty_class junk1 = arma_empty_class(), + const typename arma_real_or_cx_only::result* junk2 = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + const uword dim = 0; + + return mtSpOp(X, k, dim); + } + + + +template +arma_warn_unused +inline +const mtSpOp +vecnorm + ( + const SpBase& X, + const uword k, + const uword dim, + const typename arma_real_or_cx_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + return mtSpOp(X.get_ref(), k, dim); + } + + + +// + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_sparse_type::value && resolves_to_sparse_vector::yes, + typename T1::pod_type + >::result +vecnorm + ( + const T1& X, + const char* method, + const arma_empty_class junk1 = arma_empty_class(), + const typename arma_real_or_cx_only::result* junk2 = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + return arma::norm(X, method); + } + + + +template +arma_warn_unused +inline +typename +enable_if2 + < + is_arma_sparse_type::value && resolves_to_sparse_vector::no, + const mtSpOp + >::result +vecnorm + ( + const T1& X, + const char* method, + const arma_empty_class junk1 = arma_empty_class(), + const typename arma_real_or_cx_only::result* junk2 = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + const char sig = (method != nullptr) ? method[0] : char(0); + + uword method_id = 0; + + if( (sig == 'i') || (sig == 'I') || (sig == '+') ) { method_id = 1; } + if( (sig == '-') ) { method_id = 2; } + + const uword dim = 0; + + return mtSpOp(X, method_id, dim); + } + + + +template +arma_warn_unused +inline +const mtSpOp +vecnorm + ( + const SpBase& X, + const char* method, + const uword dim, + const typename arma_real_or_cx_only::result* junk = nullptr + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + const char sig = (method != nullptr) ? method[0] : char(0); + + uword method_id = 0; + + if( (sig == 'i') || (sig == 'I') || (sig == '+') ) { method_id = 1; } + if( (sig == '-') ) { method_id = 2; } + + return mtSpOp(X.get_ref(), method_id, dim); + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/fn_zeros.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/fn_zeros.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/fn_zeros.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/fn_zeros.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -43,14 +43,10 @@ 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); } @@ -88,15 +84,8 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - if(is_Col::value) - { - arma_debug_check( (n_cols != 1), "zeros(): incompatible size" ); - } - else - if(is_Row::value) - { - arma_debug_check( (n_rows != 1), "zeros(): incompatible size" ); - } + if(is_Col::value) { arma_debug_check( (n_cols != 1), "zeros(): incompatible size" ); } + if(is_Row::value) { arma_debug_check( (n_rows != 1), "zeros(): incompatible size" ); } return Gen(n_rows, n_cols); } @@ -178,15 +167,8 @@ arma_extra_debug_sigprint(); arma_ignore(junk); - if(is_SpCol::value) - { - arma_debug_check( (n_cols != 1), "zeros(): incompatible size" ); - } - else - if(is_SpRow::value) - { - arma_debug_check( (n_rows != 1), "zeros(): incompatible size" ); - } + if(is_SpCol::value) { arma_debug_check( (n_cols != 1), "zeros(): incompatible size" ); } + if(is_SpRow::value) { arma_debug_check( (n_rows != 1), "zeros(): incompatible size" ); } return sp_obj_type(n_rows, n_cols); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Gen_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Gen_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Gen_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Gen_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -20,11 +20,10 @@ //! @{ -//! support class for generator functions (eg. zeros, randu, randn, ...) +//! support class for generator functions (zeros, ones, eye) template class Gen : public Base< typename T1::elem_type, Gen > - , public GenSpecialiser::yes, is_same_type::yes, is_same_type::yes, is_same_type::yes> { public: @@ -32,7 +31,7 @@ typedef typename get_pod_type::result pod_type; static constexpr bool use_at = (is_same_type::value); - static constexpr bool is_simple = (is_same_type::value) || (is_same_type::value); + static constexpr bool is_simple = (is_same_type::value) || (is_same_type::value); static constexpr bool is_row = T1::is_row; static constexpr bool is_col = T1::is_col; @@ -44,9 +43,9 @@ arma_inline Gen(const uword in_n_rows, const uword in_n_cols); arma_inline ~Gen(); - arma_inline elem_type operator[] (const uword ii) const; - arma_inline elem_type at (const uword row, const uword col) const; - arma_inline elem_type at_alt (const uword ii) const; + arma_inline elem_type operator[] (const uword ii) const; + arma_inline elem_type at (const uword r, const uword c) const; + arma_inline elem_type at_alt (const uword ii) const; inline void apply (Mat& out) const; inline void apply_inplace_plus (Mat& out) const; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/GenCube_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/GenCube_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/GenCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/GenCube_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -20,11 +20,10 @@ //! @{ -//! support class for generator functions (eg. zeros, randu, randn, ...) +//! support class for generator functions (zeros, ones) template class GenCube : public BaseCube< eT, GenCube > - , public GenSpecialiser::yes, is_same_type::yes, is_same_type::yes, is_same_type::yes> { public: @@ -32,7 +31,7 @@ typedef typename get_pod_type::result pod_type; static constexpr bool use_at = false; - static constexpr bool is_simple = (is_same_type::value) || (is_same_type::value); + 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; @@ -41,9 +40,9 @@ arma_inline GenCube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices); arma_inline ~GenCube(); - arma_inline eT operator[] (const uword i) const; - arma_inline eT at (const uword row, const uword col, const uword slice) const; - arma_inline eT at_alt (const uword i) const; + arma_inline eT operator[] (const uword i) const; + arma_inline eT at (const uword r, const uword c, const uword s) const; + arma_inline eT at_alt (const uword i) const; inline void apply (Cube& out) const; inline void apply_inplace_plus (Cube& out) const; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/GenCube_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/GenCube_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/GenCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/GenCube_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -47,7 +47,10 @@ eT GenCube::operator[](const uword) const { - return (*this).generate(); + if(is_same_type::yes) { return eT(0); } + else if(is_same_type::yes) { return eT(1); } + + return eT(0); // prevent pedantic compiler warnings } @@ -57,7 +60,10 @@ eT GenCube::at(const uword, const uword, const uword) const { - return (*this).generate(); + if(is_same_type::yes) { return eT(0); } + else if(is_same_type::yes) { return eT(1); } + + return eT(0); // prevent pedantic compiler warnings } @@ -67,7 +73,10 @@ eT GenCube::at_alt(const uword) const { - return (*this).generate(); + if(is_same_type::yes) { return eT(0); } + else if(is_same_type::yes) { return eT(1); } + + return eT(0); // prevent pedantic compiler warnings } @@ -82,10 +91,8 @@ // NOTE: we're assuming that the cube has already been set to the correct size; // this is done by either the Cube contructor or operator=() - if(is_same_type::yes) { out.ones(); } - else if(is_same_type::yes) { out.zeros(); } - else if(is_same_type::yes) { out.randu(); } - else if(is_same_type::yes) { out.randn(); } + if(is_same_type::yes) { out.zeros(); } + else if(is_same_type::yes) { out.ones(); } } @@ -99,24 +106,9 @@ arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "addition"); - - eT* out_mem = out.memptr(); - const uword n_elem = out.n_elem; - - uword i,j; - - for(i=0, j=1; j::yes) { - out_mem[i] += (*this).generate(); + arrayops::inplace_plus(out.memptr(), eT(1), out.n_elem); } } @@ -132,24 +124,9 @@ arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "subtraction"); - - eT* out_mem = out.memptr(); - const uword n_elem = out.n_elem; - - uword i,j; - - for(i=0, j=1; j::yes) { - const eT tmp_i = (*this).generate(); - const eT tmp_j = (*this).generate(); - - out_mem[i] -= tmp_i; - out_mem[j] -= tmp_j; - } - - if(i < n_elem) - { - out_mem[i] -= (*this).generate(); + arrayops::inplace_minus(out.memptr(), eT(1), out.n_elem); } } @@ -165,24 +142,10 @@ arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise multiplication"); - - eT* out_mem = out.memptr(); - const uword n_elem = out.n_elem; - - uword i,j; - - for(i=0, j=1; j::yes) { - out_mem[i] *= (*this).generate(); + arrayops::inplace_mul(out.memptr(), eT(0), out.n_elem); + // NOTE: not using arrayops::fill_zeros(), as 'out' may have NaN elements } } @@ -198,24 +161,9 @@ arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise division"); - - eT* out_mem = out.memptr(); - const uword n_elem = out.n_elem; - - uword i,j; - - for(i=0, j=1; j::yes) { - out_mem[i] /= (*this).generate(); + arrayops::inplace_div(out.memptr(), eT(0), out.n_elem); } } @@ -231,10 +179,8 @@ // NOTE: we're assuming that the subcube has the same dimensions as the GenCube object // this is checked by subview_cube::operator=() - if(is_same_type::yes) { out.ones(); } - else if(is_same_type::yes) { out.zeros(); } - else if(is_same_type::yes) { out.randu(); } - else if(is_same_type::yes) { out.randn(); } + if(is_same_type::yes) { out.zeros(); } + else if(is_same_type::yes) { out.ones(); } } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Gen_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Gen_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Gen_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Gen_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -48,14 +48,11 @@ { typedef typename T1::elem_type eT; - if(is_same_type::yes) - { - return ((ii % n_rows) == (ii / n_rows)) ? eT(1) : eT(0); - } - else - { - return (*this).generate(); - } + if(is_same_type::yes) { return eT(0); } + else if(is_same_type::yes) { return eT(1); } + else if(is_same_type::yes) { return ((ii % n_rows) == (ii / n_rows)) ? eT(1) : eT(0); } + + return eT(0); // prevent pedantic compiler warnings } @@ -63,18 +60,15 @@ template arma_inline typename T1::elem_type -Gen::at(const uword row, const uword col) const +Gen::at(const uword r, const uword c) const { typedef typename T1::elem_type eT; - if(is_same_type::yes) - { - return (row == col) ? eT(1) : eT(0); - } - else - { - return (*this).generate(); - } + if(is_same_type::yes) { return eT(0); } + else if(is_same_type::yes) { return eT(1); } + else if(is_same_type::yes) { return (r == c) ? eT(1) : eT(0); } + + return eT(0); // prevent pedantic compiler warnings } @@ -99,11 +93,9 @@ // NOTE: we're assuming that the matrix has already been set to the correct size; // this is done by either the Mat contructor or operator=() - if(is_same_type::yes) { out.eye(); } + if(is_same_type::yes) { out.zeros(); } else if(is_same_type::yes) { out.ones(); } - else if(is_same_type::yes) { out.zeros(); } - else if(is_same_type::yes) { out.randu(); } - else if(is_same_type::yes) { out.randn(); } + else if(is_same_type::yes) { out.eye(); } } @@ -119,35 +111,16 @@ typedef typename T1::elem_type eT; - - if(is_same_type::yes) + if(is_same_type::yes) { - const uword N = (std::min)(n_rows, n_cols); - - for(uword iq=0; iq < N; ++iq) - { - out.at(iq,iq) += eT(1); - } + arrayops::inplace_plus(out.memptr(), eT(1), out.n_elem); } else + if(is_same_type::yes) { - eT* out_mem = out.memptr(); - const uword n_elem = out.n_elem; - - uword iq,jq; - for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2) - { - const eT tmp_i = (*this).generate(); - const eT tmp_j = (*this).generate(); - - out_mem[iq] += tmp_i; - out_mem[jq] += tmp_j; - } + const uword N = (std::min)(n_rows, n_cols); - if(iq < n_elem) - { - out_mem[iq] += (*this).generate(); - } + for(uword ii=0; ii < N; ++ii) { out.at(ii,ii) += eT(1); } } } @@ -165,35 +138,16 @@ typedef typename T1::elem_type eT; - - if(is_same_type::yes) + if(is_same_type::yes) { - const uword N = (std::min)(n_rows, n_cols); - - for(uword iq=0; iq < N; ++iq) - { - out.at(iq,iq) -= eT(1); - } + arrayops::inplace_minus(out.memptr(), eT(1), out.n_elem); } else + if(is_same_type::yes) { - eT* out_mem = out.memptr(); - const uword n_elem = out.n_elem; - - uword iq,jq; - for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2) - { - const eT tmp_i = (*this).generate(); - const eT tmp_j = (*this).generate(); - - out_mem[iq] -= tmp_i; - out_mem[jq] -= tmp_j; - } + const uword N = (std::min)(n_rows, n_cols); - if(iq < n_elem) - { - out_mem[iq] -= (*this).generate(); - } + for(uword ii=0; ii < N; ++ii) { out.at(ii,ii) -= eT(1); } } } @@ -211,35 +165,18 @@ typedef typename T1::elem_type eT; - - if(is_same_type::yes) + if(is_same_type::yes) { - const uword N = (std::min)(n_rows, n_cols); - - for(uword iq=0; iq < N; ++iq) - { - for(uword row=0; row < iq; ++row) { out.at(row,iq) = eT(0); } - for(uword row=iq+1; row < n_rows; ++row) { out.at(row,iq) = eT(0); } - } + arrayops::inplace_mul(out.memptr(), eT(0), out.n_elem); + // NOTE: not using arrayops::fill_zeros(), as 'out' may have NaN elements } else + if(is_same_type::yes) { - eT* out_mem = out.memptr(); - const uword n_elem = out.n_elem; - - uword iq,jq; - for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2) - { - const eT tmp_i = (*this).generate(); - const eT tmp_j = (*this).generate(); - - out_mem[iq] *= tmp_i; - out_mem[jq] *= tmp_j; - } - - if(iq < n_elem) + for(uword c=0; c < n_cols; ++c) + for(uword r=0; r < n_rows; ++r) { - out_mem[iq] *= (*this).generate(); + if(r != c) { out.at(r,c) *= eT(0); } } } } @@ -258,37 +195,17 @@ typedef typename T1::elem_type eT; - - if(is_same_type::yes) + if(is_same_type::yes) { - const uword N = (std::min)(n_rows, n_cols); - - for(uword iq=0; iq < N; ++iq) - { - const eT zero = eT(0); - - for(uword row=0; row < iq; ++row) { out.at(row,iq) /= zero; } - for(uword row=iq+1; row < n_rows; ++row) { out.at(row,iq) /= zero; } - } + arrayops::inplace_div(out.memptr(), eT(0), out.n_elem); } else + if(is_same_type::yes) { - eT* out_mem = out.memptr(); - const uword n_elem = out.n_elem; - - uword iq,jq; - for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2) - { - const eT tmp_i = (*this).generate(); - const eT tmp_j = (*this).generate(); - - out_mem[iq] /= tmp_i; - out_mem[jq] /= tmp_j; - } - - if(iq < n_elem) + for(uword c=0; c < n_cols; ++c) + for(uword r=0; r < n_rows; ++r) { - out_mem[iq] /= (*this).generate(); + if(r != c) { out.at(r,c) /= eT(0); } } } } @@ -305,11 +222,9 @@ // NOTE: we're assuming that the submatrix has the same dimensions as the Gen object // this is checked by subview::operator=() - if(is_same_type::yes) { out.eye(); } + if(is_same_type::yes) { out.zeros(); } else if(is_same_type::yes) { out.ones(); } - else if(is_same_type::yes) { out.zeros(); } - else if(is_same_type::yes) { out.randu(); } - else if(is_same_type::yes) { out.randn(); } + else if(is_same_type::yes) { out.eye(); } } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/GenSpecialiser.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/GenSpecialiser.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/GenSpecialiser.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/GenSpecialiser.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -// 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 GenSpecialiser -//! @{ - - -template -struct GenSpecialiser - { - arma_inline elem_type generate() const { return elem_type(); } - }; - - -template -struct GenSpecialiser - { - arma_inline elem_type generate() const { return elem_type(0); } - }; - - -template -struct GenSpecialiser - { - arma_inline elem_type generate() const { return elem_type(1); } - }; - - -template -struct GenSpecialiser - { - arma_inline elem_type generate() const { return elem_type(arma_rng::randu()); } - }; - - -template -struct GenSpecialiser - { - arma_inline elem_type generate() const { return elem_type(arma_rng::randn()); } - }; - - -//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_conv_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_conv_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_conv_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_conv_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -63,11 +63,28 @@ eT* out_mem = out.memptr(); - for(uword i=0; i < out_n_elem; ++i) + if( (arma_config::openmp) && (x_n_elem >= 128) && (h_n_elem >= 64) && (mp_thread_limit::in_parallel() == false) ) { - // out_mem[i] = dot( hh, xx.subvec(i, (i + h_n_elem_m1)) ); - - out_mem[i] = op_dot::direct_dot( h_n_elem, hh_mem, &(xx_mem[i]) ); + #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 < out_n_elem; ++i) + { + out_mem[i] = op_dot::direct_dot( h_n_elem, hh_mem, &(xx_mem[i]) ); + } + } + #endif + } + else + { + for(uword i=0; i < out_n_elem; ++i) + { + // out_mem[i] = dot( hh, xx.subvec(i, (i + h_n_elem_m1)) ); + + out_mem[i] = op_dot::direct_dot( h_n_elem, hh_mem, &(xx_mem[i]) ); + } } } @@ -264,24 +281,57 @@ out.set_size( out_n_rows, out_n_cols ); - for(uword col=0; col < out_n_cols; ++col) + if( (arma_config::openmp) && (out_n_cols >= 2) && (mp_thread_limit::in_parallel() == false) ) { - eT* out_colptr = out.colptr(col); - - for(uword row=0; row < out_n_rows; ++row) + #if defined(ARMA_USE_OPENMP) { - // out.at(row, col) = accu( H % X(row, col, size(H)) ); - - eT acc = eT(0); + const int n_threads = mp_thread_limit::get(); - for(uword H_col = 0; H_col < H_n_cols; ++H_col) + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword col=0; col < out_n_cols; ++col) { - const eT* X_colptr = X.colptr(col + H_col); + eT* out_colptr = out.colptr(col); - acc += op_dot::direct_dot( H_n_rows, H.colptr(H_col), &(X_colptr[row]) ); + for(uword row=0; row < out_n_rows; ++row) + { + // out.at(row, col) = accu( H % X(row, col, size(H)) ); + + eT acc = eT(0); + + for(uword H_col = 0; H_col < H_n_cols; ++H_col) + { + const eT* X_colptr = X.colptr(col + H_col); + + acc += op_dot::direct_dot( H_n_rows, H.colptr(H_col), &(X_colptr[row]) ); + } + + out_colptr[row] = acc; + } } + } + #endif + } + else + { + for(uword col=0; col < out_n_cols; ++col) + { + eT* out_colptr = out.colptr(col); - out_colptr[row] = acc; + for(uword row=0; row < out_n_rows; ++row) + { + // out.at(row, col) = accu( H % X(row, col, size(H)) ); + + eT acc = eT(0); + + for(uword H_col = 0; H_col < H_n_cols; ++H_col) + { + const eT* X_colptr = X.colptr(col + H_col); + + acc += op_dot::direct_dot( H_n_rows, H.colptr(H_col), &(X_colptr[row]) ); + } + + out_colptr[row] = acc; + } } } } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_kron_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_kron_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_kron_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_kron_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -125,24 +125,21 @@ typedef typename T1::elem_type eT; - const unwrap A_tmp(X.A); - const unwrap B_tmp(X.B); + const quasi_unwrap UA(X.A); + const quasi_unwrap UB(X.B); - const Mat& A = A_tmp.M; - const Mat& B = B_tmp.M; - - if( (&out != &A) && (&out != &B) ) - { - glue_kron::direct_kron(out, A, B); - } - else + if(UA.is_alias(out) || UB.is_alias(out)) { Mat tmp; - glue_kron::direct_kron(tmp, A, B); + glue_kron::direct_kron(tmp, UA.M, UB.M); out.steal_mem(tmp); } + else + { + glue_kron::direct_kron(out, UA.M, UB.M); + } } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_mvnrnd_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_mvnrnd_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_mvnrnd_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_mvnrnd_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -85,12 +85,6 @@ return true; } - // if(auxlib::rudimentary_sym_check(UC.M) == false) - // { - // 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_level(1, "mvnrnd(): given matrix is not symmetric"); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_powext_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_powext_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_powext_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_powext_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,70 @@ + +// 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_powext +//! @{ + + + +class glue_powext + : public traits_glue_or + { + public: + + template inline static void apply(Mat& out, const Glue& X); + + template inline static void apply(Mat& out, const Mat& A, const Mat& B); + + template inline static Mat apply(const subview_each1& X, const Base& Y); + + // + + template inline static void apply(Cube& out, const GlueCube& X); + + template inline static void apply(Cube& out, const Cube& A, const Cube& B); + + template inline static Cube apply(const subview_cube_each1& X, const Base& Y); + }; + + + +class glue_powext_cx + : public traits_glue_or + { + public: + + template inline static void apply(Mat& out, const mtGlue& X); + + template inline static void apply(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat& B); + + template inline static Mat apply(const subview_each1& X, const Base& Y); + + // + + template inline static void apply(Cube& out, const mtGlueCube& X); + + template inline static void apply(Cube< std::complex >& out, const Cube< std::complex >& A, const Cube& B); + + template inline static Cube< std::complex > apply(const subview_cube_each1< std::complex >& X, const Base& Y); + }; + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_powext_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_powext_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_powext_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_powext_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,674 @@ +// 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_powext +//! @{ + + +template +inline +void +glue_powext::apply(Mat& out, const Glue& X) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const quasi_unwrap UA(X.A); + const quasi_unwrap UB(X.B); + + const Mat& A = UA.M; + const Mat& B = UB.M; + + arma_debug_assert_same_size(A, B, "element-wise pow()"); + + const bool UA_bad_alias = UA.is_alias(out) && (UA.has_subview); // allow inplace operation + const bool UB_bad_alias = UB.is_alias(out); + + if(UA_bad_alias || UB_bad_alias) + { + Mat tmp; + + glue_powext::apply(tmp, A, B); + + out.steal_mem(tmp); + } + else + { + glue_powext::apply(out, A, B); + } + } + + + +template +inline +void +glue_powext::apply(Mat& out, const Mat& A, const Mat& B) + { + arma_extra_debug_sigprint(); + + out.set_size(A.n_rows, A.n_cols); + + const uword N = out.n_elem; + + eT* out_mem = out.memptr(); + const eT* A_mem = A.memptr(); + const eT* B_mem = B.memptr(); + + if( arma_config::openmp && mp_gate::eval(N) ) + { + #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 +inline +Mat +glue_powext::apply + ( + const subview_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + typedef typename parent::elem_type eT; + + const parent& A = X.P; + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + + Mat out(A_n_rows, A_n_cols, arma_nozeros_indicator()); + + const quasi_unwrap tmp(Y.get_ref()); + const Mat& B = tmp.M; + + X.check_size(B); + + const eT* B_mem = B.memptr(); + + if(mode == 0) // each column + { + if( arma_config::openmp && mp_gate::eval(A.n_elem) ) + { + #if defined(ARMA_USE_OPENMP) + { + const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_cols) ); + + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = eop_aux::pow(A_mem[row], B_mem[row]); + } + } + } + #endif + } + else + { + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = eop_aux::pow(A_mem[row], B_mem[row]); + } + } + } + } + + if(mode == 1) // each row + { + if( arma_config::openmp && mp_gate::eval(A.n_elem) ) + { + #if defined(ARMA_USE_OPENMP) + { + const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_cols) ); + + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + const eT B_val = B_mem[i]; + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = eop_aux::pow(A_mem[row], B_val); + } + } + } + #endif + } + else + { + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + const eT B_val = B_mem[i]; + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = eop_aux::pow(A_mem[row], B_val); + } + } + } + } + + return out; + } + + + +template +inline +void +glue_powext::apply(Cube& out, const GlueCube& X) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_cube UA(X.A); + const unwrap_cube UB(X.B); + + const Cube& A = UA.M; + const Cube& B = UB.M; + + arma_debug_assert_same_size(A, B, "element-wise pow()"); + + if(UB.is_alias(out)) + { + Cube tmp; + + glue_powext::apply(tmp, A, B); + + out.steal_mem(tmp); + } + else + { + glue_powext::apply(out, A, B); + } + } + + + +template +inline +void +glue_powext::apply(Cube& out, const Cube& A, const Cube& B) + { + arma_extra_debug_sigprint(); + + out.set_size(A.n_rows, A.n_cols, A.n_slices); + + const uword N = out.n_elem; + + eT* out_mem = out.memptr(); + const eT* A_mem = A.memptr(); + const eT* B_mem = B.memptr(); + + if( arma_config::openmp && mp_gate::eval(N) ) + { + #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 +inline +Cube +glue_powext::apply + ( + const subview_cube_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + const Cube& A = X.P; + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + const uword A_n_slices = A.n_slices; + + Cube out(A_n_rows, A_n_cols, A_n_slices, arma_nozeros_indicator()); + + const quasi_unwrap tmp(Y.get_ref()); + const Mat& B = tmp.M; + + X.check_size(B); + + const eT* B_mem = B.memptr(); + const uword B_n_elem = B.n_elem; + + if( arma_config::openmp && mp_gate::eval(A.n_elem) ) + { + #if defined(ARMA_USE_OPENMP) + { + const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_slices) ); + + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword s=0; s < A_n_slices; ++s) + { + const eT* A_slice_mem = A.slice_memptr(s); + eT* out_slice_mem = out.slice_memptr(s); + + for(uword i=0; i < B_n_elem; ++i) + { + out_slice_mem[i] = eop_aux::pow(A_slice_mem[i], B_mem[i]); + } + } + } + #endif + } + else + { + for(uword s=0; s < A_n_slices; ++s) + { + const eT* A_slice_mem = A.slice_memptr(s); + eT* out_slice_mem = out.slice_memptr(s); + + for(uword i=0; i < B_n_elem; ++i) + { + out_slice_mem[i] = eop_aux::pow(A_slice_mem[i], B_mem[i]); + } + } + } + + return out; + } + + + +// + + + +template +inline +void +glue_powext_cx::apply(Mat& out, const mtGlue& X) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + const quasi_unwrap UA(X.A); + const quasi_unwrap UB(X.B); + + const Mat& A = UA.M; + const Mat< T>& B = UB.M; + + arma_debug_assert_same_size(A, B, "element-wise pow()"); + + if(UA.is_alias(out) && (UA.has_subview)) + { + Mat tmp; + + glue_powext_cx::apply(tmp, A, B); + + out.steal_mem(tmp); + } + else + { + glue_powext_cx::apply(out, A, B); + } + } + + + +template +inline +void +glue_powext_cx::apply(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat& B) + { + arma_extra_debug_sigprint(); + + typedef typename std::complex eT; + + out.set_size(A.n_rows, A.n_cols); + + const uword N = out.n_elem; + + eT* out_mem = out.memptr(); + const eT* A_mem = A.memptr(); + const T* B_mem = B.memptr(); + + if( arma_config::openmp && mp_gate::eval(N) ) + { + #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 +inline +Mat +glue_powext_cx::apply + ( + const subview_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + typedef typename parent::elem_type eT; + typedef typename parent::pod_type T; + + const parent& A = X.P; + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + + Mat out(A_n_rows, A_n_cols, arma_nozeros_indicator()); + + const quasi_unwrap tmp(Y.get_ref()); + const Mat& B = tmp.M; + + X.check_size(B); + + const T* B_mem = B.memptr(); + + if(mode == 0) // each column + { + if( arma_config::openmp && mp_gate::eval(A.n_elem) ) + { + #if defined(ARMA_USE_OPENMP) + { + const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_cols) ); + + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = std::pow(A_mem[row], B_mem[row]); + } + } + } + #endif + } + else + { + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = std::pow(A_mem[row], B_mem[row]); + } + } + } + } + + if(mode == 1) // each row + { + if( arma_config::openmp && mp_gate::eval(A.n_elem) ) + { + #if defined(ARMA_USE_OPENMP) + { + const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_cols) ); + + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + const eT B_val = B_mem[i]; + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = std::pow(A_mem[row], B_val); + } + } + } + #endif + } + else + { + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + const eT B_val = B_mem[i]; + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = std::pow(A_mem[row], B_val); + } + } + } + } + + return out; + } + + + +template +inline +void +glue_powext_cx::apply(Cube& out, const mtGlueCube& X) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + typedef typename get_pod_type::result T; + + const unwrap_cube UA(X.A); + const unwrap_cube UB(X.B); + + const Cube& A = UA.M; + const Cube< T>& B = UB.M; + + arma_debug_assert_same_size(A, B, "element-wise pow()"); + + glue_powext_cx::apply(out, A, B); + } + + + +template +inline +void +glue_powext_cx::apply(Cube< std::complex >& out, const Cube< std::complex >& A, const Cube& B) + { + arma_extra_debug_sigprint(); + + typedef typename std::complex eT; + + out.set_size(A.n_rows, A.n_cols, A.n_slices); + + const uword N = out.n_elem; + + eT* out_mem = out.memptr(); + const eT* A_mem = A.memptr(); + const T* B_mem = B.memptr(); + + if( arma_config::openmp && mp_gate::eval(N) ) + { + #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 +inline +Cube< std::complex > +glue_powext_cx::apply + ( + const subview_cube_each1< std::complex >& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + typedef typename std::complex eT; + + const Cube& A = X.P; + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + const uword A_n_slices = A.n_slices; + + Cube out(A_n_rows, A_n_cols, A_n_slices, arma_nozeros_indicator()); + + const quasi_unwrap tmp(Y.get_ref()); + const Mat& B = tmp.M; + + X.check_size(B); + + const T* B_mem = B.memptr(); + const uword B_n_elem = B.n_elem; + + if( arma_config::openmp && mp_gate::eval(A.n_elem) ) + { + #if defined(ARMA_USE_OPENMP) + { + const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_slices) ); + + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword s=0; s < A_n_slices; ++s) + { + const eT* A_slice_mem = A.slice_memptr(s); + eT* out_slice_mem = out.slice_memptr(s); + + for(uword i=0; i < B_n_elem; ++i) + { + out_slice_mem[i] = std::pow(A_slice_mem[i], B_mem[i]); + } + } + } + #endif + } + else + { + for(uword s=0; s < A_n_slices; ++s) + { + const eT* A_slice_mem = A.slice_memptr(s); + eT* out_slice_mem = out.slice_memptr(s); + + for(uword i=0; i < B_n_elem; ++i) + { + out_slice_mem[i] = std::pow(A_slice_mem[i], B_mem[i]); + } + } + } + + return out; + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_quantile_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_quantile_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_quantile_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_quantile_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -178,6 +178,8 @@ const quasi_unwrap UA(expr.A); const quasi_unwrap UB(expr.B); + arma_debug_check((UA.M.internal_has_nan() || UB.M.internal_has_nan()), "quantile(): detected NaN"); + if(UA.is_alias(out) || UB.is_alias(out)) { Mat tmp; @@ -208,6 +210,8 @@ const uword dim = (T1::is_xvec) ? uword(UA.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0); + arma_debug_check((UA.M.internal_has_nan() || UB.M.internal_has_nan()), "quantile(): detected NaN"); + if(UA.is_alias(out) || UB.is_alias(out)) { Mat tmp; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_solve_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_solve_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_solve_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_solve_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,7 +22,7 @@ -class glue_solve_gen +class glue_solve_gen_default { public: @@ -34,9 +34,28 @@ static constexpr bool is_xvec = false; }; - template inline static void apply(Mat& out, const Glue& X); + template inline static void apply(Mat& out, const Glue& X); - template inline static bool apply(Mat& out, const Base& A_expr, const Base& B_expr, const uword flags); + template inline static bool apply(Mat& out, const Base& A_expr, const Base& B_expr); + }; + + + +class glue_solve_gen_full + { + public: + + template + struct traits + { + 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); + + template inline static bool apply(Mat& out, const Base& A_expr, const Base& B_expr, const uword flags); }; @@ -60,7 +79,7 @@ -class glue_solve_tri +class glue_solve_tri_full { public: @@ -72,7 +91,7 @@ static constexpr bool is_xvec = false; }; - template inline static void apply(Mat& out, const Glue& X); + template inline static void apply(Mat& out, const Glue& X); template inline static bool apply(Mat& out, const Base& A_expr, const Base& B_expr, const uword flags); }; @@ -85,12 +104,13 @@ { const uword flags; - inline explicit opts(const uword in_flags); + inline constexpr explicit opts(const uword in_flags); inline const opts operator+(const opts& rhs) const; }; inline + constexpr opts::opts(const uword in_flags) : flags(in_flags) {} @@ -121,33 +141,33 @@ 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 ) {} }; - struct opts_equilibrate : public opts { inline opts_equilibrate() : opts(flag_equilibrate ) {} }; - struct opts_no_approx : public opts { inline opts_no_approx() : opts(flag_no_approx ) {} }; - struct opts_triu : public opts { inline opts_triu() : opts(flag_triu ) {} }; - struct opts_tril : public opts { inline opts_tril() : opts(flag_tril ) {} }; - struct opts_no_band : public opts { inline opts_no_band() : opts(flag_no_band ) {} }; - struct opts_no_sympd : public opts { inline opts_no_sympd() : opts(flag_no_sympd ) {} }; - struct opts_allow_ugly : public opts { inline opts_allow_ugly() : opts(flag_allow_ugly ) {} }; - 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; - static const opts_equilibrate equilibrate; - static const opts_no_approx no_approx; - static const opts_triu triu; - static const opts_tril tril; - static const opts_no_band no_band; - static const opts_no_sympd no_sympd; - static const opts_allow_ugly allow_ugly; - 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; + struct opts_none : public opts { inline constexpr opts_none() : opts(flag_none ) {} }; + struct opts_fast : public opts { inline constexpr opts_fast() : opts(flag_fast ) {} }; + struct opts_equilibrate : public opts { inline constexpr opts_equilibrate() : opts(flag_equilibrate ) {} }; + struct opts_no_approx : public opts { inline constexpr opts_no_approx() : opts(flag_no_approx ) {} }; + struct opts_triu : public opts { inline constexpr opts_triu() : opts(flag_triu ) {} }; + struct opts_tril : public opts { inline constexpr opts_tril() : opts(flag_tril ) {} }; + struct opts_no_band : public opts { inline constexpr opts_no_band() : opts(flag_no_band ) {} }; + struct opts_no_sympd : public opts { inline constexpr opts_no_sympd() : opts(flag_no_sympd ) {} }; + struct opts_allow_ugly : public opts { inline constexpr opts_allow_ugly() : opts(flag_allow_ugly ) {} }; + struct opts_likely_sympd : public opts { inline constexpr opts_likely_sympd() : opts(flag_likely_sympd) {} }; + struct opts_refine : public opts { inline constexpr opts_refine() : opts(flag_refine ) {} }; + struct opts_no_trimat : public opts { inline constexpr opts_no_trimat() : opts(flag_no_trimat ) {} }; + struct opts_force_approx : public opts { inline constexpr opts_force_approx() : opts(flag_force_approx) {} }; + + static constexpr opts_none none; + static constexpr opts_fast fast; + static constexpr opts_equilibrate equilibrate; + static constexpr opts_no_approx no_approx; + static constexpr opts_triu triu; + static constexpr opts_tril tril; + static constexpr opts_no_band no_band; + static constexpr opts_no_sympd no_sympd; + static constexpr opts_allow_ugly allow_ugly; + static constexpr opts_likely_sympd likely_sympd; + static constexpr opts_refine refine; + static constexpr opts_no_trimat no_trimat; + static constexpr opts_force_approx force_approx; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_solve_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_solve_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_solve_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_solve_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,17 +22,17 @@ // -// glue_solve_gen +// glue_solve_gen_default template inline void -glue_solve_gen::apply(Mat& out, const Glue& X) +glue_solve_gen_default::apply(Mat& out, const Glue& X) { arma_extra_debug_sigprint(); - const bool status = glue_solve_gen::apply( out, X.A, X.B, X.aux_uword ); + const bool status = glue_solve_gen_default::apply(out, X.A, X.B); if(status == false) { @@ -46,45 +46,85 @@ template inline bool -glue_solve_gen::apply(Mat& out, const Base& A_expr, const Base& B_expr, const uword flags) +glue_solve_gen_default::apply(Mat& out, const Base& A_expr, const Base& B_expr) { arma_extra_debug_sigprint(); - typedef typename get_pod_type::result T; + return glue_solve_gen_full::apply( out, A_expr, B_expr, uword(0)); + } + + + +// +// glue_solve_gen_full + + +template +inline +void +glue_solve_gen_full::apply(Mat& out, const Glue& X) + { + arma_extra_debug_sigprint(); - const bool fast = bool(flags & solve_opts::flag_fast ); - const bool equilibrate = bool(flags & solve_opts::flag_equilibrate ); - const bool no_approx = bool(flags & solve_opts::flag_no_approx ); - const bool no_band = bool(flags & solve_opts::flag_no_band ); - const bool no_sympd = bool(flags & solve_opts::flag_no_sympd ); - const bool allow_ugly = bool(flags & solve_opts::flag_allow_ugly ); - 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); + const bool status = glue_solve_gen_full::apply( out, X.A, X.B, X.aux_uword ); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("solve(): solution not found"); + } + } + + + +template +inline +bool +glue_solve_gen_full::apply(Mat& actual_out, const Base& A_expr, const Base& B_expr, const uword flags) + { + arma_extra_debug_sigprint(); - arma_extra_debug_print("glue_solve_gen::apply(): enabled flags:"); + typedef typename get_pod_type::result T; - if(fast ) { arma_extra_debug_print("fast"); } - if(equilibrate ) { arma_extra_debug_print("equilibrate"); } - if(no_approx ) { arma_extra_debug_print("no_approx"); } - if(no_band ) { arma_extra_debug_print("no_band"); } - if(no_sympd ) { arma_extra_debug_print("no_sympd"); } - if(allow_ugly ) { arma_extra_debug_print("allow_ugly"); } - 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(has_user_flags == true ) { arma_extra_debug_print("glue_solve_gen_full::apply(): has_user_flags = true" ); } + if(has_user_flags == false) { arma_extra_debug_print("glue_solve_gen_full::apply(): has_user_flags = false"); } - 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" ); + const bool fast = has_user_flags && bool(flags & solve_opts::flag_fast ); + const bool equilibrate = has_user_flags && bool(flags & solve_opts::flag_equilibrate ); + const bool no_approx = has_user_flags && bool(flags & solve_opts::flag_no_approx ); + const bool no_band = has_user_flags && bool(flags & solve_opts::flag_no_band ); + const bool no_sympd = has_user_flags && bool(flags & solve_opts::flag_no_sympd ); + const bool allow_ugly = has_user_flags && bool(flags & solve_opts::flag_allow_ugly ); + const bool likely_sympd = has_user_flags && bool(flags & solve_opts::flag_likely_sympd); + const bool refine = has_user_flags && bool(flags & solve_opts::flag_refine ); + const bool no_trimat = has_user_flags && bool(flags & solve_opts::flag_no_trimat ); + const bool force_approx = has_user_flags && bool(flags & solve_opts::flag_force_approx); + + if(has_user_flags) + { + arma_extra_debug_print("glue_solve_gen_full::apply(): enabled flags:"); + + if(fast ) { arma_extra_debug_print("fast"); } + if(equilibrate ) { arma_extra_debug_print("equilibrate"); } + if(no_approx ) { arma_extra_debug_print("no_approx"); } + if(no_band ) { arma_extra_debug_print("no_band"); } + if(no_sympd ) { arma_extra_debug_print("no_sympd"); } + if(allow_ugly ) { arma_extra_debug_print("allow_ugly"); } + 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_extra_debug_print("glue_solve_gen_full::apply(): forced approximate solution"); arma_debug_check( no_approx, "solve(): options 'no_approx' and 'force_approx' are mutually exclusive" ); @@ -93,51 +133,59 @@ 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 + return auxlib::solve_approx_svd(actual_out, A, B_expr.get_ref()); // A is overwritten } + // A_expr and B_expr can be used more than once (sympd optimisation fails or approximate solution required), + // so ensure they are not overwritten in case we have aliasing + + bool is_alias = true; // assume we have aliasing until we can prove otherwise + + if(is_Mat::value && is_Mat::value) + { + const quasi_unwrap UA( A_expr.get_ref() ); + const quasi_unwrap UB( B_expr.get_ref() ); + + is_alias = UA.is_alias(actual_out) || UB.is_alias(actual_out); + } + + Mat tmp; + Mat& out = (is_alias) ? tmp : actual_out; + T rcond = T(0); bool status = false; if(A.n_rows == A.n_cols) { - arma_extra_debug_print("glue_solve_gen::apply(): detected square system"); + arma_extra_debug_print("glue_solve_gen_full::apply(): detected square system"); uword KL = 0; uword KU = 0; - #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; - #endif + const bool is_band = arma_config::optimise_band && ((no_band || auxlib::crippled_lapack(A)) ? false : band_helper::is_band(KL, KU, A, uword(32))); const bool is_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_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 + const bool try_sympd = arma_config::optimise_sym && ((no_sympd || auxlib::crippled_lapack(A) || is_band || is_triu || is_tril) ? false : (likely_sympd ? true : sym_helper::guess_sympd(A, uword(16)))); if(fast) { // fast mode: solvers without refinement and without rcond estimate - arma_extra_debug_print("glue_solve_gen::apply(): fast mode"); + arma_extra_debug_print("glue_solve_gen_full::apply(): fast mode"); if(is_band) { if( (KL == 1) && (KU == 1) ) { - arma_extra_debug_print("glue_solve_gen::apply(): fast + tridiagonal"); + arma_extra_debug_print("glue_solve_gen_full::apply(): fast + tridiagonal"); status = auxlib::solve_tridiag_fast(out, A, B_expr.get_ref()); } else { - arma_extra_debug_print("glue_solve_gen::apply(): fast + band"); + arma_extra_debug_print("glue_solve_gen_full::apply(): fast + band"); status = auxlib::solve_band_fast(out, A, KL, KU, B_expr.get_ref()); } @@ -145,8 +193,8 @@ else if(is_triu || is_tril) { - if(is_triu) { arma_extra_debug_print("glue_solve_gen::apply(): fast + upper triangular matrix"); } - if(is_tril) { arma_extra_debug_print("glue_solve_gen::apply(): fast + lower triangular matrix"); } + if(is_triu) { arma_extra_debug_print("glue_solve_gen_full::apply(): fast + upper triangular matrix"); } + if(is_tril) { arma_extra_debug_print("glue_solve_gen_full::apply(): fast + lower triangular matrix"); } const uword layout = (is_triu) ? uword(0) : uword(1); @@ -155,22 +203,24 @@ else if(try_sympd) { - arma_extra_debug_print("glue_solve_gen::apply(): fast + try_sympd"); + arma_extra_debug_print("glue_solve_gen_full::apply(): fast + try_sympd"); status = auxlib::solve_sympd_fast(out, A, B_expr.get_ref()); // A is overwritten if(status == false) { - arma_extra_debug_print("glue_solve_gen::apply(): auxlib::solve_sympd_fast() failed; retrying"); - // auxlib::solve_sympd_fast() may have failed because A isn't really sympd + + arma_extra_debug_print("glue_solve_gen_full::apply(): auxlib::solve_sympd_fast() failed; retrying"); + A = A_expr.get_ref(); + status = auxlib::solve_square_fast(out, A, B_expr.get_ref()); // A is overwritten } } else { - arma_extra_debug_print("glue_solve_gen::apply(): fast + dense"); + arma_extra_debug_print("glue_solve_gen_full::apply(): fast + dense"); status = auxlib::solve_square_fast(out, A, B_expr.get_ref()); // A is overwritten } @@ -180,110 +230,87 @@ { // refine mode: solvers with refinement and with rcond estimate - arma_extra_debug_print("glue_solve_gen::apply(): refine mode"); + arma_extra_debug_print("glue_solve_gen_full::apply(): refine mode"); if(is_band) { - arma_extra_debug_print("glue_solve_gen::apply(): refine + band"); + arma_extra_debug_print("glue_solve_gen_full::apply(): refine + band"); - status = auxlib::solve_band_refine(out, rcond, A, KL, KU, B_expr, equilibrate, allow_ugly); + status = auxlib::solve_band_refine(out, rcond, A, KL, KU, B_expr, equilibrate); } else if(try_sympd) { - arma_extra_debug_print("glue_solve_gen::apply(): refine + try_sympd"); + arma_extra_debug_print("glue_solve_gen_full::apply(): refine + try_sympd"); - status = auxlib::solve_sympd_refine(out, rcond, A, B_expr.get_ref(), equilibrate, allow_ugly); // A is overwritten + status = auxlib::solve_sympd_refine(out, rcond, A, B_expr.get_ref(), equilibrate); // A is overwritten - if(status == false) + if( (status == false) && (rcond == T(0)) ) { - arma_extra_debug_print("glue_solve_gen::apply(): auxlib::solve_sympd_refine() failed; retrying"); + // auxlib::solve_sympd_refine() may have failed because A isn't really sympd; + // in that case rcond is set to zero + + arma_extra_debug_print("glue_solve_gen_full::apply(): auxlib::solve_sympd_refine() failed; retrying"); - // auxlib::solve_sympd_refine() may have failed because A isn't really sympd A = A_expr.get_ref(); - status = auxlib::solve_square_refine(out, rcond, A, B_expr.get_ref(), equilibrate, allow_ugly); // A is overwritten + + status = auxlib::solve_square_refine(out, rcond, A, B_expr.get_ref(), equilibrate); // A is overwritten } } else { - arma_extra_debug_print("glue_solve_gen::apply(): refine + dense"); + arma_extra_debug_print("glue_solve_gen_full::apply(): refine + dense"); - status = auxlib::solve_square_refine(out, rcond, A, B_expr, equilibrate, allow_ugly); // A is overwritten + status = auxlib::solve_square_refine(out, rcond, A, B_expr, equilibrate); // A is overwritten } } else { // default mode: solvers without refinement but with rcond estimate - arma_extra_debug_print("glue_solve_gen::apply(): default mode"); + arma_extra_debug_print("glue_solve_gen_full::apply(): default mode"); if(is_band) { - arma_extra_debug_print("glue_solve_gen::apply(): rcond + band"); + arma_extra_debug_print("glue_solve_gen_full::apply(): rcond + band"); - status = auxlib::solve_band_rcond(out, rcond, A, KL, KU, B_expr.get_ref(), allow_ugly); + status = auxlib::solve_band_rcond(out, rcond, A, KL, KU, B_expr.get_ref()); } else if(is_triu || is_tril) { - if(is_triu) { arma_extra_debug_print("glue_solve_gen::apply(): rcond + upper triangular matrix"); } - if(is_tril) { arma_extra_debug_print("glue_solve_gen::apply(): rcond + lower triangular matrix"); } + if(is_triu) { arma_extra_debug_print("glue_solve_gen_full::apply(): rcond + upper triangular matrix"); } + if(is_tril) { arma_extra_debug_print("glue_solve_gen_full::apply(): rcond + lower triangular matrix"); } const uword layout = (is_triu) ? uword(0) : uword(1); - status = auxlib::solve_trimat_rcond(out, rcond, A, B_expr.get_ref(), layout, allow_ugly); + status = auxlib::solve_trimat_rcond(out, rcond, A, B_expr.get_ref(), layout); } else if(try_sympd) { - status = auxlib::solve_sympd_rcond(out, rcond, A, B_expr.get_ref(), allow_ugly); // A is overwritten + bool sympd_state = false; - if(status == false) + status = auxlib::solve_sympd_rcond(out, sympd_state, rcond, A, B_expr.get_ref()); // A is overwritten + + if( (status == false) && (sympd_state == false) ) { - arma_extra_debug_print("glue_solve_gen::apply(): auxlib::solve_sympd_rcond() failed; retrying"); + arma_extra_debug_print("glue_solve_gen_full::apply(): auxlib::solve_sympd_rcond() failed; retrying"); - // auxlib::solve_sympd_rcond() may have failed because A isn't really sympd A = A_expr.get_ref(); - status = auxlib::solve_square_rcond(out, rcond, A, B_expr.get_ref(), allow_ugly); // A is overwritten + + status = auxlib::solve_square_rcond(out, rcond, A, B_expr.get_ref()); // A is overwritten } } else { - status = auxlib::solve_square_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"); + status = auxlib::solve_square_rcond(out, rcond, A, B_expr.get_ref()); // A is overwritten } - - // TODO: conditionally recreate A: have a separate state flag which indicates whether A was previously overwritten - - A = A_expr.get_ref(); // as A may have been overwritten - - status = auxlib::solve_approx_svd(out, A, B_expr.get_ref()); // A is overwritten } } else { - arma_extra_debug_print("glue_solve_gen::apply(): detected non-square system"); + arma_extra_debug_print("glue_solve_gen_full::apply(): detected non-square system"); 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" ); } @@ -295,33 +322,38 @@ } else { - status = auxlib::solve_rect_rcond(out, rcond, A, B_expr.get_ref(), allow_ugly); // A is overwritten + status = auxlib::solve_rect_rcond(out, rcond, A, B_expr.get_ref()); // A is overwritten } - - if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(A)) ) + } + + + if( (status == true) && (fast == false) && (allow_ugly == false) && ((rcond < std::numeric_limits::epsilon()) || arma_isnan(rcond)) ) + { + status = false; + } + + + if( (status == false) && (no_approx == false) ) + { + arma_extra_debug_print("glue_solve_gen_full::apply(): solving rank deficient system"); + + if(rcond == T(0)) { - arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); + arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); } - - if( (status == false) && (no_approx == false) ) + else { - 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 + arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); } + + // TODO: conditionally recreate A: have a separate state flag which indicates whether A was previously overwritten + + A = A_expr.get_ref(); // as A may have been overwritten + + status = auxlib::solve_approx_svd(out, A, B_expr.get_ref()); // A is overwritten } + if(is_alias) { actual_out.steal_mem(out); } return status; } @@ -329,7 +361,7 @@ // -// glue_solve_tri +// glue_solve_tri_default template @@ -359,22 +391,29 @@ typedef typename get_pod_type::result T; - const bool triu = bool(flags & solve_opts::flag_triu); - const bool tril = bool(flags & solve_opts::flag_tril); - const bool allow_ugly = false; + const bool triu = bool(flags & solve_opts::flag_triu); + const bool tril = bool(flags & solve_opts::flag_tril); arma_extra_debug_print("glue_solve_tri_default::apply(): enabled flags:"); if(triu) { arma_extra_debug_print("triu"); } if(tril) { arma_extra_debug_print("tril"); } - const quasi_unwrap U(A_expr.get_ref()); - const Mat& A = U.M; + const quasi_unwrap UA(A_expr.get_ref()); + const Mat& A = UA.M; arma_debug_check( (A.is_square() == false), "solve(): matrix marked as triangular must be square sized" ); - const uword layout = (triu) ? uword(0) : uword(1); - const bool is_alias = U.is_alias(actual_out); + const uword layout = (triu) ? uword(0) : uword(1); + + bool is_alias = true; + + if(is_Mat::value) + { + const quasi_unwrap UB(B_expr.get_ref()); + + is_alias = UA.is_alias(actual_out) || UB.is_alias(actual_out); + } T rcond = T(0); bool status = false; @@ -382,25 +421,26 @@ Mat tmp; Mat& out = (is_alias) ? tmp : actual_out; - status = auxlib::solve_trimat_rcond(out, rcond, A, B_expr.get_ref(), layout, allow_ugly); // A is not modified + status = auxlib::solve_trimat_rcond(out, rcond, A, B_expr.get_ref(), layout); // A is not modified - if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(A)) ) + + if( (status == true) && ( (rcond < std::numeric_limits::epsilon()) || arma_isnan(rcond) ) ) { - arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); + status = false; } if(status == false) { - arma_extra_debug_print("glue_solve_tri::apply(): solving rank deficient system"); + arma_extra_debug_print("glue_solve_tri_default::apply(): solving rank deficient system"); - if(rcond > T(0)) + if(rcond == T(0)) { - arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); } else { - arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); } Mat triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type @@ -416,14 +456,18 @@ +// +// glue_solve_tri_full + + template inline void -glue_solve_tri::apply(Mat& out, const Glue& X) +glue_solve_tri_full::apply(Mat& out, const Glue& X) { arma_extra_debug_sigprint(); - const bool status = glue_solve_tri::apply( out, X.A, X.B, X.aux_uword ); + const bool status = glue_solve_tri_full::apply( out, X.A, X.B, X.aux_uword ); if(status == false) { @@ -437,7 +481,7 @@ template inline bool -glue_solve_tri::apply(Mat& actual_out, const Base& A_expr, const Base& B_expr, const uword flags) +glue_solve_tri_full::apply(Mat& actual_out, const Base& A_expr, const Base& B_expr, const uword flags) { arma_extra_debug_sigprint(); @@ -454,7 +498,7 @@ 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:"); + arma_extra_debug_print("glue_solve_tri_full::apply(): enabled flags:"); if(fast ) { arma_extra_debug_print("fast"); } if(equilibrate ) { arma_extra_debug_print("equilibrate"); } @@ -471,18 +515,26 @@ { 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)); + return glue_solve_gen_full::apply(actual_out, ((triu) ? trimatu(A_expr.get_ref()) : trimatl(A_expr.get_ref())), B_expr, (flags & mask)); } if(likely_sympd) { arma_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; + const quasi_unwrap UA(A_expr.get_ref()); + const Mat& A = UA.M; arma_debug_check( (A.is_square() == false), "solve(): matrix marked as triangular must be square sized" ); - const uword layout = (triu) ? uword(0) : uword(1); - const bool is_alias = U.is_alias(actual_out); + const uword layout = (triu) ? uword(0) : uword(1); + + bool is_alias = true; + + if(is_Mat::value) + { + const quasi_unwrap UB(B_expr.get_ref()); + + is_alias = UA.is_alias(actual_out) || UB.is_alias(actual_out); + } T rcond = T(0); bool status = false; @@ -496,26 +548,27 @@ } else { - status = auxlib::solve_trimat_rcond(out, rcond, A, B_expr.get_ref(), layout, allow_ugly); // A is not modified + status = auxlib::solve_trimat_rcond(out, rcond, A, B_expr.get_ref(), layout); // A is not modified } - if( (status == true) && (rcond > T(0)) && (rcond < auxlib::epsilon_lapack(A)) ) + + if( (status == true) && (fast == false) && (allow_ugly == false) && ((rcond < std::numeric_limits::epsilon()) || arma_isnan(rcond)) ) { - arma_debug_warn_level(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); + status = false; } if( (status == false) && (no_approx == false) ) { - arma_extra_debug_print("glue_solve_tri::apply(): solving rank deficient system"); + arma_extra_debug_print("glue_solve_tri_full::apply(): solving rank deficient system"); - if(rcond > T(0)) + if(rcond == T(0)) { - arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); } else { - arma_debug_warn_level(2, "solve(): system is singular; attempting approx solution"); + arma_debug_warn_level(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); } Mat triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_times_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_times_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -23,7 +23,6 @@ template template -arma_hot inline void glue_times_redirect2_helper::apply(Mat& out, const Glue& X) @@ -74,7 +73,6 @@ template -arma_hot inline void glue_times_redirect2_helper::apply(Mat& out, const Glue& X) @@ -83,7 +81,7 @@ typedef typename T1::elem_type eT; - if(strip_inv::do_inv) + if(arma_config::optimise_invexpr && (strip_inv::do_inv_gen || strip_inv::do_inv_spd)) { // replace inv(A)*B with solve(A,B) @@ -95,24 +93,10 @@ arma_debug_check( (A.is_square() == false), "inv(): given matrix must be square sized" ); - if(strip_inv::do_inv_sympd) + if( (strip_inv::do_inv_spd) && (arma_config::debug) && (auxlib::rudimentary_sym_check(A) == false) ) { - // if(auxlib::rudimentary_sym_check(A) == false) - // { - // 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"); - // - // return; - // } - - if( (arma_config::debug) && (auxlib::rudimentary_sym_check(A) == false) ) - { - 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(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"); } } const unwrap_check B_tmp(X.B, out); @@ -120,13 +104,7 @@ arma_debug_assert_mul_size(A, B, "matrix multiplication"); - // 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); - #endif + const bool status = (strip_inv::do_inv_spd) ? auxlib::solve_sympd_fast(out, A, B) : auxlib::solve_square_fast(out, A, B); if(status == false) { @@ -137,56 +115,41 @@ return; } - #if defined(ARMA_OPTIMISE_SYMPD) + if(arma_config::optimise_invexpr && strip_inv::do_inv_spd) { - if(strip_inv::do_inv_sympd) + // replace A*inv_sympd(B) with trans( solve(trans(B),trans(A)) ) + // transpose of B is avoided as B is explicitly marked as symmetric + + arma_extra_debug_print("glue_times_redirect<2>::apply(): detected A*inv_sympd(B)"); + + const Mat At = trans(X.A); + + const strip_inv B_strip(X.B); + + Mat B = B_strip.M; + + arma_debug_check( (B.is_square() == false), "inv_sympd(): given matrix must be square sized" ); + + if( (arma_config::debug) && (auxlib::rudimentary_sym_check(B) == false) ) { - // replace A*inv_sympd(B) with trans( solve(trans(B),trans(A)) ) - // transpose of B is avoided as B is explicitly marked as symmetric - - arma_extra_debug_print("glue_times_redirect<2>::apply(): detected A*inv_sympd(B)"); - - const Mat At = trans(X.A); - - const strip_inv B_strip(X.B); - - Mat B = B_strip.M; - - arma_debug_check( (B.is_square() == false), "inv_sympd(): given matrix must be square sized" ); - - // if(auxlib::rudimentary_sym_check(B) == false) - // { - // 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"); - // - // return; - // } - - if( (arma_config::debug) && (auxlib::rudimentary_sym_check(B) == false) ) - { - 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"); - - const bool status = auxlib::solve_sympd_fast(out, B, At); - - if(status == false) - { - out.soft_reset(); - arma_stop_runtime_error("matrix multiplication: problem with matrix inverse; suggest to use solve() instead"); - } - - out = trans(out); - - return; + 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"); + + const bool status = auxlib::solve_sympd_fast(out, B, At); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("matrix multiplication: problem with matrix inverse; suggest to use solve() instead"); } + + out = trans(out); + + return; } - #endif glue_times_redirect2_helper::apply(out, X); } @@ -195,7 +158,6 @@ template template -arma_hot inline void glue_times_redirect3_helper::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) @@ -253,7 +215,6 @@ template -arma_hot inline void glue_times_redirect3_helper::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) @@ -262,7 +223,7 @@ typedef typename T1::elem_type eT; - if(strip_inv::do_inv) + if(arma_config::optimise_invexpr && (strip_inv::do_inv_gen || strip_inv::do_inv_spd)) { // replace inv(A)*B*C with solve(A,B*C); @@ -296,13 +257,13 @@ arma_debug_assert_mul_size(A, BC, "matrix multiplication"); - // TODO: detect sympd via sympd_helper::guess_sympd(A) ? + if( (strip_inv::do_inv_spd) && (arma_config::debug) && (auxlib::rudimentary_sym_check(A) == false) ) + { + 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 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); - #endif + const bool status = (strip_inv::do_inv_spd) ? auxlib::solve_sympd_fast(out, A, BC) : auxlib::solve_square_fast(out, A, BC); if(status == false) { @@ -314,7 +275,7 @@ } - if(strip_inv::do_inv) + if(arma_config::optimise_invexpr && (strip_inv::do_inv_gen || strip_inv::do_inv_spd)) { // replace A*inv(B)*C with A*solve(B,C) @@ -331,13 +292,15 @@ arma_debug_assert_mul_size(B, C, "matrix multiplication"); + if( (strip_inv::do_inv_spd) && (arma_config::debug) && (auxlib::rudimentary_sym_check(B) == false) ) + { + 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"); } + } + Mat solve_result; - #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); - #endif + const bool status = (strip_inv::do_inv_spd) ? auxlib::solve_sympd_fast(solve_result, B, C) : auxlib::solve_square_fast(solve_result, B, C); if(status == false) { @@ -373,7 +336,6 @@ template template -arma_hot inline void glue_times_redirect::apply(Mat& out, const Glue& X) @@ -424,7 +386,6 @@ template -arma_hot inline void glue_times_redirect<2>::apply(Mat& out, const Glue& X) @@ -439,7 +400,6 @@ template -arma_hot inline void glue_times_redirect<3>::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) @@ -454,7 +414,6 @@ template -arma_hot inline void glue_times_redirect<4>::apply(Mat& out, const Glue< Glue< Glue, T3, glue_times>, T4, glue_times>& X) @@ -516,7 +475,6 @@ template -arma_hot inline void glue_times::apply(Mat& out, const Glue& X) @@ -533,7 +491,6 @@ template -arma_hot inline void glue_times::apply_inplace(Mat& out, const T1& X) @@ -546,7 +503,6 @@ template -arma_hot inline void glue_times::apply_inplace_plus(Mat& out, const Glue& X, const sword sign) @@ -556,7 +512,7 @@ typedef typename T1::elem_type eT; typedef typename get_pod_type::result T; - if( (is_outer_product::value) || (has_op_inv::value) || (has_op_inv::value) || (has_op_inv_sympd::value) || (has_op_inv_sympd::value) ) + if( (is_outer_product::value) || (has_op_inv_any::value) || (has_op_inv_any::value) ) { // partial workaround for corner cases @@ -590,11 +546,7 @@ arma_debug_assert_same_size(out.n_rows, out.n_cols, result_n_rows, result_n_cols, ( (sign > sword(0)) ? "addition" : "subtraction" ) ); - if(out.n_elem == 0) - { - return; - } - + if(out.n_elem == 0) { return; } if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == false) ) { @@ -683,7 +635,6 @@ typename TA, typename TB > -arma_hot inline void glue_times::apply @@ -704,12 +655,7 @@ out.set_size(final_n_rows, final_n_cols); - if( (A.n_elem == 0) || (B.n_elem == 0) ) - { - out.zeros(); - return; - } - + if( (A.n_elem == 0) || (B.n_elem == 0) ) { out.zeros(); return; } if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == false) ) { @@ -787,7 +733,6 @@ typename TB, typename TC > -arma_hot inline void glue_times::apply @@ -837,7 +782,6 @@ typename TC, typename TD > -arma_hot inline void glue_times::apply @@ -882,7 +826,6 @@ template -arma_hot inline void glue_times_diag::apply(Mat& actual_out, const Glue& X) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_misc_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_times_misc_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_misc_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_times_misc_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,88 @@ +// 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_times_misc +//! @{ + + + +class dense_sparse_helper + { + public: + + template + arma_inline static typename arma_not_cx::result dot(const eT* A_mem, const SpMat& B, const uword col); + + template + arma_inline static typename arma_cx_only::result dot(const eT* A_mem, const SpMat& B, const uword col); + }; + + + +class glue_times_dense_sparse + { + public: + + template + struct traits + { + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; + }; + + template + inline static void apply(Mat& out, const SpToDGlue& expr); + + template + inline static void apply_noalias(Mat& out, const T1& x, const T2& y); + + template + inline static void apply_mixed(Mat< typename promote_type::result >& out, const T1& X, const T2& Y); + }; + + + +class glue_times_sparse_dense + { + public: + + template + struct traits + { + static constexpr bool is_row = T1::is_row; + static constexpr bool is_col = T2::is_col; + static constexpr bool is_xvec = false; + }; + + template + inline static void apply(Mat& out, const SpToDGlue& expr); + + template + inline static void apply_noalias(Mat& out, const T1& x, const T2& y); + + template + inline static void apply_noalias_trans(Mat& out, const T1& x, const T2& y); + + template + inline static void apply_mixed(Mat< typename promote_type::result >& out, const T1& X, const T2& Y); + }; + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_misc_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/glue_times_misc_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/glue_times_misc_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/glue_times_misc_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,646 @@ +// 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_times_misc +//! @{ + + + +template +arma_inline +typename arma_not_cx::result +dense_sparse_helper::dot(const eT* A_mem, const SpMat& B, const uword col) + { + arma_extra_debug_sigprint(); + + uword col_offset = B.col_ptrs[col ]; + const uword next_col_offset = B.col_ptrs[col + 1]; + + const uword* start_ptr = &(B.row_indices[ col_offset]); + const uword* end_ptr = &(B.row_indices[next_col_offset]); + + const eT* B_values = B.values; + + eT acc = eT(0); + + for(const uword* ptr = start_ptr; ptr != end_ptr; ++ptr) + { + const uword index = (*ptr); + + acc += A_mem[index] * B_values[col_offset]; + + ++col_offset; + } + + return acc; + } + + + +template +arma_inline +typename arma_cx_only::result +dense_sparse_helper::dot(const eT* A_mem, const SpMat& B, const uword col) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + uword col_offset = B.col_ptrs[col ]; + const uword next_col_offset = B.col_ptrs[col + 1]; + + const uword* start_ptr = &(B.row_indices[ col_offset]); + const uword* end_ptr = &(B.row_indices[next_col_offset]); + + const eT* B_values = B.values; + + T acc_real = T(0); + T acc_imag = T(0); + + for(const uword* ptr = start_ptr; ptr != end_ptr; ++ptr) + { + const uword index = (*ptr); + + const std::complex& X = A_mem[index]; + const std::complex& Y = B_values[col_offset]; + + const T a = X.real(); + const T b = X.imag(); + + const T c = Y.real(); + const T d = Y.imag(); + + acc_real += (a*c) - (b*d); + acc_imag += (a*d) + (b*c); + + ++col_offset; + } + + return std::complex(acc_real, acc_imag); + } + + + +template +inline +void +glue_times_dense_sparse::apply(Mat& out, const SpToDGlue& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + if(is_op_diagmat::value) { out = SpMat(expr.A) * expr.B; return; } // SpMat has specialised handling for op_diagmat + + const quasi_unwrap UA(expr.A); + + if(UA.is_alias(out)) + { + Mat tmp; + + glue_times_dense_sparse::apply_noalias(tmp, UA.M, expr.B); + + out.steal_mem(tmp); + } + else + { + glue_times_dense_sparse::apply_noalias(out, UA.M, expr.B); + } + } + + + +template +inline +void +glue_times_dense_sparse::apply_noalias(Mat& out, const T1& x, const T2& y) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const quasi_unwrap UA(x); + const Mat& A = UA.M; + + const unwrap_spmat UB(y); + const SpMat& B = UB.M; + + arma_debug_assert_mul_size(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication"); + + out.set_size(A.n_rows, B.n_cols); + + if((A.n_elem == 0) || (B.n_nonzero == 0)) { out.zeros(); return; } + + if((resolves_to_rowvector::value) || (A.n_rows == 1)) + { + arma_extra_debug_print("using row vector specialisation"); + + if( (arma_config::openmp) && (mp_thread_limit::in_parallel() == false) && (B.n_cols >= 2) && mp_gate::eval(B.n_nonzero) ) + { + #if defined(ARMA_USE_OPENMP) + { + arma_extra_debug_print("openmp implementation"); + + eT* out_mem = out.memptr(); + const eT* A_mem = A.memptr(); + + 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 col=0; col < B_n_cols; ++col) + { + out_mem[col] = dense_sparse_helper::dot(A_mem, B, col); + } + } + #endif + } + else + { + arma_extra_debug_print("serial implementation"); + + eT* out_mem = out.memptr(); + const eT* A_mem = A.memptr(); + + const uword B_n_cols = B.n_cols; + + for(uword col=0; col < B_n_cols; ++col) + { + out_mem[col] = dense_sparse_helper::dot(A_mem, B, col); + } + } + } + else + 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 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 < B_n_cols; ++i) + { + 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(&(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) = A.cols(indices) * B_col; + } + } + #endif + } + else + { + arma_extra_debug_print("using standard multiplication"); + + out.zeros(); + + typename SpMat::const_iterator B_it = B.begin(); + + const uword nnz = B.n_nonzero; + const uword out_n_rows = out.n_rows; + + for(uword count = 0; count < nnz; ++count, ++B_it) + { + const eT B_it_val = (*B_it); + const uword B_it_col = B_it.col(); + const uword B_it_row = B_it.row(); + + const eT* A_col = A.colptr(B_it_row); + eT* out_col = out.colptr(B_it_col); + + for(uword row = 0; row < out_n_rows; ++row) + { + out_col[row] += A_col[row] * B_it_val; + } + } + } + } + + + +template +inline +void +glue_times_dense_sparse::apply_mixed(Mat< typename promote_type::result >& out, const T1& X, const T2& Y) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT1; + typedef typename T2::elem_type eT2; + + typedef typename promote_type::result out_eT; + + promote_type::check(); + + if( (is_same_type::no) && (is_same_type::yes) ) + { + // upgrade T1 + + const quasi_unwrap UA(X); + const unwrap_spmat UB(Y); + + const Mat& A = UA.M; + const SpMat& B = UB.M; + + const Mat AA = conv_to< Mat >::from(A); + + const SpMat& BB = reinterpret_cast< const SpMat& >(B); + + glue_times_dense_sparse::apply_noalias(out, AA, BB); + } + else + if( (is_same_type::yes) && (is_same_type::no) ) + { + // upgrade T2 + + const quasi_unwrap UA(X); + const unwrap_spmat UB(Y); + + const Mat& A = UA.M; + const SpMat& B = UB.M; + + const Mat& AA = reinterpret_cast< const Mat& >(A); + + SpMat BB(arma_layout_indicator(), B); + + for(uword i=0; i < B.n_nonzero; ++i) { access::rw(BB.values[i]) = out_eT(B.values[i]); } + + glue_times_dense_sparse::apply_noalias(out, AA, BB); + } + else + { + // upgrade T1 and T2 + + const quasi_unwrap UA(X); + const unwrap_spmat UB(Y); + + const Mat& A = UA.M; + const SpMat& B = UB.M; + + const Mat AA = conv_to< Mat >::from(A); + + SpMat BB(arma_layout_indicator(), B); + + for(uword i=0; i < B.n_nonzero; ++i) { access::rw(BB.values[i]) = out_eT(B.values[i]); } + + glue_times_dense_sparse::apply_noalias(out, AA, BB); + } + } + + + +// + + + +template +inline +void +glue_times_sparse_dense::apply(Mat& out, const SpToDGlue& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + if(is_op_diagmat::value) { out = expr.A * SpMat(expr.B); return; } // SpMat has specialised handling for op_diagmat + + const quasi_unwrap UB(expr.B); + + if((sp_strip_trans::do_htrans && is_cx::no) || (sp_strip_trans::do_strans)) + { + arma_extra_debug_print("detected non-conjugate transpose of A"); + + const sp_strip_trans x_strip(expr.A); + + if(UB.is_alias(out)) + { + Mat tmp; + + glue_times_sparse_dense::apply_noalias_trans(tmp, x_strip.M, UB.M); + + out.steal_mem(tmp); + } + else + { + glue_times_sparse_dense::apply_noalias_trans(out, x_strip.M, UB.M); + } + } + else + { + if(UB.is_alias(out)) + { + Mat tmp; + + glue_times_sparse_dense::apply_noalias(tmp, expr.A, UB.M); + + out.steal_mem(tmp); + } + else + { + glue_times_sparse_dense::apply_noalias(out, expr.A, UB.M); + } + } + } + + + +template +inline +void +glue_times_sparse_dense::apply_noalias(Mat& out, const T1& x, const T2& y) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_spmat UA(x); + const SpMat& A = UA.M; + + const quasi_unwrap UB(y); + const Mat& B = UB.M; + + 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; + + arma_debug_assert_mul_size(A_n_rows, A_n_cols, B_n_rows, B_n_cols, "matrix multiplication"); + + if((resolves_to_colvector::value) || (B_n_cols == 1)) + { + arma_extra_debug_print("using column vector specialisation"); + + out.zeros(A_n_rows, 1); + + eT* out_mem = out.memptr(); + const eT* B_mem = B.memptr(); + + typename SpMat::const_iterator A_it = A.begin(); + + const uword nnz = A.n_nonzero; + + for(uword count = 0; count < nnz; ++count, ++A_it) + { + const eT A_it_val = (*A_it); + const uword A_it_row = A_it.row(); + const uword A_it_col = A_it.col(); + + out_mem[A_it_row] += A_it_val * B_mem[A_it_col]; + } + } + else + if(B_n_cols >= (B_n_rows / uword(100))) + { + arma_extra_debug_print("using transpose-based multiplication"); + + const SpMat At = A.st(); + const Mat Bt = B.st(); + + if(A_n_rows == B_n_cols) + { + glue_times_dense_sparse::apply_noalias(out, Bt, At); + + op_strans::apply_mat(out, out); // since 'out' is square-sized, this will do an inplace transpose + } + else + { + Mat tmp; + + glue_times_dense_sparse::apply_noalias(tmp, Bt, At); + + op_strans::apply_mat(out, tmp); + } + } + else + { + arma_extra_debug_print("using standard multiplication"); + + out.zeros(A_n_rows, B_n_cols); + + typename SpMat::const_iterator A_it = A.begin(); + + const uword nnz = A.n_nonzero; + + for(uword count = 0; count < nnz; ++count, ++A_it) + { + const eT A_it_val = (*A_it); + const uword A_it_row = A_it.row(); + const uword A_it_col = A_it.col(); + + for(uword col = 0; col < B_n_cols; ++col) + { + out.at(A_it_row, col) += A_it_val * B.at(A_it_col, col); + } + } + } + } + + + +template +inline +void +glue_times_sparse_dense::apply_noalias_trans(Mat& out, const T1& x, const T2& y) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_spmat UA(x); + const SpMat& A = UA.M; // NOTE: this is the given matrix without the transpose operation applied + + const quasi_unwrap UB(y); + const Mat& B = UB.M; + + 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; + + arma_debug_assert_mul_size(A_n_cols, A_n_rows, B_n_rows, B_n_cols, "matrix multiplication"); + + if((resolves_to_colvector::value) || (B_n_cols == 1)) + { + arma_extra_debug_print("using column vector specialisation (avoiding transpose of A)"); + + if( (arma_config::openmp) && (mp_thread_limit::in_parallel() == false) && (A_n_cols >= 2) && mp_gate::eval(A.n_nonzero) ) + { + arma_extra_debug_print("opemp implementation"); + + #if defined(ARMA_USE_OPENMP) + { + out.zeros(A_n_cols, 1); + + eT* out_mem = out.memptr(); + const eT* B_mem = B.memptr(); + + const int n_threads = mp_thread_limit::get(); + + #pragma omp parallel for schedule(static) num_threads(n_threads) + for(uword col=0; col < A_n_cols; ++col) + { + out_mem[col] = dense_sparse_helper::dot(B_mem, A, col); + } + } + #endif + } + else + { + arma_extra_debug_print("serial implementation"); + + out.zeros(A_n_cols, 1); + + eT* out_mem = out.memptr(); + const eT* B_mem = B.memptr(); + + for(uword col=0; col < A_n_cols; ++col) + { + out_mem[col] = dense_sparse_helper::dot(B_mem, A, col); + } + } + } + else + if(B_n_cols >= (B_n_rows / uword(100))) + { + arma_extra_debug_print("using transpose-based multiplication (avoiding transpose of A)"); + + const Mat Bt = B.st(); + + if(A_n_cols == B_n_cols) + { + glue_times_dense_sparse::apply_noalias(out, Bt, A); + + op_strans::apply_mat(out, out); // since 'out' is square-sized, this will do an inplace transpose + } + else + { + Mat tmp; + + glue_times_dense_sparse::apply_noalias(tmp, Bt, A); + + op_strans::apply_mat(out, tmp); + } + } + else + { + arma_extra_debug_print("using standard multiplication (avoiding transpose of A)"); + + out.zeros(A_n_cols, B_n_cols); + + typename SpMat::const_iterator A_it = A.begin(); + + const uword nnz = A.n_nonzero; + + for(uword count = 0; count < nnz; ++count, ++A_it) + { + const eT A_it_val = (*A_it); + const uword A_it_row = A_it.row(); + const uword A_it_col = A_it.col(); + + for(uword col = 0; col < B_n_cols; ++col) + { + out.at(A_it_col, col) += A_it_val * B.at(A_it_row, col); + } + } + } + } + + + +template +inline +void +glue_times_sparse_dense::apply_mixed(Mat< typename promote_type::result >& out, const T1& X, const T2& Y) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT1; + typedef typename T2::elem_type eT2; + + typedef typename promote_type::result out_eT; + + promote_type::check(); + + if( (is_same_type::no) && (is_same_type::yes) ) + { + // upgrade T1 + + const unwrap_spmat UA(X); + const quasi_unwrap UB(Y); + + const SpMat& A = UA.M; + const Mat& B = UB.M; + + SpMat AA(arma_layout_indicator(), A); + + for(uword i=0; i < A.n_nonzero; ++i) { access::rw(AA.values[i]) = out_eT(A.values[i]); } + + const Mat& BB = reinterpret_cast< const Mat& >(B); + + glue_times_sparse_dense::apply_noalias(out, AA, BB); + } + else + if( (is_same_type::yes) && (is_same_type::no) ) + { + // upgrade T2 + + const unwrap_spmat UA(X); + const quasi_unwrap UB(Y); + + const SpMat& A = UA.M; + const Mat& B = UB.M; + + const SpMat& AA = reinterpret_cast< const SpMat& >(A); + + const Mat BB = conv_to< Mat >::from(B); + + glue_times_sparse_dense::apply_noalias(out, AA, BB); + } + else + { + // upgrade T1 and T2 + + const unwrap_spmat UA(X); + const quasi_unwrap UB(Y); + + const SpMat& A = UA.M; + const Mat& B = UB.M; + + SpMat AA(arma_layout_indicator(), A); + + for(uword i=0; i < A.n_nonzero; ++i) { access::rw(AA.values[i]) = out_eT(A.values[i]); } + + const Mat BB = conv_to< Mat >::from(B); + + glue_times_sparse_dense::apply_noalias(out, AA, BB); + } + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_diag_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/gmm_diag_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_diag_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/gmm_diag_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -151,9 +151,9 @@ "gmm_diag::set_params(): given parameters have inconsistent and/or wrong sizes" ); - arma_debug_check( (in_means.is_finite() == false), "gmm_diag::set_params(): given means have non-finite values" ); - arma_debug_check( (in_dcovs.is_finite() == false), "gmm_diag::set_params(): given dcovs have non-finite values" ); - arma_debug_check( (in_hefts.is_finite() == false), "gmm_diag::set_params(): given hefts have non-finite values" ); + arma_debug_check( (in_means.internal_has_nonfinite()), "gmm_diag::set_params(): given means have non-finite values" ); + arma_debug_check( (in_dcovs.internal_has_nonfinite()), "gmm_diag::set_params(): given dcovs have non-finite values" ); + arma_debug_check( (in_hefts.internal_has_nonfinite()), "gmm_diag::set_params(): given hefts have non-finite values" ); arma_debug_check( (any(vectorise(in_dcovs) <= eT(0))), "gmm_diag::set_params(): given dcovs have negative or zero values" ); arma_debug_check( (any(vectorise(in_hefts) < eT(0))), "gmm_diag::set_params(): given hefts have negative values" ); @@ -184,7 +184,7 @@ const Mat& in_means = tmp.M; arma_debug_check( (arma::size(in_means) != arma::size(means)), "gmm_diag::set_means(): given means have incompatible size" ); - arma_debug_check( (in_means.is_finite() == false), "gmm_diag::set_means(): given means have non-finite values" ); + arma_debug_check( (in_means.internal_has_nonfinite()), "gmm_diag::set_means(): given means have non-finite values" ); access::rw(means) = in_means; } @@ -204,7 +204,7 @@ const Mat& in_dcovs = tmp.M; arma_debug_check( (arma::size(in_dcovs) != arma::size(dcovs)), "gmm_diag::set_dcovs(): given dcovs have incompatible size" ); - arma_debug_check( (in_dcovs.is_finite() == false), "gmm_diag::set_dcovs(): given dcovs have non-finite values" ); + arma_debug_check( (in_dcovs.internal_has_nonfinite()), "gmm_diag::set_dcovs(): given dcovs have non-finite values" ); arma_debug_check( (any(vectorise(in_dcovs) <= eT(0))), "gmm_diag::set_dcovs(): given dcovs have negative or zero values" ); access::rw(dcovs) = in_dcovs; @@ -227,7 +227,7 @@ const Mat& in_hefts = tmp.M; arma_debug_check( (arma::size(in_hefts) != arma::size(hefts)), "gmm_diag::set_hefts(): given hefts have incompatible size" ); - arma_debug_check( (in_hefts.is_finite() == false), "gmm_diag::set_hefts(): given hefts have non-finite values" ); + arma_debug_check( (in_hefts.internal_has_nonfinite()), "gmm_diag::set_hefts(): given hefts have non-finite values" ); arma_debug_check( (any(vectorise(in_hefts) < eT(0))), "gmm_diag::set_hefts(): given hefts have negative values" ); const eT s = accu(in_hefts); @@ -690,8 +690,8 @@ const unwrap tmp_X(data.get_ref()); const Mat& X = tmp_X.M; - 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(X.is_empty() ) { arma_debug_warn_level(3, "gmm_diag::learn(): given matrix is empty" ); return false; } + if(X.internal_has_nonfinite()) { arma_debug_warn_level(3, "gmm_diag::learn(): given matrix has non-finite values"); return false; } if(N_gaus == 0) { reset(); return true; } @@ -818,8 +818,8 @@ const unwrap tmp_X(data.get_ref()); const Mat& X = tmp_X.M; - 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(X.is_empty() ) { arma_debug_warn_level(3, "kmeans(): given matrix is empty" ); return false; } + if(X.internal_has_nonfinite()) { arma_debug_warn_level(3, "kmeans(): given matrix has non-finite values"); return false; } if(N_gaus == 0) { reset(); return true; } @@ -1052,7 +1052,6 @@ template -arma_hot inline eT gmm_diag::internal_scalar_log_p(const eT* x) const @@ -1085,7 +1084,6 @@ template -arma_hot inline eT gmm_diag::internal_scalar_log_p(const eT* x, const uword g) const @@ -2159,6 +2157,10 @@ } #else { + acc_hefts.zeros(); + acc_means.zeros(); + last_indx.zeros(); + uword* acc_hefts_mem = acc_hefts.memptr(); uword* last_indx_mem = last_indx.memptr(); @@ -2275,7 +2277,7 @@ access::rw(means) = old_means; - if(means.is_finite() == false) { return false; } + if(means.internal_has_nonfinite()) { return false; } return true; } @@ -2369,9 +2371,9 @@ if(any(vectorise(dcovs) <= eT(0))) { return false; } - if(means.is_finite() == false ) { return false; } - if(dcovs.is_finite() == false ) { return false; } - if(hefts.is_finite() == false ) { return false; } + if(means.internal_has_nonfinite()) { return false; } + if(dcovs.internal_has_nonfinite()) { return false; } + if(hefts.internal_has_nonfinite()) { return false; } return true; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_full_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/gmm_full_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_full_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/gmm_full_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -151,9 +151,9 @@ "gmm_full::set_params(): given parameters have inconsistent and/or wrong sizes" ); - arma_debug_check( (in_means.is_finite() == false), "gmm_full::set_params(): given means have non-finite values" ); - arma_debug_check( (in_fcovs.is_finite() == false), "gmm_full::set_params(): given fcovs have non-finite values" ); - arma_debug_check( (in_hefts.is_finite() == false), "gmm_full::set_params(): given hefts have non-finite values" ); + arma_debug_check( (in_means.internal_has_nonfinite()), "gmm_full::set_params(): given means have non-finite values" ); + arma_debug_check( (in_fcovs.internal_has_nonfinite()), "gmm_full::set_params(): given fcovs have non-finite values" ); + arma_debug_check( (in_hefts.internal_has_nonfinite()), "gmm_full::set_params(): given hefts have non-finite values" ); for(uword g=0; g < in_fcovs.n_slices; ++g) { @@ -188,7 +188,7 @@ const Mat& in_means = tmp.M; arma_debug_check( (arma::size(in_means) != arma::size(means)), "gmm_full::set_means(): given means have incompatible size" ); - arma_debug_check( (in_means.is_finite() == false), "gmm_full::set_means(): given means have non-finite values" ); + arma_debug_check( (in_means.internal_has_nonfinite()), "gmm_full::set_means(): given means have non-finite values" ); access::rw(means) = in_means; } @@ -208,7 +208,7 @@ const Cube& in_fcovs = tmp.M; arma_debug_check( (arma::size(in_fcovs) != arma::size(fcovs)), "gmm_full::set_fcovs(): given fcovs have incompatible size" ); - arma_debug_check( (in_fcovs.is_finite() == false), "gmm_full::set_fcovs(): given fcovs have non-finite values" ); + arma_debug_check( (in_fcovs.internal_has_nonfinite()), "gmm_full::set_fcovs(): given fcovs have non-finite values" ); for(uword i=0; i < in_fcovs.n_slices; ++i) { @@ -235,7 +235,7 @@ const Mat& in_hefts = tmp.M; arma_debug_check( (arma::size(in_hefts) != arma::size(hefts)), "gmm_full::set_hefts(): given hefts have incompatible size" ); - arma_debug_check( (in_hefts.is_finite() == false), "gmm_full::set_hefts(): given hefts have non-finite values" ); + arma_debug_check( (in_hefts.internal_has_nonfinite()), "gmm_full::set_hefts(): given hefts have non-finite values" ); arma_debug_check( (any(vectorise(in_hefts) < eT(0))), "gmm_full::set_hefts(): given hefts have negative values" ); const eT s = accu(in_hefts); @@ -729,8 +729,8 @@ const unwrap tmp_X(data.get_ref()); const Mat& X = tmp_X.M; - 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(X.is_empty() ) { arma_debug_warn_level(3, "gmm_full::learn(): given matrix is empty" ); return false; } + if(X.internal_has_nonfinite()) { arma_debug_warn_level(3, "gmm_full::learn(): given matrix has non-finite values"); return false; } if(N_gaus == 0) { reset(); return true; } @@ -2188,6 +2188,10 @@ } #else { + acc_hefts.zeros(); + acc_means.zeros(); + last_indx.zeros(); + uword* acc_hefts_mem = acc_hefts.memptr(); uword* last_indx_mem = last_indx.memptr(); @@ -2304,7 +2308,7 @@ access::rw(means) = old_means; - if(means.is_finite() == false) { return false; } + if(means.internal_has_nonfinite()) { return false; } return true; } @@ -2404,9 +2408,9 @@ if(any(vectorise(fcov.diag()) <= eT(0))) { return false; } } - if(means.is_finite() == false) { return false; } - if(fcovs.is_finite() == false) { return false; } - if(hefts.is_finite() == false) { return false; } + if(means.internal_has_nonfinite()) { return false; } + if(fcovs.internal_has_nonfinite()) { return false; } + if(hefts.internal_has_nonfinite()) { return false; } return true; } @@ -2537,7 +2541,7 @@ if(val < var_floor) { val = var_floor; } } - if(acc_fcov.is_finite() == false) { continue; } + if(acc_fcov.internal_has_nonfinite()) { continue; } eT log_det_val = eT(0); eT log_det_sign = eT(0); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_misc_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/gmm_misc_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_misc_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/gmm_misc_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -20,37 +20,37 @@ //! @{ -struct gmm_dist_mode { const uword id; inline explicit gmm_dist_mode(const uword in_id) : id(in_id) {} }; +struct gmm_dist_mode { const uword id; inline constexpr explicit gmm_dist_mode(const uword in_id) : id(in_id) {} }; inline bool operator==(const gmm_dist_mode& a, const gmm_dist_mode& b) { return (a.id == b.id); } inline bool operator!=(const gmm_dist_mode& a, const gmm_dist_mode& b) { return (a.id != b.id); } -struct gmm_dist_eucl : public gmm_dist_mode { inline gmm_dist_eucl() : gmm_dist_mode(1) {} }; -struct gmm_dist_maha : public gmm_dist_mode { inline gmm_dist_maha() : gmm_dist_mode(2) {} }; -struct gmm_dist_prob : public gmm_dist_mode { inline gmm_dist_prob() : gmm_dist_mode(3) {} }; +struct gmm_dist_eucl : public gmm_dist_mode { inline constexpr gmm_dist_eucl() : gmm_dist_mode(1) {} }; +struct gmm_dist_maha : public gmm_dist_mode { inline constexpr gmm_dist_maha() : gmm_dist_mode(2) {} }; +struct gmm_dist_prob : public gmm_dist_mode { inline constexpr gmm_dist_prob() : gmm_dist_mode(3) {} }; -static const gmm_dist_eucl eucl_dist; -static const gmm_dist_maha maha_dist; -static const gmm_dist_prob prob_dist; +static constexpr gmm_dist_eucl eucl_dist; +static constexpr gmm_dist_maha maha_dist; +static constexpr gmm_dist_prob prob_dist; -struct gmm_seed_mode { const uword id; inline explicit gmm_seed_mode(const uword in_id) : id(in_id) {} }; +struct gmm_seed_mode { const uword id; inline constexpr explicit gmm_seed_mode(const uword in_id) : id(in_id) {} }; inline bool operator==(const gmm_seed_mode& a, const gmm_seed_mode& b) { return (a.id == b.id); } inline bool operator!=(const gmm_seed_mode& a, const gmm_seed_mode& b) { return (a.id != b.id); } -struct gmm_seed_keep_existing : public gmm_seed_mode { inline gmm_seed_keep_existing() : gmm_seed_mode(1) {} }; -struct gmm_seed_static_subset : public gmm_seed_mode { inline gmm_seed_static_subset() : gmm_seed_mode(2) {} }; -struct gmm_seed_static_spread : public gmm_seed_mode { inline gmm_seed_static_spread() : gmm_seed_mode(3) {} }; -struct gmm_seed_random_subset : public gmm_seed_mode { inline gmm_seed_random_subset() : gmm_seed_mode(4) {} }; -struct gmm_seed_random_spread : public gmm_seed_mode { inline gmm_seed_random_spread() : gmm_seed_mode(5) {} }; - -static const gmm_seed_keep_existing keep_existing; -static const gmm_seed_static_subset static_subset; -static const gmm_seed_static_spread static_spread; -static const gmm_seed_random_subset random_subset; -static const gmm_seed_random_spread random_spread; +struct gmm_seed_keep_existing : public gmm_seed_mode { inline constexpr gmm_seed_keep_existing() : gmm_seed_mode(1) {} }; +struct gmm_seed_static_subset : public gmm_seed_mode { inline constexpr gmm_seed_static_subset() : gmm_seed_mode(2) {} }; +struct gmm_seed_static_spread : public gmm_seed_mode { inline constexpr gmm_seed_static_spread() : gmm_seed_mode(3) {} }; +struct gmm_seed_random_subset : public gmm_seed_mode { inline constexpr gmm_seed_random_subset() : gmm_seed_mode(4) {} }; +struct gmm_seed_random_spread : public gmm_seed_mode { inline constexpr gmm_seed_random_spread() : gmm_seed_mode(5) {} }; + +static constexpr gmm_seed_keep_existing keep_existing; +static constexpr gmm_seed_static_subset static_subset; +static constexpr gmm_seed_static_spread static_spread; +static constexpr gmm_seed_random_subset random_subset; +static constexpr gmm_seed_random_spread random_spread; namespace gmm_priv diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_misc_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/gmm_misc_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/gmm_misc_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/gmm_misc_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -62,7 +62,6 @@ template -arma_hot inline void running_mean_scalar::operator() (const eT X) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/hdf5_misc.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/hdf5_misc.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/hdf5_misc.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/hdf5_misc.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -46,7 +46,7 @@ hid_t get_hdf5_type< unsigned char >() { - return arma_H5Tcopy(arma_H5T_NATIVE_UCHAR); + return H5Tcopy(H5T_NATIVE_UCHAR); } template<> @@ -54,7 +54,7 @@ hid_t get_hdf5_type< char >() { - return arma_H5Tcopy(arma_H5T_NATIVE_CHAR); + return H5Tcopy(H5T_NATIVE_CHAR); } template<> @@ -62,7 +62,7 @@ hid_t get_hdf5_type< short >() { - return arma_H5Tcopy(arma_H5T_NATIVE_SHORT); + return H5Tcopy(H5T_NATIVE_SHORT); } template<> @@ -70,7 +70,7 @@ hid_t get_hdf5_type< unsigned short >() { - return arma_H5Tcopy(arma_H5T_NATIVE_USHORT); + return H5Tcopy(H5T_NATIVE_USHORT); } template<> @@ -78,7 +78,7 @@ hid_t get_hdf5_type< int >() { - return arma_H5Tcopy(arma_H5T_NATIVE_INT); + return H5Tcopy(H5T_NATIVE_INT); } template<> @@ -86,7 +86,7 @@ hid_t get_hdf5_type< unsigned int >() { - return arma_H5Tcopy(arma_H5T_NATIVE_UINT); + return H5Tcopy(H5T_NATIVE_UINT); } template<> @@ -94,7 +94,7 @@ hid_t get_hdf5_type< long >() { - return arma_H5Tcopy(arma_H5T_NATIVE_LONG); + return H5Tcopy(H5T_NATIVE_LONG); } template<> @@ -102,7 +102,7 @@ hid_t get_hdf5_type< unsigned long >() { - return arma_H5Tcopy(arma_H5T_NATIVE_ULONG); + return H5Tcopy(H5T_NATIVE_ULONG); } template<> @@ -110,7 +110,7 @@ hid_t get_hdf5_type< long long >() { - return arma_H5Tcopy(arma_H5T_NATIVE_LLONG); + return H5Tcopy(H5T_NATIVE_LLONG); } template<> @@ -118,7 +118,7 @@ hid_t get_hdf5_type< unsigned long long >() { - return arma_H5Tcopy(arma_H5T_NATIVE_ULLONG); + return H5Tcopy(H5T_NATIVE_ULLONG); } template<> @@ -126,7 +126,7 @@ hid_t get_hdf5_type< float >() { - return arma_H5Tcopy(arma_H5T_NATIVE_FLOAT); + return H5Tcopy(H5T_NATIVE_FLOAT); } template<> @@ -134,7 +134,7 @@ hid_t get_hdf5_type< double >() { - return arma_H5Tcopy(arma_H5T_NATIVE_DOUBLE); + return H5Tcopy(H5T_NATIVE_DOUBLE); } @@ -154,10 +154,10 @@ hid_t get_hdf5_type< std::complex >() { - hid_t type = arma_H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t)); + hid_t type = H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t)); - arma_H5Tinsert(type, "real", HOFFSET(hdf5_complex_t, real), arma_H5T_NATIVE_FLOAT); - arma_H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t, imag), arma_H5T_NATIVE_FLOAT); + H5Tinsert(type, "real", HOFFSET(hdf5_complex_t, real), H5T_NATIVE_FLOAT); + H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t, imag), H5T_NATIVE_FLOAT); return type; } @@ -169,10 +169,10 @@ hid_t get_hdf5_type< std::complex >() { - hid_t type = arma_H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t)); + hid_t type = H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t)); - arma_H5Tinsert(type, "real", HOFFSET(hdf5_complex_t, real), arma_H5T_NATIVE_DOUBLE); - arma_H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t, imag), arma_H5T_NATIVE_DOUBLE); + H5Tinsert(type, "real", HOFFSET(hdf5_complex_t, real), H5T_NATIVE_DOUBLE); + H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t, imag), H5T_NATIVE_DOUBLE); return type; } @@ -192,76 +192,76 @@ // start with most likely used types: double, complex, float, complex search_type = get_hdf5_type(); - is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); - arma_H5Tclose(search_type); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + H5Tclose(search_type); if(is_equal) { return true; } search_type = get_hdf5_type< std::complex >(); - is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); - arma_H5Tclose(search_type); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + H5Tclose(search_type); if(is_equal) { return true; } search_type = get_hdf5_type< std::complex >(); - is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); - arma_H5Tclose(search_type); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + H5Tclose(search_type); if(is_equal) { return true; } // remaining supported types: u8, s8, u16, s16, u32, s32, u64, s64, ulng_t, slng_t search_type = get_hdf5_type(); - is_equal = ( arma_H5Tequal(datatype, search_type) > 0 ); - arma_H5Tclose(search_type); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + 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); + is_equal = ( H5Tequal(datatype, search_type) > 0 ); + H5Tclose(search_type); if(is_equal) { return true; } return false; @@ -297,13 +297,13 @@ 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); - hid_t datatype = arma_H5Dget_type(dataset); + hid_t dataset = H5Dopen(loc_id, name, H5P_DEFAULT); + hid_t datatype = H5Dget_type(dataset); const bool is_supported = is_supported_arma_hdf5_type(datatype); - arma_H5Tclose(datatype); - arma_H5Dclose(dataset); + H5Tclose(datatype); + H5Dclose(dataset); if(is_supported == false) { @@ -340,7 +340,7 @@ if(str == search_info->names[string_pos]) { // We found it exactly. - hid_t match_candidate = arma_H5Dopen(loc_id, name, H5P_DEFAULT); + hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT); if(match_candidate < 0) { @@ -348,8 +348,8 @@ } // Ensure that the dataset is valid and of the correct dimensionality. - hid_t filespace = arma_H5Dget_space(match_candidate); - int num_dims = arma_H5Sget_simple_extent_ndims(filespace); + hid_t filespace = H5Dget_space(match_candidate); + int num_dims = H5Sget_simple_extent_ndims(filespace); if(num_dims <= search_info->num_dims) { @@ -357,14 +357,14 @@ // If we already have an existing match we have to close it. if(search_info->best_match != -1) { - arma_H5Dclose(search_info->best_match); + H5Dclose(search_info->best_match); } search_info->best_match_position = string_pos; search_info->best_match = match_candidate; } - arma_H5Sclose(filespace); + H5Sclose(filespace); // There is no possibility of anything better, so terminate the search. return 1; } @@ -393,7 +393,7 @@ 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); + hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT); // arma_check(match_candidate < 0, "Mat::load(): cannot open an HDF5 dataset"); @@ -404,8 +404,8 @@ // Ensure that the dataset is valid and of the correct dimensionality. - hid_t filespace = arma_H5Dget_space(match_candidate); - int num_dims = arma_H5Sget_simple_extent_ndims(filespace); + hid_t filespace = H5Dget_space(match_candidate); + int num_dims = H5Sget_simple_extent_ndims(filespace); if(num_dims <= search_info->num_dims) { @@ -413,14 +413,14 @@ // If we already have an existing match we have to close it. if(search_info->best_match != -1) { - arma_H5Dclose(search_info->best_match); + H5Dclose(search_info->best_match); } search_info->best_match_position = string_pos; search_info->best_match = match_candidate; } - arma_H5Sclose(filespace); + H5Sclose(filespace); } } @@ -428,7 +428,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)) { - hid_t match_candidate = arma_H5Dopen(loc_id, name, H5P_DEFAULT); + hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT); // arma_check(match_candidate < 0, "Mat::load(): cannot open an HDF5 dataset"); if(match_candidate < 0) @@ -436,16 +436,16 @@ return -1; } - hid_t filespace = arma_H5Dget_space(match_candidate); - int num_dims = arma_H5Sget_simple_extent_ndims(filespace); + hid_t filespace = H5Dget_space(match_candidate); + int num_dims = H5Sget_simple_extent_ndims(filespace); if(num_dims <= search_info->num_dims) { // Valid dataset -- we'll keep it. - search_info->best_match = arma_H5Dopen(loc_id, name, H5P_DEFAULT); + search_info->best_match = H5Dopen(loc_id, name, H5P_DEFAULT); } - arma_H5Sclose(filespace); + H5Sclose(filespace); } } } @@ -475,7 +475,7 @@ hdf5_search_info search_info = { names, num_dims, exact, -1, names.size() }; // We'll use the H5Ovisit to track potential entries. - herr_t status = arma_H5Ovisit(hdf5_file, H5_INDEX_NAME, H5_ITER_NATIVE, hdf5_search_callback, void_ptr(&search_info)); + herr_t status = H5Ovisit(hdf5_file, H5_INDEX_NAME, H5_ITER_NATIVE, hdf5_search_callback, void_ptr(&search_info)); // Return the best match; it will be -1 if there was a problem. return (status < 0) ? -1 : search_info.best_match; @@ -508,13 +508,13 @@ // u8 search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -523,13 +523,13 @@ // s8 search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -538,13 +538,13 @@ // u16 search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -553,13 +553,13 @@ // s16 search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -568,13 +568,13 @@ // u32 search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -583,13 +583,13 @@ // s32 search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -598,13 +598,13 @@ // u64 search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -613,13 +613,13 @@ // s64 search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -628,13 +628,13 @@ // ulng_t search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -643,13 +643,13 @@ // slng_t search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -658,13 +658,13 @@ // float search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -673,13 +673,13 @@ // double search_type = get_hdf5_type(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert(dest, v.memptr(), n_elem); return status; @@ -688,8 +688,8 @@ // complex float search_type = get_hdf5_type< std::complex >(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + H5Tclose(search_type); if(is_equal) { @@ -699,7 +699,7 @@ } 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert_cx(dest, v.memptr(), n_elem); return status; @@ -708,8 +708,8 @@ // complex double search_type = get_hdf5_type< std::complex >(); - is_equal = (arma_H5Tequal(datatype, search_type) > 0); - arma_H5Tclose(search_type); + is_equal = (H5Tequal(datatype, search_type) > 0); + H5Tclose(search_type); if(is_equal) { @@ -719,7 +719,7 @@ } 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())); + hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr())); arrayops::convert_cx(dest, v.memptr(), n_elem); return status; @@ -733,7 +733,7 @@ struct hdf5_suspend_printing_errors { - #if defined(ARMA_PRINT_HDF5_ERRORS) + #if (ARMA_WARN_LEVEL >= 3) inline hdf5_suspend_printing_errors() {} @@ -747,16 +747,16 @@ hdf5_suspend_printing_errors() { // Save old error handler. - arma_H5Eget_auto(H5E_DEFAULT, &old_client_func, &old_client_data); + H5Eget_auto(H5E_DEFAULT, &old_client_func, &old_client_data); // Disable annoying HDF5 error messages. - arma_H5Eset_auto(H5E_DEFAULT, NULL, NULL); + H5Eset_auto(H5E_DEFAULT, NULL, NULL); } inline ~hdf5_suspend_printing_errors() { - arma_H5Eset_auto(H5E_DEFAULT, old_client_func, old_client_data); + H5Eset_auto(H5E_DEFAULT, old_client_func, old_client_data); } #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/hdf5_name.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/hdf5_name.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/hdf5_name.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/hdf5_name.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -28,12 +28,13 @@ { const flag_type flags; - inline explicit opts(const flag_type in_flags); + inline constexpr explicit opts(const flag_type in_flags); inline const opts operator+(const opts& rhs) const; }; inline + constexpr opts::opts(const flag_type in_flags) : flags(in_flags) {} @@ -50,20 +51,20 @@ // 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; + static constexpr flag_type flag_none = flag_type(0 ); + static constexpr flag_type flag_trans = flag_type(1u << 0); + static constexpr flag_type flag_append = flag_type(1u << 1); + static constexpr flag_type flag_replace = flag_type(1u << 2); + + struct opts_none : public opts { inline constexpr opts_none() : opts(flag_none ) {} }; + struct opts_trans : public opts { inline constexpr opts_trans() : opts(flag_trans ) {} }; + struct opts_append : public opts { inline constexpr opts_append() : opts(flag_append ) {} }; + struct opts_replace : public opts { inline constexpr opts_replace() : opts(flag_replace) {} }; + + static constexpr opts_none none; + static constexpr opts_trans trans; + static constexpr opts_append append; + static constexpr opts_replace replace; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/include_atlas.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/include_atlas.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/include_atlas.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/include_atlas.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -// 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. -// ------------------------------------------------------------------------ - - -#if defined(ARMA_USE_ATLAS) - #if !defined(ARMA_ATLAS_INCLUDE_DIR) - extern "C" - { - #include - #include - } - #else - #define ARMA_STR1(x) x - #define ARMA_STR2(x) ARMA_STR1(x) - - #define ARMA_CBLAS ARMA_STR2(ARMA_ATLAS_INCLUDE_DIR)ARMA_STR2(cblas.h) - #define ARMA_CLAPACK ARMA_STR2(ARMA_ATLAS_INCLUDE_DIR)ARMA_STR2(clapack.h) - - extern "C" - { - #include ARMA_INCFILE_WRAP(ARMA_CBLAS) - #include ARMA_INCFILE_WRAP(ARMA_CLAPACK) - } - - #undef ARMA_STR1 - #undef ARMA_STR2 - #undef ARMA_CBLAS - #undef ARMA_CLAPACK - #endif -#endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/include_hdf5.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/include_hdf5.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/include_hdf5.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/include_hdf5.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,24 +21,25 @@ #undef H5_USE_110_API #define H5_USE_110_API - #if !defined(ARMA_HDF5_INCLUDE_DIR) - #include + #if defined(__has_include) + #if __has_include() + #include + #else + #undef ARMA_USE_HDF5 + #pragma message ("WARNING: use of HDF5 disabled; hdf5.h header not found") + #endif #else - #define ARMA_STR1(x) x - #define ARMA_STR2(x) ARMA_STR1(x) - - #define ARMA_HDF5_HEADER ARMA_STR2(ARMA_HDF5_INCLUDE_DIR)ARMA_STR2(hdf5.h) - - #include ARMA_INCFILE_WRAP(ARMA_HDF5_HEADER) - - #undef ARMA_STR1 - #undef ARMA_STR2 - #undef ARMA_HDF5_HEADER + #include #endif - - #if defined(H5_USE_16_API_DEFAULT) || defined(H5_USE_16_API) - #pragma message ("WARNING: disabling use of HDF5 due to its incompatible configuration") + + #if defined(H5_USE_16_API) || defined(H5_USE_16_API_DEFAULT) + #pragma message ("WARNING: use of HDF5 disabled; incompatible configuration: H5_USE_16_API or H5_USE_16_API_DEFAULT") #undef ARMA_USE_HDF5 - #undef ARMA_USE_HDF5_ALT #endif + + // // TODO + // #if defined(H5_USE_18_API) || defined(H5_USE_18_API_DEFAULT) + // #pragma message ("WARNING: detected possibly incompatible configuration of HDF5: H5_USE_18_API or H5_USE_18_API_DEFAULT") + // #endif + #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/include_superlu.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/include_superlu.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/include_superlu.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/include_superlu.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 +// 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) @@ -54,8 +54,7 @@ #if defined(ARMA_USE_SUPERLU) - -#if defined(ARMA_USE_SUPERLU_HEADERS) || defined(ARMA_SUPERLU_INCLUDE_DIR) +#undef ARMA_SLU_HEADERS_FOUND // Since we need to suport float, double, cx_float and cx_double, // as well as preserve the sanity of the user, @@ -70,142 +69,173 @@ namespace arma { - namespace superlu { // slu_*defs.h has int typedefed to int_t. // I'll just write it as int for simplicity, where I can, but supermatrix.h needs int_t. typedef int int_t; - + } +} + +#if defined(ARMA_USE_SUPERLU_HEADERS) || defined(ARMA_SUPERLU_INCLUDE_DIR) + +namespace arma +{ +namespace superlu + { // Include supermatrix.h. This gives us SuperMatrix. // Put it in the slu namespace. // For versions of SuperLU I am familiar with, supermatrix.h does not include any other files. // Therefore, putting it in the superlu namespace is reasonably safe. // This same reasoning is true for superlu_enum_consts.h. + #undef ARMA_SLU_HEADER_A + #undef ARMA_SLU_HEADER_B + #if defined(ARMA_SUPERLU_INCLUDE_DIR) - #define ARMA_SLU_STR(x) x - #define ARMA_SLU_STR2(x) ARMA_SLU_STR(x) + #undef ARMA_SLU_STR1 + #undef ARMA_SLU_STR2 - #define ARMA_SLU_SUPERMATRIX_H ARMA_SLU_STR2(ARMA_SUPERLU_INCLUDE_DIR)ARMA_SLU_STR2(supermatrix.h) - #define ARMA_SLU_SUPERLU_ENUM_CONSTS_H ARMA_SLU_STR2(ARMA_SUPERLU_INCLUDE_DIR)ARMA_SLU_STR2(superlu_enum_consts.h) + #define ARMA_SLU_STR1(x) x + #define ARMA_SLU_STR2(x) ARMA_SLU_STR1(x) + + #define ARMA_SLU_HEADER_A ARMA_SLU_STR2(ARMA_SUPERLU_INCLUDE_DIR)ARMA_SLU_STR2(supermatrix.h) + #define ARMA_SLU_HEADER_B ARMA_SLU_STR2(ARMA_SUPERLU_INCLUDE_DIR)ARMA_SLU_STR2(superlu_enum_consts.h) #else - #define ARMA_SLU_SUPERMATRIX_H supermatrix.h - #define ARMA_SLU_SUPERLU_ENUM_CONSTS_H superlu_enum_consts.h + #define ARMA_SLU_HEADER_A supermatrix.h + #define ARMA_SLU_HEADER_B superlu_enum_consts.h #endif - #include ARMA_INCFILE_WRAP(ARMA_SLU_SUPERMATRIX_H) - #include ARMA_INCFILE_WRAP(ARMA_SLU_SUPERLU_ENUM_CONSTS_H) - - #undef ARMA_SLU_SUPERMATRIX_H - #undef ARMA_SLU_SUPERLU_ENUM_CONSTS_H - - - typedef struct - { - int* panel_histo; - double* utime; - float* ops; - int TinyPivots; - int RefineSteps; - int expansions; - } SuperLUStat_t; - - - typedef struct - { - fact_t Fact; - yes_no_t Equil; - colperm_t ColPerm; - trans_t Trans; - IterRefine_t IterRefine; - double DiagPivotThresh; - yes_no_t SymmetricMode; - yes_no_t PivotGrowth; - yes_no_t ConditionNumber; - rowperm_t RowPerm; - int ILU_DropRule; - double ILU_DropTol; - double ILU_FillFactor; - norm_t ILU_Norm; - double ILU_FillTol; - milu_t ILU_MILU; - double ILU_MILU_Dim; - yes_no_t ParSymbFact; - yes_no_t ReplaceTinyPivot; - yes_no_t SolveInitialized; - yes_no_t RefineInitialized; - yes_no_t PrintStat; - int nnzL, nnzU; - int num_lookaheads; - yes_no_t lookahead_etree; - yes_no_t SymPattern; - } superlu_options_t; - - - typedef struct - { - float for_lu; - float total_needed; - } mem_usage_t; - - - typedef struct e_node - { - int size; - void* mem; - } ExpHeader; - - - typedef struct - { - int size; - int used; - int top1; - int top2; - void* array; - } LU_stack_t; + #if defined(__has_include) + #if __has_include(ARMA_INCFILE_WRAP(ARMA_SLU_HEADER_A)) && __has_include(ARMA_INCFILE_WRAP(ARMA_SLU_HEADER_B)) + #include ARMA_INCFILE_WRAP(ARMA_SLU_HEADER_A) + #include ARMA_INCFILE_WRAP(ARMA_SLU_HEADER_B) + #define ARMA_SLU_HEADERS_FOUND + #endif + #else + #include ARMA_INCFILE_WRAP(ARMA_SLU_HEADER_A) + #include ARMA_INCFILE_WRAP(ARMA_SLU_HEADER_B) + #define ARMA_SLU_HEADERS_FOUND + #endif + #undef ARMA_SLU_STR1 + #undef ARMA_SLU_STR2 + + #undef ARMA_SLU_HEADER_A + #undef ARMA_SLU_HEADER_B - typedef struct - { - int* xsup; - int* supno; - int* lsub; - int* xlsub; - void* lusup; - int* xlusup; - void* ucol; - int* usub; - int* xusub; - int nzlmax; - int nzumax; - int nzlumax; - int n; - LU_space_t MemModel; - int num_expansions; - ExpHeader* expanders; - LU_stack_t stack; - } GlobalLU_t; + #if defined(ARMA_SLU_HEADERS_FOUND) + + typedef struct + { + int* panel_histo; + double* utime; + float* ops; + int TinyPivots; + int RefineSteps; + int expansions; + } SuperLUStat_t; + + typedef struct + { + fact_t Fact; + yes_no_t Equil; + colperm_t ColPerm; + trans_t Trans; + IterRefine_t IterRefine; + double DiagPivotThresh; + yes_no_t SymmetricMode; + yes_no_t PivotGrowth; + yes_no_t ConditionNumber; + rowperm_t RowPerm; + int ILU_DropRule; + double ILU_DropTol; + double ILU_FillFactor; + norm_t ILU_Norm; + double ILU_FillTol; + milu_t ILU_MILU; + double ILU_MILU_Dim; + yes_no_t ParSymbFact; + yes_no_t ReplaceTinyPivot; + yes_no_t SolveInitialized; + yes_no_t RefineInitialized; + yes_no_t PrintStat; + int nnzL, nnzU; + int num_lookaheads; + yes_no_t lookahead_etree; + yes_no_t SymPattern; + } superlu_options_t; + + typedef struct + { + float for_lu; + float total_needed; + } mem_usage_t; + + typedef struct e_node + { + int size; + void* mem; + } ExpHeader; + + typedef struct + { + int size; + int used; + int top1; + int top2; + void* array; + } LU_stack_t; + + typedef struct + { + int* xsup; + int* supno; + int* lsub; + int* xlsub; + void* lusup; + int* xlusup; + void* ucol; + int* usub; + int* xusub; + int nzlmax; + int nzumax; + int nzlumax; + int n; + LU_space_t MemModel; + int num_expansions; + ExpHeader* expanders; + LU_stack_t stack; + } GlobalLU_t; + + #endif } } -#else +#endif + +#if defined(ARMA_USE_SUPERLU_HEADERS) && !defined(ARMA_SLU_HEADERS_FOUND) + #undef ARMA_USE_SUPERLU + #pragma message ("WARNING: use of SuperLU disabled; required headers not found") +#endif + +#endif + + + +#if defined(ARMA_USE_SUPERLU) && !defined(ARMA_SLU_HEADERS_FOUND) // Not using any SuperLU headers, so define all required enums and structs. -// -// CAVEAT: -// This code requires SuperLU version 5.2, -// and assumes that newer 5.x versions will have no API changes. + +#if defined(ARMA_SUPERLU_INCLUDE_DIR) + #pragma message ("WARNING: SuperLU headers not found; using built-in definitions") +#endif namespace arma { - namespace superlu { - typedef int int_t; - typedef enum { SLU_NC, @@ -218,7 +248,6 @@ SLU_NR_loc } Stype_t; - typedef enum { SLU_S, @@ -227,7 +256,6 @@ SLU_Z } Dtype_t; - typedef enum { SLU_GE, @@ -241,7 +269,6 @@ SLU_HEU } Mtype_t; - typedef struct { Stype_t Stype; @@ -252,7 +279,6 @@ void* Store; } SuperMatrix; - typedef struct { int* panel_histo; @@ -263,7 +289,6 @@ int expansions; } SuperLUStat_t; - typedef enum {NO, YES} yes_no_t; typedef enum {DOFACT, SamePattern, SamePattern_SameRowPerm, FACTORED} fact_t; typedef enum {NOROWPERM, LargeDiag, MY_PERMR} rowperm_t; @@ -275,7 +300,6 @@ typedef enum {ONE_NORM, TWO_NORM, INF_NORM} norm_t; typedef enum {SILU, SMILU_1, SMILU_2, SMILU_3} milu_t; - typedef struct { fact_t Fact; @@ -306,14 +330,12 @@ yes_no_t SymPattern; } superlu_options_t; - typedef struct { float for_lu; float total_needed; } mem_usage_t; - typedef struct { int_t nnz; @@ -322,21 +344,18 @@ int_t* colptr; } NCformat; - typedef struct { int_t lda; void* nzval; } DNformat; - typedef struct e_node { int size; void* mem; } ExpHeader; - typedef struct { int size; @@ -346,7 +365,6 @@ void* array; } LU_stack_t; - typedef struct { int* xsup; @@ -370,7 +388,6 @@ } } -#endif - +#undef ARMA_SLU_HEADERS_FOUND #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/injector_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/injector_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/injector_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/injector_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,22 +21,6 @@ -template -class mat_injector_row - { - public: - - arma_cold inline mat_injector_row(); - - arma_cold inline void insert(const eT val) const; - - mutable uword n_cols; - mutable podarray A; - mutable podarray B; - }; - - - template class mat_injector { @@ -51,14 +35,13 @@ private: - 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); + inline mat_injector(T1& in_X, const elem_type val); + inline mat_injector(T1& in_X, const injector_end_of_row<>&); - T1& X; - mutable uword n_rows; + T1& parent; - mutable podarray< mat_injector_row* >* AA; - mutable podarray< mat_injector_row* >* BB; + mutable std::vector values; + mutable std::vector rowend; friend class Mat; friend class Row; @@ -71,23 +54,6 @@ -template -class field_injector_row - { - public: - - arma_cold inline field_injector_row(); - arma_cold inline ~field_injector_row(); - - arma_cold inline void insert(const oT& val) const; - - mutable uword n_cols; - mutable field* AA; - mutable field* BB; - }; - - - template class field_injector { @@ -102,14 +68,13 @@ private: - 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); + inline field_injector(T1& in_X, const object_type& val); + inline field_injector(T1& in_X, const injector_end_of_row<>&); - T1& X; - mutable uword n_rows; + T1& parent; - mutable podarray< field_injector_row* >* AA; - mutable podarray< field_injector_row* >* BB; + mutable std::vector values; + mutable std::vector rowend; friend class field; }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/injector_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/injector_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/injector_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/injector_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,230 +21,177 @@ -template -arma_cold +template inline -mat_injector_row::mat_injector_row() - : n_cols(0) +mat_injector::mat_injector(T1& in_parent, const typename mat_injector::elem_type val) + : parent(in_parent) { arma_extra_debug_sigprint(); - A.set_size( podarray_prealloc_n_elem::val ); - } - - - -template -arma_cold -inline -void -mat_injector_row::insert(const eT val) const - { - arma_extra_debug_sigprint(); + values.reserve(16); + rowend.reserve(16); - if(n_cols < A.n_elem) - { - A[n_cols] = val; - ++n_cols; - } - else - { - B.set_size(2 * A.n_elem); - - arrayops::copy(B.memptr(), A.memptr(), n_cols); - - B[n_cols] = val; - ++n_cols; - - std::swap( access::rw(A.mem), access::rw(B.mem) ); - std::swap( access::rw(A.n_elem), access::rw(B.n_elem) ); - } + insert(val); } -// -// -// - - - template -arma_cold inline -mat_injector::mat_injector(T1& in_X, const typename mat_injector::elem_type val) - : X(in_X) - , n_rows(1) +mat_injector::mat_injector(T1& in_parent, const injector_end_of_row<>&) + : parent(in_parent) { arma_extra_debug_sigprint(); - typedef typename mat_injector::elem_type eT; - - AA = new podarray< mat_injector_row* >; - BB = new podarray< mat_injector_row* >; - - podarray< mat_injector_row* >& A = *AA; - - A.set_size(n_rows); - - for(uword row=0; row; - } + values.reserve(16); + rowend.reserve(16); - (*(A[0])).insert(val); + end_of_row(); } template -arma_cold inline -mat_injector::mat_injector(T1& in_X, const injector_end_of_row<>& x) - : X(in_X) - , n_rows(1) +mat_injector::~mat_injector() { arma_extra_debug_sigprint(); - arma_ignore(x); - typedef typename mat_injector::elem_type eT; + const uword N = values.size(); + + if(N == 0) { return; } - AA = new podarray< mat_injector_row* >; - BB = new podarray< mat_injector_row* >; + uword n_rows = 1; + uword n_cols = 0; - podarray< mat_injector_row* >& A = *AA; + for(uword i=0; i; + if(rowend[i]) + { + n_cols = (std::max)(n_cols, n_cols_in_row); + n_cols_in_row = 0; + } + else + { + ++n_cols_in_row; + } } - (*this).end_of_row(); - } - - - -template -arma_cold -inline -mat_injector::~mat_injector() - { - arma_extra_debug_sigprint(); - - typedef typename mat_injector::elem_type eT; - - podarray< mat_injector_row* >& A = *AA; + n_rows = (rowend[N-1]) ? (n_rows-1) : n_rows; + n_cols = (std::max)(n_cols, n_cols_in_row); - if(n_rows > 0) + if(is_Row::value) { - uword max_n_cols = (*(A[0])).n_cols; + arma_debug_check( (n_rows > 1), "matrix initialisation: incompatible dimensions" ); + + parent.zeros(1,n_cols); - for(uword row=1; row::value) + { + const bool is_vec = ((n_cols == 1) || (n_rows == 1)); - const uword max_n_rows = ((*(A[n_rows-1])).n_cols == 0) ? n_rows-1 : n_rows; + arma_debug_check( (is_vec == false), "matrix initialisation: incompatible dimensions" ); - if(is_Mat_only::value) + if(n_cols == 1) { - X.set_size(max_n_rows, max_n_cols); + parent.zeros(n_rows,1); + + uword row = 0; - for(uword row=0; row 0) && rowend[i-1]) { ++row; } } - - for(uword col=n_cols; col::value) - { - arma_debug_check( (max_n_rows > 1), "matrix initialisation: incompatible dimensions" ); - - const uword n_cols = (*(A[0])).n_cols; - - X.set_size(1, n_cols); - - arrayops::copy( X.memptr(), (*(A[0])).A.memptr(), n_cols ); - } - else - if(is_Col::value) + if(n_rows == 1) { - const bool is_vec = ( (max_n_rows == 1) || (max_n_cols == 1) ); - - arma_debug_check( (is_vec == false), "matrix initialisation: incompatible dimensions" ); + parent.zeros(n_cols,1); - const uword n_elem = (std::max)(max_n_rows, max_n_cols); + uword row = 0; - X.set_size(n_elem, 1); - - uword i = 0; - for(uword row=0; row -arma_cold inline void mat_injector::insert(const typename mat_injector::elem_type val) const { arma_extra_debug_sigprint(); - typedef typename mat_injector::elem_type eT; - - podarray< mat_injector_row* >& A = *AA; - - (*(A[n_rows-1])).insert(val); + values.push_back(val ); + rowend.push_back(char(0)); } template -arma_cold inline void mat_injector::end_of_row() const @@ -253,27 +200,14 @@ typedef typename mat_injector::elem_type eT; - podarray< mat_injector_row* >& A = *AA; - podarray< mat_injector_row* >& B = *BB; - - B.set_size( n_rows+1 ); - - arrayops::copy(B.memptr(), A.memptr(), n_rows); - - for(uword row=n_rows; row<(n_rows+1); ++row) - { - B[row] = new mat_injector_row; - } - - std::swap(AA, BB); - - n_rows += 1; + values.push_back( eT(0)); + rowend.push_back(char(1)); } template -arma_cold +inline const mat_injector& operator<<(const mat_injector& ref, const typename mat_injector::elem_type val) { @@ -287,12 +221,11 @@ template -arma_cold +inline const mat_injector& -operator<<(const mat_injector& ref, const injector_end_of_row<>& x) +operator<<(const mat_injector& ref, const injector_end_of_row<>&) { arma_extra_debug_sigprint(); - arma_ignore(x); ref.end_of_row(); @@ -301,252 +234,106 @@ -//// using a mixture of operator << and , doesn't work yet -//// eg. A << 1, 2, 3 << endr -//// in the above "3 << endr" requires special handling. -//// similarly, special handling is necessary for "endr << 3" -//// -// template -// arma_inline -// const mat_injector& -// operator,(const mat_injector& ref, const typename mat_injector::elem_type val) -// { -// arma_extra_debug_sigprint(); -// -// ref.insert(val); -// -// return ref; -// } - - - -// template -// arma_inline -// const mat_injector& -// operator,(const mat_injector& ref, const injector_end_of_row<>& x) -// { -// arma_extra_debug_sigprint(); -// arma_ignore(x); -// -// ref.end_of_row(); -// -// return ref; -// } - - - - // // // -template -arma_cold -inline -field_injector_row::field_injector_row() - : n_cols(0) - { - arma_extra_debug_sigprint(); - - AA = new field; - BB = new field; - - field& A = *AA; - - A.set_size( field_prealloc_n_elem::val ); - } - - - -template -arma_cold -inline -field_injector_row::~field_injector_row() - { - arma_extra_debug_sigprint(); - - delete AA; - delete BB; - } - - - -template -arma_cold +template inline -void -field_injector_row::insert(const oT& val) const +field_injector::field_injector(T1& in_parent, const typename field_injector::object_type& val) + : parent(in_parent) { arma_extra_debug_sigprint(); - field& A = *AA; - field& B = *BB; - - if(n_cols < A.n_elem) - { - A[n_cols] = val; - ++n_cols; - } - else - { - B.set_size(2 * A.n_elem); - - for(uword i=0; i -arma_cold inline -field_injector::field_injector(T1& in_X, const typename field_injector::object_type& val) - : X(in_X) - , n_rows(1) +field_injector::field_injector(T1& in_parent, const injector_end_of_row<>&) + : parent(in_parent) { arma_extra_debug_sigprint(); - typedef typename field_injector::object_type oT; - - AA = new podarray< field_injector_row* >; - BB = new podarray< field_injector_row* >; - - podarray< field_injector_row* >& A = *AA; - - A.set_size(n_rows); - - for(uword row=0; row; - } - - (*(A[0])).insert(val); + end_of_row(); } template -arma_cold inline -field_injector::field_injector(T1& in_X, const injector_end_of_row<>& x) - : X(in_X) - , n_rows(1) +field_injector::~field_injector() { arma_extra_debug_sigprint(); - arma_ignore(x); - typedef typename field_injector::object_type oT; + const uword N = values.size(); + + if(N == 0) { return; } - AA = new podarray< field_injector_row* >; - BB = new podarray< field_injector_row* >; + uword n_rows = 1; + uword n_cols = 0; - podarray< field_injector_row* >& A = *AA; + for(uword i=0; i; + if(rowend[i]) + { + n_cols = (std::max)(n_cols, n_cols_in_row); + n_cols_in_row = 0; + } + else + { + ++n_cols_in_row; + } } - (*this).end_of_row(); - } - - - -template -arma_cold -inline -field_injector::~field_injector() - { - arma_extra_debug_sigprint(); + n_rows = (rowend[N-1]) ? (n_rows-1) : n_rows; + n_cols = (std::max)(n_cols, n_cols_in_row); - typedef typename field_injector::object_type oT; + parent.set_size(n_rows,n_cols); - podarray< field_injector_row* >& A = *AA; + uword row = 0; + uword col = 0; - if(n_rows > 0) + for(uword i=0; i& tmp = *((*(A[row])).AA); - X.at(row,col) = tmp[col]; - } - - for(uword col=n_cols; col -arma_cold inline void field_injector::insert(const typename field_injector::object_type& val) const { arma_extra_debug_sigprint(); - typedef typename field_injector::object_type oT; - - podarray< field_injector_row* >& A = *AA; - - (*(A[n_rows-1])).insert(val); + values.push_back(val ); + rowend.push_back(char(0)); } template -arma_cold inline void field_injector::end_of_row() const @@ -555,30 +342,14 @@ typedef typename field_injector::object_type oT; - podarray< field_injector_row* >& A = *AA; - podarray< field_injector_row* >& B = *BB; - - B.set_size( n_rows+1 ); - - for(uword row=0; row; - } - - std::swap(AA, BB); - - n_rows += 1; + values.push_back(oT() ); + rowend.push_back(char(1)); } template -arma_cold +inline const field_injector& operator<<(const field_injector& ref, const typename field_injector::object_type& val) { @@ -592,12 +363,11 @@ template -arma_cold +inline const field_injector& -operator<<(const field_injector& ref, const injector_end_of_row<>& x) +operator<<(const field_injector& ref, const injector_end_of_row<>&) { arma_extra_debug_sigprint(); - arma_ignore(x); ref.end_of_row(); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/MapMat_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/MapMat_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/MapMat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/MapMat_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -81,23 +81,23 @@ inline void speye(const uword in_n_rows, const uword in_n_cols); inline void speye(const SizeMat& s); - arma_inline arma_warn_unused MapMat_val operator[](const uword index); - inline arma_warn_unused eT operator[](const uword index) const; + arma_warn_unused arma_inline MapMat_val operator[](const uword index); + arma_warn_unused inline eT operator[](const uword index) const; - arma_inline arma_warn_unused MapMat_val operator()(const uword index); - inline arma_warn_unused eT operator()(const uword index) const; + arma_warn_unused arma_inline MapMat_val operator()(const uword index); + arma_warn_unused inline eT operator()(const uword index) const; - arma_inline arma_warn_unused MapMat_val 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_warn_unused arma_inline MapMat_val at(const uword in_row, const uword in_col); + arma_warn_unused inline eT at(const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused MapMat_val 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 bool is_empty() const; - inline arma_warn_unused bool is_vec() const; - inline arma_warn_unused bool is_rowvec() const; - inline arma_warn_unused bool is_colvec() const; - inline arma_warn_unused bool is_square() const; + arma_warn_unused arma_inline MapMat_val operator()(const uword in_row, const uword in_col); + arma_warn_unused inline eT operator()(const uword in_row, const uword in_col) const; + + arma_warn_unused inline bool is_empty() const; + arma_warn_unused inline bool is_vec() const; + arma_warn_unused inline bool is_rowvec() const; + arma_warn_unused inline bool is_colvec() const; + arma_warn_unused inline bool is_square() const; inline void sprandu(const uword in_n_rows, const uword in_n_cols, const double density); @@ -195,11 +195,11 @@ inline SpMat_MapMat_val& operator*=(const eT in_val); inline SpMat_MapMat_val& operator/=(const eT in_val); - inline SpMat_MapMat_val& operator++(); - inline arma_warn_unused eT operator++(int); + inline SpMat_MapMat_val& operator++(); + arma_warn_unused inline eT operator++(int); - inline SpMat_MapMat_val& operator--(); - inline arma_warn_unused eT operator--(int); + inline SpMat_MapMat_val& operator--(); + arma_warn_unused inline eT operator--(int); inline void set(const eT in_val); inline void add(const eT in_val); @@ -235,11 +235,11 @@ inline SpSubview_MapMat_val& operator*=(const eT in_val); inline SpSubview_MapMat_val& operator/=(const eT in_val); - inline SpSubview_MapMat_val& operator++(); - inline arma_warn_unused eT operator++(int); + inline SpSubview_MapMat_val& operator++(); + arma_warn_unused inline eT operator++(int); - inline SpSubview_MapMat_val& operator--(); - inline arma_warn_unused eT operator--(int); + inline SpSubview_MapMat_val& operator--(); + arma_warn_unused inline eT operator--(int); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/MapMat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/MapMat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/MapMat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/MapMat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -198,6 +198,8 @@ { arma_extra_debug_sigprint(); + if(this == &x) { return; } + reset(); if(map_ptr) { delete map_ptr; } @@ -406,7 +408,6 @@ template arma_inline -arma_warn_unused MapMat_val MapMat::operator[](const uword index) { @@ -417,7 +418,6 @@ template inline -arma_warn_unused eT MapMat::operator[](const uword index) const { @@ -433,7 +433,6 @@ template arma_inline -arma_warn_unused MapMat_val MapMat::operator()(const uword index) { @@ -446,7 +445,6 @@ template inline -arma_warn_unused eT MapMat::operator()(const uword index) const { @@ -464,7 +462,6 @@ template arma_inline -arma_warn_unused MapMat_val MapMat::at(const uword in_row, const uword in_col) { @@ -477,7 +474,6 @@ template inline -arma_warn_unused eT MapMat::at(const uword in_row, const uword in_col) const { @@ -495,7 +491,6 @@ template arma_inline -arma_warn_unused MapMat_val MapMat::operator()(const uword in_row, const uword in_col) { @@ -510,7 +505,6 @@ template inline -arma_warn_unused eT MapMat::operator()(const uword in_row, const uword in_col) const { @@ -530,7 +524,6 @@ template inline -arma_warn_unused bool MapMat::is_empty() const { @@ -541,7 +534,6 @@ template inline -arma_warn_unused bool MapMat::is_vec() const { @@ -552,7 +544,6 @@ template inline -arma_warn_unused bool MapMat::is_rowvec() const { @@ -564,7 +555,6 @@ //! returns true if the object can be interpreted as a column vector template inline -arma_warn_unused bool MapMat::is_colvec() const { @@ -575,7 +565,6 @@ template inline -arma_warn_unused bool MapMat::is_square() const { @@ -1184,11 +1173,9 @@ } #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { - s_parent.cache_mutex.lock(); + const std::lock_guard lock(s_parent.cache_mutex); (*this).set(in_val); - - s_parent.cache_mutex.unlock(); } #else { @@ -1219,11 +1206,9 @@ } #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { - s_parent.cache_mutex.lock(); + const std::lock_guard lock(s_parent.cache_mutex); (*this).add(in_val); - - s_parent.cache_mutex.unlock(); } #else { @@ -1254,11 +1239,9 @@ } #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { - s_parent.cache_mutex.lock(); + const std::lock_guard lock(s_parent.cache_mutex); (*this).sub(in_val); - - s_parent.cache_mutex.unlock(); } #else { @@ -1287,11 +1270,9 @@ } #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { - s_parent.cache_mutex.lock(); + const std::lock_guard lock(s_parent.cache_mutex); (*this).mul(in_val); - - s_parent.cache_mutex.unlock(); } #else { @@ -1320,11 +1301,9 @@ } #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { - s_parent.cache_mutex.lock(); + const std::lock_guard lock(s_parent.cache_mutex); (*this).div(in_val); - - s_parent.cache_mutex.unlock(); } #else { @@ -1351,7 +1330,6 @@ template inline -arma_warn_unused eT SpMat_MapMat_val::operator++(int) { @@ -1380,7 +1358,6 @@ template inline -arma_warn_unused eT SpMat_MapMat_val::operator--(int) { @@ -1743,7 +1720,6 @@ template inline -arma_warn_unused eT SpSubview_MapMat_val::operator++(int) { @@ -1782,7 +1758,6 @@ template inline -arma_warn_unused eT SpSubview_MapMat_val::operator--(int) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Mat_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Mat_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Mat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Mat_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -72,11 +72,11 @@ 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); + arma_cold inline Mat(const char* text); + arma_cold inline Mat& operator=(const char* text); - inline arma_cold Mat(const std::string& text); - inline arma_cold Mat& operator=(const std::string& text); + arma_cold inline Mat(const std::string& text); + arma_cold inline Mat& operator=(const std::string& text); inline Mat(const std::vector& x); inline Mat& operator=(const std::vector& x); @@ -118,7 +118,7 @@ template inline explicit Mat(const Base& A, const Base& B); - inline explicit Mat(const subview& X, const bool use_colmem); // only to be used by the quasi_unwrap class + 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); @@ -188,8 +188,8 @@ inline Mat& operator/=(const spdiagview& X); - arma_cold inline mat_injector operator<<(const eT val); - arma_cold inline mat_injector operator<<(const injector_end_of_row<>& x); + arma_frown("use braced initialiser list instead") inline mat_injector operator<<(const eT val); + arma_frown("use braced initialiser list instead") inline mat_injector operator<<(const injector_end_of_row<>& x); arma_inline subview_row row(const uword row_num); @@ -285,10 +285,10 @@ 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; - inline const Mat& each_col(const std::function< void( Col&) >& F); + inline 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 Mat& each_row(const std::function< void( Row&) >& F); inline const Mat& each_row(const std::function< void(const Row&) >& F) const; @@ -308,8 +308,11 @@ template inline void shed_rows(const Base& indices); template inline void shed_cols(const Base& indices); - inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero = true); - inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero = true); + arma_deprecated inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero); + arma_deprecated inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero); + + inline void insert_rows(const uword row_num, const uword N); + inline void insert_cols(const uword col_num, const uword N); template inline void insert_rows(const uword row_num, const Base& X); template inline void insert_cols(const uword col_num, const Base& X); @@ -390,20 +393,33 @@ template inline Mat& operator%=(const mtGlue& X); template inline Mat& operator/=(const mtGlue& X); + template inline Mat(const SpToDGlue& X); + template inline Mat& operator= (const SpToDGlue& X); + template inline Mat& operator+=(const SpToDGlue& X); + template inline Mat& operator-=(const SpToDGlue& X); + template inline Mat& operator*=(const SpToDGlue& X); + template inline Mat& operator%=(const SpToDGlue& X); + template inline Mat& operator/=(const SpToDGlue& X); + + + arma_warn_unused arma_inline const eT& at_alt (const uword ii) const; + + arma_warn_unused arma_inline eT& operator[] (const uword ii); + arma_warn_unused arma_inline const eT& operator[] (const uword ii) const; + arma_warn_unused arma_inline eT& at (const uword ii); + arma_warn_unused arma_inline const eT& at (const uword ii) const; + arma_warn_unused arma_inline eT& operator() (const uword ii); + arma_warn_unused arma_inline const eT& operator() (const uword ii) const; + + #if defined(__cpp_multidimensional_subscript) + arma_warn_unused arma_inline eT& operator[] (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& operator[] (const uword in_row, const uword in_col) const; + #endif - arma_inline arma_warn_unused const eT& at_alt (const uword ii) const; - - arma_inline arma_warn_unused eT& operator[] (const uword ii); - arma_inline arma_warn_unused const eT& operator[] (const uword ii) const; - arma_inline arma_warn_unused eT& at (const uword ii); - arma_inline arma_warn_unused const eT& at (const uword ii) const; - arma_inline arma_warn_unused eT& operator() (const uword ii); - arma_inline arma_warn_unused const eT& operator() (const uword ii) const; - - arma_inline arma_warn_unused eT& at (const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& at (const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline eT& at (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& at (const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const; arma_inline const Mat& operator++(); arma_inline void operator++(int); @@ -411,108 +427,109 @@ arma_inline const Mat& operator--(); arma_inline void operator--(int); - arma_inline arma_warn_unused bool is_empty() const; - arma_inline arma_warn_unused bool is_vec() const; - arma_inline arma_warn_unused bool is_rowvec() const; - arma_inline arma_warn_unused bool is_colvec() const; - arma_inline arma_warn_unused bool is_square() const; - inline arma_warn_unused bool is_finite() const; + arma_warn_unused arma_inline bool is_empty() const; + arma_warn_unused arma_inline bool is_vec() const; + arma_warn_unused arma_inline bool is_rowvec() const; + arma_warn_unused arma_inline bool is_colvec() const; + arma_warn_unused arma_inline bool is_square() const; + + arma_warn_unused inline bool internal_is_finite() const; + arma_warn_unused inline bool internal_has_inf() const; + arma_warn_unused inline bool internal_has_nan() const; + arma_warn_unused inline bool internal_has_nonfinite() const; - inline arma_warn_unused bool has_inf() const; - inline arma_warn_unused bool has_nan() const; - - inline arma_warn_unused bool is_sorted(const char* direction = "ascend") const; - inline arma_warn_unused bool is_sorted(const char* direction, const uword dim) const; + arma_warn_unused inline bool is_sorted(const char* direction = "ascend") const; + arma_warn_unused inline bool is_sorted(const char* direction, const uword dim) const; template - inline arma_warn_unused bool is_sorted_helper(const comparator& comp, const uword dim) const; + arma_warn_unused inline bool is_sorted_helper(const comparator& comp, const uword dim) const; - arma_inline arma_warn_unused bool in_range(const uword ii) const; - arma_inline arma_warn_unused bool in_range(const span& x ) const; + arma_warn_unused arma_inline bool in_range(const uword ii) const; + arma_warn_unused arma_inline bool in_range(const span& x ) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused bool in_range(const span& row_span, const uword in_col) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const span& col_span) const; - arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline bool in_range(const span& row_span, const uword in_col) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const span& col_span) const; + arma_warn_unused arma_inline bool in_range(const span& row_span, const span& col_span) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; - arma_inline arma_warn_unused eT* colptr(const uword in_col); - arma_inline arma_warn_unused const eT* colptr(const uword in_col) const; + arma_warn_unused arma_inline eT* colptr(const uword in_col); + arma_warn_unused arma_inline const eT* colptr(const uword in_col) const; - arma_inline arma_warn_unused eT* memptr(); - arma_inline arma_warn_unused const eT* memptr() const; + arma_warn_unused arma_inline eT* memptr(); + arma_warn_unused arma_inline const eT* memptr() const; template - inline void copy_size(const Base& X); + inline Mat& copy_size(const Base& X); - 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 new_n_elem); - inline void resize(const uword new_n_rows, const uword new_n_cols); - inline void resize(const SizeMat& s); + inline Mat& set_size(const uword new_n_elem); + inline Mat& set_size(const uword new_n_rows, const uword new_n_cols); + inline Mat& set_size(const SizeMat& s); + + inline Mat& resize(const uword new_n_elem); + inline Mat& resize(const uword new_n_rows, const uword new_n_cols); + inline Mat& resize(const SizeMat& s); - inline void reshape(const uword new_n_rows, const uword new_n_cols); - inline void reshape(const SizeMat& s); + inline Mat& reshape(const uword new_n_rows, const uword new_n_cols); + inline Mat& reshape(const SizeMat& s); 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); + template inline Mat& for_each(functor F); template inline const Mat& for_each(functor F) const; - template inline const Mat& transform(functor F); - template inline const Mat& imbue(functor F); + template inline Mat& transform(functor F); + template inline Mat& imbue(functor F); - inline const Mat& replace(const eT old_val, const eT new_val); + inline Mat& replace(const eT old_val, const eT new_val); - inline const Mat& clean(const pod_type threshold); + inline Mat& clean(const pod_type threshold); - inline const Mat& clamp(const eT min_val, const eT max_val); + inline Mat& clamp(const eT min_val, const eT max_val); - inline const Mat& fill(const eT val); + inline Mat& fill(const eT val); template - inline const Mat& fill(const fill::fill_class& f); + inline Mat& fill(const fill::fill_class& f); - inline const Mat& zeros(); - 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 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 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 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 new_n_rows, const uword new_n_cols); - inline const Mat& eye(const SizeMat& s); + inline Mat& zeros(); + inline Mat& zeros(const uword new_n_elem); + inline Mat& zeros(const uword new_n_rows, const uword new_n_cols); + inline Mat& zeros(const SizeMat& s); + + inline Mat& ones(); + inline Mat& ones(const uword new_n_elem); + inline Mat& ones(const uword new_n_rows, const uword new_n_cols); + inline Mat& ones(const SizeMat& s); + + inline Mat& randu(); + inline Mat& randu(const uword new_n_elem); + inline Mat& randu(const uword new_n_rows, const uword new_n_cols); + inline Mat& randu(const SizeMat& s); + + inline Mat& randn(); + inline Mat& randn(const uword new_n_elem); + inline Mat& randn(const uword new_n_rows, const uword new_n_cols); + inline Mat& randn(const SizeMat& s); + + inline Mat& eye(); + inline Mat& eye(const uword new_n_rows, const uword new_n_cols); + inline Mat& eye(const SizeMat& s); - inline arma_cold void reset(); - inline arma_cold void soft_reset(); + arma_cold inline void reset(); + arma_cold inline void soft_reset(); template inline void set_real(const Base& X); template inline void set_imag(const Base& X); - inline arma_warn_unused eT min() const; - inline arma_warn_unused eT max() const; + arma_warn_unused inline eT min() const; + arma_warn_unused inline eT max() const; inline eT min(uword& index_of_min_val) const; inline eT max(uword& index_of_max_val) const; @@ -521,25 +538,25 @@ 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; - 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); + arma_cold inline bool save(const std::string name, const file_type type = arma_binary) const; + arma_cold inline bool save(const hdf5_name& spec, const file_type type = hdf5_binary) const; + arma_cold inline bool save(const csv_name& spec, const file_type type = csv_ascii) const; + arma_cold inline bool save( std::ostream& os, const file_type type = arma_binary) const; + + arma_cold inline bool load(const std::string name, const file_type type = auto_detect); + arma_cold inline bool load(const hdf5_name& spec, const file_type type = hdf5_binary); + arma_cold inline bool load(const csv_name& spec, const file_type type = csv_ascii); + arma_cold inline bool load( std::istream& is, const file_type type = auto_detect); + + arma_deprecated inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; + arma_deprecated inline bool quiet_save(const hdf5_name& spec, const file_type type = hdf5_binary) const; + arma_deprecated inline bool quiet_save(const csv_name& spec, const file_type type = csv_ascii) const; + arma_deprecated inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; + + arma_deprecated inline bool quiet_load(const std::string name, const file_type type = auto_detect); + arma_deprecated inline bool quiet_load(const hdf5_name& spec, const file_type type = hdf5_binary); + arma_deprecated inline bool quiet_load(const csv_name& spec, const file_type type = csv_ascii); + arma_deprecated inline bool quiet_load( std::istream& is, const file_type type = auto_detect); // for container-like functionality @@ -563,18 +580,18 @@ inline row_iterator(const row_iterator& X); inline row_iterator(Mat& in_M, const uword in_row, const uword in_col); - inline arma_warn_unused eT& operator* (); + arma_warn_unused inline eT& operator* (); - inline row_iterator& operator++(); - inline arma_warn_unused row_iterator operator++(int); + inline row_iterator& operator++(); + arma_warn_unused inline row_iterator operator++(int); - inline row_iterator& operator--(); - inline arma_warn_unused row_iterator operator--(int); + inline row_iterator& operator--(); + arma_warn_unused inline row_iterator operator--(int); - inline arma_warn_unused bool operator!=(const row_iterator& X) const; - inline arma_warn_unused bool operator==(const row_iterator& X) const; - inline arma_warn_unused bool operator!=(const const_row_iterator& X) const; - inline arma_warn_unused bool operator==(const const_row_iterator& X) const; + arma_warn_unused inline bool operator!=(const row_iterator& X) const; + arma_warn_unused inline bool operator==(const row_iterator& X) const; + arma_warn_unused inline bool operator!=(const const_row_iterator& X) const; + arma_warn_unused inline bool operator==(const const_row_iterator& X) const; typedef std::bidirectional_iterator_tag iterator_category; typedef eT value_type; @@ -597,18 +614,18 @@ inline const_row_iterator(const const_row_iterator& X); inline const_row_iterator(const Mat& in_M, const uword in_row, const uword in_col); - inline arma_warn_unused const eT& operator*() const; + arma_warn_unused inline const eT& operator*() const; - inline const_row_iterator& operator++(); - inline arma_warn_unused const_row_iterator operator++(int); + inline const_row_iterator& operator++(); + arma_warn_unused inline const_row_iterator operator++(int); - inline const_row_iterator& operator--(); - inline arma_warn_unused const_row_iterator operator--(int); + inline const_row_iterator& operator--(); + arma_warn_unused inline const_row_iterator operator--(int); - inline arma_warn_unused bool operator!=(const row_iterator& X) const; - inline arma_warn_unused bool operator==(const row_iterator& X) const; - inline arma_warn_unused bool operator!=(const const_row_iterator& X) const; - inline arma_warn_unused bool operator==(const const_row_iterator& X) const; + arma_warn_unused inline bool operator!=(const row_iterator& X) const; + arma_warn_unused inline bool operator==(const row_iterator& X) const; + arma_warn_unused inline bool operator!=(const const_row_iterator& X) const; + arma_warn_unused inline bool operator==(const const_row_iterator& X) const; typedef std::bidirectional_iterator_tag iterator_category; typedef eT value_type; @@ -632,21 +649,21 @@ inline row_col_iterator(const row_col_iterator& in_it); inline row_col_iterator(Mat& in_M, const uword row = 0, const uword col = 0); - inline arma_warn_unused eT& operator*(); + arma_warn_unused inline eT& operator*(); - inline row_col_iterator& operator++(); - inline arma_warn_unused row_col_iterator operator++(int); + inline row_col_iterator& operator++(); + arma_warn_unused inline row_col_iterator operator++(int); - inline row_col_iterator& operator--(); - inline arma_warn_unused row_col_iterator operator--(int); + inline row_col_iterator& operator--(); + arma_warn_unused inline row_col_iterator operator--(int); - inline arma_warn_unused uword row() const; - inline arma_warn_unused uword col() const; + arma_warn_unused inline uword row() const; + arma_warn_unused inline uword col() const; - inline arma_warn_unused bool operator==(const row_col_iterator& rhs) const; - inline arma_warn_unused bool operator!=(const row_col_iterator& rhs) const; - inline arma_warn_unused bool operator==(const const_row_col_iterator& rhs) const; - inline arma_warn_unused bool operator!=(const const_row_col_iterator& rhs) const; + arma_warn_unused inline bool operator==(const row_col_iterator& rhs) const; + arma_warn_unused inline bool operator!=(const row_col_iterator& rhs) const; + arma_warn_unused inline bool operator==(const const_row_col_iterator& rhs) const; + arma_warn_unused inline bool operator!=(const const_row_col_iterator& rhs) const; typedef std::bidirectional_iterator_tag iterator_category; typedef eT value_type; @@ -670,21 +687,21 @@ inline const_row_col_iterator(const const_row_col_iterator& in_it); inline const_row_col_iterator(const Mat& in_M, const uword row = 0, const uword col = 0); - inline arma_warn_unused const eT& operator*() const; + arma_warn_unused inline const eT& operator*() const; - inline const_row_col_iterator& operator++(); - inline arma_warn_unused const_row_col_iterator operator++(int); + inline const_row_col_iterator& operator++(); + arma_warn_unused inline const_row_col_iterator operator++(int); - inline const_row_col_iterator& operator--(); - inline arma_warn_unused const_row_col_iterator operator--(int); + inline const_row_col_iterator& operator--(); + arma_warn_unused inline const_row_col_iterator operator--(int); - inline arma_warn_unused uword row() const; - inline arma_warn_unused uword col() const; + arma_warn_unused inline uword row() const; + arma_warn_unused inline uword col() const; - inline arma_warn_unused bool operator==(const const_row_col_iterator& rhs) const; - inline arma_warn_unused bool operator!=(const const_row_col_iterator& rhs) const; - inline arma_warn_unused bool operator==(const row_col_iterator& rhs) const; - inline arma_warn_unused bool operator!=(const row_col_iterator& rhs) const; + arma_warn_unused inline bool operator==(const const_row_col_iterator& rhs) const; + arma_warn_unused inline bool operator!=(const const_row_col_iterator& rhs) const; + arma_warn_unused inline bool operator==(const row_col_iterator& rhs) const; + arma_warn_unused inline bool operator!=(const row_col_iterator& rhs) const; // So that we satisfy the STL iterator types. typedef std::bidirectional_iterator_tag iterator_category; @@ -731,15 +748,16 @@ inline bool empty() const; inline uword size() const; - inline arma_warn_unused eT& front(); - inline arma_warn_unused const eT& front() const; + arma_warn_unused inline eT& front(); + arma_warn_unused inline const eT& front() const; - inline arma_warn_unused eT& back(); - inline arma_warn_unused const eT& back() const; + arma_warn_unused inline eT& back(); + arma_warn_unused inline const eT& back() const; inline void swap(Mat& B); - inline void steal_mem(Mat& X); //!< don't use this unless you're writing code internal to Armadillo + inline void steal_mem(Mat& X); //!< don't use this unless you're writing code internal to Armadillo + inline void steal_mem(Mat& X, const bool is_move); //!< don't use this unless you're writing code internal to Armadillo inline void steal_mem_col(Mat& X, const uword max_n_rows); @@ -752,7 +770,7 @@ inline void init_cold(); inline void init_warm(uword in_n_rows, uword in_n_cols); - inline arma_cold void init(const std::string& text); + arma_cold inline void init(const std::string& text); inline void init(const std::initializer_list& list); inline void init(const std::initializer_list< std::initializer_list >& list); @@ -781,7 +799,7 @@ public: - #ifdef ARMA_EXTRA_MAT_PROTO + #if defined(ARMA_EXTRA_MAT_PROTO) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_PROTO) #endif }; @@ -844,31 +862,36 @@ template inline Mat& operator=(const eGlue& X); #endif - 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; - - arma_inline arma_warn_unused eT& operator[] (const uword i); - arma_inline arma_warn_unused const eT& operator[] (const uword i) const; - arma_inline arma_warn_unused eT& at (const uword i); - arma_inline arma_warn_unused const eT& at (const uword i) const; - arma_inline arma_warn_unused eT& operator() (const uword i); - arma_inline arma_warn_unused const eT& operator() (const uword i) const; - - arma_inline arma_warn_unused eT& at (const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& at (const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline const Op< Mat_fixed_type, op_htrans > t() const; + arma_warn_unused arma_inline const Op< Mat_fixed_type, op_htrans > ht() const; + arma_warn_unused arma_inline const Op< Mat_fixed_type, op_strans > st() const; + + arma_warn_unused arma_inline const eT& at_alt (const uword i) const; + + arma_warn_unused arma_inline eT& operator[] (const uword i); + arma_warn_unused arma_inline const eT& operator[] (const uword i) const; + arma_warn_unused arma_inline eT& at (const uword i); + arma_warn_unused arma_inline const eT& at (const uword i) const; + arma_warn_unused arma_inline eT& operator() (const uword i); + arma_warn_unused arma_inline const eT& operator() (const uword i) const; + + #if defined(__cpp_multidimensional_subscript) + arma_warn_unused arma_inline eT& operator[] (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& operator[] (const uword in_row, const uword in_col) const; + #endif + + arma_warn_unused arma_inline eT& at (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& at (const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused eT* colptr(const uword in_col); - arma_inline arma_warn_unused const eT* colptr(const uword in_col) const; + arma_warn_unused arma_inline eT* colptr(const uword in_col); + arma_warn_unused arma_inline const eT* colptr(const uword in_col) const; - arma_inline arma_warn_unused eT* memptr(); - arma_inline arma_warn_unused const eT* memptr() const; + arma_warn_unused arma_inline eT* memptr(); + arma_warn_unused arma_inline const eT* memptr() const; - arma_inline arma_warn_unused bool is_vec() const; + arma_warn_unused arma_inline bool is_vec() const; inline const Mat& fill(const eT val); inline const Mat& zeros(); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Mat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Mat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Mat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Mat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -72,12 +72,11 @@ init_cold(); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Mat::constructor: zeroing memory"); arrayops::fill_zeros(memptr(), n_elem); } - #endif } @@ -97,12 +96,11 @@ init_cold(); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Mat::constructor: zeroing memory"); arrayops::fill_zeros(memptr(), n_elem); } - #endif } @@ -300,7 +298,7 @@ void Mat::init_cold() { - arma_extra_debug_sigprint( arma_str::format("n_rows = %d, n_cols = %d") % n_rows % n_cols ); + arma_extra_debug_sigprint( arma_str::format("n_rows = %u, n_cols = %u") % n_rows % n_cols ); // ensure that n_elem can hold the result of (n_rows * n_cols) @@ -343,7 +341,7 @@ void Mat::init_warm(uword in_n_rows, uword in_n_cols) { - arma_extra_debug_sigprint( arma_str::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols ); + arma_extra_debug_sigprint( arma_str::format("in_n_rows = %u, in_n_cols = %u") % in_n_rows % in_n_cols ); if( (n_rows == in_n_rows) && (n_cols == in_n_cols) ) { return; } @@ -353,7 +351,11 @@ const uhword t_vec_state = vec_state; const uhword t_mem_state = mem_state; - arma_debug_set_error( err_state, err_msg, (t_mem_state == 3), "Mat::init(): size is fixed and hence cannot be changed" ); + const char* error_message_1 = "Mat::init(): size is fixed and hence cannot be changed"; + const char* error_message_2 = "Mat::init(): requested size is not compatible with column vector layout"; + const char* error_message_3 = "Mat::init(): requested size is not compatible with row vector layout"; + + arma_debug_set_error( err_state, err_msg, (t_mem_state == 3), error_message_1 ); if(t_vec_state > 0) { @@ -364,17 +366,17 @@ } else { - if(t_vec_state == 1) { arma_debug_set_error( err_state, err_msg, (in_n_cols != 1), "Mat::init(): requested size is not compatible with column vector layout" ); } - if(t_vec_state == 2) { arma_debug_set_error( err_state, err_msg, (in_n_rows != 1), "Mat::init(): requested size is not compatible with row vector layout" ); } + if(t_vec_state == 1) { arma_debug_set_error( err_state, err_msg, (in_n_cols != 1), error_message_2 ); } + if(t_vec_state == 2) { arma_debug_set_error( err_state, err_msg, (in_n_rows != 1), error_message_3 ); } } } // ensure that n_elem can hold the result of (n_rows * n_cols) #if defined(ARMA_64BIT_WORD) - const char* error_message = "Mat::init(): requested size is too large"; + const char* error_message_4 = "Mat::init(): requested size is too large"; #else - const char* error_message = "Mat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; + const char* error_message_4 = "Mat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; #endif arma_debug_set_error @@ -386,7 +388,7 @@ ? ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) ) : false ), - error_message + error_message_4 ); arma_debug_check(err_state, err_msg); @@ -455,7 +457,6 @@ //! create the matrix from a textual description template inline -arma_cold Mat::Mat(const char* text) : n_rows(0) , n_cols(0) @@ -475,7 +476,6 @@ //! create the matrix from a textual description template inline -arma_cold Mat& Mat::operator=(const char* text) { @@ -491,7 +491,6 @@ //! create the matrix from a textual description template inline -arma_cold Mat::Mat(const std::string& text) : n_rows(0) , n_cols(0) @@ -511,7 +510,6 @@ //! create the matrix from a textual description template inline -arma_cold Mat& Mat::operator=(const std::string& text) { @@ -527,7 +525,6 @@ //! internal function to create the matrix from a textual description template inline -arma_cold void Mat::init(const std::string& text_orig) { @@ -794,15 +791,7 @@ { arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - (*this).steal_mem(X); - - if( (X.mem_state == 0) && (X.n_alloc <= 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) = nullptr; - } + (*this).steal_mem(X, true); return *this; } @@ -939,7 +928,7 @@ set_size(1, N); - arrayops::copy( memptr(), list.begin(), N ); + if(N > 0) { arrayops::copy( memptr(), list.begin(), N ); } } @@ -1199,6 +1188,18 @@ { arma_extra_debug_sigprint(); + (*this).steal_mem(x, false); + } + + + +template +inline +void +Mat::steal_mem(Mat& x, const bool is_move) + { + arma_extra_debug_sigprint(); + if(this == &x) { return; } const uword x_n_rows = x.n_rows; @@ -1213,8 +1214,10 @@ 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( layout_ok && (t_mem_state <= 1) && ((x_n_alloc > arma_config::mat_prealloc) || (x_mem_state == 1)) ) + if( layout_ok && (t_mem_state <= 1) && ( (x_n_alloc > arma_config::mat_prealloc) || (x_mem_state == 1) || (is_move && (x_mem_state == 2)) ) ) { + arma_extra_debug_print("Mat::steal_mem(): stealing memory"); + reset(); access::rw(n_rows) = x_n_rows; @@ -1224,8 +1227,8 @@ 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_rows) = (x_vec_state == 2) ? 1 : 0; + access::rw(x.n_cols) = (x_vec_state == 1) ? 1 : 0; access::rw(x.n_elem) = 0; access::rw(x.n_alloc) = 0; access::rw(x.mem_state) = 0; @@ -1233,7 +1236,17 @@ } else { + arma_extra_debug_print("Mat::steal_mem(): copying memory"); + (*this).operator=(x); + + if( (is_move) && (x_mem_state == 0) && (x_n_alloc <= arma_config::mat_prealloc) ) + { + access::rw(x.n_rows) = (x_vec_state == 2) ? 1 : 0; + access::rw(x.n_cols) = (x_vec_state == 1) ? 1 : 0; + access::rw(x.n_elem) = 0; + access::rw(x.mem) = nullptr; + } } } @@ -2744,7 +2757,7 @@ typename SpProxy::const_iterator_type it_end = p.end(); // We have to zero everything that isn't being used. - arrayops::inplace_set(memptr(), eT(0), (it.col() * n_rows) + it.row()); + arrayops::fill_zeros(memptr(), (it.col() * n_rows) + it.row()); while(it != it_end) { @@ -2758,7 +2771,7 @@ ? (p.get_n_cols() * n_rows) : (it.col() * n_rows) + it.row(); - arrayops::inplace_set(memptr() + cur_loc + 1, eT(0), (next_loc - cur_loc - 1)); + arrayops::fill_zeros(memptr() + cur_loc + 1, (next_loc - cur_loc - 1)); } return *this; @@ -2818,8 +2831,12 @@ (*this).zeros(X.n_rows, X.n_cols); + if(X.n_nonzero == 0) { return *this; } + if(X.n_rows == X.m.n_rows) { + X.m.sync(); + const uword sv_col_start = X.aux_col1; const uword sv_col_end = X.aux_col1 + X.n_cols - 1; @@ -2973,7 +2990,6 @@ template -arma_cold inline mat_injector< Mat > Mat::operator<<(const eT val) @@ -2984,7 +3000,6 @@ template -arma_cold inline mat_injector< Mat > Mat::operator<<(const injector_end_of_row<>& x) @@ -4025,7 +4040,7 @@ //! apply a lambda function to each column, where each column is interpreted as a column vector template inline -const Mat& +Mat& Mat::each_col(const std::function< void(Col&) >& F) { arma_extra_debug_sigprint(); @@ -4062,7 +4077,7 @@ //! apply a lambda function to each row, where each row is interpreted as a row vector template inline -const Mat& +Mat& Mat::each_row(const std::function< void(Row&) >& F) { arma_extra_debug_sigprint(); @@ -4521,8 +4536,6 @@ -//! insert N rows at the specified row position, -//! optionally setting the elements of the inserted rows to zero template inline void @@ -4530,6 +4543,20 @@ { arma_extra_debug_sigprint(); + arma_ignore(set_to_zero); + + (*this).insert_rows(row_num, N); + } + + + +template +inline +void +Mat::insert_rows(const uword row_num, const uword N) + { + arma_extra_debug_sigprint(); + const uword t_n_rows = n_rows; const uword t_n_cols = n_cols; @@ -4539,33 +4566,27 @@ // insertion at row_num == n_rows is in effect an append operation arma_debug_check_bounds( (row_num > t_n_rows), "Mat::insert_rows(): index out of bounds" ); - if(N > 0) + if(N == 0) { return; } + + Mat out(t_n_rows + N, t_n_cols, arma_nozeros_indicator()); + + if(A_n_rows > 0) { - Mat out(t_n_rows + N, t_n_cols, arma_nozeros_indicator()); - - if(A_n_rows > 0) - { - out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1); - } - - if(B_n_rows > 0) - { - out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1); - } - - if(set_to_zero) - { - out.rows(row_num, row_num + N - 1).zeros(); - } - - steal_mem(out); + out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1); } + + if(B_n_rows > 0) + { + out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1); + } + + out.rows(row_num, row_num + N - 1).zeros(); + + steal_mem(out); } -//! insert N columns at the specified column position, -//! optionally setting the elements of the inserted columns to zero template inline void @@ -4573,6 +4594,20 @@ { arma_extra_debug_sigprint(); + arma_ignore(set_to_zero); + + (*this).insert_cols(col_num, N); + } + + + +template +inline +void +Mat::insert_cols(const uword col_num, const uword N) + { + arma_extra_debug_sigprint(); + const uword t_n_rows = n_rows; const uword t_n_cols = n_cols; @@ -4582,27 +4617,23 @@ // insertion at col_num == n_cols is in effect an append operation arma_debug_check_bounds( (col_num > t_n_cols), "Mat::insert_cols(): index out of bounds" ); - if(N > 0) + if(N == 0) { return; } + + Mat out(t_n_rows, t_n_cols + N, arma_nozeros_indicator()); + + if(A_n_cols > 0) { - Mat out(t_n_rows, t_n_cols + N, arma_nozeros_indicator()); - - if(A_n_cols > 0) - { - out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1); - } - - if(B_n_cols > 0) - { - out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1); - } - - if(set_to_zero) - { - out.cols(col_num, col_num + N - 1).zeros(); - } - - steal_mem(out); + out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1); + } + + if(B_n_cols > 0) + { + out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1); } + + out.cols(col_num, col_num + N - 1).zeros(); + + steal_mem(out); } @@ -4632,6 +4663,9 @@ bool err_state = false; char* err_msg = nullptr; + const char* error_message_1 = "Mat::insert_rows(): index out of bounds"; + const char* error_message_2 = "Mat::insert_rows(): given object has an incompatible number of columns"; + // insertion at row_num == n_rows is in effect an append operation arma_debug_set_error @@ -4639,7 +4673,7 @@ err_state, err_msg, (row_num > t_n_rows), - "Mat::insert_rows(): index out of bounds" + error_message_1 ); arma_debug_set_error @@ -4647,7 +4681,7 @@ err_state, err_msg, ( (C_n_cols != t_n_cols) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ), - "Mat::insert_rows(): given object has an incompatible number of columns" + error_message_2 ); arma_debug_check_bounds(err_state, err_msg); @@ -4705,6 +4739,9 @@ bool err_state = false; char* err_msg = nullptr; + const char* error_message_1 = "Mat::insert_cols(): index out of bounds"; + const char* error_message_2 = "Mat::insert_cols(): given object has an incompatible number of rows"; + // insertion at col_num == n_cols is in effect an append operation arma_debug_set_error @@ -4712,7 +4749,7 @@ err_state, err_msg, (col_num > t_n_cols), - "Mat::insert_cols(): index out of bounds" + error_message_1 ); arma_debug_set_error @@ -4720,7 +4757,7 @@ err_state, err_msg, ( (C_n_rows != t_n_rows) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ), - "Mat::insert_cols(): given object has an incompatible number of rows" + error_message_2 ); arma_debug_check_bounds(err_state, err_msg); @@ -5047,20 +5084,11 @@ const bool bad_alias = (eOp::proxy_type::has_subview && X.P.is_alias(*this)); - if(bad_alias == false) - { - init_warm(X.get_n_rows(), X.get_n_cols()); - - eop_type::apply(*this, X); - } - else - { - arma_extra_debug_print("bad_alias = true"); - - Mat tmp(X); - - steal_mem(tmp); - } + if(bad_alias) { Mat tmp(X); steal_mem(tmp); return *this; } + + init_warm(X.get_n_rows(), X.get_n_cols()); + + eop_type::apply(*this, X); return *this; } @@ -5074,9 +5102,13 @@ Mat::operator+=(const eOp& X) { arma_extra_debug_sigprint(); - + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + const bool bad_alias = (eOp::proxy_type::has_subview && X.P.is_alias(*this)); + + if(bad_alias) { const Mat tmp(X); return (*this).operator+=(tmp); } + eop_type::apply_inplace_plus(*this, X); return *this; @@ -5091,9 +5123,13 @@ Mat::operator-=(const eOp& X) { arma_extra_debug_sigprint(); - + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + const bool bad_alias = (eOp::proxy_type::has_subview && X.P.is_alias(*this)); + + if(bad_alias) { const Mat tmp(X); return (*this).operator-=(tmp); } + eop_type::apply_inplace_minus(*this, X); return *this; @@ -5125,9 +5161,13 @@ Mat::operator%=(const eOp& X) { arma_extra_debug_sigprint(); - + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + const bool bad_alias = (eOp::proxy_type::has_subview && X.P.is_alias(*this)); + + if(bad_alias) { const Mat tmp(X); return (*this).operator%=(tmp); } + eop_type::apply_inplace_schur(*this, X); return *this; @@ -5142,9 +5182,13 @@ Mat::operator/=(const eOp& X) { arma_extra_debug_sigprint(); - + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + const bool bad_alias = (eOp::proxy_type::has_subview && X.P.is_alias(*this)); + + if(bad_alias) { const Mat tmp(X); return (*this).operator/=(tmp); } + eop_type::apply_inplace_div(*this, X); return *this; @@ -5724,20 +5768,11 @@ (eGlue::proxy2_type::has_subview && X.P2.is_alias(*this)) ); - if(bad_alias == false) - { - init_warm(X.get_n_rows(), X.get_n_cols()); - - eglue_type::apply(*this, X); - } - else - { - arma_extra_debug_print("bad_alias = true"); - - Mat tmp(X); - - steal_mem(tmp); - } + if(bad_alias) { Mat tmp(X); steal_mem(tmp); return *this; } + + init_warm(X.get_n_rows(), X.get_n_cols()); + + eglue_type::apply(*this, X); return *this; } @@ -5756,6 +5791,15 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + const bool bad_alias = + ( + (eGlue::proxy1_type::has_subview && X.P1.is_alias(*this)) + || + (eGlue::proxy2_type::has_subview && X.P2.is_alias(*this)) + ); + + if(bad_alias) { const Mat tmp(X); return (*this).operator+=(tmp); } + eglue_type::apply_inplace_plus(*this, X); return *this; @@ -5775,6 +5819,15 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + const bool bad_alias = + ( + (eGlue::proxy1_type::has_subview && X.P1.is_alias(*this)) + || + (eGlue::proxy2_type::has_subview && X.P2.is_alias(*this)) + ); + + if(bad_alias) { const Mat tmp(X); return (*this).operator-=(tmp); } + eglue_type::apply_inplace_minus(*this, X); return *this; @@ -5811,6 +5864,15 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + const bool bad_alias = + ( + (eGlue::proxy1_type::has_subview && X.P1.is_alias(*this)) + || + (eGlue::proxy2_type::has_subview && X.P2.is_alias(*this)) + ); + + if(bad_alias) { const Mat tmp(X); return (*this).operator%=(tmp); } + eglue_type::apply_inplace_schur(*this, X); return *this; @@ -5829,6 +5891,15 @@ arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + const bool bad_alias = + ( + (eGlue::proxy1_type::has_subview && X.P1.is_alias(*this)) + || + (eGlue::proxy2_type::has_subview && X.P2.is_alias(*this)) + ); + + if(bad_alias) { const Mat tmp(X); return (*this).operator/=(tmp); } + eglue_type::apply_inplace_div(*this, X); return *this; @@ -5947,10 +6018,139 @@ +template +template +inline +Mat::Mat(const SpToDGlue& 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); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + + glue_type::apply(*this, X); + } + + + +template +template +inline +Mat& +Mat::operator=(const SpToDGlue& X) + { + arma_extra_debug_sigprint(); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + + glue_type::apply(*this, X); + + return *this; + } + + + +template +template +inline +Mat& +Mat::operator+=(const SpToDGlue& X) + { + arma_extra_debug_sigprint(); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + + const Mat m(X); + + return (*this).operator+=(m); + } + + + +template +template +inline +Mat& +Mat::operator-=(const SpToDGlue& X) + { + arma_extra_debug_sigprint(); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + + const Mat m(X); + + return (*this).operator-=(m); + } + + + +template +template +inline +Mat& +Mat::operator*=(const SpToDGlue& X) + { + arma_extra_debug_sigprint(); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + + glue_times::apply_inplace(*this, X); + + return *this; + } + + + +template +template +inline +Mat& +Mat::operator%=(const SpToDGlue& X) + { + arma_extra_debug_sigprint(); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + + const Mat m(X); + + return (*this).operator%=(m); + } + + + +template +template +inline +Mat& +Mat::operator/=(const SpToDGlue& X) + { + arma_extra_debug_sigprint(); + + arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); + arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); + + const Mat m(X); + + return (*this).operator/=(m); + } + + + //! linear element accessor (treats the matrix as a vector); no bounds check; assumes memory is aligned template arma_inline -arma_warn_unused const eT& Mat::at_alt(const uword ii) const { @@ -5966,7 +6166,6 @@ //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline -arma_warn_unused eT& Mat::operator() (const uword ii) { @@ -5980,7 +6179,6 @@ //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline -arma_warn_unused const eT& Mat::operator() (const uword ii) const { @@ -5993,7 +6191,6 @@ //! linear element accessor (treats the matrix as a vector); no bounds check. template arma_inline -arma_warn_unused eT& Mat::operator[] (const uword ii) { @@ -6005,7 +6202,6 @@ //! linear element accessor (treats the matrix as a vector); no bounds check template arma_inline -arma_warn_unused const eT& Mat::operator[] (const uword ii) const { @@ -6017,7 +6213,6 @@ //! linear element accessor (treats the matrix as a vector); no bounds check. template arma_inline -arma_warn_unused eT& Mat::at(const uword ii) { @@ -6029,7 +6224,6 @@ //! linear element accessor (treats the matrix as a vector); no bounds check template arma_inline -arma_warn_unused const eT& Mat::at(const uword ii) const { @@ -6041,7 +6235,6 @@ //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline -arma_warn_unused eT& Mat::operator() (const uword in_row, const uword in_col) { @@ -6055,7 +6248,6 @@ //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined template arma_inline -arma_warn_unused const eT& Mat::operator() (const uword in_row, const uword in_col) const { @@ -6069,7 +6261,6 @@ //! element accessor; no bounds check template arma_inline -arma_warn_unused eT& Mat::at(const uword in_row, const uword in_col) { @@ -6081,7 +6272,6 @@ //! element accessor; no bounds check template arma_inline -arma_warn_unused const eT& Mat::at(const uword in_row, const uword in_col) const { @@ -6090,6 +6280,32 @@ +#if defined(__cpp_multidimensional_subscript) + + //! element accessor; no bounds check + template + arma_inline + eT& + Mat::operator[] (const uword in_row, const uword in_col) + { + return access::rw( mem[in_row + in_col*n_rows] ); + } + + + + //! element accessor; no bounds check + template + arma_inline + const eT& + Mat::operator[] (const uword in_row, const uword in_col) const + { + return mem[in_row + in_col*n_rows]; + } + +#endif + + + //! prefix ++ template arma_inline @@ -6141,7 +6357,6 @@ //! returns true if the matrix has no elements template arma_inline -arma_warn_unused bool Mat::is_empty() const { @@ -6153,7 +6368,6 @@ //! returns true if the object can be interpreted as a column or row vector template arma_inline -arma_warn_unused bool Mat::is_vec() const { @@ -6165,7 +6379,6 @@ //! returns true if the object can be interpreted as a row vector template arma_inline -arma_warn_unused bool Mat::is_rowvec() const { @@ -6177,7 +6390,6 @@ //! returns true if the object can be interpreted as a column vector template arma_inline -arma_warn_unused bool Mat::is_colvec() const { @@ -6189,7 +6401,6 @@ //! returns true if the object has the same number of non-zero rows and columnns template arma_inline -arma_warn_unused bool Mat::is_square() const { @@ -6198,23 +6409,22 @@ -//! returns true if all of the elements are finite template inline -arma_warn_unused bool -Mat::is_finite() const +Mat::internal_is_finite() const { - return arrayops::is_finite( memptr(), n_elem ); + arma_extra_debug_sigprint(); + + return arrayops::is_finite(memptr(), n_elem); } template inline -arma_warn_unused bool -Mat::has_inf() const +Mat::internal_has_inf() const { arma_extra_debug_sigprint(); @@ -6225,9 +6435,8 @@ template inline -arma_warn_unused bool -Mat::has_nan() const +Mat::internal_has_nan() const { arma_extra_debug_sigprint(); @@ -6238,7 +6447,18 @@ template inline -arma_warn_unused +bool +Mat::internal_has_nonfinite() const + { + arma_extra_debug_sigprint(); + + return (arrayops::is_finite(memptr(), n_elem) == false); + } + + + +template +inline bool Mat::is_sorted(const char* direction) const { @@ -6251,7 +6471,6 @@ template inline -arma_warn_unused bool Mat::is_sorted(const char* direction, const uword dim) const { @@ -6327,7 +6546,6 @@ template template inline -arma_warn_unused bool Mat::is_sorted_helper(const comparator& comp, const uword dim) const { @@ -6397,7 +6615,6 @@ //! returns true if the given index is currently in range template arma_inline -arma_warn_unused bool Mat::in_range(const uword ii) const { @@ -6409,7 +6626,6 @@ //! returns true if the given start and end indices are currently in range template arma_inline -arma_warn_unused bool Mat::in_range(const span& x) const { @@ -6433,7 +6649,6 @@ //! returns true if the given location is currently in range template arma_inline -arma_warn_unused bool Mat::in_range(const uword in_row, const uword in_col) const { @@ -6444,7 +6659,6 @@ template arma_inline -arma_warn_unused bool Mat::in_range(const span& row_span, const uword in_col) const { @@ -6467,7 +6681,6 @@ template arma_inline -arma_warn_unused bool Mat::in_range(const uword in_row, const span& col_span) const { @@ -6490,7 +6703,6 @@ template arma_inline -arma_warn_unused bool Mat::in_range(const span& row_span, const span& col_span) const { @@ -6512,7 +6724,6 @@ template arma_inline -arma_warn_unused bool Mat::in_range(const uword in_row, const uword in_col, const SizeMat& s) const { @@ -6534,7 +6745,6 @@ //! returns a pointer to array of eTs for a specified column; no bounds check template arma_inline -arma_warn_unused eT* Mat::colptr(const uword in_col) { @@ -6546,7 +6756,6 @@ //! returns a pointer to array of eTs for a specified column; no bounds check template arma_inline -arma_warn_unused const eT* Mat::colptr(const uword in_col) const { @@ -6558,7 +6767,6 @@ //! returns a pointer to array of eTs used by the matrix template arma_inline -arma_warn_unused eT* Mat::memptr() { @@ -6570,7 +6778,6 @@ //! returns a pointer to array of eTs used by the matrix template arma_inline -arma_warn_unused const eT* Mat::memptr() const { @@ -6582,7 +6789,7 @@ //! change the matrix to have user specified dimensions (data is not preserved) template inline -void +Mat& Mat::set_size(const uword new_n_elem) { arma_extra_debug_sigprint(); @@ -6602,6 +6809,8 @@ default: ; } + + return *this; } @@ -6609,24 +6818,28 @@ //! change the matrix to have user specified dimensions (data is not preserved) template inline -void +Mat& Mat::set_size(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); init_warm(new_n_rows, new_n_cols); + + return *this; } template inline -void +Mat& Mat::set_size(const SizeMat& s) { arma_extra_debug_sigprint(); init_warm(s.n_rows, s.n_cols); + + return *this; } @@ -6634,7 +6847,7 @@ //! change the matrix to have user specified dimensions (data is preserved) template inline -void +Mat& Mat::resize(const uword new_n_elem) { arma_extra_debug_sigprint(); @@ -6654,6 +6867,8 @@ default: ; } + + return *this; } @@ -6661,24 +6876,28 @@ //! change the matrix to have user specified dimensions (data is preserved) template inline -void +Mat& Mat::resize(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); op_resize::apply_mat_inplace((*this), new_n_rows, new_n_cols); + + return *this; } template inline -void +Mat& Mat::resize(const SizeMat& s) { arma_extra_debug_sigprint(); op_resize::apply_mat_inplace((*this), s.n_rows, s.n_cols); + + return *this; } @@ -6686,42 +6905,55 @@ //! change the matrix to have user specified dimensions (data is preserved) template inline -void +Mat& Mat::reshape(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); op_reshape::apply_mat_inplace((*this), new_n_rows, new_n_cols); + + return *this; } template inline -void +Mat& Mat::reshape(const SizeMat& s) { arma_extra_debug_sigprint(); op_reshape::apply_mat_inplace((*this), s.n_rows, s.n_cols); + + return *this; } //! NOTE: don't use this form; it's deprecated and will be removed template -arma_deprecated inline void Mat::reshape(const uword new_n_rows, const uword new_n_cols, const uword dim) { arma_extra_debug_sigprint(); - // 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); + if(dim == 0) + { + op_reshape::apply_mat_inplace((*this), new_n_rows, new_n_cols); + } + else + if(dim == 1) + { + Mat tmp; + + op_strans::apply_mat_noalias(tmp, (*this)); + + op_reshape::apply_mat_noalias((*this), tmp, new_n_rows, new_n_cols); + } } @@ -6730,7 +6962,7 @@ template template inline -void +Mat& Mat::copy_size(const Base& X) { arma_extra_debug_sigprint(); @@ -6741,6 +6973,8 @@ const uword X_n_cols = P.get_n_cols(); init_warm(X_n_rows, X_n_cols); + + return *this; } @@ -6749,7 +6983,7 @@ template template inline -const Mat& +Mat& Mat::for_each(functor F) { arma_extra_debug_sigprint(); @@ -6810,7 +7044,7 @@ template template inline -const Mat& +Mat& Mat::transform(functor F) { arma_extra_debug_sigprint(); @@ -6847,7 +7081,7 @@ template template inline -const Mat& +Mat& Mat::imbue(functor F) { arma_extra_debug_sigprint(); @@ -6879,7 +7113,7 @@ template inline -const Mat& +Mat& Mat::replace(const eT old_val, const eT new_val) { arma_extra_debug_sigprint(); @@ -6893,7 +7127,7 @@ template inline -const Mat& +Mat& Mat::clean(const typename get_pod_type::result threshold) { arma_extra_debug_sigprint(); @@ -6907,7 +7141,7 @@ template inline -const Mat& +Mat& Mat::clamp(const eT min_val, const eT max_val) { arma_extra_debug_sigprint(); @@ -6932,7 +7166,7 @@ //! fill the matrix with the specified value template inline -const Mat& +Mat& Mat::fill(const eT val) { arma_extra_debug_sigprint(); @@ -6948,7 +7182,7 @@ template template inline -const Mat& +Mat& Mat::fill(const fill::fill_class&) { arma_extra_debug_sigprint(); @@ -6966,7 +7200,7 @@ template inline -const Mat& +Mat& Mat::zeros() { arma_extra_debug_sigprint(); @@ -6980,7 +7214,7 @@ template inline -const Mat& +Mat& Mat::zeros(const uword new_n_elem) { arma_extra_debug_sigprint(); @@ -6994,7 +7228,7 @@ template inline -const Mat& +Mat& Mat::zeros(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); @@ -7008,7 +7242,7 @@ template inline -const Mat& +Mat& Mat::zeros(const SizeMat& s) { arma_extra_debug_sigprint(); @@ -7020,7 +7254,7 @@ template inline -const Mat& +Mat& Mat::ones() { arma_extra_debug_sigprint(); @@ -7032,7 +7266,7 @@ template inline -const Mat& +Mat& Mat::ones(const uword new_n_elem) { arma_extra_debug_sigprint(); @@ -7046,7 +7280,7 @@ template inline -const Mat& +Mat& Mat::ones(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); @@ -7060,7 +7294,7 @@ template inline -const Mat& +Mat& Mat::ones(const SizeMat& s) { arma_extra_debug_sigprint(); @@ -7072,7 +7306,7 @@ template inline -const Mat& +Mat& Mat::randu() { arma_extra_debug_sigprint(); @@ -7086,7 +7320,7 @@ template inline -const Mat& +Mat& Mat::randu(const uword new_n_elem) { arma_extra_debug_sigprint(); @@ -7100,7 +7334,7 @@ template inline -const Mat& +Mat& Mat::randu(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); @@ -7114,7 +7348,7 @@ template inline -const Mat& +Mat& Mat::randu(const SizeMat& s) { arma_extra_debug_sigprint(); @@ -7126,7 +7360,7 @@ template inline -const Mat& +Mat& Mat::randn() { arma_extra_debug_sigprint(); @@ -7140,7 +7374,7 @@ template inline -const Mat& +Mat& Mat::randn(const uword new_n_elem) { arma_extra_debug_sigprint(); @@ -7154,7 +7388,7 @@ template inline -const Mat& +Mat& Mat::randn(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); @@ -7168,7 +7402,7 @@ template inline -const Mat& +Mat& Mat::randn(const SizeMat& s) { arma_extra_debug_sigprint(); @@ -7180,7 +7414,7 @@ template inline -const Mat& +Mat& Mat::eye() { arma_extra_debug_sigprint(); @@ -7198,7 +7432,7 @@ template inline -const Mat& +Mat& Mat::eye(const uword new_n_rows, const uword new_n_cols) { arma_extra_debug_sigprint(); @@ -7212,7 +7446,7 @@ template inline -const Mat& +Mat& Mat::eye(const SizeMat& s) { arma_extra_debug_sigprint(); @@ -7224,7 +7458,6 @@ template inline -arma_cold void Mat::reset() { @@ -7240,7 +7473,6 @@ template inline -arma_cold void Mat::soft_reset() { @@ -7287,7 +7519,6 @@ template inline -arma_warn_unused eT Mat::min() const { @@ -7307,7 +7538,6 @@ template inline -arma_warn_unused eT Mat::max() const { @@ -7428,7 +7658,6 @@ //! save the matrix to a file template inline -arma_cold bool Mat::save(const std::string name, const file_type type) const { @@ -7483,7 +7712,7 @@ save_okay = false; } - if(save_okay == false) { arma_debug_warn_level(3, "Mat::save(): couldn't write; file: ", name); } + if(save_okay == false) { arma_debug_warn_level(3, "Mat::save(): write failed; file: ", name); } return save_okay; } @@ -7492,7 +7721,6 @@ template inline -arma_cold bool Mat::save(const hdf5_name& spec, const file_type type) const { @@ -7541,7 +7769,7 @@ } else { - arma_debug_warn_level(3, "Mat::save(): couldn't write; file: ", spec.filename); + arma_debug_warn_level(3, "Mat::save(): write failed; file: ", spec.filename); } } @@ -7552,7 +7780,6 @@ template inline -arma_cold bool Mat::save(const csv_name& spec, const file_type type) const { @@ -7564,10 +7791,10 @@ 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); + 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 ); + const bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header) && (no_header == false); + 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:"); @@ -7578,8 +7805,6 @@ 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) ) @@ -7621,7 +7846,7 @@ 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); } + if(save_okay == false) { arma_debug_warn_level(3, "Mat::save(): write failed; file: ", spec.filename); } return save_okay; } @@ -7631,7 +7856,6 @@ //! save the matrix to a stream template inline -arma_cold bool Mat::save(std::ostream& os, const file_type type) const { @@ -7678,7 +7902,7 @@ save_okay = false; } - if(save_okay == false) { arma_debug_warn_level(3, "Mat::save(): couldn't write to stream"); } + if(save_okay == false) { arma_debug_warn_level(3, "Mat::save(): stream write failed"); } return save_okay; } @@ -7688,7 +7912,6 @@ //! load a matrix from a file template inline -arma_cold bool Mat::load(const std::string name, const file_type type) { @@ -7756,7 +7979,7 @@ } else { - arma_debug_warn_level(3, "Mat::load(): couldn't read; file: ", name); + arma_debug_warn_level(3, "Mat::load(): read failed; file: ", name); } } @@ -7769,7 +7992,6 @@ template inline -arma_cold bool Mat::load(const hdf5_name& spec, const file_type type) { @@ -7808,7 +8030,7 @@ } else { - arma_debug_warn_level(3, "Mat::load(): couldn't read; file: ", spec.filename); + arma_debug_warn_level(3, "Mat::load(): read failed; file: ", spec.filename); } } @@ -7821,7 +8043,6 @@ template inline -arma_cold bool Mat::load(const csv_name& spec, const file_type type) { @@ -7833,10 +8054,11 @@ 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); + 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 ); + const bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header) && (no_header == false); + const bool use_semicolon = bool(spec.opts.flags & csv_opts::flag_semicolon ) || (type == ssv_ascii); + const bool strict = bool(spec.opts.flags & csv_opts::flag_strict ); arma_extra_debug_print("Mat::load(csv_name): enabled flags:"); @@ -7844,11 +8066,10 @@ 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"); } + if(strict ) { arma_extra_debug_print("strict"); } const char separator = (use_semicolon) ? char(';') : char(','); - if(no_header) { with_header = false; } - bool load_okay = false; std::string err_msg; @@ -7856,7 +8077,7 @@ { Mat tmp_mat; - load_okay = diskio::load_csv_ascii(tmp_mat, spec.filename, err_msg, spec.header_rw, with_header, separator); + load_okay = diskio::load_csv_ascii(tmp_mat, spec.filename, err_msg, spec.header_rw, with_header, separator, strict); if(load_okay) { @@ -7871,7 +8092,7 @@ } else { - load_okay = diskio::load_csv_ascii(*this, spec.filename, err_msg, spec.header_rw, with_header, separator); + load_okay = diskio::load_csv_ascii(*this, spec.filename, err_msg, spec.header_rw, with_header, separator, strict); } if(load_okay == false) @@ -7882,7 +8103,7 @@ } else { - arma_debug_warn_level(3, "Mat::load(): couldn't read; file: ", spec.filename); + arma_debug_warn_level(3, "Mat::load(): read failed; file: ", spec.filename); } } else @@ -7910,7 +8131,6 @@ //! load a matrix from a stream template inline -arma_cold bool Mat::load(std::istream& is, const file_type type) { @@ -7934,11 +8154,11 @@ break; case csv_ascii: - load_okay = diskio::load_csv_ascii(*this, is, err_msg, char(',')); + load_okay = diskio::load_csv_ascii(*this, is, err_msg, char(','), false); break; case ssv_ascii: - load_okay = diskio::load_csv_ascii(*this, is, err_msg, char(';')); + load_okay = diskio::load_csv_ascii(*this, is, err_msg, char(';'), false); break; case coord_ascii: @@ -7970,7 +8190,7 @@ } else { - arma_debug_warn_level(3, "Mat::load(): couldn't load from stream"); + arma_debug_warn_level(3, "Mat::load(): stream read failed"); } } @@ -7981,10 +8201,8 @@ -//! save the matrix to a file, without printing any error messages template inline -arma_cold bool Mat::quiet_save(const std::string name, const file_type type) const { @@ -7997,7 +8215,6 @@ template inline -arma_cold bool Mat::quiet_save(const hdf5_name& spec, const file_type type) const { @@ -8010,7 +8227,6 @@ template inline -arma_cold bool Mat::quiet_save(const csv_name& spec, const file_type type) const { @@ -8021,10 +8237,8 @@ -//! save the matrix to a stream, without printing any error messages template inline -arma_cold bool Mat::quiet_save(std::ostream& os, const file_type type) const { @@ -8035,10 +8249,8 @@ -//! load a matrix from a file, without printing any error messages template inline -arma_cold bool Mat::quiet_load(const std::string name, const file_type type) { @@ -8051,7 +8263,6 @@ template inline -arma_cold bool Mat::quiet_load(const hdf5_name& spec, const file_type type) { @@ -8064,7 +8275,6 @@ template inline -arma_cold bool Mat::quiet_load(const csv_name& spec, const file_type type) { @@ -8075,10 +8285,8 @@ -//! load a matrix from a stream, without printing any error messages template inline -arma_cold bool Mat::quiet_load(std::istream& is, const file_type type) { @@ -8129,7 +8337,6 @@ template inline -arma_warn_unused eT& Mat::row_iterator::operator*() { @@ -8158,7 +8365,6 @@ template inline -arma_warn_unused typename Mat::row_iterator Mat::row_iterator::operator++(int) { @@ -8196,7 +8402,6 @@ template inline -arma_warn_unused typename Mat::row_iterator Mat::row_iterator::operator--(int) { @@ -8211,7 +8416,6 @@ template inline -arma_warn_unused bool Mat::row_iterator::operator!=(const typename Mat::row_iterator& X) const { @@ -8222,7 +8426,6 @@ template inline -arma_warn_unused bool Mat::row_iterator::operator==(const typename Mat::row_iterator& X) const { @@ -8233,7 +8436,6 @@ template inline -arma_warn_unused bool Mat::row_iterator::operator!=(const typename Mat::const_row_iterator& X) const { @@ -8244,7 +8446,6 @@ template inline -arma_warn_unused bool Mat::row_iterator::operator==(const typename Mat::const_row_iterator& X) const { @@ -8305,7 +8506,6 @@ template inline -arma_warn_unused const eT& Mat::const_row_iterator::operator*() const { @@ -8334,7 +8534,6 @@ template inline -arma_warn_unused typename Mat::const_row_iterator Mat::const_row_iterator::operator++(int) { @@ -8372,7 +8571,6 @@ template inline -arma_warn_unused typename Mat::const_row_iterator Mat::const_row_iterator::operator--(int) { @@ -8387,7 +8585,6 @@ template inline -arma_warn_unused bool Mat::const_row_iterator::operator!=(const typename Mat::row_iterator& X) const { @@ -8398,7 +8595,6 @@ template inline -arma_warn_unused bool Mat::const_row_iterator::operator==(const typename Mat::row_iterator& X) const { @@ -8409,7 +8605,6 @@ template inline -arma_warn_unused bool Mat::const_row_iterator::operator!=(const typename Mat::const_row_iterator& X) const { @@ -8420,7 +8615,6 @@ template inline -arma_warn_unused bool Mat::const_row_iterator::operator==(const typename Mat::const_row_iterator& X) const { @@ -8471,7 +8665,6 @@ template inline -arma_warn_unused eT& Mat::row_col_iterator::operator*() { @@ -8505,7 +8698,6 @@ template inline -arma_warn_unused typename Mat::row_col_iterator Mat::row_col_iterator::operator++(int) { @@ -8542,7 +8734,6 @@ template inline -arma_warn_unused typename Mat::row_col_iterator Mat::row_col_iterator::operator--(int) { @@ -8557,7 +8748,6 @@ template inline -arma_warn_unused uword Mat::row_col_iterator::row() const { @@ -8568,7 +8758,6 @@ template inline -arma_warn_unused uword Mat::row_col_iterator::col() const { @@ -8579,7 +8768,6 @@ template inline -arma_warn_unused bool Mat::row_col_iterator::operator==(const row_col_iterator& rhs) const { @@ -8590,7 +8778,6 @@ template inline -arma_warn_unused bool Mat::row_col_iterator::operator!=(const row_col_iterator& rhs) const { @@ -8601,7 +8788,6 @@ template inline -arma_warn_unused bool Mat::row_col_iterator::operator==(const const_row_col_iterator& rhs) const { @@ -8612,7 +8798,6 @@ template inline -arma_warn_unused bool Mat::row_col_iterator::operator!=(const const_row_col_iterator& rhs) const { @@ -8676,7 +8861,6 @@ template inline -arma_warn_unused const eT& Mat::const_row_col_iterator::operator*() const { @@ -8710,7 +8894,6 @@ template inline -arma_warn_unused typename Mat::const_row_col_iterator Mat::const_row_col_iterator::operator++(int) { @@ -8748,7 +8931,6 @@ template inline -arma_warn_unused typename Mat::const_row_col_iterator Mat::const_row_col_iterator::operator--(int) { @@ -8763,7 +8945,6 @@ template inline -arma_warn_unused uword Mat::const_row_col_iterator::row() const { @@ -8774,7 +8955,6 @@ template inline -arma_warn_unused uword Mat::const_row_col_iterator::col() const { @@ -8785,7 +8965,6 @@ template inline -arma_warn_unused bool Mat::const_row_col_iterator::operator==(const const_row_col_iterator& rhs) const { @@ -8796,7 +8975,6 @@ template inline -arma_warn_unused bool Mat::const_row_col_iterator::operator!=(const const_row_col_iterator& rhs) const { @@ -8807,7 +8985,6 @@ template inline -arma_warn_unused bool Mat::const_row_col_iterator::operator==(const row_col_iterator& rhs) const { @@ -8818,7 +8995,6 @@ template inline -arma_warn_unused bool Mat::const_row_col_iterator::operator!=(const row_col_iterator& rhs) const { @@ -9084,7 +9260,6 @@ template inline -arma_warn_unused eT& Mat::front() { @@ -9097,7 +9272,6 @@ template inline -arma_warn_unused const eT& Mat::front() const { @@ -9110,7 +9284,6 @@ template inline -arma_warn_unused eT& Mat::back() { @@ -9123,7 +9296,6 @@ template inline -arma_warn_unused const eT& Mat::back() const { @@ -9142,7 +9314,7 @@ { arma_extra_debug_sigprint_this(this); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Mat::fixed::constructor: zeroing memory"); @@ -9150,7 +9322,6 @@ arrayops::inplace_set_fixed( mem_use, eT(0) ); } - #endif } @@ -9371,20 +9542,11 @@ const bool bad_alias = (eOp::proxy_type::has_subview && X.P.is_alias(*this)); - if(bad_alias == false) - { - arma_debug_assert_same_size(fixed_n_rows, fixed_n_cols, X.get_n_rows(), X.get_n_cols(), "Mat::fixed::operator="); - - eop_type::apply(*this, X); - } - else - { - arma_extra_debug_print("bad_alias = true"); - - Mat tmp(X); - - (*this) = tmp; - } + if(bad_alias) { const Mat tmp(X); (*this) = tmp; return *this; } + + arma_debug_assert_same_size(fixed_n_rows, fixed_n_cols, X.get_n_rows(), X.get_n_cols(), "Mat::fixed::operator="); + + eop_type::apply(*this, X); return *this; } @@ -9410,20 +9572,11 @@ (eGlue::proxy2_type::has_subview && X.P2.is_alias(*this)) ); - if(bad_alias == false) - { - arma_debug_assert_same_size(fixed_n_rows, fixed_n_cols, X.get_n_rows(), X.get_n_cols(), "Mat::fixed::operator="); - - eglue_type::apply(*this, X); - } - else - { - arma_extra_debug_print("bad_alias = true"); - - Mat tmp(X); - - (*this) = tmp; - } + if(bad_alias) { const Mat tmp(X); (*this) = tmp; return *this; } + + arma_debug_assert_same_size(fixed_n_rows, fixed_n_cols, X.get_n_rows(), X.get_n_cols(), "Mat::fixed::operator="); + + eglue_type::apply(*this, X); return *this; } @@ -9435,7 +9588,6 @@ template template arma_inline -arma_warn_unused const Op< typename Mat::template fixed::Mat_fixed_type, op_htrans > Mat::fixed::t() const { @@ -9447,7 +9599,6 @@ template template arma_inline -arma_warn_unused const Op< typename Mat::template fixed::Mat_fixed_type, op_htrans > Mat::fixed::ht() const { @@ -9459,7 +9610,6 @@ template template arma_inline -arma_warn_unused const Op< typename Mat::template fixed::Mat_fixed_type, op_strans > Mat::fixed::st() const { @@ -9471,7 +9621,6 @@ template template arma_inline -arma_warn_unused const eT& Mat::fixed::at_alt(const uword ii) const { @@ -9493,7 +9642,6 @@ template template arma_inline -arma_warn_unused eT& Mat::fixed::operator[] (const uword ii) { @@ -9505,7 +9653,6 @@ template template arma_inline -arma_warn_unused const eT& Mat::fixed::operator[] (const uword ii) const { @@ -9517,7 +9664,6 @@ template template arma_inline -arma_warn_unused eT& Mat::fixed::at(const uword ii) { @@ -9529,7 +9675,6 @@ template template arma_inline -arma_warn_unused const eT& Mat::fixed::at(const uword ii) const { @@ -9541,7 +9686,6 @@ template template arma_inline -arma_warn_unused eT& Mat::fixed::operator() (const uword ii) { @@ -9555,7 +9699,6 @@ template template arma_inline -arma_warn_unused const eT& Mat::fixed::operator() (const uword ii) const { @@ -9566,10 +9709,39 @@ +#if defined(__cpp_multidimensional_subscript) + + template + template + arma_inline + eT& + Mat::fixed::operator[] (const uword in_row, const uword in_col) + { + const uword iq = in_row + in_col*fixed_n_rows; + + return (use_extra) ? mem_local_extra[iq] : mem_local[iq]; + } + + + + template + template + arma_inline + const eT& + Mat::fixed::operator[] (const uword in_row, const uword in_col) const + { + const uword iq = in_row + in_col*fixed_n_rows; + + return (use_extra) ? mem_local_extra[iq] : mem_local[iq]; + } + +#endif + + + template template arma_inline -arma_warn_unused eT& Mat::fixed::at(const uword in_row, const uword in_col) { @@ -9583,7 +9755,6 @@ template template arma_inline -arma_warn_unused const eT& Mat::fixed::at(const uword in_row, const uword in_col) const { @@ -9597,7 +9768,6 @@ template template arma_inline -arma_warn_unused eT& Mat::fixed::operator() (const uword in_row, const uword in_col) { @@ -9613,7 +9783,6 @@ template template arma_inline -arma_warn_unused const eT& Mat::fixed::operator() (const uword in_row, const uword in_col) const { @@ -9629,7 +9798,6 @@ template template arma_inline -arma_warn_unused eT* Mat::fixed::colptr(const uword in_col) { @@ -9643,7 +9811,6 @@ template template arma_inline -arma_warn_unused const eT* Mat::fixed::colptr(const uword in_col) const { @@ -9657,7 +9824,6 @@ template template arma_inline -arma_warn_unused eT* Mat::fixed::memptr() { @@ -9669,7 +9835,6 @@ template template arma_inline -arma_warn_unused const eT* Mat::fixed::memptr() const { @@ -9681,7 +9846,6 @@ template template arma_inline -arma_warn_unused bool Mat::fixed::is_vec() const { @@ -9938,17 +10102,14 @@ const uword N = out.n_elem; - for(uword i=0; i( A[i], out_mem[i].imag() ); - } + for(uword i=0; i( P.at(row,col), (*out_mem).imag() ); + (*out_mem).real(P.at(row,col)); out_mem++; } } @@ -9982,17 +10143,14 @@ const uword N = out.n_elem; - for(uword i=0; i( out_mem[i].real(), A[i] ); - } + for(uword i=0; i( (*out_mem).real(), P.at(row,col) ); + (*out_mem).imag(P.at(row,col)); out_mem++; } } @@ -10000,7 +10158,7 @@ -#ifdef ARMA_EXTRA_MAT_MEAT +#if defined(ARMA_EXTRA_MAT_MEAT) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_MEAT) #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/memory.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/memory.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/memory.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/memory.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -24,7 +24,7 @@ { public: - template inline arma_malloc static eT* acquire(const uword n_elem); + template arma_malloc inline static eT* acquire(const uword n_elem); template arma_inline static void release(eT* mem); @@ -36,8 +36,8 @@ template -inline arma_malloc +inline eT* memory::acquire(const uword n_elem) { @@ -77,6 +77,8 @@ } #elif defined(_MSC_VER) { + // Windoze is too primitive to handle C++17 std::aligned_alloc() + //out_memptr = (eT *) malloc(sizeof(eT)*n_elem); //out_memptr = (eT *) _aligned_malloc( sizeof(eT)*n_elem, 16 ); // lives in malloc.h @@ -180,6 +182,9 @@ } #endif + // TODO: look into C++20 std::assume_aligned() + // TODO: https://en.cppreference.com/w/cpp/memory/assume_aligned + // TODO: MSVC? __assume( (mem & 0x0F) == 0 ); // // http://comments.gmane.org/gmane.comp.gcc.patches/239430 diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemm.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/mul_gemm.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemm.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/mul_gemm.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -239,7 +239,7 @@ //! \brief -//! Wrapper for ATLAS/BLAS dgemm function, using template arguments to control the arguments passed to dgemm. +//! Wrapper for 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 (ie. taking into account transposes) template @@ -280,9 +280,9 @@ atlas::cblas_gemm ( - atlas::CblasColMajor, - (do_trans_A) ? ( is_cx::yes ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans, - (do_trans_B) ? ( is_cx::yes ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans, + atlas_CblasColMajor, + (do_trans_A) ? ( is_cx::yes ? atlas_CblasConjTrans : atlas_CblasTrans ) : atlas_CblasNoTrans, + (do_trans_B) ? ( is_cx::yes ? atlas_CblasConjTrans : atlas_CblasTrans ) : atlas_CblasNoTrans, C.n_rows, C.n_cols, (do_trans_A) ? A.n_rows : A.n_cols, diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemv.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/mul_gemv.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/mul_gemv.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/mul_gemv.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -209,7 +209,7 @@ //! \brief -//! Partial emulation of ATLAS/BLAS gemv(). +//! Partial emulation of BLAS gemv(). //! 'y' is assumed to have been set to the correct size (ie. taking into account the transpose) template @@ -293,7 +293,7 @@ //! \brief -//! Wrapper for ATLAS/BLAS gemv function, using template arguments to control the arguments passed to gemv. +//! Wrapper for BLAS gemv function, using template arguments to control the arguments passed to gemv. //! 'y' is assumed to have been set to the correct size (ie. taking into account the transpose) template @@ -327,9 +327,9 @@ atlas::cblas_gemm ( - atlas::CblasColMajor, - (do_trans_A) ? ( is_cx::yes ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans, - atlas::CblasNoTrans, + atlas_CblasColMajor, + (do_trans_A) ? ( is_cx::yes ? atlas_CblasConjTrans : atlas_CblasTrans ) : atlas_CblasNoTrans, + atlas_CblasNoTrans, (do_trans_A) ? A.n_cols : A.n_rows, 1, (do_trans_A) ? A.n_rows : A.n_cols, @@ -349,8 +349,8 @@ atlas::cblas_gemv ( - atlas::CblasColMajor, - (do_trans_A) ? ( is_cx::yes ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans, + atlas_CblasColMajor, + (do_trans_A) ? ( is_cx::yes ? atlas_CblasConjTrans : atlas_CblasTrans ) : atlas_CblasNoTrans, A.n_rows, A.n_cols, (use_alpha) ? alpha : eT(1), diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/mul_herk.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/mul_herk.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/mul_herk.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/mul_herk.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -48,9 +48,9 @@ template - static arma_hot inline + static eT dot_conj_row(const uword n_elem, const eT* const A, const Mat& B, const uword row) { @@ -326,7 +326,7 @@ if(A.is_vec()) { - // work around poor handling of vectors by herk() in ATLAS 3.8.4 and standard BLAS + // work around poor handling of vectors by herk() in standard BLAS herk_vec::apply(C,A,alpha,beta); @@ -359,9 +359,9 @@ atlas::cblas_herk ( - atlas::CblasColMajor, - atlas::CblasUpper, - (do_trans_A) ? CblasConjTrans : atlas::CblasNoTrans, + atlas_CblasColMajor, + atlas_CblasUpper, + (do_trans_A) ? atlas_CblasConjTrans : atlas_CblasNoTrans, C.n_cols, (do_trans_A) ? A.n_rows : A.n_cols, (use_alpha) ? alpha : T(1), diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/mul_syrk.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/mul_syrk.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/mul_syrk.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/mul_syrk.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -286,7 +286,7 @@ if(A.is_vec()) { - // work around poor handling of vectors by syrk() in ATLAS 3.8.4 and standard BLAS + // work around poor handling of vectors by syrk() in standard BLAS syrk_vec::apply(C,A,alpha,beta); @@ -318,9 +318,9 @@ atlas::cblas_syrk ( - atlas::CblasColMajor, - atlas::CblasUpper, - (do_trans_A) ? atlas::CblasTrans : atlas::CblasNoTrans, + atlas_CblasColMajor, + atlas_CblasUpper, + (do_trans_A) ? atlas_CblasTrans : atlas_CblasNoTrans, C.n_cols, (do_trans_A) ? A.n_rows : A.n_cols, (use_alpha) ? alpha : eT(1), diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_GenEigsSolver_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_GenEigsSolver_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_GenEigsSolver_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_GenEigsSolver_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -25,18 +25,18 @@ class GenEigsSolver { protected: - + 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 - + // Sort the first nev Ritz pairs in decreasing magnitude order // This is used to return the final results virtual void sort_ritzpair(); - - + + private: - + const uword dim_n; // dimension of matrix A const uword ncv; // number of ritz values uword nmatop; // number of matrix operations called @@ -54,46 +54,50 @@ // used to test the orthogonality of vectors, // and in convergence test, tol*approx0 is // the absolute tolerance - + + std::mt19937_64 local_rng; // local random number generator + + inline void fill_rand(eT* dest, const uword N, const uword seed_val); + // Arnoldi factorisation starting from step-k inline void factorise_from(uword from_k, uword to_m, const Col& fk); - + // Implicitly restarted Arnoldi factorisation inline void restart(uword k); - + // Calculate the number of converged Ritz values inline uword num_converged(eT tol); - + // Return the adjusted nev for restarting inline uword nev_adjusted(uword nconv); - + // Retrieve and sort ritz values and ritz vectors inline void retrieve_ritzpair(); - - + + public: - + //! Constructor to create a solver object. inline GenEigsSolver(const OpType& op_, uword nev_, uword ncv_); - + //! Providing the initial residual vector for the algorithm. inline void init(eT* init_resid); - + //! Providing a random initial residual vector. inline void init(); - + //! Conducting the major computation procedure. inline uword compute(uword maxit = 1000, eT tol = 1e-10); - + //! Returning the number of iterations used in the computation. inline int num_iterations() { return niter; } - + //! Returning the number of matrix operations used in the computation. inline int num_operations() { return nmatop; } - + //! Returning the converged eigenvalues. inline Col< std::complex > eigenvalues(); - + //! Returning the eigenvectors associated with the converged eigenvalues. inline Mat< std::complex > eigenvectors(uword nvec); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_GenEigsSolver_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_GenEigsSolver_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_GenEigsSolver_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_GenEigsSolver_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -23,6 +23,24 @@ template inline void +GenEigsSolver::fill_rand(eT* dest, const uword N, const uword seed_val) + { + arma_extra_debug_sigprint(); + + typedef typename std::mt19937_64::result_type seed_type; + + local_rng.seed( seed_type(seed_val) ); + + std::uniform_real_distribution dist(-1.0, +1.0); + + for(uword i=0; i < N; ++i) { dest[i] = eT(dist(local_rng)); } + } + + + +template +inline +void GenEigsSolver::factorise_from(uword from_k, uword to_m, const Col& fk) { arma_extra_debug_sigprint(); @@ -44,12 +62,16 @@ // to the current V, which we call a restart if(beta < eps) { + // // Generate new random vector for fac_f + // blas_int idist = 2; + // blas_int iseed[4] = {1, 3, 5, 7}; + // iseed[0] = (i + 100) % 4095; + // blas_int n = dim_n; + // lapack::larnv(&idist, &iseed[0], &n, fac_f.memptr()); + // Generate new random vector for fac_f - blas_int idist = 2; - blas_int iseed[4] = {1, 3, 5, 7}; - iseed[0] = (i + 100) % 4095; - blas_int n = dim_n; - lapack::larnv(&idist, &iseed[0], &n, fac_f.memptr()); + fill_rand(fac_f.memptr(), dim_n, i+1); + // f <- f - V * V' * f, so that f is orthogonal to V Mat Vs(fac_V.memptr(), dim_n, i, false); // First i columns Col Vf = Vs.t() * fac_f; @@ -362,11 +384,17 @@ { arma_extra_debug_sigprint(); + // podarray init_resid(dim_n); + // blas_int idist = 2; // Uniform(-1, 1) + // blas_int iseed[4] = {1, 3, 5, 7}; // Fixed random seed + // blas_int n = dim_n; + // lapack::larnv(&idist, &iseed[0], &n, init_resid.memptr()); + // init(init_resid.memptr()); + podarray init_resid(dim_n); - blas_int idist = 2; // Uniform(-1, 1) - blas_int iseed[4] = {1, 3, 5, 7}; // Fixed random seed - blas_int n = dim_n; - lapack::larnv(&idist, &iseed[0], &n, init_resid.memptr()); + + fill_rand(init_resid.memptr(), dim_n, 0); + init(init_resid.memptr()); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -27,6 +27,7 @@ private: const SpMat& op_mat; + SpMat op_mat_st; public: diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SparseGenMatProd_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -28,6 +28,8 @@ , n_cols(mat_obj.n_cols) { arma_extra_debug_sigprint(); + + op_mat_st = op_mat.st(); // pre-calculate transpose } @@ -41,10 +43,20 @@ { arma_extra_debug_sigprint(); - const Col x(x_in , n_cols, false, true); - Col y(y_out, n_rows, false, true); + // // OLD METHOD + // + // const Col x(x_in , n_cols, false, true); + // Col y(y_out, n_rows, false, true); + // + // y = op_mat * x; + + + // NEW METHOD + + const Row x(x_in , n_cols, false, true); + Row y(y_out, n_rows, false, true); - y = op_mat * x; + y = x * op_mat_st; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -28,6 +28,9 @@ , perm_r(mat_obj.n_rows + 1) , n_rows(mat_obj.n_rows) , n_cols(mat_obj.n_cols) + #else + : n_rows(0) + , n_cols(0) #endif { arma_extra_debug_sigprint(); @@ -74,8 +77,8 @@ 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"); } + if(x_rcond == eT(0)) { arma_debug_warn_level(2, "matrix is singular to working precision"); } + else { arma_debug_warn_level(2, "matrix is singular to working precision (rcond: ", x_rcond, ")"); } return; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsSolver_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SymEigsSolver_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsSolver_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SymEigsSolver_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -25,18 +25,18 @@ class SymEigsSolver { protected: - + 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 ascending algebraic order // This is used to return the final results virtual void sort_ritzpair(); - - + + private: - + const uword dim_n; // dimension of matrix A const uword ncv; // number of ritz values uword nmatop; // number of matrix operations called @@ -52,48 +52,53 @@ 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 - + + std::mt19937_64 local_rng; // local random number generator + + inline void fill_rand(eT* dest, const uword N, const uword seed_val); + // Arnoldi factorisation starting from step-k inline void factorise_from(uword from_k, uword to_m, const Col& fk); - + // Implicitly restarted Arnoldi factorisation inline void restart(uword k); - + // Calculate the number of converged Ritz values inline uword num_converged(eT tol); - + // Return the adjusted nev for restarting inline uword nev_adjusted(uword nconv); - + // Retrieve and sort ritz values and ritz vectors inline void retrieve_ritzpair(); - - + + public: - + //! Constructor to create a solver object. inline SymEigsSolver(const OpType& op_, uword nev_, uword ncv_); - + //! Providing the initial residual vector for the algorithm. inline void init(eT* init_resid); - + //! Providing a random initial residual vector. inline void init(); - + //! Conducting the major computation procedure. inline uword compute(uword maxit = 1000, eT tol = 1e-10); - + //! Returning the number of iterations used in the computation. inline uword num_iterations() { return niter; } - + //! Returning the number of matrix operations used in the computation. inline uword num_operations() { return nmatop; } - + //! Returning the converged eigenvalues. inline Col eigenvalues(); - + //! Returning the eigenvectors associated with the converged eigenvalues. inline Mat eigenvectors(uword nvec); + //! Returning all converged eigenvectors. inline Mat eigenvectors() { return eigenvectors(nev); } }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsSolver_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SymEigsSolver_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_SymEigsSolver_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_SymEigsSolver_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -23,6 +23,24 @@ template inline void +SymEigsSolver::fill_rand(eT* dest, const uword N, const uword seed_val) + { + arma_extra_debug_sigprint(); + + typedef typename std::mt19937_64::result_type seed_type; + + local_rng.seed( seed_type(seed_val) ); + + std::uniform_real_distribution dist(-1.0, +1.0); + + for(uword i=0; i < N; ++i) { dest[i] = eT(dist(local_rng)); } + } + + + +template +inline +void SymEigsSolver::factorise_from(uword from_k, uword to_m, const Col& fk) { arma_extra_debug_sigprint(); @@ -47,12 +65,16 @@ // to the current V, which we call a restart if(beta < near0) { + // // Generate new random vector for fac_f + // blas_int idist = 2; + // blas_int iseed[4] = {1, 3, 5, 7}; + // iseed[0] = (i + 100) % 4095; + // blas_int n = dim_n; + // lapack::larnv(&idist, &iseed[0], &n, fac_f.memptr()); + // Generate new random vector for fac_f - blas_int idist = 2; - blas_int iseed[4] = {1, 3, 5, 7}; - iseed[0] = (i + 100) % 4095; - blas_int n = dim_n; - lapack::larnv(&idist, &iseed[0], &n, fac_f.memptr()); + fill_rand(fac_f.memptr(), dim_n, i+1); + // f <- f - V * V' * f, so that f is orthogonal to V Mat Vs(fac_V.memptr(), dim_n, i, false); // First i columns Col Vf = Vs.t() * fac_f; @@ -221,15 +243,13 @@ // Adjust nev_new, according to dsaup2.f line 677~684 in ARPACK nev_new += (std::min)(nconv, (ncv - nev_new) / 2); + if(nev_new >= ncv) { nev_new = ncv - 1; } - if(nev_new == 1 && ncv >= 6) - { - nev_new = ncv / 2; - } - else - if(nev_new == 1 && ncv > 2) + + if(nev_new == 1) { - nev_new = 2; + if(ncv >= 6) { nev_new = ncv / 2; } + else if(ncv > 2) { nev_new = 2; } } return nev_new; @@ -266,7 +286,8 @@ { // If i is even, pick values from the left (large values) // If i is odd, pick values from the right (small values) - if(i % 2 == 0) { ind[i] = ind_copy[i / 2]; } else { ind[i] = ind_copy[ncv - 1 - i / 2]; } + + ind[i] = (i % 2 == 0) ? ind_copy[i / 2] : ind_copy[ncv - 1 - i / 2]; } } @@ -384,11 +405,17 @@ { arma_extra_debug_sigprint(); + // podarray init_resid(dim_n); + // blas_int idist = 2; // Uniform(-1, 1) + // blas_int iseed[4] = {1, 3, 5, 7}; // Fixed random seed + // blas_int n = dim_n; + // lapack::larnv(&idist, &iseed[0], &n, init_resid.memptr()); + // init(init_resid.memptr()); + podarray init_resid(dim_n); - blas_int idist = 2; // Uniform(-1, 1) - blas_int iseed[4] = {1, 3, 5, 7}; // Fixed random seed - blas_int n = dim_n; - lapack::larnv(&idist, &iseed[0], &n, init_resid.memptr()); + + fill_rand(init_resid.memptr(), dim_n, 0); + init(init_resid.memptr()); } @@ -437,13 +464,10 @@ if(nconv > 0) { uword j = 0; - for(uword i = 0; i < nev; i++) + + for(uword i=0; i < nev; i++) { - if(ritz_conv[i]) - { - res(j) = ritz_val(i); - j++; - } + if(ritz_conv[i]) { res(j) = ritz_val(i); j++; } } } @@ -468,13 +492,10 @@ Mat ritz_vec_conv(ncv, nvec, arma_zeros_indicator()); uword j = 0; - for(uword i = 0; i < nev && j < nvec; i++) + + for(uword i=0; i < nev && j < nvec; i++) { - if(ritz_conv[i]) - { - ritz_vec_conv.col(j) = ritz_vec.col(i); - j++; - } + if(ritz_conv[i]) { ritz_vec_conv.col(j) = ritz_vec.col(i); j++; } } res = fac_V * ritz_vec_conv; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_TridiagEigen_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_TridiagEigen_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_TridiagEigen_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_TridiagEigen_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -61,37 +61,40 @@ evecs.set_size(n, n); char compz = 'I'; - blas_int lwork = blas_int(-1); - eT lwork_opt = eT(0); - - blas_int liwork = blas_int(-1); - blas_int liwork_opt = blas_int(0); + blas_int lwork_min = 1 + 4*n + n*n; + blas_int liwork_min = 3 + 5*n; blas_int info = blas_int(0); - // query for lwork and liwork - lapack::stedc(&compz, &n, main_diag.memptr(), sub_diag.memptr(), evecs.memptr(), &n, &lwork_opt, &lwork, &liwork_opt, &liwork, &info); + blas_int lwork_proposed = 0; + blas_int liwork_proposed = 0; - if(info == 0) - { - lwork = blas_int(lwork_opt); - liwork = liwork_opt; - } - else + if(n >= 32) { - lwork = 1 + 4 * n + n * n; - liwork = 3 + 5 * n; + eT work_query[2] = {}; + blas_int lwork_query = blas_int(-1); + + blas_int iwork_query[2] = {}; + blas_int liwork_query = blas_int(-1); + + arma_extra_debug_print("lapack::stedc()"); + lapack::stedc(&compz, &n, main_diag.memptr(), sub_diag.memptr(), evecs.memptr(), &n, &work_query[0], &lwork_query, &iwork_query[0], &liwork_query, &info); + + if(info != 0) { arma_stop_runtime_error("lapack::stedc(): couldn't get size of work arrays"); return; } + + lwork_proposed = static_cast( work_query[0] ); + liwork_proposed = iwork_query[0]; } - info = blas_int(0); + blas_int lwork = (std::max)( lwork_min, lwork_proposed); + blas_int liwork = (std::max)(liwork_min, liwork_proposed); - podarray work(static_cast(lwork) ); - podarray iwork(static_cast(liwork)); + podarray work( static_cast( lwork) ); + podarray iwork( static_cast(liwork) ); + arma_extra_debug_print("lapack::stedc()"); lapack::stedc(&compz, &n, main_diag.memptr(), sub_diag.memptr(), evecs.memptr(), &n, work.memptr(), &lwork, iwork.memptr(), &liwork, &info); - if(info < 0) { arma_stop_logic_error("lapack::stedc(): illegal value"); return; } - - if(info > 0) { arma_stop_runtime_error("lapack::stedc(): failed to compute all eigenvalues"); return; } + if(info != 0) { arma_stop_runtime_error("lapack::stedc(): failed to compute all eigenvalues"); return; } computed = true; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,36 +21,36 @@ //! Calculate the eigenvalues and eigenvectors of an upper Hessenberg matrix. -//! This class is a wrapper of the Lapack functions `_lahqr` and `_trevc`. +//! This class is uses lapack::lahqr() and lapack::trevc() template class UpperHessenbergEigen { private: - - blas_int n; + + uword n_rows; Mat mat_Z; // In the first stage, H = ZTZ', Z is an orthogonal matrix // In the second stage, Z will be overwritten by the eigenvectors of H Mat mat_T; // H = ZTZ', T is a Schur form matrix Col< std::complex > evals; // eigenvalues of H bool computed; - - + + public: - + //! Default constructor. Computation can //! be performed later by calling the compute() method. inline UpperHessenbergEigen(); - + //! Constructor to create an object that calculates the eigenvalues //! and eigenvectors of an upper Hessenberg matrix `mat_obj`. inline UpperHessenbergEigen(const Mat& mat_obj); - + //! Compute the eigenvalue decomposition of an upper Hessenberg matrix. inline void compute(const Mat& mat_obj); - + //! Retrieve the eigenvalues. inline Col< std::complex > eigenvalues(); - + //! Retrieve the eigenvectors. inline Mat< std::complex > eigenvectors(); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/newarp_UpperHessenbergEigen_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -23,7 +23,7 @@ template inline UpperHessenbergEigen::UpperHessenbergEigen() - : n(0) + : n_rows(0) , computed(false) { arma_extra_debug_sigprint(); @@ -34,7 +34,7 @@ template inline UpperHessenbergEigen::UpperHessenbergEigen(const Mat& mat_obj) - : n(mat_obj.n_rows) + : n_rows(mat_obj.n_rows) , computed(false) { arma_extra_debug_sigprint(); @@ -53,11 +53,11 @@ arma_debug_check( (mat_obj.is_square() == false), "newarp::UpperHessenbergEigen::compute(): matrix must be square" ); - n = blas_int(mat_obj.n_rows); + n_rows = mat_obj.n_rows; - mat_Z.set_size(n, n); - mat_T.set_size(n, n); - evals.set_size(n); + mat_Z.set_size(n_rows, n_rows); + mat_T.set_size(n_rows, n_rows); + evals.set_size(n_rows); mat_Z.eye(); mat_T = mat_obj; @@ -65,35 +65,34 @@ blas_int want_T = blas_int(1); blas_int want_Z = blas_int(1); + blas_int n = blas_int(n_rows); blas_int ilo = blas_int(1); - blas_int ihi = blas_int(n); + blas_int ihi = blas_int(n_rows); blas_int iloz = blas_int(1); - blas_int ihiz = blas_int(n); + blas_int ihiz = blas_int(n_rows); blas_int info = blas_int(0); - podarray wr(static_cast(n)); - podarray wi(static_cast(n)); - + podarray wr(n_rows); + podarray wi(n_rows); + arma_extra_debug_print("lapack::lahqr()"); lapack::lahqr(&want_T, &want_Z, &n, &ilo, &ihi, mat_T.memptr(), &n, wr.memptr(), wi.memptr(), &iloz, &ihiz, mat_Z.memptr(), &n, &info); - for(blas_int i = 0; i < n; i++) - { - evals(i) = std::complex(wr[i], wi[i]); - } + if(info != 0) { arma_stop_runtime_error("lapack::lahqr(): failed to compute all eigenvalues"); return; } - if(info > 0) { arma_stop_runtime_error("lapack::lahqr(): failed to compute all eigenvalues"); return; } + for(uword i=0; i < n_rows; i++) { evals(i) = std::complex(wr[i], wi[i]); } char side = 'R'; char howmny = 'B'; blas_int m = blas_int(0); - podarray work(static_cast(3 * n)); + podarray work(3*n); + arma_extra_debug_print("lapack::trevc()"); lapack::trevc(&side, &howmny, (blas_int*) NULL, &n, mat_T.memptr(), &n, (eT*) NULL, &n, mat_Z.memptr(), &n, &n, &m, work.memptr(), &info); - if(info < 0) { arma_stop_logic_error("lapack::trevc(): illegal value"); return; } + if(info != 0) { arma_stop_runtime_error("lapack::trevc(): illegal value"); return; } computed = true; } @@ -108,7 +107,7 @@ arma_extra_debug_sigprint(); arma_debug_check( (computed == false), "newarp::UpperHessenbergEigen::eigenvalues(): need to call compute() first" ); - + return evals; } @@ -122,46 +121,46 @@ arma_extra_debug_sigprint(); 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, arma_zeros_indicator()); + Mat< std::complex > evecs(n_rows, n_rows, arma_zeros_indicator()); std::complex* col_ptr = evecs.memptr(); - for(blas_int i = 0; i < n; i++) + for(uword i=0; i < n_rows; i++) { if(cx_attrib::is_real(evals(i), eT(0))) { // for real eigenvector, normalise and copy - eT z_norm = norm(mat_Z.col(i)); + const eT z_norm = norm(mat_Z.col(i)); - for(blas_int j = 0; j < n; j++) + for(uword j=0; j < n_rows; j++) { col_ptr[j] = std::complex(mat_Z(j, i) / z_norm, eT(0)); } - - col_ptr += n; + + col_ptr += n_rows; } else { // complex eigenvectors are stored in consecutive columns - eT r2 = dot(mat_Z.col(i), mat_Z.col(i)); - eT i2 = dot(mat_Z.col(i + 1), mat_Z.col(i + 1)); + const eT r2 = dot(mat_Z.col(i ), mat_Z.col(i )); + const eT i2 = dot(mat_Z.col(i+1), mat_Z.col(i+1)); - eT z_norm = std::sqrt(r2 + i2); - eT* z_ptr = mat_Z.colptr(i); + const eT z_norm = std::sqrt(r2 + i2); + const eT* z_ptr = mat_Z.colptr(i); - for(blas_int j = 0; j < n; j++) + for(uword j=0; j < n_rows; j++) { - col_ptr[j ] = std::complex(z_ptr[j] / z_norm, z_ptr[j + n] / z_norm); - col_ptr[j + n] = std::conj(col_ptr[j]); + col_ptr[j ] = std::complex(z_ptr[j] / z_norm, z_ptr[j + n_rows] / z_norm); + col_ptr[j + n_rows] = std::conj(col_ptr[j]); } - + i++; - col_ptr += 2 * n; + col_ptr += 2 * n_rows; } } - + return evecs; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Op_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Op_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Op_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Op_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -56,14 +56,12 @@ inline Op(const T1& in_m, const elem_type in_aux); inline Op(const T1& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b); inline Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); - inline Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const char junk); inline ~Op(); arma_aligned const T1& m; //!< the operand; must be derived from Base arma_aligned elem_type aux; //!< auxiliary data, using the element type as used by T1 arma_aligned uword aux_uword_a; //!< auxiliary data, uword format arma_aligned uword aux_uword_b; //!< auxiliary data, uword format - arma_aligned uword aux_uword_c; //!< auxiliary data, uword format }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_chol_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_chol_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_chol_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_chol_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -50,17 +50,10 @@ out = A_expr.get_ref(); - arma_debug_check( (out.is_square() == false), "chol(): given matrix must be square sized" ); + arma_debug_check( (out.is_square() == false), "chol(): given matrix must be square sized", [&](){ out.soft_reset(); } ); if(out.is_empty()) { return true; } - // if(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"); } - // return false; - // } - 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"); } @@ -69,11 +62,7 @@ uword KD = 0; - #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 is_band = arma_config::optimise_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)))); const bool status = (is_band) ? auxlib::chol_band(out, KD, layout) : auxlib::chol(out, layout); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_col_as_mat_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_col_as_mat_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_col_as_mat_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_col_as_mat_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,33 @@ +// 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_col_as_mat +//! @{ + + +class op_col_as_mat + : public traits_op_default + { + public: + + template inline static void apply(Mat& out, const CubeToMatOp& expr); + }; + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_col_as_mat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_col_as_mat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_col_as_mat_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_col_as_mat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,53 @@ +// 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_col_as_mat +//! @{ + + + +template +inline +void +op_col_as_mat::apply(Mat& out, const CubeToMatOp& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_cube U(expr.m); + const Cube& A = U.M; + + const uword in_col = expr.aux_uword; + + arma_debug_check_bounds( (in_col >= A.n_cols), "Cube::col_as_mat(): index out of bounds" ); + + const uword A_n_rows = A.n_rows; + const uword A_n_slices = A.n_slices; + + out.set_size(A_n_rows, A_n_slices); + + for(uword s=0; s < A_n_slices; ++s) + { + arrayops::copy(out.colptr(s), A.slice_colptr(s, in_col), A_n_rows); + } + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_cond_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_cond_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_cond_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_cond_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -25,8 +25,11 @@ { public: - template static inline typename T1::pod_type cond(const Base& X); - template static inline typename T1::pod_type rcond(const Base& X); + template static inline typename T1::pod_type apply(const Base& X); + + template static inline typename get_pod_type::result apply_diag(const Mat& A); + template static inline typename get_pod_type::result apply_sym ( Mat& A); + template static inline typename get_pod_type::result apply_gen ( Mat& A); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_cond_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_cond_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_cond_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_cond_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -24,7 +24,7 @@ template inline typename T1::pod_type -op_cond::cond(const Base& X) +op_cond::apply(const Base& X) { arma_extra_debug_sigprint(); @@ -33,86 +33,140 @@ Mat A(X.get_ref()); - Col S; + if(A.n_elem == 0) { return T(0); } - const bool status = auxlib::svd_dc(S, A); + if(is_op_diagmat::value || A.is_diagmat()) + { + arma_extra_debug_print("op_cond::apply(): detected diagonal matrix"); + + return op_cond::apply_diag(A); + } - if(status == false) + bool is_approx_sym = false; + bool is_approx_sympd = false; + + sym_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A); + + const bool do_sym = (is_cx::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd); + + if(do_sym) { - arma_debug_warn_level(3, "cond(): svd failed"); + arma_extra_debug_print("op_cond: symmetric/hermitian optimisation"); - return T(0); + return op_cond::apply_sym(A); } - return (S.n_elem > 0) ? T( max(S) / min(S) ) : T(0); + return op_cond::apply_gen(A); } -template +template inline -typename T1::pod_type -op_cond::rcond(const Base& X) +typename get_pod_type::result +op_cond::apply_diag(const Mat& A) { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - typedef typename T1::pod_type T; + typedef typename get_pod_type::result T; - if(strip_trimat::do_trimat) + const uword N = (std::min)(A.n_rows, A.n_cols); + + T abs_min = Datum::inf; + T abs_max = T(0); + + for(uword i=0; i < N; ++i) { - const strip_trimat S(X.get_ref()); - - const quasi_unwrap::stored_type> U(S.M); - - arma_debug_check( (U.M.is_square() == false), "rcond(): matrix must be square sized" ); + const T abs_val = std::abs(A.at(i,i)); - const uword layout = (S.do_triu) ? uword(0) : uword(1); + if(arma_isnan(abs_val)) + { + arma_debug_warn_level(3, "cond(): failed"); + + return Datum::nan; + } - return auxlib::rcond_trimat(U.M, layout); + abs_min = (abs_val < abs_min) ? abs_val : abs_min; + abs_max = (abs_val > abs_max) ? abs_val : abs_max; } - Mat A = X.get_ref(); + if((abs_min == T(0)) || (abs_max == T(0))) { return Datum::inf; } - arma_debug_check( (A.is_square() == false), "rcond(): matrix must be square sized" ); + return T(abs_max / abs_min); + } + + + +template +inline +typename get_pod_type::result +op_cond::apply_sym(Mat& A) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; - if(A.is_empty()) { return Datum::inf; } + Col eigval; - const bool is_triu = trimat_helper::is_triu(A); - const bool is_tril = (is_triu) ? false : trimat_helper::is_tril(A); + const bool status = auxlib::eig_sym(eigval, A); - if(is_triu || is_tril) + if(status == false) { - const uword layout = (is_triu) ? uword(0) : uword(1); + arma_debug_warn_level(3, "cond(): failed"); - return auxlib::rcond_trimat(A, layout); + return Datum::nan; } - #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(eigval.n_elem == 0) { return T(0); } - if(try_sympd) + const T* eigval_mem = eigval.memptr(); + + T abs_min = std::abs(eigval_mem[0]); + T abs_max = abs_min; + + for(uword i=1; i < eigval.n_elem; ++i) { - arma_extra_debug_print("op_cond::rcond(): attempting sympd optimisation"); - - bool calc_ok = false; - - const T out_val = auxlib::rcond_sympd(A, calc_ok); + const T abs_val = std::abs(eigval_mem[i]); - if(calc_ok) { return out_val; } - - arma_extra_debug_print("op_cond::rcond(): sympd optimisation failed"); + abs_min = (abs_val < abs_min) ? abs_val : abs_min; + abs_max = (abs_val > abs_max) ? abs_val : abs_max; + } + + if((abs_min == T(0)) || (abs_max == T(0))) { return Datum::inf; } + + return T(abs_max / abs_min); + } + + + +template +inline +typename get_pod_type::result +op_cond::apply_gen(Mat& A) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + Col S; + + const bool status = auxlib::svd_dc(S, A); + + if(status == false) + { + arma_debug_warn_level(3, "cond(): failed"); - // auxlib::rcond_sympd() may have failed because A isn't really sympd - // restore A, as auxlib::rcond_sympd() may have destroyed it - A = X.get_ref(); - // fallthrough to the next return statement + return Datum::nan; } - return auxlib::rcond(A); + if(S.n_elem == 0) { return T(0); } + + const T S_max = S[0]; + const T S_min = S[S.n_elem-1]; + + if((S_max == T(0)) || (S_min == T(0))) { return Datum::inf; } + + return T(S_max / S_min); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/OpCube_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/OpCube_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/OpCube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/OpCube_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -20,8 +20,6 @@ //! @{ -//! Analog of the Op class, intended for cubes - template class OpCube : public BaseCube< typename T1::elem_type, OpCube > { @@ -30,13 +28,11 @@ typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; - inline explicit OpCube(const BaseCube& in_m); inline OpCube(const BaseCube& in_m, const elem_type in_aux); inline OpCube(const BaseCube& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c); inline OpCube(const BaseCube& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); inline OpCube(const BaseCube& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c); - inline OpCube(const BaseCube& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const uword in_aux_uword_d, const char junk); inline ~OpCube(); arma_aligned const T1& m; //!< the operand; must be derived from BaseCube @@ -44,8 +40,6 @@ arma_aligned uword aux_uword_a; //!< auxiliary data, uword format arma_aligned uword aux_uword_b; //!< auxiliary data, uword format arma_aligned uword aux_uword_c; //!< auxiliary data, uword format - arma_aligned uword aux_uword_d; //!< auxiliary data, uword format - }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/OpCube_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/OpCube_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/OpCube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/OpCube_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -77,19 +77,6 @@ template -OpCube::OpCube(const BaseCube& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const uword in_aux_uword_d, const char) - : m(in_m.get_ref()) - , aux_uword_a(in_aux_uword_a) - , aux_uword_b(in_aux_uword_b) - , aux_uword_c(in_aux_uword_c) - , aux_uword_d(in_aux_uword_d) - { - arma_extra_debug_sigprint(); - } - - - -template OpCube::~OpCube() { arma_extra_debug_sigprint(); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_det_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_det_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_det_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_det_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -44,7 +44,13 @@ inline static typename T1::elem_type apply_trimat(const Base& expr); template - arma_cold inline static eT apply_tiny(const Mat& X); + arma_cold inline static eT apply_tiny_2x2(const Mat& X); + + template + arma_cold inline static eT apply_tiny_3x3(const Mat& X); + + template + arma_cold inline static eT apply_tiny_4x4(const Mat& X); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_det_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_det_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_det_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_det_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -53,13 +53,23 @@ arma_debug_check( (A.is_square() == false), "det(): given matrix must be square sized" ); - if((A.n_rows <= 4) && is_cx::no) + const uword N = A.n_rows; + + if(N == 0) { out_val = eT(1); return true; } + if(N == 1) { out_val = A[0]; return true; } + + if((is_cx::no) && (N <= 4)) { 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); + eT det_val = eT(0); + + if(N == 2) { det_val = op_det::apply_tiny_2x2(A); } + if(N == 3) { det_val = op_det::apply_tiny_3x3(A); } + if(N == 4) { det_val = op_det::apply_tiny_4x4(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; } @@ -127,109 +137,114 @@ template -arma_cold inline eT -op_det::apply_tiny(const Mat& X) +op_det::apply_tiny_2x2(const Mat& X) { arma_extra_debug_sigprint(); - // NOTE: assuming matrix X is square sized + const eT* Xm = X.memptr(); - const uword N = X.n_rows; - const eT* Xm = X.memptr(); + return ( Xm[pos<0,0>::n2]*Xm[pos<1,1>::n2] - Xm[pos<0,1>::n2]*Xm[pos<1,0>::n2] ); + } + + + +template +inline +eT +op_det::apply_tiny_3x3(const Mat& X) + { + arma_extra_debug_sigprint(); - if(N == 0) { return eT(1); } + const eT* Xm = X.memptr(); - if(N == 1) { return Xm[0]; } + // 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]); - 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 ); - } + return ( val1 - val2 + val3 ); + } + + + +template +inline +eT +op_det::apply_tiny_4x4(const Mat& X) + { + arma_extra_debug_sigprint(); - 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; - } + const eT* Xm = X.memptr(); - return eT(0); + 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; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_dot_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_dot_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_dot_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_dot_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -29,7 +29,7 @@ { arma_extra_debug_sigprint(); - #if defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ > 0) + #if defined(__FAST_MATH__) { eT val = eT(0); @@ -67,7 +67,6 @@ //! for two arrays, generic version for complex values template -arma_hot inline typename arma_cx_only::result op_dot::direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B) @@ -101,7 +100,6 @@ //! for two arrays, float and double version template -arma_hot inline typename arma_real_only::result op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) @@ -139,7 +137,6 @@ //! for two arrays, complex version template inline -arma_hot typename arma_cx_only::result op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) { @@ -173,7 +170,6 @@ //! for two arrays, integral version template -arma_hot inline typename arma_integral_only::result op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) @@ -186,7 +182,6 @@ //! for three arrays template -arma_hot inline eT op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B, const eT* C) @@ -206,7 +201,6 @@ template -arma_hot inline typename T1::elem_type op_dot::apply(const T1& X, const T2& Y) @@ -266,7 +260,6 @@ template -arma_hot inline typename arma_not_cx::result op_dot::apply_proxy(const Proxy& PA, const Proxy& PB) @@ -304,7 +297,6 @@ template -arma_hot inline typename arma_cx_only::result op_dot::apply_proxy(const Proxy& PA, const Proxy& PB) @@ -351,7 +343,6 @@ template -arma_hot inline typename T1::elem_type op_norm_dot::apply(const T1& X, const T2& Y) @@ -382,7 +373,6 @@ template -arma_hot inline eT op_cdot::direct_cdot_arma(const uword n_elem, const eT* const A, const eT* const B) @@ -415,7 +405,6 @@ template -arma_hot inline eT op_cdot::direct_cdot(const uword n_elem, const eT* const A, const eT* const B) @@ -451,12 +440,6 @@ return result[0]; } - #elif defined(ARMA_USE_ATLAS) - { - // TODO: use dedicated atlas functions cblas_cdotc_sub() and cblas_zdotc_sub() and retune threshold - - return op_cdot::direct_cdot_arma(n_elem, A, B); - } #else { return op_cdot::direct_cdot_arma(n_elem, A, B); @@ -468,7 +451,6 @@ template -arma_hot inline typename T1::elem_type op_cdot::apply(const T1& X, const T2& Y) @@ -488,7 +470,6 @@ template -arma_hot inline typename T1::elem_type op_cdot::apply_unwrap(const T1& X, const T2& Y) @@ -511,7 +492,6 @@ template -arma_hot inline typename T1::elem_type op_cdot::apply_proxy(const T1& X, const T2& Y) @@ -567,7 +547,6 @@ template -arma_hot inline typename promote_type::result op_dot_mixed::apply(const T1& A, const T2& B) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/operator_times.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/operator_times.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/operator_times.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/operator_times.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -361,7 +361,7 @@ enable_if2 < (is_arma_sparse_type::value && is_arma_type::value && is_same_type::value), - Mat + const SpToDGlue >::result operator* ( @@ -371,13 +371,7 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - - Mat result; - - spglue_times_misc::sparse_times_dense(result, x, y); - - return result; + return SpToDGlue(x, y); } @@ -389,7 +383,7 @@ enable_if2 < (is_arma_type::value && is_arma_sparse_type::value && is_same_type::value), - Mat + const SpToDGlue >::result operator* ( @@ -399,13 +393,7 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; - - Mat result; - - spglue_times_misc::dense_times_sparse(result, x, y); - - return result; + return SpToDGlue(x, y); } @@ -458,7 +446,7 @@ Mat< typename promote_type::result > out; - spglue_times_mixed::sparse_times_dense(out, X, Y); + glue_times_sparse_dense::apply_mixed(out, X, Y); return out; } @@ -484,7 +472,7 @@ Mat< typename promote_type::result > out; - spglue_times_mixed::dense_times_sparse(out, X, Y); + glue_times_dense_sparse::apply_mixed(out, X, Y); return out; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_expmat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_expmat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_expmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_expmat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -60,105 +60,106 @@ { out = expr.get_ref(); // force the evaluation of diagmat() - arma_debug_check( (out.is_square() == false), "expmat(): given matrix must be square sized" ); + arma_debug_check( (out.is_square() == false), "expmat(): given matrix must be square sized", [&](){ out.soft_reset(); } ); const uword N = (std::min)(out.n_rows, out.n_cols); for(uword i=0; i A = expr.get_ref(); + + arma_debug_check( (A.is_square() == false), "expmat(): given matrix must be square sized" ); + + if(A.is_diagmat()) { - Mat A = expr.get_ref(); - - arma_debug_check( (A.is_square() == false), "expmat(): given matrix must be square sized" ); + arma_extra_debug_print("op_expmat: detected diagonal matrix"); - if(A.is_diagmat()) - { - arma_extra_debug_print("op_expmat: detected diagonal matrix"); - - const uword N = (std::min)(A.n_rows, A.n_cols); - - out.zeros(N,N); - - 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 uword N = (std::min)(A.n_rows, A.n_cols); - const T norm_val = arma::norm(A, "inf"); + out.zeros(N,N); - const double log2_val = (norm_val > T(0)) ? double(eop_aux::log2(norm_val)) : double(0); + for(uword i=0; i::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd)); + } + + if(do_sym) + { + arma_extra_debug_print("op_expmat: symmetric/hermitian optimisation"); - T c = T(0.5); + Col< T> eigval; + Mat eigvec; - Mat E(A.n_rows, A.n_rows, fill::eye); E += c * A; - Mat D(A.n_rows, A.n_rows, fill::eye); D -= c * A; + const bool eig_status = eig_sym_helper(eigval, eigvec, A, 'd', "expmat()"); - Mat X = A; + if(eig_status == false) { return false; } - bool positive = true; + eigval = exp(eigval); - const uword N = 6; + out = eigvec * diagmat(eigval) * eigvec.t(); - for(uword i = 2; i <= N; ++i) - { - c = c * T(N - i + 1) / T(i * (2*N - i + 1)); - - X = A * X; - - E += c * X; - - if(positive) { D += c * X; } else { D -= c * X; } - - positive = (positive) ? false : true; - } + return true; + } + + const T norm_val = arma::norm(A, "inf"); + + if(arma_isfinite(norm_val) == false) { return false; } + + const double log2_val = (norm_val > T(0)) ? double(eop_aux::log2(norm_val)) : double(0); + + int exponent = int(0); std::frexp(log2_val, &exponent); + + const uword s = uword( (std::max)(int(0), exponent + int(1)) ); + + A /= eT(eop_aux::pow(double(2), double(s))); + + T c = T(0.5); + + Mat E(A.n_rows, A.n_rows, fill::eye); E += c * A; + Mat D(A.n_rows, A.n_rows, fill::eye); D -= c * A; + + Mat X = A; + + bool positive = true; + + const uword N = 6; + + for(uword i = 2; i <= N; ++i) + { + c = c * T(N - i + 1) / T(i * (2*N - i + 1)); - if( (D.is_finite() == false) || (E.is_finite() == false) ) { return false; } + X = A * X; - const bool status = solve(out, D, E, solve_opts::no_approx); + E += c * X; - if(status == false) { return false; } + if(positive) { D += c * X; } else { D -= c * X; } - for(uword i=0; i < s; ++i) { out = out * out; } + positive = (positive) ? false : true; } + if( (D.internal_has_nonfinite()) || (E.internal_has_nonfinite()) ) { return false; } + + const bool status = solve(out, D, E, solve_opts::no_approx); + + if(status == false) { return false; } + + for(uword i=0; i < s; ++i) { out = out * out; } + return true; } @@ -191,14 +192,42 @@ #if defined(ARMA_USE_LAPACK) { - typedef typename T1::pod_type T; typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; const unwrap U(expr.get_ref()); const Mat& X = U.M; arma_debug_check( (X.is_square() == false), "expmat_sym(): given matrix must be square sized" ); + if((arma_config::debug) && (arma_config::warn_level > 0) && (is_cx::yes) && (sym_helper::check_diag_imag(X) == false)) + { + arma_debug_warn_level(1, "inv_sympd(): imaginary components on diagonal are non-zero"); + } + + if(is_op_diagmat::value || X.is_diagmat()) + { + arma_extra_debug_print("op_expmat_sym: detected diagonal matrix"); + + out = X; + + eT* colmem = out.memptr(); + + const uword N = X.n_rows; + + for(uword i=0; i eigval; Mat eigvec; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_fft_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_fft_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_fft_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_fft_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -41,12 +41,8 @@ template inline static void apply( Mat& out, const Op& in ); - template - inline static void apply_noalias(Mat& out, const Proxy& P, const uword a, const uword b); - - template arma_hot inline static void copy_vec (typename Proxy::elem_type* dest, const Proxy& P, const uword N); - template arma_hot inline static void copy_vec_proxy (typename Proxy::elem_type* dest, const Proxy& P, const uword N); - template arma_hot inline static void copy_vec_unwrap(typename Proxy::elem_type* dest, const Proxy& P, const uword N); + template + inline static void apply_noalias(Mat& out, const Mat& X, const uword a, const uword b); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_fft_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_fft_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_fft_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_fft_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,12 +21,56 @@ //! @{ +#if defined(ARMA_USE_FFTW3) + +template +class fft_engine_wrapper + { + public: + + static constexpr uword threshold = 512; + + fft_engine_kissfft* worker_kissfft = nullptr; + fft_engine_fftw3 * worker_fftw3 = nullptr; + + inline + ~fft_engine_wrapper() + { + arma_extra_debug_sigprint(); + + if(worker_kissfft != nullptr) { delete worker_kissfft; } + if(worker_fftw3 != nullptr) { delete worker_fftw3; } + } + + inline + fft_engine_wrapper(const uword N_samples, const uword N_exec) + { + arma_extra_debug_sigprint(); + + const bool use_fftw3 = N_samples >= (threshold / N_exec); + + worker_kissfft = (use_fftw3 == false) ? new fft_engine_kissfft(N_samples) : nullptr; + worker_fftw3 = (use_fftw3 == true ) ? new fft_engine_fftw3 (N_samples) : nullptr; + } + + inline + void + run(cx_type* Y, const cx_type* X) + { + arma_extra_debug_sigprint(); + + if(worker_kissfft != nullptr) { (*worker_kissfft).run(Y,X); } + else if(worker_fftw3 != nullptr) { (*worker_fftw3).run(Y,X); } + } + }; + +#endif + // // op_fft_real - template inline void @@ -37,62 +81,43 @@ typedef typename T1::pod_type in_eT; typedef typename std::complex out_eT; - const Proxy P(in.m); + // no need to worry about aliasing, as we're going from a real object to complex complex, which by definition cannot alias + + const quasi_unwrap U(in.m); + const Mat& X = U.M; - 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 uword n_rows = X.n_rows; + const uword n_cols = X.n_cols; + const uword n_elem = X.n_elem; const bool is_vec = ( (n_rows == 1) || (n_cols == 1) ); const uword N_orig = (is_vec) ? n_elem : n_rows; const uword N_user = (in.aux_uword_b == 0) ? in.aux_uword_a : N_orig; - fft_engine worker(N_user); - - // no need to worry about aliasing, as we're going from a real object to complex complex, which by definition cannot alias + #if defined(ARMA_USE_FFTW3) + const uword N_exec = (is_vec) ? uword(1) : n_cols; + fft_engine_wrapper worker(N_user, N_exec); + #else + fft_engine_kissfft worker(N_user); + #endif if(is_vec) { (n_cols == 1) ? out.set_size(N_user, 1) : out.set_size(1, N_user); - if( (out.n_elem == 0) || (N_orig == 0) ) - { - out.zeros(); - return; - } - - if( (N_user == 1) && (N_orig >= 1) ) - { - out[0] = out_eT( P[0] ); - return; - } + if( (out.n_elem == 0) || (N_orig == 0) ) { out.zeros(); return; } - podarray data(N_user); + if( (N_user == 1) && (N_orig >= 1) ) { out[0] = out_eT( X[0] ); return; } - out_eT* data_mem = data.memptr(); + podarray data(N_user, arma_zeros_indicator()); - if(N_user > N_orig) { arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); } + out_eT* data_mem = data.memptr(); + const in_eT* X_mem = X.memptr(); const uword N = (std::min)(N_user, N_orig); - if(Proxy::use_at == false) - { - typename Proxy::ea_type X = P.get_ea(); - - for(uword i=0; i < N; ++i) { data_mem[i] = out_eT( X[i], in_eT(0) ); } - } - else - { - if(n_cols == 1) - { - for(uword i=0; i < N; ++i) { data_mem[i] = out_eT( P.at(i,0), in_eT(0) ); } - } - else - { - for(uword i=0; i < N; ++i) { data_mem[i] = out_eT( P.at(0,i), in_eT(0) ); } - } - } + for(uword i=0; i < N; ++i) { data_mem[i].real(X_mem[i]); } worker.run( out.memptr(), data_mem ); } @@ -102,30 +127,24 @@ out.set_size(N_user, n_cols); - if( (out.n_elem == 0) || (N_orig == 0) ) - { - out.zeros(); - return; - } + if( (out.n_elem == 0) || (N_orig == 0) ) { out.zeros(); return; } if( (N_user == 1) && (N_orig >= 1) ) { - for(uword col=0; col < n_cols; ++col) { out.at(0,col) = out_eT( P.at(0,col) ); } + for(uword col=0; col < n_cols; ++col) { out.at(0,col).real( X.at(0,col) ); } return; } - podarray data(N_user); + podarray data(N_user, arma_zeros_indicator()); out_eT* data_mem = data.memptr(); - if(N_user > N_orig) { arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); } - const uword N = (std::min)(N_user, N_orig); for(uword col=0; col < n_cols; ++col) { - for(uword i=0; i < N; ++i) { data_mem[i] = P.at(i, col); } + for(uword i=0; i < N; ++i) { data_mem[i].real( X.at(i, col) ); } worker.run( out.colptr(col), data_mem ); } @@ -147,77 +166,70 @@ typedef typename T1::elem_type eT; - const Proxy P(in.m); + const quasi_unwrap U(in.m); - if(P.is_alias(out) == false) - { - op_fft_cx::apply_noalias(out, P, in.aux_uword_a, in.aux_uword_b); - } - else + if(U.is_alias(out)) { Mat tmp; - op_fft_cx::apply_noalias(tmp, P, in.aux_uword_a, in.aux_uword_b); + op_fft_cx::apply_noalias(tmp, U.M, in.aux_uword_a, in.aux_uword_b); out.steal_mem(tmp); } + else + { + op_fft_cx::apply_noalias(out, U.M, in.aux_uword_a, in.aux_uword_b); + } } -template +template inline void -op_fft_cx::apply_noalias(Mat& out, const Proxy& P, const uword a, const uword b) +op_fft_cx::apply_noalias(Mat& out, const Mat& X, const uword a, const uword b) { 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_elem = P.get_n_elem(); + const uword n_rows = X.n_rows; + const uword n_cols = X.n_cols; + const uword n_elem = X.n_elem; const bool is_vec = ( (n_rows == 1) || (n_cols == 1) ); const uword N_orig = (is_vec) ? n_elem : n_rows; const uword N_user = (b == 0) ? a : N_orig; - fft_engine worker(N_user); + #if defined(ARMA_USE_FFTW3) + const uword N_exec = (is_vec) ? uword(1) : n_cols; + fft_engine_wrapper worker(N_user, N_exec); + #else + fft_engine_kissfft worker(N_user); + #endif if(is_vec) { (n_cols == 1) ? out.set_size(N_user, 1) : out.set_size(1, N_user); - if( (out.n_elem == 0) || (N_orig == 0) ) - { - out.zeros(); - return; - } + if( (out.n_elem == 0) || (N_orig == 0) ) { out.zeros(); return; } - if( (N_user == 1) && (N_orig >= 1) ) - { - out[0] = P[0]; - return; - } + if( (N_user == 1) && (N_orig >= 1) ) { out[0] = X[0]; return; } - if( (N_user > N_orig) || (is_Mat::stored_type>::value == false) ) + if(N_user > N_orig) { podarray data(N_user); eT* data_mem = data.memptr(); - if(N_user > N_orig) { arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); } + arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); - op_fft_cx::copy_vec( data_mem, P, (std::min)(N_user, N_orig) ); + arrayops::copy(data_mem, X.memptr(), (std::min)(N_user, N_orig)); worker.run( out.memptr(), data_mem ); } else { - const unwrap< typename Proxy::stored_type > tmp(P.Q); - - worker.run( out.memptr(), tmp.M.memptr() ); + worker.run( out.memptr(), X.memptr() ); } } else @@ -226,43 +238,37 @@ out.set_size(N_user, n_cols); - if( (out.n_elem == 0) || (N_orig == 0) ) - { - out.zeros(); - return; - } + if( (out.n_elem == 0) || (N_orig == 0) ) { out.zeros(); return; } if( (N_user == 1) && (N_orig >= 1) ) { - for(uword col=0; col < n_cols; ++col) { out.at(0,col) = P.at(0,col); } + for(uword col=0; col < n_cols; ++col) { out.at(0,col) = X.at(0,col); } return; } - if( (N_user > N_orig) || (is_Mat::stored_type>::value == false) ) + if(N_user > N_orig) { podarray data(N_user); eT* data_mem = data.memptr(); - if(N_user > N_orig) { arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); } + arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); const uword N = (std::min)(N_user, N_orig); for(uword col=0; col < n_cols; ++col) { - for(uword i=0; i < N; ++i) { data_mem[i] = P.at(i, col); } + arrayops::copy(data_mem, X.colptr(col), N); worker.run( out.colptr(col), data_mem ); } } else { - const unwrap< typename Proxy::stored_type > tmp(P.Q); - for(uword col=0; col < n_cols; ++col) { - worker.run( out.colptr(col), tmp.M.colptr(col) ); + worker.run( out.colptr(col), X.colptr(col) ); } } } @@ -285,70 +291,6 @@ -template -arma_hot -inline -void -op_fft_cx::copy_vec(typename Proxy::elem_type* dest, const Proxy& P, const uword N) - { - arma_extra_debug_sigprint(); - - if(is_Mat< typename Proxy::stored_type >::value) - { - op_fft_cx::copy_vec_unwrap(dest, P, N); - } - else - { - op_fft_cx::copy_vec_proxy(dest, P, N); - } - } - - - -template -arma_hot -inline -void -op_fft_cx::copy_vec_unwrap(typename Proxy::elem_type* dest, const Proxy& P, const uword N) - { - arma_extra_debug_sigprint(); - - const unwrap< typename Proxy::stored_type > tmp(P.Q); - - arrayops::copy(dest, tmp.M.memptr(), N); - } - - - -template -arma_hot -inline -void -op_fft_cx::copy_vec_proxy(typename Proxy::elem_type* dest, const Proxy& P, const uword N) - { - arma_extra_debug_sigprint(); - - if(Proxy::use_at == false) - { - typename Proxy::ea_type X = P.get_ea(); - - for(uword i=0; i < N; ++i) { dest[i] = X[i]; } - } - else - { - if(P.get_n_cols() == 1) - { - for(uword i=0; i < N; ++i) { dest[i] = P.at(i,0); } - } - else - { - for(uword i=0; i < N; ++i) { dest[i] = P.at(0,i); } - } - } - } - - - // // op_ifft_cx @@ -362,20 +304,20 @@ typedef typename T1::elem_type eT; - const Proxy P(in.m); + const quasi_unwrap U(in.m); - if(P.is_alias(out) == false) - { - op_fft_cx::apply_noalias(out, P, in.aux_uword_a, in.aux_uword_b); - } - else + if(U.is_alias(out)) { Mat tmp; - op_fft_cx::apply_noalias(tmp, P, in.aux_uword_a, in.aux_uword_b); + op_fft_cx::apply_noalias(tmp, U.M, in.aux_uword_a, in.aux_uword_b); out.steal_mem(tmp); } + else + { + op_fft_cx::apply_noalias(out, U.M, in.aux_uword_a, in.aux_uword_b); + } } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_find_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_find_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -116,4 +116,15 @@ +class op_find_nan + : public traits_op_col + { + public: + + template + inline static void apply(Mat& out, const mtOp& X); + }; + + + //! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_find_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_find_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_find_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -520,6 +520,8 @@ { arma_extra_debug_sigprint(); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "find_finite(): detection of non-finite values is not reliable in fast math mode"); } + const Proxy P(X.m); const uword n_elem = P.get_n_elem(); @@ -566,6 +568,8 @@ { arma_extra_debug_sigprint(); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "find_nonfinite(): detection of non-finite values is not reliable in fast math mode"); } + const Proxy P(X.m); const uword n_elem = P.get_n_elem(); @@ -598,6 +602,54 @@ i++; } + } + + out.steal_mem_col(indices, count); + } + + + +template +inline +void +op_find_nan::apply(Mat& out, const mtOp& X) + { + arma_extra_debug_sigprint(); + + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "find_nan(): detection of non-finite values is not reliable in fast math mode"); } + + const Proxy P(X.m); + + const uword n_elem = P.get_n_elem(); + + Mat indices(n_elem, 1, arma_nozeros_indicator()); + + uword* indices_mem = indices.memptr(); + uword count = 0; + + if(Proxy::use_at == false) + { + const typename Proxy::ea_type Pea = P.get_ea(); + + for(uword i=0; i -arma_hot inline void op_htrans::apply_mat_noalias(Mat& out, const Mat& A, const typename arma_not_cx::result* junk) @@ -36,7 +35,6 @@ template -arma_hot inline void op_htrans::apply_mat_noalias(Mat& out, const Mat& A, const typename arma_cx_only::result* junk) @@ -88,7 +86,6 @@ template -arma_hot inline void op_htrans::block_worker(std::complex* Y, const std::complex* X, const uword X_n_rows, const uword Y_n_rows, const uword n_rows, const uword n_cols) @@ -109,7 +106,6 @@ template -arma_hot inline void op_htrans::apply_mat_noalias_large(Mat< std::complex >& out, const Mat< std::complex >& A) @@ -165,7 +161,6 @@ template -arma_hot inline void op_htrans::apply_mat_inplace(Mat& out, const typename arma_not_cx::result* junk) @@ -179,7 +174,6 @@ template -arma_hot inline void op_htrans::apply_mat_inplace(Mat& out, const typename arma_cx_only::result* junk) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_bones.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -// 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_inv -//! @{ - - - -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 bool apply_direct(Mat& out, const Base& expr, const char* caller_sig); - - template - 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); - }; - - - -class op_inv_sympd - : public traits_op_default - { - public: - - template - inline static void apply(Mat& out, const Op& in); - - template - inline static bool apply_direct(Mat& out, const Base& expr); - }; - - - -//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_gen_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_gen_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_gen_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_gen_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,144 @@ +// 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_inv_gen +//! @{ + + + +class op_inv_gen_default + : public traits_op_default + { + public: + + template + inline static void apply(Mat& out, const Op& in); + + template + inline static bool apply_direct(Mat& out, const Base& expr, const char* caller_sig); + }; + + + +class op_inv_gen_full + : 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 bool apply_direct(Mat& out, const Base& expr, const char* caller_sig, const uword flags); + + template + arma_cold inline static bool apply_tiny_2x2(Mat& X); + + template + arma_cold inline static bool apply_tiny_3x3(Mat& X); + + template + arma_cold inline static bool apply_tiny_4x4(Mat& X); + }; + + + +template +struct op_inv_gen_state + { + uword size = uword(0); + T rcond = T(0); + bool is_diag = false; + bool is_sym = false; + }; + + + +class op_inv_gen_rcond + : public traits_op_default + { + public: + + template + inline static bool apply_direct(Mat& out_inv, op_inv_gen_state& out_state, const Base& expr); + }; + + + +namespace inv_opts + { + struct opts + { + const uword flags; + + inline constexpr explicit opts(const uword in_flags); + + inline const opts operator+(const opts& rhs) const; + }; + + inline + constexpr + opts::opts(const uword 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 << 1) are for internal Armadillo use only. + // The values can change without notice. + + static constexpr uword flag_none = uword(0 ); + static constexpr uword flag_tiny = uword(1u << 0); + static constexpr uword flag_allow_approx = uword(1u << 1); + static constexpr uword flag_likely_sympd = uword(1u << 2); + static constexpr uword flag_no_sympd = uword(1u << 3); + static constexpr uword flag_no_ugly = uword(1u << 4); + + struct opts_none : public opts { inline constexpr opts_none() : opts(flag_none ) {} }; + struct opts_tiny : public opts { inline constexpr opts_tiny() : opts(flag_tiny ) {} }; + struct opts_allow_approx : public opts { inline constexpr opts_allow_approx() : opts(flag_allow_approx) {} }; + struct opts_likely_sympd : public opts { inline constexpr opts_likely_sympd() : opts(flag_likely_sympd) {} }; + struct opts_no_sympd : public opts { inline constexpr opts_no_sympd() : opts(flag_no_sympd ) {} }; + struct opts_no_ugly : public opts { inline constexpr opts_no_ugly() : opts(flag_no_ugly ) {} }; + + static constexpr opts_none none; + static constexpr opts_tiny tiny; + static constexpr opts_allow_approx allow_approx; + static constexpr opts_likely_sympd likely_sympd; + static constexpr opts_no_sympd no_sympd; + static constexpr opts_no_ugly no_ugly; + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_gen_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_gen_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_gen_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_gen_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,495 @@ +// 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_inv_gen +//! @{ + + + +template +inline +void +op_inv_gen_default::apply(Mat& out, const Op& X) + { + arma_extra_debug_sigprint(); + + const bool status = op_inv_gen_default::apply_direct(out, X.m, "inv()"); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("inv(): matrix is singular"); + } + } + + + +template +inline +bool +op_inv_gen_default::apply_direct(Mat& out, const Base& expr, const char* caller_sig) + { + arma_extra_debug_sigprint(); + + return op_inv_gen_full::apply_direct(out, expr, caller_sig, uword(0)); + } + + + +// + + + +template +inline +void +op_inv_gen_full::apply(Mat& out, const Op& X) + { + arma_extra_debug_sigprint(); + + const uword flags = X.aux_uword_a; + + const bool status = op_inv_gen_full::apply_direct(out, X.m, "inv()", flags); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("inv(): matrix is singular"); + } + } + + + +template +inline +bool +op_inv_gen_full::apply_direct(Mat& out, const Base& expr, const char* caller_sig, const uword flags) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + if(has_user_flags == true ) { arma_extra_debug_print("op_inv_gen_full: has_user_flags = true"); } + if(has_user_flags == false) { arma_extra_debug_print("op_inv_gen_full: has_user_flags = false"); } + + const bool tiny = has_user_flags && bool(flags & inv_opts::flag_tiny ); + const bool allow_approx = has_user_flags && bool(flags & inv_opts::flag_allow_approx); + const bool likely_sympd = has_user_flags && bool(flags & inv_opts::flag_likely_sympd); + const bool no_sympd = has_user_flags && bool(flags & inv_opts::flag_no_sympd ); + const bool no_ugly = has_user_flags && bool(flags & inv_opts::flag_no_ugly ); + + if(has_user_flags) + { + arma_extra_debug_print("op_inv_gen_full: enabled flags:"); + + if(tiny ) { arma_extra_debug_print("tiny"); } + if(allow_approx) { arma_extra_debug_print("allow_approx"); } + if(likely_sympd) { arma_extra_debug_print("likely_sympd"); } + if(no_sympd ) { arma_extra_debug_print("no_sympd"); } + if(no_ugly ) { arma_extra_debug_print("no_ugly"); } + + arma_debug_check( (no_sympd && likely_sympd), "inv(): options 'no_sympd' and 'likely_sympd' are mutually exclusive" ); + arma_debug_check( (no_ugly && allow_approx), "inv(): options 'no_ugly' and 'allow_approx' are mutually exclusive" ); + } + + if(no_ugly) + { + op_inv_gen_state inv_state; + + const bool status = op_inv_gen_rcond::apply_direct(out, inv_state, expr); + + // workaround for bug in gcc 4.8 + const uword local_size = inv_state.size; + const T local_rcond = inv_state.rcond; + + if((status == false) || (local_rcond < ((std::max)(local_size, uword(1)) * std::numeric_limits::epsilon())) || arma_isnan(local_rcond)) { return false; } + + return true; + } + + if(allow_approx) + { + op_inv_gen_state inv_state; + + Mat tmp; + + const bool status = op_inv_gen_rcond::apply_direct(tmp, inv_state, expr); + + // workaround for bug in gcc 4.8 + const uword local_size = inv_state.size; + const T local_rcond = inv_state.rcond; + + if((status == false) || (local_rcond < ((std::max)(local_size, uword(1)) * std::numeric_limits::epsilon())) || arma_isnan(local_rcond)) + { + Mat A = expr.get_ref(); + + if(inv_state.is_diag) { return op_pinv::apply_diag(out, A, T(0) ); } + if(inv_state.is_sym ) { return op_pinv::apply_sym (out, A, T(0), uword(0)); } + + return op_pinv::apply_gen(out, A, T(0), uword(0)); + } + + out.steal_mem(tmp); + + return true; + } + + out = expr.get_ref(); + + arma_debug_check( (out.is_square() == false), caller_sig, ": given matrix must be square sized", [&](){ out.soft_reset(); } ); + + const uword N = out.n_rows; + + if(N == 0) { return true; } + + if(is_cx::no) + { + if(N == 1) + { + const eT a = out[0]; + + out[0] = eT(1) / a; + + return (a != eT(0)); + } + else + if(N == 2) + { + const bool status = op_inv_gen_full::apply_tiny_2x2(out); + + if(status) { return true; } + } + else + if((N == 3) && tiny) + { + const bool status = op_inv_gen_full::apply_tiny_3x3(out); + + if(status) { return true; } + } + else + if((N == 4) && tiny) + { + const bool status = op_inv_gen_full::apply_tiny_4x4(out); + + if(status) { return true; } + } + + // fallthrough if optimisation failed + } + + if(is_op_diagmat::value || out.is_diagmat()) + { + arma_extra_debug_print("op_inv_gen_full: detected diagonal matrix"); + + eT* colmem = out.memptr(); + + for(uword i=0; i strip(expr.get_ref()); + + const bool is_triu_expr = strip.do_triu; + const bool is_tril_expr = strip.do_tril; + + const bool is_triu_mat = (is_triu_expr || is_tril_expr) ? false : ( trimat_helper::is_triu(out)); + const bool is_tril_mat = (is_triu_expr || is_tril_expr) ? false : ((is_triu_mat) ? false : trimat_helper::is_tril(out)); + + if(is_triu_expr || is_tril_expr || is_triu_mat || is_tril_mat) + { + return auxlib::inv_tr(out, ((is_triu_expr || is_triu_mat) ? uword(0) : uword(1))); + } + + const bool try_sympd = arma_config::optimise_sym && ((no_sympd) ? false : (likely_sympd ? true : sym_helper::guess_sympd(out))); + + if(try_sympd) + { + arma_extra_debug_print("op_inv_gen_full: attempting sympd optimisation"); + + Mat tmp = out; + + bool sympd_state = false; + + const bool status = auxlib::inv_sympd(tmp, sympd_state); + + if(status) { out.steal_mem(tmp); return true; } + + if((status == false) && (sympd_state == true)) { return false; } + + arma_extra_debug_print("op_inv_gen_full: sympd optimisation failed"); + + // fallthrough if optimisation failed + } + + return auxlib::inv(out); + } + + + +template +inline +bool +op_inv_gen_full::apply_tiny_2x2(Mat& X) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + // NOTE: assuming matrix X is square sized + + constexpr T det_min = std::numeric_limits::epsilon(); + constexpr T det_max = T(1) / std::numeric_limits::epsilon(); + + eT* Xm = X.memptr(); + + 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) || arma_isnan(det_val)) { return false; } + + Xm[pos<0,0>::n2] = d / det_val; + Xm[pos<0,1>::n2] = -b / det_val; + Xm[pos<1,0>::n2] = -c / det_val; + Xm[pos<1,1>::n2] = a / det_val; + + return true; + } + + + +template +inline +bool +op_inv_gen_full::apply_tiny_3x3(Mat& X) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + // NOTE: assuming matrix X is square sized + + constexpr T det_min = std::numeric_limits::epsilon(); + constexpr T det_max = T(1) / std::numeric_limits::epsilon(); + + Mat Y(3, 3, arma_nozeros_indicator()); + + eT* Xm = X.memptr(); + eT* Ym = Y.memptr(); + + const eT det_val = op_det::apply_tiny_3x3(X); + const T abs_det_val = std::abs(det_val); + + if((abs_det_val < det_min) || (abs_det_val > det_max) || arma_isnan(det_val)) { return false; } + + Ym[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; + Ym[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; + Ym[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; + + Ym[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; + Ym[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; + Ym[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; + + Ym[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; + Ym[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; + Ym[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]*Ym[pos<0,0>::n3] + Xm[pos<0,1>::n3]*Ym[pos<1,0>::n3] + Xm[pos<0,2>::n3]*Ym[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; } + + arrayops::copy(Xm, Ym, uword(3*3)); + + return true; + } + + + +template +inline +bool +op_inv_gen_full::apply_tiny_4x4(Mat& X) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + // NOTE: assuming matrix X is square sized + + constexpr T det_min = std::numeric_limits::epsilon(); + constexpr T det_max = T(1) / std::numeric_limits::epsilon(); + + Mat Y(4, 4, arma_nozeros_indicator()); + + eT* Xm = X.memptr(); + eT* Ym = Y.memptr(); + + const eT det_val = op_det::apply_tiny_4x4(X); + const T abs_det_val = std::abs(det_val); + + if((abs_det_val < det_min) || (abs_det_val > det_max) || arma_isnan(det_val)) { return false; } + + Ym[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; + Ym[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; + Ym[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; + Ym[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; + + Ym[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; + Ym[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; + Ym[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; + Ym[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; + + Ym[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; + Ym[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; + Ym[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; + Ym[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; + + Ym[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; + Ym[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; + Ym[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; + Ym[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]*Ym[pos<0,0>::n4] + Xm[pos<0,1>::n4]*Ym[pos<1,0>::n4] + Xm[pos<0,2>::n4]*Ym[pos<2,0>::n4] + Xm[pos<0,3>::n4]*Ym[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; } + + arrayops::copy(Xm, Ym, uword(4*4)); + + return true; + } + + + +template +inline +bool +op_inv_gen_rcond::apply_direct(Mat& out, op_inv_gen_state& out_state, const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + out = expr.get_ref(); + out_state.size = out.n_rows; + out_state.rcond = T(0); + + arma_debug_check( (out.is_square() == false), "inv(): given matrix must be square sized", [&](){ out.soft_reset(); } ); + + if(is_op_diagmat::value || out.is_diagmat()) + { + arma_extra_debug_print("op_inv_gen_rcond: detected diagonal matrix"); + + out_state.is_diag = true; + + eT* colmem = out.memptr(); + + T max_abs_src_val = T(0); + T max_abs_inv_val = T(0); + + const uword N = out.n_rows; + + for(uword i=0; i max_abs_src_val) ? abs_src_val : max_abs_src_val; + max_abs_inv_val = (abs_inv_val > max_abs_inv_val) ? abs_inv_val : max_abs_inv_val; + + colmem += N; + } + + out_state.rcond = T(1) / (max_abs_src_val * max_abs_inv_val); + + return true; + } + + const strip_trimat strip(expr.get_ref()); + + const bool is_triu_expr = strip.do_triu; + const bool is_tril_expr = strip.do_tril; + + const bool is_triu_mat = (is_triu_expr || is_tril_expr) ? false : ( trimat_helper::is_triu(out)); + const bool is_tril_mat = (is_triu_expr || is_tril_expr) ? false : ((is_triu_mat) ? false : trimat_helper::is_tril(out)); + + if(is_triu_expr || is_tril_expr || is_triu_mat || is_tril_mat) + { + return auxlib::inv_tr_rcond(out, out_state.rcond, ((is_triu_expr || is_triu_mat) ? uword(0) : uword(1))); + } + + const bool try_sympd = arma_config::optimise_sym && ((auxlib::crippled_lapack(out)) ? false : sym_helper::guess_sympd(out)); + + if(try_sympd) + { + arma_extra_debug_print("op_inv_gen_rcond: attempting sympd optimisation"); + + out_state.is_sym = true; + + Mat tmp = out; + + bool sympd_state = false; + + const bool status = auxlib::inv_sympd_rcond(tmp, sympd_state, out_state.rcond); + + if(status) { out.steal_mem(tmp); return true; } + + if((status == false) && (sympd_state == true)) { return false; } + + arma_extra_debug_print("op_inv_gen_rcond: sympd optimisation failed"); + + // fallthrough if optimisation failed + } + + return auxlib::inv_rcond(out, out_state.rcond); + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_meat.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,369 +0,0 @@ -// 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_inv -//! @{ - - - -template -inline -void -op_inv::apply(Mat& out, const Op& X) - { - arma_extra_debug_sigprint(); - - const bool status = op_inv::apply_direct(out, X.m, "inv()"); - - if(status == false) - { - out.soft_reset(); - arma_stop_runtime_error("inv(): matrix is singular"); - } - } - - - -template -inline -bool -op_inv::apply_direct(Mat& out, const Base& expr, const char* caller_sig) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - if(strip_diagmat::do_diagmat) - { - const strip_diagmat strip(expr.get_ref()); - - return op_inv::apply_diagmat(out, strip.M, caller_sig); - } - - if(strip_trimat::do_trimat) - { - 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))); - } - - 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) - { - 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(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) - { - 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 -bool -op_inv::apply_diagmat(Mat& out, const T1& X, const char* caller_sig) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - const diagmat_proxy A(X); - - 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); - - bool status = true; - - if(A.is_alias(out) == false) - { - out.zeros(N,N); - - for(uword i=0; i 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) - { - 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; - } - - - -template -inline -void -op_inv_sympd::apply(Mat& out, const Op& X) - { - arma_extra_debug_sigprint(); - - const bool status = op_inv_sympd::apply_direct(out, X.m); - - if(status == false) - { - out.soft_reset(); - arma_stop_runtime_error("inv_sympd(): matrix is singular or not positive definite"); - } - } - - - -template -inline -bool -op_inv_sympd::apply_direct(Mat& out, const Base& expr) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - typedef typename T1::pod_type T; - - out = expr.get_ref(); - - 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)) - { - 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 void apply(Mat& out, const Op& in); + + template + inline static bool apply_direct(Mat& out, const Base& expr); + }; + + + +class op_inv_spd_full + : public traits_op_default + { + public: + + template + inline static void apply(Mat& out, const Op& in); + + template + inline static bool apply_direct(Mat& out, const Base& expr, const uword flags); + + template + arma_cold inline static bool apply_tiny_2x2(Mat& X); + + template + arma_cold inline static bool apply_tiny_3x3(Mat& X); + + template + arma_cold inline static bool apply_tiny_4x4(Mat& X); + }; + + + +template +struct op_inv_spd_state + { + uword size = uword(0); + T rcond = T(0); + bool is_diag = false; + }; + + + +class op_inv_spd_rcond + : public traits_op_default + { + public: + + template + inline static bool apply_direct(Mat& out_inv, op_inv_spd_state& out_state, const Base& expr); + }; + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_spd_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_spd_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_inv_spd_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_inv_spd_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,444 @@ +// 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_inv_spd +//! @{ + + + +template +inline +void +op_inv_spd_default::apply(Mat& out, const Op& X) + { + arma_extra_debug_sigprint(); + + const bool status = op_inv_spd_default::apply_direct(out, X.m); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("inv_sympd(): matrix is singular or not positive definite"); + } + } + + + +template +inline +bool +op_inv_spd_default::apply_direct(Mat& out, const Base& expr) + { + arma_extra_debug_sigprint(); + + return op_inv_spd_full::apply_direct(out, expr, uword(0)); + } + + + +// + + + +template +inline +void +op_inv_spd_full::apply(Mat& out, const Op& X) + { + arma_extra_debug_sigprint(); + + const uword flags = X.aux_uword_a; + + const bool status = op_inv_spd_full::apply_direct(out, X.m, flags); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("inv_sympd(): matrix is singular or not positive definite"); + } + } + + + +template +inline +bool +op_inv_spd_full::apply_direct(Mat& out, const Base& expr, const uword flags) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + if(has_user_flags == true ) { arma_extra_debug_print("op_inv_spd_full: has_user_flags = true"); } + if(has_user_flags == false) { arma_extra_debug_print("op_inv_spd_full: has_user_flags = false"); } + + const bool tiny = has_user_flags && bool(flags & inv_opts::flag_tiny ); + const bool allow_approx = has_user_flags && bool(flags & inv_opts::flag_allow_approx); + const bool likely_sympd = has_user_flags && bool(flags & inv_opts::flag_likely_sympd); + const bool no_sympd = has_user_flags && bool(flags & inv_opts::flag_no_sympd ); + const bool no_ugly = has_user_flags && bool(flags & inv_opts::flag_no_ugly ); + + if(has_user_flags) + { + arma_extra_debug_print("op_inv_spd_full: enabled flags:"); + + if(tiny ) { arma_extra_debug_print("tiny"); } + if(allow_approx) { arma_extra_debug_print("allow_approx"); } + if(likely_sympd) { arma_extra_debug_print("likely_sympd"); } + if(no_sympd ) { arma_extra_debug_print("no_sympd"); } + if(no_ugly ) { arma_extra_debug_print("no_ugly"); } + + if(likely_sympd) { arma_debug_warn_level(1, "inv_sympd(): option 'likely_sympd' ignored" ); } + if(no_sympd) { arma_debug_warn_level(1, "inv_sympd(): option 'no_sympd' ignored" ); } + + arma_debug_check( (no_ugly && allow_approx), "inv_sympd(): options 'no_ugly' and 'allow_approx' are mutually exclusive" ); + } + + if(no_ugly) + { + op_inv_spd_state inv_state; + + const bool status = op_inv_spd_rcond::apply_direct(out, inv_state, expr); + + // workaround for bug in gcc 4.8 + const uword local_size = inv_state.size; + const T local_rcond = inv_state.rcond; + + if((status == false) || (local_rcond < ((std::max)(local_size, uword(1)) * std::numeric_limits::epsilon())) || arma_isnan(local_rcond)) { return false; } + + return true; + } + + if(allow_approx) + { + op_inv_spd_state inv_state; + + Mat tmp; + + const bool status = op_inv_spd_rcond::apply_direct(tmp, inv_state, expr); + + // workaround for bug in gcc 4.8 + const uword local_size = inv_state.size; + const T local_rcond = inv_state.rcond; + + if((status == false) || (local_rcond < ((std::max)(local_size, uword(1)) * std::numeric_limits::epsilon())) || arma_isnan(local_rcond)) + { + const Mat A = expr.get_ref(); + + if(inv_state.is_diag) { return op_pinv::apply_diag(out, A, T(0)); } + + return op_pinv::apply_sym(out, A, T(0), uword(0)); + } + + out.steal_mem(tmp); + + return true; + } + + out = expr.get_ref(); + + arma_debug_check( (out.is_square() == false), "inv_sympd(): given matrix must be square sized", [&](){ out.soft_reset(); } ); + + if((arma_config::debug) && (arma_config::warn_level > 0)) + { + if(auxlib::rudimentary_sym_check(out) == false) + { + 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"); } + } + else + if((is_cx::yes) && (sym_helper::check_diag_imag(out) == false)) + { + arma_debug_warn_level(1, "inv_sympd(): imaginary components on diagonal are non-zero"); + } + } + + const uword N = out.n_rows; + + if(N == 0) { return true; } + + if(is_cx::no) + { + if(N == 1) + { + const T a = access::tmp_real(out[0]); + + out[0] = eT(T(1) / a); + + return (a > T(0)); + } + else + if(N == 2) + { + const bool status = op_inv_spd_full::apply_tiny_2x2(out); + + if(status) { return true; } + } + else + if((N == 3) && tiny) + { + const bool status = op_inv_spd_full::apply_tiny_3x3(out); + + if(status) { return true; } + } + else + if((N == 4) && tiny) + { + const bool status = op_inv_spd_full::apply_tiny_4x4(out); + + if(status) { return true; } + } + + // fallthrough if optimisation failed + } + + if(is_op_diagmat::value || out.is_diagmat()) + { + arma_extra_debug_print("op_inv_spd_full: detected diagonal matrix"); + + eT* colmem = out.memptr(); + + for(uword i=0; i +inline +bool +op_inv_spd_full::apply_tiny_2x2(Mat& X) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + // NOTE: assuming matrix X is square sized + // NOTE: assuming matrix X is symmetric + // NOTE: assuming matrix X is real + + constexpr T det_min = std::numeric_limits::epsilon(); + constexpr T det_max = T(1) / std::numeric_limits::epsilon(); + + eT* Xm = X.memptr(); + + T a = access::tmp_real(Xm[0]); + T c = access::tmp_real(Xm[1]); + T d = access::tmp_real(Xm[3]); + + const T det_val = (a*d - c*c); + + // positive definite iff all leading principal minors are positive + // a = first leading principal minor (top-left 1x1 submatrix) + // det_val = second leading principal minor (top-left 2x2 submatrix) + + if(a <= T(0)) { return false; } + + // NOTE: since det_min is positive, this also checks whether det_val is positive + if((det_val < det_min) || (det_val > det_max) || arma_isnan(det_val)) { return false; } + + d /= det_val; + c /= det_val; + a /= det_val; + + Xm[0] = d; + Xm[1] = -c; + Xm[2] = -c; + Xm[3] = a; + + return true; + } + + + +template +inline +bool +op_inv_spd_full::apply_tiny_3x3(Mat& X) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming matrix X is square sized + // NOTE: assuming matrix X is symmetric + // NOTE: assuming matrix X is real + + Mat Y(3, 3, arma_nozeros_indicator()); + + arrayops::copy(Y.memptr(), X.memptr(), uword(3*3)); + + const bool is_posdef = auxlib::chol_simple(Y); + + if(is_posdef == false) { return false; } + + const bool status = op_inv_gen_full::apply_tiny_3x3(X); + + if(status == false) { return false; } + + X = symmatl(X); + + return true; + } + + + +template +inline +bool +op_inv_spd_full::apply_tiny_4x4(Mat& X) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming matrix X is square sized + // NOTE: assuming matrix X is symmetric + // NOTE: assuming matrix X is real + + Mat Y(4, 4, arma_nozeros_indicator()); + + arrayops::copy(Y.memptr(), X.memptr(), uword(4*4)); + + const bool is_posdef = auxlib::chol_simple(Y); + + if(is_posdef == false) { return false; } + + const bool status = op_inv_gen_full::apply_tiny_4x4(X); + + if(status == false) { return false; } + + X = symmatl(X); + + return true; + } + + + +// + + + +template +inline +bool +op_inv_spd_rcond::apply_direct(Mat& out, op_inv_spd_state& out_state, const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + out = expr.get_ref(); + out_state.size = out.n_rows; + out_state.rcond = T(0); + + arma_debug_check( (out.is_square() == false), "inv_sympd(): given matrix must be square sized", [&](){ out.soft_reset(); } ); + + if((arma_config::debug) && (arma_config::warn_level > 0)) + { + if(auxlib::rudimentary_sym_check(out) == false) + { + 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"); } + } + else + if((is_cx::yes) && (sym_helper::check_diag_imag(out) == false)) + { + arma_debug_warn_level(1, "inv_sympd(): imaginary components on diagonal are non-zero"); + } + } + + if(is_op_diagmat::value || out.is_diagmat()) + { + arma_extra_debug_print("op_inv_spd_rcond: detected diagonal matrix"); + + out_state.is_diag = true; + + eT* colmem = out.memptr(); + + T max_abs_src_val = T(0); + T max_abs_inv_val = T(0); + + const uword N = out.n_rows; + + for(uword i=0; i max_abs_src_val) ? abs_src_val : max_abs_src_val; + max_abs_inv_val = (abs_inv_val > max_abs_inv_val) ? abs_inv_val : max_abs_inv_val; + + colmem += N; + } + + out_state.rcond = T(1) / (max_abs_src_val * max_abs_inv_val); + + return true; + } + + if(auxlib::crippled_lapack(out)) + { + arma_extra_debug_print("op_inv_spd_rcond: workaround for crippled lapack"); + + Mat tmp = out; + + bool sympd_state = false; + + auxlib::inv_sympd(out, sympd_state); + + if(sympd_state == false) { out.soft_reset(); out_state.rcond = T(0); return false; } + + out_state.rcond = auxlib::rcond(tmp); + + if(out_state.rcond == T(0)) { out.soft_reset(); return false; } + + return true; + } + + bool is_sympd_junk = false; + + return auxlib::inv_sympd_rcond(out, is_sympd_junk, out_state.rcond); + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_log_det_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_log_det_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_log_det_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_log_det_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -29,6 +29,7 @@ arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; + // typedef typename T1::pod_type T; if(strip_diagmat::do_diagmat) { @@ -55,6 +56,32 @@ if(is_triu || is_tril) { return op_log_det::apply_trimat(out_val, out_sign, A); } + // const bool try_sympd = arma_config::optimise_sym && sym_helper::guess_sympd(A); + // + // if(try_sympd) + // { + // arma_extra_debug_print("op_log_det: attempting sympd optimisation"); + // + // T out_val_real = T(0); + // + // const bool status = auxlib::log_det_sympd(out_val_real, A); + // + // if(status) + // { + // out_val = eT(out_val_real); + // out_sign = T(1); + // + // return true; + // } + // + // arma_extra_debug_print("op_log_det: sympd optimisation failed"); + // + // // restore A as it's destroyed by auxlib::log_det_sympd() + // A = expr.get_ref(); + // + // // fallthrough to the next return statement + // } + return auxlib::log_det(out_val, out_sign, A); } @@ -162,11 +189,42 @@ arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; 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) && (arma_config::warn_level > 0) && (is_cx::yes) && (sym_helper::check_diag_imag(A) == false)) + { + arma_debug_warn_level(1, "log_det_sympd(): imaginary components on diagonal are non-zero"); + } + + if(is_op_diagmat::value || A.is_diagmat()) + { + arma_extra_debug_print("op_log_det_sympd: detected diagonal matrix"); + + eT* colmem = A.memptr(); + + out_val = T(0); + + const uword N = A.n_rows; + + for(uword i=0; i::no ) { arma_debug_warn_level(1, "log_det_sympd(): given matrix is not symmetric"); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_logmat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_logmat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_logmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_logmat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -134,11 +134,7 @@ return true; } - #if defined(ARMA_OPTIMISE_SYMPD) - const bool try_sympd = sympd_helper::guess_sympd(A); - #else - const bool try_sympd = false; - #endif + const bool try_sympd = arma_config::optimise_sym && sym_helper::guess_sympd(A); if(try_sympd) { @@ -174,7 +170,7 @@ arma_extra_debug_print("op_logmat: sympd optimisation failed"); - // fallthrough if eigen decomposition failed or an eigenvalue is zero + // fallthrough if eigen decomposition failed or an eigenvalue is <= 0 } @@ -307,11 +303,7 @@ return true; } - #if defined(ARMA_OPTIMISE_SYMPD) - const bool try_sympd = sympd_helper::guess_sympd(S); - #else - const bool try_sympd = false; - #endif + const bool try_sympd = arma_config::optimise_sym && sym_helper::guess_sympd(S); if(try_sympd) { @@ -347,7 +339,7 @@ arma_extra_debug_print("op_logmat_cx: sympd optimisation failed"); - // fallthrough if eigen decomposition failed or an eigenvalue is zero + // fallthrough if eigen decomposition failed or an eigenvalue is <= 0 } return op_logmat_cx::apply_common(out, S, n_iters); @@ -370,9 +362,8 @@ if(schur_ok == false) { arma_extra_debug_print("logmat(): schur decomposition failed"); return false; } -//double theta[] = { 1.10e-5, 1.82e-3, 1.62e-2, 5.39e-2, 1.14e-1, 1.87e-1, 2.64e-1 }; - double theta[] = { 0.0, 0.0, 1.6206284795015624e-2, 5.3873532631381171e-2, 1.1352802267628681e-1, 1.8662860613541288e-1, 2.642960831111435e-1 }; - // theta[0] and theta[1] not really used + // NOTE: theta[0] and theta[1] not really used + double theta[] = { 1.10e-5, 1.82e-3, 1.6206284795015624e-2, 5.3873532631381171e-2, 1.1352802267628681e-1, 1.8662860613541288e-1, 2.642960831111435e-1 }; const uword N = S.n_rows; @@ -435,7 +426,7 @@ { arma_extra_debug_sigprint(); - if(A.is_finite() == false) { return false; } + if(A.internal_has_nonfinite()) { return false; } const vec indices = regspace(1,m-1); @@ -514,6 +505,36 @@ arma_debug_check( (X.is_square() == false), "logmat_sympd(): given matrix must be square sized" ); + if((arma_config::debug) && (arma_config::warn_level > 0) && (is_cx::yes) && (sym_helper::check_diag_imag(X) == false)) + { + arma_debug_warn_level(1, "logmat_sympd(): imaginary components on diagonal are non-zero"); + } + + if(is_op_diagmat::value || X.is_diagmat()) + { + arma_extra_debug_print("op_logmat_sympd: detected diagonal matrix"); + + out = X; + + eT* colmem = out.memptr(); + + const uword N = X.n_rows; + + for(uword i=0; i eigval; Mat eigvec; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_max_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_max_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_max_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_max_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -361,7 +361,8 @@ { arma_extra_debug_sigprint(); - eT max_val = priv::most_neg(); + eT max_val_i = priv::most_neg(); + eT max_val_j = priv::most_neg(); uword i,j; for(i=0, j=1; j max_val) { max_val = X_i; } - if(X_j > max_val) { max_val = X_j; } + if(X_i > max_val_i) { max_val_i = X_i; } + if(X_j > max_val_j) { max_val_j = X_j; } } if(i < n_elem) { const eT X_i = X[i]; - if(X_i > max_val) { max_val = X_i; } + if(X_i > max_val_i) { max_val_i = X_i; } } - return max_val; + return (max_val_i > max_val_j) ? max_val_i : max_val_j; } @@ -392,9 +393,11 @@ { arma_extra_debug_sigprint(); - eT max_val = priv::most_neg(); + eT max_val_i = priv::most_neg(); + eT max_val_j = priv::most_neg(); - uword best_index = 0; + uword best_index_i = 0; + uword best_index_j = 0; uword i,j; for(i=0, j=1; j max_val) - { - max_val = X_i; - best_index = i; - } - - if(X_j > max_val) - { - max_val = X_j; - best_index = j; - } + if(X_i > max_val_i) { max_val_i = X_i; best_index_i = i; } + if(X_j > max_val_j) { max_val_j = X_j; best_index_j = j; } } if(i < n_elem) { const eT X_i = X[i]; - if(X_i > max_val) - { - max_val = X_i; - best_index = i; - } + if(X_i > max_val_i) { max_val_i = X_i; best_index_i = i; } } - index_of_max_val = best_index; + index_of_max_val = (max_val_i > max_val_j) ? best_index_i : best_index_j; - return max_val; + return (max_val_i > max_val_j) ? max_val_i : max_val_j; } @@ -442,7 +432,8 @@ const uword X_n_cols = X.n_cols; - eT max_val = priv::most_neg(); + eT max_val_i = priv::most_neg(); + eT max_val_j = priv::most_neg(); uword i,j; for(i=0, j=1; j < X_n_cols; i+=2, j+=2) @@ -450,18 +441,18 @@ const eT tmp_i = X.at(row,i); const eT tmp_j = X.at(row,j); - if(tmp_i > max_val) { max_val = tmp_i; } - if(tmp_j > max_val) { max_val = tmp_j; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } + if(tmp_j > max_val_j) { max_val_j = tmp_j; } } if(i < X_n_cols) { const eT tmp_i = X.at(row,i); - if(tmp_i > max_val) { max_val = tmp_i; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } } - return max_val; + return (max_val_i > max_val_j) ? max_val_i : max_val_j; } @@ -483,10 +474,11 @@ const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; - eT max_val = priv::most_neg(); - if(X_n_rows == 1) { + eT max_val_i = priv::most_neg(); + eT max_val_j = priv::most_neg(); + const Mat& A = X.m; const uword start_row = X.aux_row1; @@ -500,23 +492,25 @@ const eT tmp_i = A.at(start_row, i); const eT tmp_j = A.at(start_row, j); - if(tmp_i > max_val) { max_val = tmp_i; } - if(tmp_j > max_val) { max_val = tmp_j; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } + if(tmp_j > max_val_j) { max_val_j = tmp_j; } } if(i < end_col_p1) { const eT tmp_i = A.at(start_row, i); - if(tmp_i > max_val) { max_val = tmp_i; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } } + + return (max_val_i > max_val_j) ? max_val_i : max_val_j; } - else + + eT max_val = priv::most_neg(); + + for(uword col=0; col < X_n_cols; ++col) { - for(uword col=0; col < X_n_cols; ++col) - { - max_val = (std::max)(max_val, op_max::direct_max(X.colptr(col), X_n_rows)); - } + max_val = (std::max)(max_val, op_max::direct_max(X.colptr(col), X_n_rows)); } return max_val; @@ -544,7 +538,8 @@ return Datum::nan; } - eT max_val = priv::most_neg(); + eT max_val_i = priv::most_neg(); + eT max_val_j = priv::most_neg(); if(Proxy::use_at == false) { @@ -559,15 +554,15 @@ const eT tmp_i = A[i]; const eT tmp_j = A[j]; - if(tmp_i > max_val) { max_val = tmp_i; } - if(tmp_j > max_val) { max_val = tmp_j; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } + if(tmp_j > max_val_j) { max_val_j = tmp_j; } } if(i < n_elem) { const eT tmp_i = A[i]; - if(tmp_i > max_val) { max_val = tmp_i; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } } } else @@ -583,15 +578,15 @@ const eT tmp_i = P.at(0,i); const eT tmp_j = P.at(0,j); - if(tmp_i > max_val) { max_val = tmp_i; } - if(tmp_j > max_val) { max_val = tmp_j; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } + if(tmp_j > max_val_j) { max_val_j = tmp_j; } } if(i < n_cols) { const eT tmp_i = P.at(0,i); - if(tmp_i > max_val) { max_val = tmp_i; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } } } else @@ -604,21 +599,21 @@ const eT tmp_i = P.at(i,col); const eT tmp_j = P.at(j,col); - if(tmp_i > max_val) { max_val = tmp_i; } - if(tmp_j > max_val) { max_val = tmp_j; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } + if(tmp_j > max_val_j) { max_val_j = tmp_j; } } if(i < n_rows) { const eT tmp_i = P.at(i,col); - if(tmp_i > max_val) { max_val = tmp_i; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } } } } } - return max_val; + return (max_val_i > max_val_j) ? max_val_i : max_val_j; } @@ -647,6 +642,9 @@ if(ProxyCube::use_at == false) { + eT max_val_i = priv::most_neg(); + eT max_val_j = priv::most_neg(); + typedef typename ProxyCube::ea_type ea_type; ea_type A = P.get_ea(); @@ -658,16 +656,18 @@ const eT tmp_i = A[i]; const eT tmp_j = A[j]; - if(tmp_i > max_val) { max_val = tmp_i; } - if(tmp_j > max_val) { max_val = tmp_j; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } + if(tmp_j > max_val_j) { max_val_j = tmp_j; } } if(i < n_elem) { const eT tmp_i = A[i]; - if(tmp_i > max_val) { max_val = tmp_i; } + if(tmp_i > max_val_i) { max_val_i = tmp_i; } } + + max_val = (max_val_i > max_val_j) ? max_val_i : max_val_j; } else { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_mean_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_mean_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_mean_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_mean_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -136,7 +136,6 @@ template -arma_hot inline void op_mean::apply_noalias_proxy(Mat& out, const Proxy& P, const uword dim) @@ -195,7 +194,7 @@ out /= T(P_n_cols); } - if(out.is_finite() == false) + if(out.internal_has_nonfinite()) { // TODO: replace with dedicated handling to avoid unwrapping op_mean::apply_noalias_unwrap(out, P, dim); @@ -365,7 +364,6 @@ template -arma_hot inline void op_mean::apply_noalias_proxy(Cube& out, const ProxyCube& P, const uword dim) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Op_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Op_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Op_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Op_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -69,19 +69,6 @@ template inline -Op::Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const char) - : m(in_m) - , aux_uword_a(in_aux_uword_a) - , aux_uword_b(in_aux_uword_b) - , aux_uword_c(in_aux_uword_c) - { - arma_extra_debug_sigprint(); - } - - - -template -inline Op::~Op() { arma_extra_debug_sigprint(); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_median_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_median_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_median_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_median_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -34,22 +34,24 @@ bool operator< (const arma_cx_median_packet& A, const arma_cx_median_packet& B) { - return A.val < B.val; + return (A.val < B.val); } -//! Class for finding median values of a matrix class op_median : public traits_op_xvec { public: - template - inline static void apply(Mat& out, const Op& in, const typename arma_not_cx::result* junk = nullptr); + template + inline static void apply(Mat& out, const Op& expr); - template - inline static void apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk = nullptr); + template + 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 = nullptr); // // diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_median_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_median_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_median_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_median_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,114 +21,83 @@ -//! \brief -//! 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, const typename arma_not_cx::result* junk) +op_median::apply(Mat& out, const Op& expr) { arma_extra_debug_sigprint(); - arma_ignore(junk); - // 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" ); + typedef typename T1::elem_type eT; - const Proxy P(in.m); + const quasi_unwrap U(expr.m); - typedef typename Proxy::stored_type P_stored_type; + const uword dim = expr.aux_uword_a; - const bool is_alias = P.is_alias(out); + arma_debug_check( U.M.internal_has_nan(), "median(): detected NaN" ); + arma_debug_check( (dim > 1), "median(): parameter 'dim' must be 0 or 1" ); - if(is_Mat::value || is_alias) + if(U.is_alias(out)) { - const unwrap_check tmp(P.Q, is_alias); + Mat tmp; - const typename unwrap_check::stored_type& X = tmp.M; + op_median::apply_noalias(out, U.M, dim); + + out.steal_mem(tmp); + } + else + { + op_median::apply_noalias(out, U.M, dim); + } + } + + + +template +inline +void +op_median::apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_not_cx::result* junk) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + const uword X_n_rows = X.n_rows; + const uword X_n_cols = X.n_cols; + + if(dim == 0) // in each column + { + arma_extra_debug_print("op_median::apply(): dim = 0"); - const uword X_n_rows = X.n_rows; - const uword X_n_cols = X.n_cols; + out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); - if(dim == 0) // in each column + if(X_n_rows > 0) { - arma_extra_debug_print("op_median::apply(): dim = 0"); - - out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); + std::vector tmp_vec(X_n_rows); - if(X_n_rows > 0) + for(uword col=0; col < X_n_cols; ++col) { - std::vector tmp_vec(X_n_rows); + arrayops::copy( &(tmp_vec[0]), X.colptr(col), X_n_rows ); - for(uword col=0; col < X_n_cols; ++col) - { - arrayops::copy( &(tmp_vec[0]), X.colptr(col), X_n_rows ); - - out[col] = op_median::direct_median(tmp_vec); - } - } - } - else // in each row - { - arma_extra_debug_print("op_median::apply(): dim = 1"); - - out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); - - if(X_n_cols > 0) - { - std::vector tmp_vec(X_n_cols); - - for(uword row=0; row < X_n_rows; ++row) - { - for(uword col=0; col < X_n_cols; ++col) { tmp_vec[col] = X.at(row,col); } - - out[row] = op_median::direct_median(tmp_vec); - } + out[col] = op_median::direct_median(tmp_vec); } } } else + if(dim == 1) // in each row { - const uword P_n_rows = P.get_n_rows(); - const uword P_n_cols = P.get_n_cols(); + arma_extra_debug_print("op_median::apply(): dim = 1"); + + out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); - if(dim == 0) // in each column + if(X_n_cols > 0) { - arma_extra_debug_print("op_median::apply(): dim = 0"); - - out.set_size((P_n_rows > 0) ? 1 : 0, P_n_cols); - - if(P_n_rows > 0) - { - std::vector tmp_vec(P_n_rows); + std::vector tmp_vec(X_n_cols); - for(uword col=0; col < P_n_cols; ++col) - { - for(uword row=0; row < P_n_rows; ++row) { tmp_vec[row] = P.at(row,col); } - - out[col] = op_median::direct_median(tmp_vec); - } - } - } - else // in each row - { - arma_extra_debug_print("op_median::apply(): dim = 1"); - - out.set_size(P_n_rows, (P_n_cols > 0) ? 1 : 0); - - if(P_n_cols > 0) + for(uword row=0; row < X_n_rows; ++row) { - std::vector tmp_vec(P_n_cols); - - for(uword row=0; row < P_n_rows; ++row) - { - for(uword col=0; col < P_n_cols; ++col) { tmp_vec[col] = P.at(row,col); } - - out[row] = op_median::direct_median(tmp_vec); - } + for(uword col=0; col < X_n_cols; ++col) { tmp_vec[col] = X.at(row,col); } + + out[row] = op_median::direct_median(tmp_vec); } } } @@ -136,29 +105,19 @@ -//! Implementation for complex numbers -template +template inline void -op_median::apply(Mat& out, const Op& in, const typename arma_cx_only::result* junk) +op_median::apply_noalias(Mat& out, const Mat& X, const uword dim, const typename arma_cx_only::result* junk) { arma_extra_debug_sigprint(); arma_ignore(junk); - // typedef typename std::complex eT; typedef typename get_pod_type::result T; - arma_type_check(( is_same_type::no )); - - const unwrap_check tmp(in.m, out); - const Mat& X = tmp.M; - const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; - const uword dim = in.aux_uword_a; - arma_debug_check( (dim > 1), "median(): parameter 'dim' must be 0 or 1" ); - if(dim == 0) // in each column { arma_extra_debug_print("op_median::apply(): dim = 0"); @@ -179,8 +138,8 @@ tmp_vec[row].index = row; } - uword index1; - uword index2; + uword index1 = 0; + uword index2 = 0; op_median::direct_cx_median_index(index1, index2, tmp_vec); out[col] = op_mean::robust_mean(colmem[index1], colmem[index2]); @@ -206,8 +165,8 @@ tmp_vec[col].index = col; } - uword index1; - uword index2; + uword index1 = 0; + uword index2 = 0; op_median::direct_cx_median_index(index1, index2, tmp_vec); out[row] = op_mean::robust_mean( X.at(row,index1), X.at(row,index2) ); @@ -232,11 +191,9 @@ typedef typename T1::elem_type eT; - typedef typename Proxy::stored_type P_stored_type; - - const Proxy P(X); + const quasi_unwrap U(X); - const uword n_elem = P.get_n_elem(); + const uword n_elem = U.M.n_elem; if(n_elem == 0) { @@ -245,46 +202,11 @@ return Datum::nan; } + arma_debug_check( U.M.internal_has_nan(), "median(): detected NaN" ); + std::vector tmp_vec(n_elem); - if(is_Mat::value) - { - const unwrap tmp(P.Q); - - const typename unwrap::stored_type& Y = tmp.M; - - arrayops::copy( &(tmp_vec[0]), Y.memptr(), n_elem ); - } - else - { - if(Proxy::use_at == false) - { - typedef typename Proxy::ea_type ea_type; - - ea_type A = P.get_ea(); - - for(uword i=0; i P(X); + const quasi_unwrap U(X); - const uword n_elem = P.get_n_elem(); + const uword n_elem = U.M.n_elem; if(n_elem == 0) { @@ -317,72 +239,27 @@ return Datum::nan; } + arma_debug_check( U.M.internal_has_nan(), "median(): detected NaN" ); + std::vector< arma_cx_median_packet > tmp_vec(n_elem); - if(Proxy::use_at == false) - { - typedef typename Proxy::ea_type ea_type; - - ea_type A = P.get_ea(); - - for(uword i=0; i inline eT @@ -390,8 +267,6 @@ { arma_extra_debug_sigprint(); - // TODO: if NaN is detected, return NaN - const uword n_elem = uword(X.size()); const uword half = n_elem/2; @@ -433,8 +308,6 @@ 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-10.8.2+dfsg/include/armadillo_bits/op_min_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_min_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_min_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_min_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -361,7 +361,8 @@ { arma_extra_debug_sigprint(); - eT min_val = priv::most_pos(); + eT min_val_i = priv::most_pos(); + eT min_val_j = priv::most_pos(); uword i,j; for(i=0, j=1; j -inline +inline eT op_min::direct_min(const eT* const X, const uword n_elem, uword& index_of_min_val) { arma_extra_debug_sigprint(); - eT min_val = priv::most_pos(); + eT min_val_i = priv::most_pos(); + eT min_val_j = priv::most_pos(); - uword best_index = 0; + uword best_index_i = 0; + uword best_index_j = 0; uword i,j; for(i=0, j=1; j(); + eT min_val_i = priv::most_pos(); + eT min_val_j = priv::most_pos(); uword i,j; for(i=0, j=1; j < X_n_cols; i+=2, j+=2) @@ -450,18 +441,18 @@ const eT tmp_i = X.at(row,i); const eT tmp_j = X.at(row,j); - if(tmp_i < min_val) { min_val = tmp_i; } - if(tmp_j < min_val) { min_val = tmp_j; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } + if(tmp_j < min_val_j) { min_val_j = tmp_j; } } if(i < X_n_cols) { const eT tmp_i = X.at(row,i); - if(tmp_i < min_val) { min_val = tmp_i; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } } - return min_val; + return (min_val_i < min_val_j) ? min_val_i : min_val_j; } @@ -479,14 +470,15 @@ return Datum::nan; } - + const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; - eT min_val = priv::most_pos(); - if(X_n_rows == 1) { + eT min_val_i = priv::most_pos(); + eT min_val_j = priv::most_pos(); + const Mat& A = X.m; const uword start_row = X.aux_row1; @@ -500,23 +492,25 @@ const eT tmp_i = A.at(start_row, i); const eT tmp_j = A.at(start_row, j); - if(tmp_i < min_val) { min_val = tmp_i; } - if(tmp_j < min_val) { min_val = tmp_j; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } + if(tmp_j < min_val_j) { min_val_j = tmp_j; } } if(i < end_col_p1) { const eT tmp_i = A.at(start_row, i); - if(tmp_i < min_val) { min_val = tmp_i; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } } + + return (min_val_i < min_val_j) ? min_val_i : min_val_j; } - else + + eT min_val = priv::most_pos(); + + for(uword col=0; col < X_n_cols; ++col) { - for(uword col=0; col < X_n_cols; ++col) - { - min_val = (std::min)(min_val, op_min::direct_min(X.colptr(col), X_n_rows)); - } + min_val = (std::min)(min_val, op_min::direct_min(X.colptr(col), X_n_rows)); } return min_val; @@ -544,7 +538,8 @@ return Datum::nan; } - eT min_val = priv::most_pos(); + eT min_val_i = priv::most_pos(); + eT min_val_j = priv::most_pos(); if(Proxy::use_at == false) { @@ -559,15 +554,15 @@ const eT tmp_i = A[i]; const eT tmp_j = A[j]; - if(tmp_i < min_val) { min_val = tmp_i; } - if(tmp_j < min_val) { min_val = tmp_j; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } + if(tmp_j < min_val_j) { min_val_j = tmp_j; } } if(i < n_elem) { const eT tmp_i = A[i]; - if(tmp_i < min_val) { min_val = tmp_i; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } } } else @@ -583,15 +578,15 @@ const eT tmp_i = P.at(0,i); const eT tmp_j = P.at(0,j); - if(tmp_i < min_val) { min_val = tmp_i; } - if(tmp_j < min_val) { min_val = tmp_j; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } + if(tmp_j < min_val_j) { min_val_j = tmp_j; } } if(i < n_cols) { const eT tmp_i = P.at(0,i); - if(tmp_i < min_val) { min_val = tmp_i; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } } } else @@ -604,21 +599,21 @@ const eT tmp_i = P.at(i,col); const eT tmp_j = P.at(j,col); - if(tmp_i < min_val) { min_val = tmp_i; } - if(tmp_j < min_val) { min_val = tmp_j; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } + if(tmp_j < min_val_j) { min_val_j = tmp_j; } } if(i < n_rows) { const eT tmp_i = P.at(i,col); - if(tmp_i < min_val) { min_val = tmp_i; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } } } } } - return min_val; + return (min_val_i < min_val_j) ? min_val_i : min_val_j; } @@ -647,6 +642,9 @@ if(ProxyCube::use_at == false) { + eT min_val_i = priv::most_pos(); + eT min_val_j = priv::most_pos(); + typedef typename ProxyCube::ea_type ea_type; ea_type A = P.get_ea(); @@ -658,16 +656,18 @@ const eT tmp_i = A[i]; const eT tmp_j = A[j]; - if(tmp_i < min_val) { min_val = tmp_i; } - if(tmp_j < min_val) { min_val = tmp_j; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } + if(tmp_j < min_val_j) { min_val_j = tmp_j; } } if(i < n_elem) { const eT tmp_i = A[i]; - if(tmp_i < min_val) { min_val = tmp_i; } + if(tmp_i < min_val_i) { min_val_i = tmp_i; } } + + min_val = (min_val_i < min_val_j) ? min_val_i : min_val_j; } else { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_nonzeros_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_nonzeros_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_nonzeros_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_nonzeros_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -113,23 +113,37 @@ out.set_size(N,1); - if(N > 0) + if(N == 0) { return; } + + if(is_SpMat::stored_type>::value) { - if(is_SpMat::stored_type>::value) - { - const unwrap_spmat::stored_type> U(P.Q); - - arrayops::copy(out.memptr(), U.M.values, N); - } - else + const unwrap_spmat::stored_type> U(P.Q); + + arrayops::copy(out.memptr(), U.M.values, N); + + return; + } + + if(is_SpSubview::stored_type>::value) + { + const SpSubview& sv = reinterpret_cast< const SpSubview& >(P.Q); + + if(sv.n_rows == sv.m.n_rows) { - eT* out_mem = out.memptr(); + const SpMat& m = sv.m; + const uword col = sv.aux_col1; - typename SpProxy::const_iterator_type it = P.begin(); + arrayops::copy(out.memptr(), &(m.values[ m.col_ptrs[col] ]), N); - for(uword i=0; i::const_iterator_type it = P.begin(); + + for(uword i=0; i +struct norm2est_randu_filler + { + std::mt19937_64 local_engine; + std::uniform_real_distribution local_u_distr; + + inline norm2est_randu_filler(); + + inline void fill(eT* mem, const uword N); + }; + + +template +struct norm2est_randu_filler< std::complex > + { + std::mt19937_64 local_engine; + std::uniform_real_distribution local_u_distr; + + inline norm2est_randu_filler(); + + inline void fill(std::complex* mem, const uword N); + }; + + + +class op_norm2est + : public traits_op_default + { + public: + + template inline static typename T1::pod_type norm2est(const Base& X, const typename T1::pod_type tolerance, const uword max_iter); + template inline static typename T1::pod_type norm2est(const SpBase& X, const typename T1::pod_type tolerance, const uword max_iter); + }; + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_norm2est_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_norm2est_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_norm2est_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_norm2est_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,248 @@ +// 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_norm2est +//! @{ + + + +template +inline +norm2est_randu_filler::norm2est_randu_filler() + { + arma_extra_debug_sigprint(); + + typedef typename std::mt19937_64::result_type local_seed_type; + + local_engine.seed(local_seed_type(123)); + + typedef typename std::uniform_real_distribution::param_type local_param_type; + + local_u_distr.param(local_param_type(-1.0, +1.0)); + } + + +template +inline +void +norm2est_randu_filler::fill(eT* mem, const uword N) + { + arma_extra_debug_sigprint(); + + for(uword i=0; i +inline +norm2est_randu_filler< std::complex >::norm2est_randu_filler() + { + arma_extra_debug_sigprint(); + + typedef typename std::mt19937_64::result_type local_seed_type; + + local_engine.seed(local_seed_type(123)); + + typedef typename std::uniform_real_distribution::param_type local_param_type; + + local_u_distr.param(local_param_type(-1.0, +1.0)); + } + + +template +inline +void +norm2est_randu_filler< std::complex >::fill(std::complex* mem, const uword N) + { + arma_extra_debug_sigprint(); + + for(uword i=0; i& mem_i = mem[i]; + + mem_i.real( T(local_u_distr(local_engine)) ); + mem_i.imag( T(local_u_distr(local_engine)) ); + } + } + + + +// +// +// + + + +template +inline +typename T1::pod_type +op_norm2est::norm2est + ( + const Base& X, + const typename T1::pod_type tolerance, + const uword max_iter + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + typedef typename T1::elem_type eT; + + arma_debug_check( (tolerance < T(0)), "norm2est(): parameter 'tolerance' must be > 0" ); + arma_debug_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" ); + + const T tol = (tolerance == T(0)) ? T(1e-6) : T(tolerance); + + const quasi_unwrap U(X.get_ref()); + const Mat& A = U.M; + + if(A.n_elem == 0) { return T(0); } + + if(A.internal_has_nonfinite()) { arma_debug_warn_level(1, "norm2est(): given matrix has non-finite elements"); } + + if((A.n_rows == 1) || (A.n_cols == 1)) { return op_norm::vec_norm_2( Proxy< Mat >(A) ); } + + norm2est_randu_filler randu_filler; + + Col x(A.n_rows, fill::none); + Col y(A.n_cols, fill::none); + + randu_filler.fill(y.memptr(), y.n_elem); + + T est_old = 0; + T est_cur = 0; + + for(uword i=0; i >(x) ); + + if(x_norm == T(0) || (arma_isfinite(x_norm) == false) || (x.internal_has_nonfinite())) + { + randu_filler.fill(x.memptr(), x.n_elem); + + x_norm = op_norm::vec_norm_2( Proxy< Col >(x) ); + } + + if(x_norm != T(0)) { x /= x_norm; } + + y = A.t() * x; + + est_old = est_cur; + est_cur = op_norm::vec_norm_2( Proxy< Col >(y) ); + + arma_extra_debug_print(arma_str::format("norm2est(): est_old: %e") % est_old); + arma_extra_debug_print(arma_str::format("norm2est(): est_cur: %e") % est_cur); + + if(arma_isfinite(est_cur) == false) { return est_old; } + + if( ((std::abs)(est_cur - est_old)) <= (tol * (std::max)(est_cur,est_old)) ) { break; } + } + + return est_cur; + } + + + +// +// +// + + + +template +inline +typename T1::pod_type +op_norm2est::norm2est + ( + const SpBase& X, + const typename T1::pod_type tolerance, + const uword max_iter + ) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + typedef typename T1::elem_type eT; + + arma_debug_check( (tolerance < T(0)), "norm2est(): parameter 'tolerance' must be > 0" ); + arma_debug_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" ); + + const T tol = (tolerance == T(0)) ? T(1e-6) : T(tolerance); + + const unwrap_spmat U(X.get_ref()); + const SpMat& A = U.M; + + if(A.n_nonzero == 0) { return T(0); } + + if(A.internal_has_nonfinite()) { arma_debug_warn_level(1, "norm2est(): given matrix has non-finite elements"); } + + if((A.n_rows == 1) || (A.n_cols == 1)) { return spop_norm::vec_norm_k(A.values, A.n_nonzero, 2); } + + norm2est_randu_filler randu_filler; + + Mat x(A.n_rows, 1, fill::none); + Mat y(A.n_cols, 1, fill::none); + + randu_filler.fill(y.memptr(), y.n_elem); + + T est_old = 0; + T est_cur = 0; + + for(uword i=0; i >(x) ); + + if(x_norm == T(0) || (arma_isfinite(x_norm) == false) || (x.internal_has_nonfinite())) + { + randu_filler.fill(x.memptr(), x.n_elem); + + x_norm = op_norm::vec_norm_2( Proxy< Mat >(x) ); + } + + if(x_norm != T(0)) { x /= x_norm; } + + y = A.t() * x; + + est_old = est_cur; + est_cur = op_norm::vec_norm_2( Proxy< Mat >(y) ); + + arma_extra_debug_print(arma_str::format("norm2est(): est_old: %e") % est_old); + arma_extra_debug_print(arma_str::format("norm2est(): est_cur: %e") % est_cur); + + if(arma_isfinite(est_cur) == false) { return est_old; } + + if( ((std::abs)(est_cur - est_old)) <= (tol * (std::max)(est_cur,est_old)) ) { break; } + } + + return est_cur; + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_normalise_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_normalise_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_normalise_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_normalise_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -34,7 +34,7 @@ const uword p = in.aux_uword_a; - arma_debug_check( (p == 0), "normalise(): parameter 'p' must be greater than zero" ); + arma_debug_check( (p == 0), "normalise(): unsupported vector norm type" ); const quasi_unwrap U(in.m); @@ -67,8 +67,8 @@ const uword p = in.aux_uword_a; const uword dim = in.aux_uword_b; - arma_debug_check( (p == 0), "normalise(): parameter 'p' must be greater than zero" ); - arma_debug_check( (dim > 1), "normalise(): parameter 'dim' must be 0 or 1" ); + arma_debug_check( (p == 0), "normalise(): unsupported vector norm type" ); + arma_debug_check( (dim > 1), "normalise(): parameter 'dim' must be 0 or 1" ); const quasi_unwrap U(in.m); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_norm_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_norm_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_norm_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_norm_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,7 +22,6 @@ template -arma_hot inline typename T1::pod_type op_norm::vec_norm_1(const Proxy& P, const typename arma_not_cx::result* junk) @@ -109,7 +108,6 @@ template -arma_hot inline typename T1::pod_type op_norm::vec_norm_1(const Proxy& P, const typename arma_cx_only::result* junk) @@ -217,7 +215,6 @@ template -arma_hot inline eT op_norm::vec_norm_1_direct_std(const Mat& X) @@ -252,14 +249,13 @@ template -arma_hot inline eT op_norm::vec_norm_1_direct_mem(const uword N, const eT* A) { arma_extra_debug_sigprint(); - #if defined(ARMA_SIMPLE_LOOPS) || (defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ > 0)) + #if (defined(ARMA_SIMPLE_LOOPS) || defined(__FAST_MATH__)) { eT acc1 = eT(0); @@ -305,7 +301,6 @@ template -arma_hot inline typename T1::pod_type op_norm::vec_norm_2(const Proxy& P, const typename arma_not_cx::result* junk) @@ -413,7 +408,6 @@ template -arma_hot inline typename T1::pod_type op_norm::vec_norm_2(const Proxy& P, const typename arma_cx_only::result* junk) @@ -516,7 +510,6 @@ template -arma_hot inline eT op_norm::vec_norm_2_direct_std(const Mat& X) @@ -564,7 +557,6 @@ template -arma_hot inline eT op_norm::vec_norm_2_direct_mem(const uword N, const eT* A) @@ -573,7 +565,7 @@ eT acc; - #if defined(ARMA_SIMPLE_LOOPS) || (defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ > 0)) + #if (defined(ARMA_SIMPLE_LOOPS) || defined(__FAST_MATH__)) { eT acc1 = eT(0); @@ -623,7 +615,6 @@ template -arma_hot inline eT op_norm::vec_norm_2_direct_robust(const Mat& X) @@ -688,7 +679,6 @@ template -arma_hot inline typename T1::pod_type op_norm::vec_norm_k(const Proxy& P, const int k) @@ -738,7 +728,6 @@ template -arma_hot inline typename T1::pod_type op_norm::vec_norm_max(const Proxy& P) @@ -804,7 +793,6 @@ template -arma_hot inline typename T1::pod_type op_norm::vec_norm_min(const Proxy& P) @@ -891,7 +879,7 @@ typedef typename get_pod_type::result T; - if(X.is_finite() == false) { arma_debug_warn_level(1, "norm(): given matrix has non-finite elements"); } + if(X.internal_has_nonfinite()) { arma_debug_warn_level(1, "norm(): given matrix has non-finite elements"); } Col S; svd(S, X); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_pinv_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_pinv_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_pinv_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_pinv_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,6 +22,18 @@ +class op_pinv_default + : public traits_op_default + { + public: + + template inline static void apply(Mat& out, const Op& in); + + template inline static bool apply_direct(Mat& out, const Base& expr); + }; + + + class op_pinv : public traits_op_default { @@ -34,6 +46,8 @@ 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); + + template inline static bool apply_gen (Mat& out, Mat& A, typename get_pod_type::result tol, const uword method_id); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_pinv_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_pinv_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_pinv_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_pinv_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -25,6 +25,45 @@ template inline void +op_pinv_default::apply(Mat& out, const Op& in) + { + arma_extra_debug_sigprint(); + + const bool status = op_pinv_default::apply_direct(out, in.m); + + if(status == false) + { + out.soft_reset(); + arma_stop_runtime_error("pinv(): svd failed"); + } + } + + + +template +inline +bool +op_pinv_default::apply_direct(Mat& out, const Base& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::pod_type T; + + constexpr T tol = T(0); + constexpr uword method_id = uword(0); + + return op_pinv::apply_direct(out, expr, tol, method_id); + } + + + +// + + + +template +inline +void op_pinv::apply(Mat& out, const Op& in) { arma_extra_debug_sigprint(); @@ -63,10 +102,7 @@ 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(A.is_empty()) { out.set_size(A.n_cols,A.n_rows); return true; } if(is_op_diagmat::value || A.is_diagmat()) { @@ -75,42 +111,18 @@ return op_pinv::apply_diag(out, A, tol); } - #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 + bool do_sym = false; - if(do_sympd) + const bool is_sym_size_ok = (A.n_rows == A.n_cols) && (A.n_rows > (is_cx::yes ? uword(20) : uword(40))); + + if( (is_sym_size_ok) && (arma_config::optimise_sym) && (auxlib::crippled_lapack(A) == false) ) { - arma_extra_debug_print("op_pinv: attempting sympd optimisation"); - - out = A; + bool is_approx_sym = false; + bool is_approx_sympd = false; - const T rcond_threshold = T((std::max)(uword(100), uword(A.n_rows))) * std::numeric_limits::epsilon(); + sym_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A); - 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 + do_sym = ((is_cx::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd)); } if(do_sym) @@ -120,60 +132,7 @@ return op_pinv::apply_sym(out, A, tol, method_id); } - // economical SVD decomposition - Mat U; - Col< T> s; - Mat V; - - 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(); } - - 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) - { - const T val = s[i]; - - if(val >= tol) { s2[count2] = (val > T(0)) ? T(T(1) / val) : T(0); ++count2; } - } - - 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) - { - // 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); - } - else - { - // 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); - } - - return true; + return op_pinv::apply_gen(out, A, tol, method_id); } @@ -277,6 +236,77 @@ return true; } + + + + +template +inline +bool +op_pinv::apply_gen(Mat& out, Mat& A, typename get_pod_type::result tol, const uword method_id) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + const uword n_rows = A.n_rows; + const uword n_cols = A.n_cols; + + // economical SVD decomposition + Mat U; + Col< T> s; + Mat V; + + 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(); } + + 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) + { + const T val = s[i]; + + if(val >= tol) { s2[count2] = (val > T(0)) ? T(T(1) / val) : T(0); ++count2; } + } + + 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) + { + // 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); + } + else + { + // 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); + } + + return true; + } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_powmat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_powmat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_powmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_powmat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -55,13 +55,13 @@ { if(y == uword(1)) { - return op_inv::apply_direct(out, X.get_ref(), "powmat()"); + return op_inv_gen_default::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()"); + const bool inv_status = op_inv_gen_default::apply_direct(X_inv, X.get_ref(), "powmat()"); if(inv_status == false) { return false; } @@ -207,11 +207,7 @@ return true; } - #if defined(ARMA_OPTIMISE_SYMPD) - const bool try_sympd = sympd_helper::guess_sympd(A); - #else - const bool try_sympd = false; - #endif + const bool try_sympd = arma_config::optimise_sym && sym_helper::guess_sympd(A); if(try_sympd) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_rank_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_rank_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_rank_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_rank_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -42,21 +42,17 @@ return op_rank::apply_diag(out, A, tol); } - #if defined(ARMA_OPTIMISE_SYMPD) - bool do_sym = false; + bool do_sym = false; + + if((arma_config::optimise_sym) && (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; - 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 + sym_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A); + + do_sym = (is_cx::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd); + } if(do_sym) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_rcond_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_rcond_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_rcond_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_rcond_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,32 @@ +// 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_rcond +//! @{ + + +class op_rcond + : public traits_op_default + { + public: + + template static inline typename T1::pod_type apply(const Base& X); + }; + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_rcond_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_rcond_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_rcond_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_rcond_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,113 @@ +// 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_rcond +//! @{ + + + +template +inline +typename T1::pod_type +op_rcond::apply(const Base& X) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + if(strip_trimat::do_trimat) + { + const strip_trimat S(X.get_ref()); + + const quasi_unwrap::stored_type> U(S.M); + + arma_debug_check( (U.M.is_square() == false), "rcond(): matrix must be square sized" ); + + const uword layout = (S.do_triu) ? uword(0) : uword(1); + + return auxlib::rcond_trimat(U.M, layout); + } + + Mat A = X.get_ref(); + + arma_debug_check( (A.is_square() == false), "rcond(): matrix must be square sized" ); + + if(A.is_empty()) { return Datum::inf; } + + if(is_op_diagmat::value || A.is_diagmat()) + { + arma_extra_debug_print("op_rcond::apply(): detected diagonal matrix"); + + const eT* colmem = A.memptr(); + const uword N = A.n_rows; + + T abs_min = Datum::inf; + T abs_max = T(0); + + for(uword i=0; i abs_max) ? abs_val : abs_max; + + colmem += N; + } + + if((abs_min == T(0)) || (abs_max == T(0))) { return T(0); } + + return T(abs_min / abs_max); + } + + 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) + { + const uword layout = (is_triu) ? uword(0) : uword(1); + + return auxlib::rcond_trimat(A, layout); + } + + const bool try_sympd = arma_config::optimise_sym && (auxlib::crippled_lapack(A) ? false : sym_helper::guess_sympd(A)); + + if(try_sympd) + { + arma_extra_debug_print("op_rcond::apply(): 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_rcond::apply(): sympd optimisation failed"); + + // auxlib::rcond_sympd() may have failed because A isn't really sympd + // restore A, as auxlib::rcond_sympd() may have destroyed it + A = X.get_ref(); + // fallthrough to the next return statement + } + + return auxlib::rcond(A); + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_reshape_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_reshape_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_reshape_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_reshape_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -46,19 +46,4 @@ -//! NOTE: deprecated -class op_reshape_old - : public traits_op_default - { - public: - - 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-10.8.2+dfsg/include/armadillo_bits/op_reshape_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_reshape_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_reshape_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_reshape_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -243,87 +243,4 @@ -// - - - -template -arma_cold -inline -void -op_reshape_old::apply(Mat& out, const Op& in) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - 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 unwrap U(in.m); - const Mat& A = U.M; - - 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(dim == 0) - { - op_reshape::apply_mat_inplace(A, new_n_rows, new_n_cols); - } - else - if(dim == 1) - { - Mat tmp; - - op_strans::apply_mat_noalias(tmp, A); - - 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; - - op_strans::apply_mat_noalias(tmp, A); - - op_reshape::apply_mat_noalias(out, tmp, new_n_rows, new_n_cols); - } - } - - - //! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_roots_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_roots_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_roots_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_roots_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -83,7 +83,7 @@ arma_debug_check( (X.is_vec() == false), "roots(): given object must be a vector" ); - if(X.is_finite() == false) { return false; } + if(X.internal_has_nonfinite()) { return false; } // treat X as a column vector diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_row_as_mat_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_row_as_mat_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_row_as_mat_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_row_as_mat_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,33 @@ +// 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_row_as_mat +//! @{ + + +class op_row_as_mat + : public traits_op_default + { + public: + + template inline static void apply(Mat& out, const CubeToMatOp& expr); + }; + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_row_as_mat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_row_as_mat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_row_as_mat_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_row_as_mat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,63 @@ +// 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_row_as_mat +//! @{ + + + +template +inline +void +op_row_as_mat::apply(Mat& out, const CubeToMatOp& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_cube U(expr.m); + const Cube& A = U.M; + + const uword in_row = expr.aux_uword; + + arma_debug_check_bounds( (in_row >= A.n_rows), "Cube::row_as_mat(): index out of bounds" ); + + const uword A_n_cols = A.n_cols; + const uword A_n_rows = A.n_rows; + const uword A_n_slices = A.n_slices; + + out.set_size(A_n_slices, A_n_cols); + + for(uword s=0; s < A_n_slices; ++s) + { + const eT* A_mem = &(A.at(in_row, 0, s)); + eT* out_mem = &(out.at(s,0)); + + for(uword c=0; c < A_n_cols; ++c) + { + (*out_mem) = (*A_mem); + + A_mem += A_n_rows; + out_mem += A_n_slices; + } + } + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_shift_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_shift_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_shift_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_shift_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -37,13 +37,7 @@ { public: - template inline static void apply(Mat& out, const Op& in); - - template inline static void apply_direct(Mat& out, const Mat& X, const uword len, const uword neg, const uword dim); - template inline static void apply_noalias(Mat& out, const Mat& X, const uword len, const uword neg, const uword dim); - - template inline static void apply_alias(Mat& out, const uword len, const uword neg, const uword dim); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_shift_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_shift_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_shift_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_shift_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -29,55 +29,26 @@ { arma_extra_debug_sigprint(); - const unwrap U(in.m); + typedef typename T1::elem_type eT; - const uword len = in.aux_uword_a; - const uword neg = in.aux_uword_b; - - const uword dim = (T1::is_xvec) ? uword(U.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0); - - op_shift::apply_direct(out, U.M, len, neg, dim); - } - - - -template -inline -void -op_shift::apply(Mat& out, const Op& in) - { - arma_extra_debug_sigprint(); - - const unwrap U(in.m); + const quasi_unwrap U(in.m); const uword len = in.aux_uword_a; const uword neg = in.aux_uword_b; - const uword dim = in.aux_uword_c; - - arma_debug_check( (dim > 1), "shift(): parameter 'dim' must be 0 or 1" ); - - op_shift::apply_direct(out, U.M, len, neg, dim); - } - - - -template -inline -void -op_shift::apply_direct(Mat& out, const Mat& X, const uword len, const uword neg, const uword dim) - { - arma_extra_debug_sigprint(); - 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" ); + const uword dim = (T1::is_xvec) ? uword(U.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0); - if(&out == &X) + if(U.is_alias(out)) { - op_shift::apply_alias(out, len, neg, dim); + Mat tmp; + + op_shift::apply_noalias(tmp, U.M, len, neg, dim); + + out.steal_mem(tmp); } else { - op_shift::apply_noalias(out, X, len, neg, dim); + op_shift::apply_noalias(out, U.M, len, neg, dim); } } @@ -90,6 +61,9 @@ { arma_extra_debug_sigprint(); + 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" ); + out.copy_size(X); const uword X_n_rows = X.n_rows; @@ -203,23 +177,5 @@ } - -template -inline -void -op_shift::apply_alias(Mat& X, const uword len, const uword neg, const uword dim) - { - arma_extra_debug_sigprint(); - - // TODO: replace with better implementation - - Mat tmp; - - op_shift::apply_noalias(tmp, X, len, neg, dim); - - X.steal_mem(tmp); - } - - //! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_shuffle_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_shuffle_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_shuffle_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_shuffle_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -33,10 +33,12 @@ const uword N = (dim == 0) ? X.n_rows : X.n_cols; - // see op_sort_index_bones.hpp for the definition of arma_sort_index_packet // and the associated comparison functor - std::vector< arma_sort_index_packet > packet_vec(N); + + typedef arma_sort_index_packet packet; + + std::vector packet_vec(N); for(uword i=0; i 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" ); + 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.internal_has_nan()), "sort(): detected NaN" ); if(U.is_alias(out)) { @@ -211,8 +211,8 @@ const uword sort_type = in.aux_uword_a; - arma_debug_check( (sort_type > 1), "sort(): parameter 'sort_type' must be 0 or 1" ); - arma_debug_check( (X.has_nan()), "sort(): detected NaN" ); + arma_debug_check( (sort_type > 1), "sort(): parameter 'sort_type' must be 0 or 1" ); + arma_debug_check( (X.internal_has_nan()), "sort(): detected NaN" ); out = X; // not checking for aliasing, to allow inplace sorting of vectors diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_sqrtmat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_sqrtmat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_sqrtmat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_sqrtmat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -139,11 +139,7 @@ return true; } - #if defined(ARMA_OPTIMISE_SYMPD) - const bool try_sympd = sympd_helper::guess_sympd(A); - #else - const bool try_sympd = false; - #endif + const bool try_sympd = arma_config::optimise_sym && sym_helper::guess_sympd(A); if(try_sympd) { @@ -179,7 +175,7 @@ arma_extra_debug_print("op_sqrtmat: sympd optimisation failed"); - // fallthrough if eigen decomposition failed or an eigenvalue is zero + // fallthrough if eigen decomposition failed or an eigenvalue is <= 0 } @@ -340,11 +336,7 @@ return true; } - #if defined(ARMA_OPTIMISE_SYMPD) - const bool try_sympd = sympd_helper::guess_sympd(S); - #else - const bool try_sympd = false; - #endif + const bool try_sympd = arma_config::optimise_sym && sym_helper::guess_sympd(S); if(try_sympd) { @@ -380,7 +372,7 @@ arma_extra_debug_print("op_sqrtmat_cx: sympd optimisation failed"); - // fallthrough if eigen decomposition failed or an eigenvalue is zero + // fallthrough if eigen decomposition failed or an eigenvalue is <= 0 } const bool schur_ok = auxlib::schur(U, S); @@ -482,14 +474,44 @@ #if defined(ARMA_USE_LAPACK) { - typedef typename T1::pod_type T; typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; const unwrap U(expr.get_ref()); const Mat& X = U.M; arma_debug_check( (X.is_square() == false), "sqrtmat_sympd(): given matrix must be square sized" ); + if((arma_config::debug) && (is_cx::yes) && (sym_helper::check_diag_imag(X) == false)) + { + arma_debug_warn_level(1, "sqrtmat_sympd(): imaginary components on the diagonal are non-zero"); + } + + if(is_op_diagmat::value || X.is_diagmat()) + { + arma_extra_debug_print("op_sqrtmat_sympd: detected diagonal matrix"); + + out = X; + + eT* colmem = out.memptr(); + + const uword N = X.n_rows; + + for(uword i=0; i eigval; Mat eigvec; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_stddev_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_stddev_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_stddev_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_stddev_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -19,7 +19,8 @@ //! \addtogroup op_stddev //! @{ -//! Class for finding the standard deviation + + class op_stddev : public traits_op_xvec { @@ -27,6 +28,11 @@ template inline static void apply(Mat& out, const mtOp& in); + + template + inline static void apply_noalias(Mat::result>& out, const Mat& X, const uword norm_type, const uword dim); }; + + //! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_stddev_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_stddev_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_stddev_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_stddev_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -20,10 +20,7 @@ //! @{ -//! \brief -//! For each row or for each column, find the standard deviation. -//! The result is stored in a dense matrix that has either one column or one row. -//! The dimension for which the standard deviations are found is set via the stddev() function. + template inline void @@ -31,11 +28,7 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type in_eT; - typedef typename T1::pod_type out_eT; - - const unwrap_check_mixed tmp(in.m, out); - const Mat& X = tmp.M; + typedef typename T1::pod_type out_eT; const uword norm_type = in.aux_uword_a; const uword dim = in.aux_uword_b; @@ -43,12 +36,39 @@ arma_debug_check( (norm_type > 1), "stddev(): parameter 'norm_type' must be 0 or 1" ); arma_debug_check( (dim > 1), "stddev(): parameter 'dim' must be 0 or 1" ); + const quasi_unwrap U(in.m); + + if(U.is_alias(out)) + { + Mat tmp; + + op_stddev::apply_noalias(tmp, U.M, norm_type, dim); + + out.steal_mem(tmp); + } + else + { + op_stddev::apply_noalias(out, U.M, norm_type, dim); + } + } + + + +template +inline +void +op_stddev::apply_noalias(Mat::result>& out, const Mat& X, const uword norm_type, const uword dim) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result out_eT; + const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; if(dim == 0) { - arma_extra_debug_print("op_stddev::apply(): dim = 0"); + arma_extra_debug_print("op_stddev::apply_noalias(): dim = 0"); out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); @@ -65,7 +85,7 @@ else if(dim == 1) { - arma_extra_debug_print("op_stddev::apply(): dim = 1"); + arma_extra_debug_print("op_stddev::apply_noalias(): dim = 1"); out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_strans_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_strans_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_strans_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_strans_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -23,7 +23,6 @@ //! for tiny square matrices (size <= 4x4) template -arma_cold inline void op_strans::apply_mat_noalias_tinysq(Mat& out, const TA& A) @@ -98,7 +97,6 @@ template -arma_hot inline void op_strans::block_worker(eT* Y, const eT* X, const uword X_n_rows, const uword Y_n_rows, const uword n_rows, const uword n_cols) @@ -119,7 +117,6 @@ template -arma_hot inline void op_strans::apply_mat_noalias_large(Mat& out, const Mat& A) @@ -176,7 +173,6 @@ //! Immediate transpose of a dense matrix template -arma_hot inline void op_strans::apply_mat_noalias(Mat& out, const TA& A) @@ -233,7 +229,6 @@ template -arma_hot inline void op_strans::apply_mat_inplace(Mat& out) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_sum_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_sum_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_sum_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_sum_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,7 +22,6 @@ template -arma_hot inline void op_sum::apply(Mat& out, const Op& in) @@ -53,7 +52,6 @@ template -arma_hot inline void op_sum::apply_noalias(Mat& out, const Proxy& P, const uword dim) @@ -73,7 +71,6 @@ template -arma_hot inline void op_sum::apply_noalias_unwrap(Mat& out, const Proxy& P, const uword dim) @@ -91,26 +88,36 @@ const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; + const uword out_n_rows = (dim == 0) ? uword(1) : X_n_rows; + const uword out_n_cols = (dim == 0) ? X_n_cols : uword(1); + + out.set_size(out_n_rows, out_n_cols); + + if(X.n_elem == 0) { out.zeros(); return; } + + const eT* X_colptr = X.memptr(); + eT* out_mem = out.memptr(); + if(dim == 0) { - out.set_size(1, X_n_cols); - - eT* out_mem = out.memptr(); - for(uword col=0; col < X_n_cols; ++col) { - out_mem[col] = arrayops::accumulate( X.colptr(col), X_n_rows ); + out_mem[col] = arrayops::accumulate( X_colptr, X_n_rows ); + + X_colptr += X_n_rows; } } else { - out.zeros(X_n_rows, 1); + arrayops::copy(out_mem, X_colptr, X_n_rows); - eT* out_mem = out.memptr(); + X_colptr += X_n_rows; - for(uword col=0; col < X_n_cols; ++col) + for(uword col=1; col < X_n_cols; ++col) { - arrayops::inplace_plus( out_mem, X.colptr(col), X_n_rows ); + arrayops::inplace_plus( out_mem, X_colptr, X_n_rows ); + + X_colptr += X_n_rows; } } } @@ -118,7 +125,6 @@ template -arma_hot inline void op_sum::apply_noalias_proxy(Mat& out, const Proxy& P, const uword dim) @@ -130,42 +136,93 @@ const uword P_n_rows = P.get_n_rows(); const uword P_n_cols = P.get_n_cols(); - if(dim == 0) + const uword out_n_rows = (dim == 0) ? uword(1) : P_n_rows; + const uword out_n_cols = (dim == 0) ? P_n_cols : uword(1); + + out.set_size(out_n_rows, out_n_cols); + + if(P.get_n_elem() == 0) { out.zeros(); return; } + + eT* out_mem = out.memptr(); + + if(Proxy::use_at == false) { - out.set_size(1, P_n_cols); - - eT* out_mem = out.memptr(); - - for(uword col=0; col < P_n_cols; ++col) + if(dim == 0) { - eT val1 = eT(0); - eT val2 = eT(0); + uword count = 0; - uword i,j; - for(i=0, j=1; j < P_n_rows; i+=2, j+=2) + for(uword col=0; col < P_n_cols; ++col) { - val1 += P.at(i,col); - val2 += P.at(j,col); + eT val1 = eT(0); + eT val2 = eT(0); + + uword j; + for(j=1; j < P_n_rows; j+=2) + { + val1 += P[count]; ++count; + val2 += P[count]; ++count; + } + + if((j-1) < P_n_rows) + { + val1 += P[count]; ++count; + } + + out_mem[col] = (val1 + val2); } + } + else + { + uword count = 0; - if(i < P_n_rows) + for(uword row=0; row < P_n_rows; ++row) { - val1 += P.at(i,col); + out_mem[row] = P[count]; ++count; } - out_mem[col] = (val1 + val2); + for(uword col=1; col < P_n_cols; ++col) + for(uword row=0; row < P_n_rows; ++row) + { + out_mem[row] += P[count]; ++count; + } } } else { - out.zeros(P_n_rows, 1); - - eT* out_mem = out.memptr(); - - for(uword col=0; col < P_n_cols; ++col) - for(uword row=0; row < P_n_rows; ++row) + if(dim == 0) { - out_mem[row] += P.at(row,col); + 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 + { + for(uword row=0; row < P_n_rows; ++row) + { + out_mem[row] = P.at(row,0); + } + + for(uword col=1; col < P_n_cols; ++col) + for(uword row=0; row < P_n_rows; ++row) + { + out_mem[row] += P.at(row,col); + } } } } @@ -178,7 +235,6 @@ template -arma_hot inline void op_sum::apply(Cube& out, const OpCube& in) @@ -209,7 +265,6 @@ template -arma_hot inline void op_sum::apply_noalias(Cube& out, const ProxyCube& P, const uword dim) @@ -229,7 +284,6 @@ template -arma_hot inline void op_sum::apply_noalias_unwrap(Cube& out, const ProxyCube& P, const uword dim) @@ -294,7 +348,6 @@ template -arma_hot inline void op_sum::apply_noalias_proxy(Cube& out, const ProxyCube& P, const uword dim) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_var_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_var_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_var_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_var_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,7 +21,6 @@ -//! Class for finding variance values of a matrix class op_var : public traits_op_xvec { @@ -30,12 +29,14 @@ template inline static void apply(Mat& out, const mtOp& in); + template + inline static void apply_noalias(Mat::result>& out, const Mat& X, const uword norm_type, const uword dim); // template inline static typename get_pod_type::result var_vec(const subview_col& X, const uword norm_type = 0); - + template inline static typename get_pod_type::result var_vec(const subview_row& X, const uword norm_type = 0); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_var_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_var_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_var_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_var_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -20,10 +20,7 @@ //! @{ -//! \brief -//! For each row or for each column, find the variance. -//! The result is stored in a dense matrix that has either one column or one row. -//! The dimension, for which the variances are found, is set via the var() function. + template inline void @@ -31,11 +28,7 @@ { arma_extra_debug_sigprint(); - typedef typename T1::elem_type in_eT; - typedef typename T1::pod_type out_eT; - - const unwrap_check_mixed tmp(in.m, out); - const Mat& X = tmp.M; + typedef typename T1::pod_type out_eT; const uword norm_type = in.aux_uword_a; const uword dim = in.aux_uword_b; @@ -43,12 +36,39 @@ arma_debug_check( (norm_type > 1), "var(): parameter 'norm_type' must be 0 or 1" ); arma_debug_check( (dim > 1), "var(): parameter 'dim' must be 0 or 1" ); + const quasi_unwrap U(in.m); + + if(U.is_alias(out)) + { + Mat tmp; + + op_var::apply_noalias(tmp, U.M, norm_type, dim); + + out.steal_mem(tmp); + } + else + { + op_var::apply_noalias(out, U.M, norm_type, dim); + } + } + + + +template +inline +void +op_var::apply_noalias(Mat::result>& out, const Mat& X, const uword norm_type, const uword dim) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result out_eT; + const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; if(dim == 0) { - arma_extra_debug_print("op_var::apply(): dim = 0"); + arma_extra_debug_print("op_var::apply_noalias(): dim = 0"); out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); @@ -65,7 +85,7 @@ else if(dim == 1) { - arma_extra_debug_print("op_var::apply(): dim = 1"); + arma_extra_debug_print("op_var::apply_noalias(): dim = 1"); out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_vecnorm_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_vecnorm_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_vecnorm_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_vecnorm_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,55 @@ +// 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_vecnorm +//! @{ + + +class op_vecnorm + : public traits_op_xvec + { + public: + + template + inline static void apply(Mat& out, const mtOp& in); + + template + inline static void apply_noalias(Mat::result>& out, const Mat& X, const uword k, const uword dim); + + template + inline static void apply_rawmem(typename get_pod_type::result& out_val, const in_eT* mem, const uword N, const uword k); + }; + + +class op_vecnorm_ext + : public traits_op_xvec + { + public: + + template + inline static void apply(Mat& out, const mtOp& in); + + template + inline static void apply_noalias(Mat::result>& out, const Mat& X, const uword method_id, const uword dim); + + template + inline static void apply_rawmem(typename get_pod_type::result& out_val, const in_eT* mem, const uword N, const uword method_id); + }; + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/op_vecnorm_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/op_vecnorm_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/op_vecnorm_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/op_vecnorm_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,254 @@ +// 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_vecnorm +//! @{ + + + +template +inline +void +op_vecnorm::apply(Mat& out, const mtOp& in) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type in_eT; + typedef typename T1::pod_type out_eT; + + const quasi_unwrap U(in.m); + const Mat& X = U.M; + + const uword k = in.aux_uword_a; + const uword dim = in.aux_uword_b; + + arma_debug_check( (k == 0), "vecnorm(): unsupported vector norm type" ); + arma_debug_check( (dim > 1), "vecnorm(): parameter 'dim' must be 0 or 1" ); + + if(U.is_alias(out)) + { + Mat tmp; + + op_vecnorm::apply_noalias(tmp, X, k, dim); + + out.steal_mem(tmp); + } + else + { + op_vecnorm::apply_noalias(out, X, k, dim); + } + } + + + + +template +inline +void +op_vecnorm::apply_noalias(Mat::result>& out, const Mat& X, const uword k, const uword dim) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result out_eT; + + const uword X_n_rows = X.n_rows; + const uword X_n_cols = X.n_cols; + + if(dim == 0) + { + arma_extra_debug_print("op_vecnorm::apply(): dim = 0"); + + out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); + + if(X_n_rows > 0) + { + out_eT* out_mem = out.memptr(); + + for(uword col=0; col < X_n_cols; ++col) + { + op_vecnorm::apply_rawmem( out_mem[col], X.colptr(col), X_n_rows, k ); + } + } + } + else + if(dim == 1) + { + arma_extra_debug_print("op_vecnorm::apply(): dim = 1"); + + out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); + + if(X_n_cols > 0) + { + podarray dat(X_n_cols); + + in_eT* dat_mem = dat.memptr(); + out_eT* out_mem = out.memptr(); + + for(uword row=0; row < X_n_rows; ++row) + { + dat.copy_row(X, row); + + op_vecnorm::apply_rawmem( out_mem[row], dat_mem, X_n_cols, k ); + } + } + } + } + + + +template +inline +void +op_vecnorm::apply_rawmem(typename get_pod_type::result& out_val, const in_eT* mem, const uword N, const uword k) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result out_eT; + + const Col tmp(const_cast(mem), N, false, false); + + const Proxy< Col > P(tmp); + + if(P.get_n_elem() == 0) { out_val = out_eT(0); return; } + + if(k == uword(1)) { out_val = op_norm::vec_norm_1(P); return; } + if(k == uword(2)) { out_val = op_norm::vec_norm_2(P); return; } + + out_val = op_norm::vec_norm_k(P, int(k)); + } + + + +// + + + +template +inline +void +op_vecnorm_ext::apply(Mat& out, const mtOp& in) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type in_eT; + typedef typename T1::pod_type out_eT; + + const quasi_unwrap U(in.m); + const Mat& X = U.M; + + const uword method_id = in.aux_uword_a; + const uword dim = in.aux_uword_b; + + arma_debug_check( (method_id == 0), "vecnorm(): unsupported vector norm type" ); + arma_debug_check( (dim > 1), "vecnorm(): parameter 'dim' must be 0 or 1" ); + + if(U.is_alias(out)) + { + Mat tmp; + + op_vecnorm_ext::apply_noalias(tmp, X, method_id, dim); + + out.steal_mem(tmp); + } + else + { + op_vecnorm_ext::apply_noalias(out, X, method_id, dim); + } + } + + + + +template +inline +void +op_vecnorm_ext::apply_noalias(Mat::result>& out, const Mat& X, const uword method_id, const uword dim) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result out_eT; + + const uword X_n_rows = X.n_rows; + const uword X_n_cols = X.n_cols; + + if(dim == 0) + { + arma_extra_debug_print("op_vecnorm_ext::apply(): dim = 0"); + + out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); + + if(X_n_rows > 0) + { + out_eT* out_mem = out.memptr(); + + for(uword col=0; col < X_n_cols; ++col) + { + op_vecnorm_ext::apply_rawmem( out_mem[col], X.colptr(col), X_n_rows, method_id ); + } + } + } + else + if(dim == 1) + { + arma_extra_debug_print("op_vecnorm_ext::apply(): dim = 1"); + + out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); + + if(X_n_cols > 0) + { + podarray dat(X_n_cols); + + in_eT* dat_mem = dat.memptr(); + out_eT* out_mem = out.memptr(); + + for(uword row=0; row < X_n_rows; ++row) + { + dat.copy_row(X, row); + + op_vecnorm_ext::apply_rawmem( out_mem[row], dat_mem, X_n_cols, method_id ); + } + } + } + } + + + +template +inline +void +op_vecnorm_ext::apply_rawmem(typename get_pod_type::result& out_val, const in_eT* mem, const uword N, const uword method_id) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result out_eT; + + const Col tmp(const_cast(mem), N, false, false); + + const Proxy< Col > P(tmp); + + if(P.get_n_elem() == 0) { out_val = out_eT(0); return; } + + if(method_id == uword(1)) { out_val = op_norm::vec_norm_max(P); return; } + if(method_id == uword(2)) { out_val = op_norm::vec_norm_min(P); return; } + + out_val = out_eT(0); + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/podarray_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/podarray_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/podarray_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/podarray_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -53,10 +53,8 @@ arma_inline explicit podarray(const uword new_N); - arma_inline explicit podarray(const eT* X, const uword new_N); - - // template - // inline explicit podarray(const Proxy& P); + template + inline explicit podarray(const uword new_N, const arma_initmode_indicator&); arma_inline eT& operator[] (const uword i); arma_inline eT operator[] (const uword i) const; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/podarray_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/podarray_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/podarray_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/podarray_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -21,7 +21,6 @@ template -arma_hot inline podarray::~podarray() { @@ -84,7 +83,6 @@ template -arma_hot arma_inline podarray::podarray(const uword new_n_elem) : n_elem(new_n_elem) @@ -97,79 +95,24 @@ template -arma_inline -podarray::podarray(const eT* X, const uword new_n_elem) +template +inline +podarray::podarray(const uword new_n_elem, const arma_initmode_indicator&) : n_elem(new_n_elem) { arma_extra_debug_sigprint_this(this); init_cold(new_n_elem); - arrayops::copy( memptr(), X, new_n_elem ); + if(do_zeros) + { + arma_extra_debug_print("podarray::constructor: zeroing memory"); + arrayops::fill_zeros(memptr(), n_elem); + } } -// template -// template -// inline -// podarray::podarray(const Proxy& P) -// : n_elem(P.get_n_elem()) -// { -// arma_extra_debug_sigprint_this(this); -// -// const uword P_n_elem = P.get_n_elem(); -// -// init_cold(P_n_elem); -// -// eT* out_mem = (*this).memptr(); -// -// if(Proxy::use_at == false) -// { -// typename Proxy::ea_type A = P.get_ea(); -// -// uword i,j; -// for(i=0, j=1; j < P_n_elem; i+=2, j+=2) -// { -// const eT val_i = A[i]; -// const eT val_j = A[j]; -// -// out_mem[i] = val_i; -// out_mem[j] = val_j; -// } -// -// if(i < P_n_elem) -// { -// out_mem[i] = A[i]; -// } -// } -// else -// { -// const uword P_n_rows = P.get_n_rows(); -// const uword P_n_cols = P.get_n_cols(); -// -// if(P_n_rows != 1) -// { -// uword count = 0; -// -// for(uword col=0; col < P_n_cols; ++col) -// for(uword row=0; row < P_n_rows; ++row, ++count) -// { -// out_mem[count] = P.at(row,col); -// } -// } -// else -// { -// for(uword col=0; col < P_n_cols; ++col) -// { -// out_mem[col] = P.at(0,col); -// } -// } -// } -// } - - - template arma_inline eT @@ -313,54 +256,26 @@ void podarray::copy_row(const Mat& A, const uword row) { - const uword cols = A.n_cols; + arma_extra_debug_sigprint(); // note: this function assumes that the podarray has been set to the correct size beforehand - eT* out = memptr(); - switch(cols) + const uword n_rows = A.n_rows; + const uword n_cols = A.n_cols; + + const eT* A_mem = &(A.at(row,0)); + eT* out_mem = memptr(); + + for(uword i=0; i < n_cols; ++i) { - default: - { - uword i,j; - for(i=0, j=1; j < cols; i+=2, j+=2) - { - const eT tmp_i = A.at(row, i); - const eT tmp_j = A.at(row, j); - - out[i] = tmp_i; - out[j] = tmp_j; - } - - if(i < cols) - { - out[i] = A.at(row, i); - } - } - break; + out_mem[i] = (*A_mem); - case 8: out[7] = A.at(row, 7); - // fallthrough - case 7: out[6] = A.at(row, 6); - // fallthrough - case 6: out[5] = A.at(row, 5); - // fallthrough - case 5: out[4] = A.at(row, 4); - // fallthrough - case 4: out[3] = A.at(row, 3); - // fallthrough - case 3: out[2] = A.at(row, 2); - // fallthrough - case 2: out[1] = A.at(row, 1); - // fallthrough - case 1: out[0] = A.at(row, 0); - // fallthrough - case 0: ; - // fallthrough + A_mem += n_rows; } } + template inline void diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/ProxyCube.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/ProxyCube.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/ProxyCube.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/ProxyCube.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -120,97 +120,7 @@ template constexpr bool has_overlap(const subview_cube&) const { return false; } - arma_inline bool is_aligned() const { return GenCube::is_simple; } - }; - - - -template -struct ProxyCube< GenCube > - { - 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 constexpr bool use_at = false; - static constexpr bool use_mp = false; - static constexpr bool has_subview = false; - - arma_aligned const Cube Q; - - inline explicit ProxyCube(const GenCube& 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_slice() const { return Q.n_elem_slice; } - 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 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 - 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()); } - }; - - - -template -struct ProxyCube< GenCube > - { - 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 constexpr bool use_at = false; - static constexpr bool use_mp = false; - static constexpr bool has_subview = false; - - arma_aligned const Cube Q; - - inline explicit ProxyCube(const GenCube& 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_slice() const { return Q.n_elem_slice; } - 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 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 - 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()); } + constexpr bool is_aligned() const { return GenCube::is_simple; } }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Proxy.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Proxy.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Proxy.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Proxy.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -334,101 +334,7 @@ template constexpr bool has_overlap(const subview&) const { return false; } - arma_inline bool is_aligned() const { return Gen::is_simple; } - }; - - - -template -struct Proxy< Gen > - { - 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 = Gen::is_row; - static constexpr bool is_col = Gen::is_col; - static constexpr bool is_xvec = Gen::is_xvec; - - arma_aligned const Mat Q; - - inline explicit Proxy(const Gen& A) - : Q(A) - { - arma_extra_debug_sigprint(); - } - - arma_inline uword get_n_rows() const { return (is_row ? 1 : Q.n_rows); } - 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 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 - 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< Gen > - { - 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 = Gen::is_row; - static constexpr bool is_col = Gen::is_col; - static constexpr bool is_xvec = Gen::is_xvec; - - arma_aligned const Mat Q; - - inline explicit Proxy(const Gen& A) - : Q(A) - { - arma_extra_debug_sigprint(); - } - - arma_inline uword get_n_rows() const { return (is_row ? 1 : Q.n_rows); } - 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 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 - 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()); } + constexpr bool is_aligned() const { return Gen::is_simple; } }; @@ -1011,6 +917,53 @@ 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< SpToDGlue > + { + 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 = SpToDGlue::is_row; + static constexpr bool is_col = SpToDGlue::is_col; + static constexpr bool is_xvec = SpToDGlue::is_xvec; + + arma_aligned const Mat Q; + + inline explicit Proxy(const SpToDGlue& A) + : Q(A) + { + arma_extra_debug_sigprint(); + } + + arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; } + 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 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 constexpr bool is_alias(const Mat&) const { return false; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Row_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Row_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Row_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Row_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -67,6 +67,9 @@ inline Row(Row&& m); inline Row& operator=(Row&& m); + // inline Row(Mat&& m); + // inline Row& operator=(Mat&& m); + inline Row& operator=(const eT val); inline Row& operator=(const Row& X); @@ -88,13 +91,13 @@ inline Row(const subview_cube& X); inline Row& operator=(const subview_cube& X); - arma_cold inline mat_injector operator<<(const eT val); + arma_frown("use braced initialiser list instead") inline mat_injector operator<<(const eT val); - 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_warn_unused arma_inline const Op,op_htrans> t() const; + arma_warn_unused arma_inline const Op,op_htrans> ht() const; + arma_warn_unused arma_inline const Op,op_strans> st() const; - arma_inline arma_warn_unused const Op,op_strans> as_col() const; + arma_warn_unused arma_inline 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; @@ -138,15 +141,17 @@ template inline void shed_cols(const Base& indices); - inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero = true); + arma_deprecated inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero); + inline void insert_cols(const uword col_num, const uword N); + template inline void insert_cols(const uword col_num, const Base& X); - arma_inline arma_warn_unused eT& at(const uword i); - arma_inline arma_warn_unused const eT& at(const uword i) const; + arma_warn_unused arma_inline eT& at(const uword i); + arma_warn_unused arma_inline const eT& at(const uword i) const; - arma_inline arma_warn_unused eT& at(const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& at(const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline eT& at(const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& at(const uword in_row, const uword in_col) const; typedef eT* row_iterator; @@ -169,7 +174,7 @@ public: - #ifdef ARMA_EXTRA_ROW_PROTO + #if defined(ARMA_EXTRA_ROW_PROTO) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_ROW_PROTO) #endif }; @@ -235,30 +240,30 @@ template inline Row& operator=(const eGlue& X); #endif - 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; - - arma_inline arma_warn_unused eT& operator[] (const uword i); - arma_inline arma_warn_unused const eT& operator[] (const uword i) const; - arma_inline arma_warn_unused eT& at (const uword i); - arma_inline arma_warn_unused const eT& at (const uword i) const; - arma_inline arma_warn_unused eT& operator() (const uword i); - arma_inline arma_warn_unused const eT& operator() (const uword i) const; - - arma_inline arma_warn_unused eT& at (const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& at (const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col); - arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col) const; - - arma_inline arma_warn_unused eT* memptr(); - arma_inline arma_warn_unused const eT* memptr() const; - - arma_hot inline const Row& fill(const eT val); - arma_hot inline const Row& zeros(); - arma_hot inline const Row& ones(); + arma_warn_unused arma_inline const Op< Row_fixed_type, op_htrans > t() const; + arma_warn_unused arma_inline const Op< Row_fixed_type, op_htrans > ht() const; + arma_warn_unused arma_inline const Op< Row_fixed_type, op_strans > st() const; + + arma_warn_unused arma_inline const eT& at_alt (const uword i) const; + + arma_warn_unused arma_inline eT& operator[] (const uword i); + arma_warn_unused arma_inline const eT& operator[] (const uword i) const; + arma_warn_unused arma_inline eT& at (const uword i); + arma_warn_unused arma_inline const eT& at (const uword i) const; + arma_warn_unused arma_inline eT& operator() (const uword i); + arma_warn_unused arma_inline const eT& operator() (const uword i) const; + + arma_warn_unused arma_inline eT& at (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& at (const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col); + arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const; + + arma_warn_unused arma_inline eT* memptr(); + arma_warn_unused arma_inline const eT* memptr() const; + + inline const Row& fill(const eT val); + inline const Row& zeros(); + inline const Row& ones(); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/Row_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/Row_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/Row_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/Row_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -51,12 +51,11 @@ { arma_extra_debug_sigprint(); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Row::constructor: zeroing memory"); arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); } - #endif } @@ -70,12 +69,11 @@ Mat::init_warm(in_n_rows, in_n_cols); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Row::constructor: zeroing memory"); arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); } - #endif } @@ -89,12 +87,11 @@ Mat::init_warm(s.n_rows, s.n_cols); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Row::constructor: zeroing memory"); arrayops::fill_zeros(Mat::memptr(), Mat::n_elem); } - #endif } @@ -314,10 +311,9 @@ { arma_extra_debug_sigprint_this(this); - if(x.size() > 0) - { - arrayops::copy( Mat::memptr(), &(x[0]), uword(x.size()) ); - } + const uword N = uword(x.size()); + + if(N > 0) { arrayops::copy( Mat::memptr(), &(x[0]), N ); } } @@ -330,12 +326,11 @@ { arma_extra_debug_sigprint(); - Mat::init_warm(1, uword(x.size())); + const uword N = uword(x.size()); - if(x.size() > 0) - { - arrayops::copy( Mat::memptr(), &(x[0]), uword(x.size()) ); - } + Mat::init_warm(1, N); + + if(N > 0) { arrayops::copy( Mat::memptr(), &(x[0]), N ); } return *this; } @@ -345,11 +340,13 @@ template inline Row::Row(const std::initializer_list& list) - : Mat(arma_vec_indicator(), 2) + : Mat(arma_vec_indicator(), 1, uword(list.size()), 2) { - arma_extra_debug_sigprint(); + arma_extra_debug_sigprint_this(this); - (*this).operator=(list); + const uword N = uword(list.size()); + + if(N > 0) { arrayops::copy( Mat::memptr(), list.begin(), N ); } } @@ -361,14 +358,11 @@ { arma_extra_debug_sigprint(); - Mat tmp(list); + const uword N = uword(list.size()); - arma_debug_check( ((tmp.n_elem > 0) && (tmp.is_vec() == false)), "Mat::init(): requested size is not compatible with row vector layout" ); + Mat::init_warm(1, N); - access::rw(tmp.n_rows) = 1; - access::rw(tmp.n_cols) = tmp.n_elem; - - (*this).steal_mem(tmp); + if(N > 0) { arrayops::copy( Mat::memptr(), list.begin(), N ); } return *this; } @@ -424,21 +418,71 @@ { arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); - (*this).steal_mem(X); - - if( (X.mem_state == 0) && (X.n_alloc <= 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) = nullptr; - } + (*this).steal_mem(X, true); return *this; } +// template +// inline +// Row::Row(Mat&& X) +// : Mat(arma_vec_indicator(), 2) +// { +// arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); +// +// if(X.n_rows != 1) { const Mat& XX = X; Mat::operator=(XX); return; } +// +// 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_cols) = 0; +// access::rw(X.n_elem) = 0; +// access::rw(X.n_alloc) = 0; +// access::rw(X.mem_state) = 0; +// access::rw(X.mem) = nullptr; +// } +// else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3) +// { +// (*this).init_cold(); +// +// arrayops::copy( (*this).memptr(), X.mem, X.n_elem ); +// +// if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) +// { +// access::rw(X.n_cols) = 0; +// access::rw(X.n_elem) = 0; +// access::rw(X.mem) = nullptr; +// } +// } +// } +// +// +// +// template +// inline +// Row& +// Row::operator=(Mat&& X) +// { +// arma_extra_debug_sigprint(arma_str::format("this = %x X = %x") % this % &X); +// +// if(X.n_rows != 1) { const Mat& XX = X; Mat::operator=(XX); return *this; } +// +// (*this).steal_mem(X, true); +// +// return *this; +// } + + + template inline Row& @@ -625,7 +669,6 @@ template inline -arma_cold mat_injector< Row > Row::operator<<(const eT val) { @@ -636,7 +679,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> Row::t() const { @@ -647,7 +689,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> Row::ht() const { @@ -658,7 +699,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> Row::st() const { @@ -669,7 +709,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> Row::as_col() const { @@ -1068,8 +1107,6 @@ -//! insert N cols at the specified col position, -//! optionally setting the elements of the inserted cols to zero template inline void @@ -1077,6 +1114,20 @@ { arma_extra_debug_sigprint(); + arma_ignore(set_to_zero); + + (*this).insert_cols(col_num, N); + } + + + +template +inline +void +Row::insert_cols(const uword col_num, const uword N) + { + arma_extra_debug_sigprint(); + const uword t_n_cols = Mat::n_cols; const uword A_n_cols = col_num; @@ -1085,30 +1136,26 @@ // insertion at col_num == n_cols is in effect an append operation arma_debug_check_bounds( (col_num > t_n_cols), "Row::insert_cols(): index out of bounds" ); - if(N > 0) + if(N == 0) { return; } + + Row out(t_n_cols + N, arma_nozeros_indicator()); + + eT* out_mem = out.memptr(); + const eT* t_mem = (*this).memptr(); + + if(A_n_cols > 0) { - Row out(t_n_cols + N, arma_nozeros_indicator()); - - eT* out_mem = out.memptr(); - const eT* t_mem = (*this).memptr(); - - if(A_n_cols > 0) - { - arrayops::copy( out_mem, t_mem, A_n_cols ); - } - - if(B_n_cols > 0) - { - arrayops::copy( &(out_mem[col_num + N]), &(t_mem[col_num]), B_n_cols ); - } - - if(set_to_zero) - { - arrayops::inplace_set( &(out_mem[col_num]), eT(0), N ); - } - - Mat::steal_mem(out); + arrayops::copy( out_mem, t_mem, A_n_cols ); + } + + if(B_n_cols > 0) + { + arrayops::copy( &(out_mem[col_num + N]), &(t_mem[col_num]), B_n_cols ); } + + arrayops::fill_zeros( &(out_mem[col_num]), N ); + + Mat::steal_mem(out); } @@ -1130,7 +1177,6 @@ template arma_inline -arma_warn_unused eT& Row::at(const uword i) { @@ -1141,7 +1187,6 @@ template arma_inline -arma_warn_unused const eT& Row::at(const uword i) const { @@ -1152,7 +1197,6 @@ template arma_inline -arma_warn_unused eT& Row::at(const uword, const uword in_col) { @@ -1163,7 +1207,6 @@ template arma_inline -arma_warn_unused const eT& Row::at(const uword, const uword in_col) const { @@ -1236,7 +1279,7 @@ { arma_extra_debug_sigprint_this(this); - #if (!defined(ARMA_DONT_ZERO_INIT)) + if(arma_config::zero_init) { arma_extra_debug_print("Row::fixed::constructor: zeroing memory"); @@ -1244,7 +1287,6 @@ arrayops::inplace_set_fixed( mem_use, eT(0) ); } - #endif } @@ -1585,7 +1627,6 @@ template template arma_inline -arma_warn_unused const Op< typename Row::template fixed::Row_fixed_type, op_htrans > Row::fixed::t() const { @@ -1597,7 +1638,6 @@ template template arma_inline -arma_warn_unused const Op< typename Row::template fixed::Row_fixed_type, op_htrans > Row::fixed::ht() const { @@ -1609,7 +1649,6 @@ template template arma_inline -arma_warn_unused const Op< typename Row::template fixed::Row_fixed_type, op_strans > Row::fixed::st() const { @@ -1621,7 +1660,6 @@ template template arma_inline -arma_warn_unused const eT& Row::fixed::at_alt(const uword ii) const { @@ -1643,7 +1681,6 @@ template template arma_inline -arma_warn_unused eT& Row::fixed::operator[] (const uword ii) { @@ -1655,7 +1692,6 @@ template template arma_inline -arma_warn_unused const eT& Row::fixed::operator[] (const uword ii) const { @@ -1667,7 +1703,6 @@ template template arma_inline -arma_warn_unused eT& Row::fixed::at(const uword ii) { @@ -1679,7 +1714,6 @@ template template arma_inline -arma_warn_unused const eT& Row::fixed::at(const uword ii) const { @@ -1691,7 +1725,6 @@ template template arma_inline -arma_warn_unused eT& Row::fixed::operator() (const uword ii) { @@ -1705,7 +1738,6 @@ template template arma_inline -arma_warn_unused const eT& Row::fixed::operator() (const uword ii) const { @@ -1719,7 +1751,6 @@ template template arma_inline -arma_warn_unused eT& Row::fixed::at(const uword, const uword in_col) { @@ -1731,7 +1762,6 @@ template template arma_inline -arma_warn_unused const eT& Row::fixed::at(const uword, const uword in_col) const { @@ -1743,7 +1773,6 @@ template template arma_inline -arma_warn_unused eT& Row::fixed::operator() (const uword in_row, const uword in_col) { @@ -1757,7 +1786,6 @@ template template arma_inline -arma_warn_unused const eT& Row::fixed::operator() (const uword in_row, const uword in_col) const { @@ -1771,7 +1799,6 @@ template template arma_inline -arma_warn_unused eT* Row::fixed::memptr() { @@ -1783,7 +1810,6 @@ template template arma_inline -arma_warn_unused const eT* Row::fixed::memptr() const { @@ -1794,7 +1820,6 @@ template template -arma_hot inline const Row& Row::fixed::fill(const eT val) @@ -1812,7 +1837,6 @@ template template -arma_hot inline const Row& Row::fixed::zeros() @@ -1830,7 +1854,6 @@ template template -arma_hot inline const Row& Row::fixed::ones() @@ -1856,7 +1879,7 @@ -#ifdef ARMA_EXTRA_ROW_MEAT +#if defined(ARMA_EXTRA_ROW_MEAT) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_ROW_MEAT) #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_vec_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/running_stat_vec_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_vec_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/running_stat_vec_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -64,8 +64,8 @@ inline running_stat_vec& operator=(const running_stat_vec& in_rsv); - template arma_hot inline void operator() (const Base< T, T1>& X); - template arma_hot inline void operator() (const Base, T1>& X); + template inline void operator() (const Base< T, T1>& X); + template inline void operator() (const Base, T1>& X); inline void reset(); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_vec_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/running_stat_vec_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/running_stat_vec_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/running_stat_vec_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -84,7 +84,6 @@ //! update statistics to reflect new sample template template -arma_hot inline void running_stat_vec::operator() (const Base::T, T1>& X) @@ -99,7 +98,7 @@ return; } - if( sample.is_finite() == false ) + if( sample.internal_has_nonfinite() ) { arma_debug_warn_level(3, "running_stat_vec: sample ignored as it has non-finite elements"); return; @@ -112,7 +111,6 @@ template template -arma_hot inline void running_stat_vec::operator() (const Base< std::complex::T>, T1>& X) @@ -128,7 +126,7 @@ return; } - if( sample.is_finite() == false ) + if( sample.internal_has_nonfinite() ) { arma_debug_warn_level(3, "running_stat_vec: sample ignored as it has non-finite elements"); return; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/sp_auxlib_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/sp_auxlib_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/sp_auxlib_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/sp_auxlib_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -86,12 +86,6 @@ 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 @@ -134,7 +128,7 @@ inline static void run_aupd_plain ( const uword n_eigvals, char* which, - const SpMat& X, const bool sym, + const SpMat& X, const SpMat& Xst, 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, @@ -215,15 +209,47 @@ public: inline ~superlu_array_wrangler(); + inline superlu_array_wrangler(); inline superlu_array_wrangler(const uword n_elem); - inline superlu_array_wrangler() = delete; + inline void set_size(const uword n_elem); + inline void reset(); + inline superlu_array_wrangler(const superlu_array_wrangler&) = delete; inline void operator= (const superlu_array_wrangler&) = delete; inline eT* get_ptr(); }; + +template +class superlu_worker + { + private: + + bool factorisation_valid = false; + + superlu_supermatrix_wrangler* l = nullptr; + superlu_supermatrix_wrangler* u = nullptr; + + superlu_array_wrangler perm_c; + superlu_array_wrangler perm_r; + + superlu_stat_wrangler stat; + + public: + + inline ~superlu_worker(); + inline superlu_worker(); + + inline bool factorise(typename get_pod_type::result& out_rcond, const SpMat& A, const superlu_opts& user_opts); + + inline bool solve(Mat& X, const Mat& B); + + inline superlu_worker(const superlu_worker&) = delete; + inline void operator= (const superlu_worker&) = delete; + }; + #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/sp_auxlib_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/sp_auxlib_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/sp_auxlib_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/sp_auxlib_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -73,6 +73,12 @@ if(is_cx::yes) { arma_debug_warn_level(1, "eigs_sym(): given matrix is not hermitian"); } } + if(arma_config::check_nonfinite && U.M.internal_has_nonfinite()) + { + arma_debug_warn_level(3, "eigs_sym(): detected non-finite elements"); + return false; + } + // 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) @@ -120,6 +126,12 @@ if(is_cx::yes) { arma_debug_warn_level(1, "eigs_sym(): given matrix is not hermitian"); } } + if(arma_config::check_nonfinite && U.M.internal_has_nonfinite()) + { + arma_debug_warn_level(3, "eigs_sym(): detected non-finite elements"); + return false; + } + #if (defined(ARMA_USE_NEWARP) && defined(ARMA_USE_SUPERLU)) { return sp_auxlib::eigs_sym_newarp(eigval, eigvec, U.M, n_eigvals, sigma, opts); @@ -467,7 +479,9 @@ } 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); + const SpMat Xst = X.st(); + + run_aupd_plain(n_eigvals, which, X, Xst, true /* sym, not gen */, n, tol, maxiter, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); } if(info != 0) { return false; } @@ -479,11 +493,11 @@ char howmny = 'A'; char bmat = 'I'; // We are considering the standard eigenvalue problem. - podarray select(ncv); // Logical array of dimension NCV. + podarray select(ncv, arma_zeros_indicator()); // Logical array of dimension NCV. blas_int ldz = n; // seupd() will output directly into the eigval and eigvec objects. - eigval.zeros(n_eigvals); + eigval.zeros( n_eigvals); eigvec.zeros(n, n_eigvals); 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); @@ -522,6 +536,12 @@ arma_debug_check( (U.M.is_square() == false), "eigs_gen(): given matrix must be square sized" ); + if(arma_config::check_nonfinite && U.M.internal_has_nonfinite()) + { + arma_debug_warn_level(3, "eigs_gen(): detected non-finite elements"); + return false; + } + // 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) @@ -563,6 +583,12 @@ arma_debug_check( (U.M.is_square() == false), "eigs_gen(): given matrix must be square sized" ); + if(arma_config::check_nonfinite && U.M.internal_has_nonfinite()) + { + arma_debug_warn_level(3, "eigs_gen(): detected non-finite elements"); + return false; + } + #if (defined(ARMA_USE_ARPACK) && defined(ARMA_USE_SUPERLU)) { constexpr form_type form_val = form_sigma; @@ -839,11 +865,13 @@ } 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); + const SpMat Xst = X.st(); + + run_aupd_plain(n_eigvals, which, X, Xst, 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 = blas_int(n_eigvals); @@ -851,16 +879,13 @@ 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' - blas_int ldz = n; - podarray workev(3 * ncv); + podarray select(ncv, arma_zeros_indicator()); // logical array of dimension NCV + podarray dr(nev + 1, arma_zeros_indicator()); // real array of dimension NEV + 1 + podarray di(nev + 1, arma_zeros_indicator()); // real array of dimension NEV + 1 + podarray z(n * (nev + 1), arma_zeros_indicator()); // real N by NEV array if HOWMNY = 'A' + podarray workev(3 * ncv, arma_zeros_indicator()); - dr.zeros(); - di.zeros(); - z.zeros(); + blas_int ldz = n; 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); @@ -940,6 +965,12 @@ arma_debug_check( (U.M.is_square() == false), "eigs_gen(): given matrix must be square sized" ); + if(arma_config::check_nonfinite && U.M.internal_has_nonfinite()) + { + arma_debug_warn_level(3, "eigs_gen(): detected non-finite elements"); + return false; + } + constexpr std::complex sigma = T(0); return sp_auxlib::eigs_gen(eigval, eigvec, U.M, n_eigvals, form_val, sigma, opts); @@ -959,6 +990,12 @@ arma_debug_check( (U.M.is_square() == false), "eigs_gen(): given matrix must be square sized" ); + if(arma_config::check_nonfinite && U.M.internal_has_nonfinite()) + { + arma_debug_warn_level(3, "eigs_gen(): detected non-finite elements"); + return false; + } + #if (defined(ARMA_USE_ARPACK) && defined(ARMA_USE_SUPERLU)) { constexpr form_type form_val = form_sigma; @@ -1072,7 +1109,9 @@ } 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); + const SpMat< std::complex > Xst = X.st(); + + run_aupd_plain(n_eigvals, which, X, Xst, false /* gen, not sym */, n, tol, maxiter, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); } if(info != 0) { return false; } @@ -1084,11 +1123,12 @@ 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); // complex array of dimension NEV + 1 - podarray> z(n * nev); // complex N by NEV array if HOWMNY = 'A' + podarray select(ncv, arma_zeros_indicator()); // logical array of dimension NCV + podarray> d(nev + 1, arma_zeros_indicator()); // complex array of dimension NEV + 1 + podarray> z(n * nev, arma_zeros_indicator()); // complex N by NEV array if HOWMNY = 'A' + podarray> workev(2 * ncv, arma_zeros_indicator()); + blas_int ldz = n; - podarray> workev(2 * ncv); // Prepare the outputs; neupd() will write directly to them. eigval.zeros(n_eigvals); @@ -1111,7 +1151,7 @@ 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; } @@ -1139,21 +1179,14 @@ X = B_expr.get_ref(); // superlu::gssv() uses X as input (the B matrix) and as output (the solution) - if(A.n_rows > A.n_cols) - { - arma_stop_logic_error("spsolve(): solving over-determined systems currently not supported"); - X.soft_reset(); - return false; - } - else - if(A.n_rows < A.n_cols) + if(A.is_square() == false) { - arma_stop_logic_error("spsolve(): solving under-determined systems currently not supported"); X.soft_reset(); + arma_stop_logic_error("spsolve(): solving under-determined / over-determined systems is currently not supported"); return false; } - arma_debug_check( (A.n_rows != X.n_rows), "spsolve(): number of rows in the given objects must be the same" ); + arma_debug_check( (A.n_rows != X.n_rows), "spsolve(): number of rows in the given objects must be the same", [&](){ X.soft_reset(); } ); if(A.is_empty() || X.is_empty()) { @@ -1163,6 +1196,12 @@ if(A.n_nonzero == uword(0)) { X.soft_reset(); return false; } + if(arma_config::check_nonfinite && (A.internal_has_nonfinite() || X.internal_has_nonfinite())) + { + arma_debug_warn_level(3, "spsolve(): detected non-finite elements"); + return false; + } + if(arma_config::debug) { bool overflow = false; @@ -1214,7 +1253,7 @@ else if(info > int(A.n_cols)) { - arma_debug_warn_level(1, "spsolve(): memory allocation failure: could not allocate ", (info - int(A.n_cols)), " bytes"); + arma_debug_warn_level(1, "spsolve(): memory allocation failure"); } else if(info < 0) @@ -1267,31 +1306,27 @@ const Mat& B = (B_is_modified) ? B_copy : B_unwrap; - if(A.n_rows > A.n_cols) + if(A.is_square() == false) { - arma_stop_logic_error("spsolve(): solving over-determined systems currently not supported"); - X.soft_reset(); - return false; - } - else - if(A.n_rows < A.n_cols) - { - arma_stop_logic_error("spsolve(): solving under-determined systems currently not supported"); X.soft_reset(); + arma_stop_logic_error("spsolve(): solving under-determined / over-determined systems is currently not supported"); return false; } - arma_debug_check( (A.n_rows != B.n_rows), "spsolve(): number of rows in the given objects must be the same" ); + arma_debug_check( (A.n_rows != B.n_rows), "spsolve(): number of rows in the given objects must be the same", [&](){ X.soft_reset(); } ); X.zeros(A.n_cols, B.n_cols); // set the elements to zero, as we don't trust the SuperLU spaghetti code - if(A.is_empty() || B.is_empty()) - { - return true; - } + if(A.is_empty() || B.is_empty()) { return true; } if(A.n_nonzero == uword(0)) { X.soft_reset(); return false; } + if(arma_config::check_nonfinite && (A.internal_has_nonfinite() || B.internal_has_nonfinite())) + { + arma_debug_warn_level(3, "spsolve(): detected non-finite elements"); + return false; + } + if(arma_config::debug) { bool overflow; @@ -1336,20 +1371,20 @@ superlu_array_wrangler berr(B.n_cols+1); superlu::GlobalLU_t glu; - arrayops::inplace_set(reinterpret_cast(&glu), char(0), sizeof(superlu::GlobalLU_t)); + arrayops::fill_zeros(reinterpret_cast(&glu), sizeof(superlu::GlobalLU_t)); superlu::mem_usage_t mu; - arrayops::inplace_set(reinterpret_cast(&mu), char(0), sizeof(superlu::mem_usage_t)); + arrayops::fill_zeros(reinterpret_cast(&mu), sizeof(superlu::mem_usage_t)); superlu_stat_wrangler stat; - char equed[8]; // extra characters for paranoia - T rpg = T(0); - T rcond = T(0); - int info = int(0); // Return code. + char equed[8] = {}; // extra characters for paranoia + T rpg = T(0); + T rcond = T(0); + int info = int(0); // Return code. - char work[8]; - int lwork = int(0); // 0 means superlu will allocate memory + char work[8] = {}; + int lwork = int(0); // 0 means superlu will allocate memory arma_extra_debug_print("superlu::gssvx()"); 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); @@ -1376,7 +1411,7 @@ else if(info > int(A.n_cols+1)) { - arma_debug_warn_level(1, "spsolve(): memory allocation failure: could not allocate ", (info - int(A.n_cols)), " bytes"); + arma_debug_warn_level(1, "spsolve(): memory allocation failure"); } else if(info < 0) @@ -1405,79 +1440,6 @@ -// 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 @@ -1489,6 +1451,7 @@ char norm_id = '1'; + arma_extra_debug_print("superlu::langs()"); return superlu::langs(&norm_id, A); } @@ -1509,6 +1472,7 @@ superlu_stat_wrangler stat; + arma_extra_debug_print("superlu::gscon()"); superlu::gscon(&norm_id, L, U, norm_val, &rcond_out, stat.get_ptr(), &info); return (info == 0) ? T(rcond_out) : T(0); @@ -1678,10 +1642,10 @@ 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 ); + arma_extra_debug_print( arma_str::format("A.n_nonzero: %u") % A.n_nonzero ); + arma_extra_debug_print( arma_str::format("n_nonzero_diag_old: %u") % n_nonzero_diag_old ); + arma_extra_debug_print( arma_str::format("n_nonzero_diag_new: %u") % n_nonzero_diag_new ); + arma_extra_debug_print( arma_str::format("out_n_nonzero: %u") % out_n_nonzero ); nc->nnz = out_n_nonzero; nc->nzval = (void*) superlu::malloc(sizeof(eT) * out_n_nonzero ); @@ -1773,7 +1737,7 @@ nc->colptr[j + 1] = superlu::int_t(nc->colptr[j] + nnz_col); } - arma_extra_debug_print( arma_str::format("count: %d") % count ); + arma_extra_debug_print( arma_str::format("count: %u") % count ); arma_check( (count != out_n_nonzero), "internal error: sp_auxlib::copy_to_supermatrix_with_shift(): count != out_n_nonzero" ); @@ -1804,6 +1768,9 @@ // arma_debug_check( (type_matched == false), "copy_to_spmat(): type mismatch" ); // arma_debug_check( (A.Mtype != superlu::SLU_GE), "copy_to_spmat(): unknown layout" ); // +// // NOTE: the l and u instances of SuperMatrix resulting from superlu::gstrf() +// // NOTE: do not have the superlu::SLU_GE layout +// // const superlu::NCformat* nc = (const superlu::NCformat*)(A.Store); // // if(nc == nullptr) { out.reset(); return; } @@ -1822,6 +1789,8 @@ // // 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); +// +// out.remove_zeros(); // in case SuperLU has bugs and stores zeros in sparse matrices // } @@ -1930,7 +1899,7 @@ sp_auxlib::run_aupd_plain ( const uword n_eigvals, char* which, - const SpMat& X, const bool sym, + const SpMat& X, const SpMat& Xst, 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, @@ -1952,7 +1921,7 @@ n = X.n_rows; // The size of the matrix (should already be set outside). blas_int nev = n_eigvals; - resid.set_size(n); + resid.zeros(n); // Two contraints on NCV: (NCV > NEV) for sym problems or // (NCV > NEV + 2) for gen problems and (NCV <= N) @@ -1965,8 +1934,8 @@ 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. + v.zeros(n * ncv); // Array N by NCV (output). + rwork.zeros(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. @@ -1976,16 +1945,16 @@ iparam(6) = 1; // Mode 1: A * x = lambda * x. // IPNTR: integer array of length 14 (output). - ipntr.set_size(14); + ipntr.zeros(14); // Real work array used in the basic Arnoldi iteration for reverse communication. - workd.set_size(3 * n); + workd.zeros(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); + workl.zeros(lworkl); info = 0; // Set to 0 initially to use random initial vector. @@ -2015,30 +1984,46 @@ // 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... + // // OLD METHOD + // + // // 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 */); + // + // out.zeros(); + // + // T* out_mem = out.memptr(); + // const T* in_mem = in.memptr(); + // + // typename SpMat::const_iterator X_it = X.begin(); + // + // const uword X_nnz = X.n_nonzero; + // + // for(uword count=0; count < X_nnz; ++count, ++X_it) + // { + // const eT X_it_val = (*X_it); + // const uword X_it_row = X_it.row(); + // const uword X_it_col = X_it.col(); + // + // out_mem[X_it_row] += X_it_val * in_mem[X_it_col]; + // } + // + // // No need to modify memory further since it was all done in-place. - // 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 */); - - out.zeros(); - typename SpMat::const_iterator X_it = X.begin(); - typename SpMat::const_iterator X_it_end = X.end(); + // NEW METHOD + // + // both operator*(rowvec, sp_mat) and operator*(sp_mat, colvec) can now write to an existing object - while(X_it != X_it_end) - { - 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; - } + Row out(workd.memptr() + ipntr(1) - 1, n, false, true); + Row in(workd.memptr() + ipntr(0) - 1, n, false, true); - // No need to modify memory further since it was all done in-place. + out = in * Xst; break; } @@ -2124,7 +2109,7 @@ n = X.n_rows; // The size of the matrix (should already be set outside). blas_int nev = n_eigvals; - resid.set_size(n); + resid.zeros(n); // Two contraints on NCV: (NCV > NEV) for sym problems or // (NCV > NEV + 2) for gen problems and (NCV <= N) @@ -2137,8 +2122,8 @@ 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. + v.zeros(n * ncv); // Array N by NCV (output). + rwork.zeros(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. @@ -2151,16 +2136,16 @@ 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); + ipntr.zeros(14); // Real work array used in the basic Arnoldi iteration for reverse communication. - workd.set_size(3 * n); + workd.zeros(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); + workl.zeros(lworkl); info = 0; // Set to 0 initially to use random initial vector. @@ -2234,6 +2219,7 @@ return; } + // NOTE: potential problem with inconsistent/mismatched use of eT and T types 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); @@ -2270,9 +2256,6 @@ // 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 */); @@ -2541,19 +2524,36 @@ { arma_extra_debug_sigprint_this(this); - if(mem != nullptr) - { - superlu::free(mem); - mem = nullptr; - } + (*this).reset(); + } + +template +inline +superlu_array_wrangler::superlu_array_wrangler() + : mem(nullptr) + { + arma_extra_debug_sigprint_this(this); } template inline superlu_array_wrangler::superlu_array_wrangler(const uword n_elem) + : mem(nullptr) { arma_extra_debug_sigprint_this(this); + (*this).set_size(n_elem); + } + +template +inline +void +superlu_array_wrangler::set_size(const uword n_elem) + { + arma_extra_debug_sigprint(); + + if(mem != nullptr) { (*this).reset(); } + mem = (eT*)(superlu::malloc(n_elem * sizeof(eT))); arma_check_bad_alloc( (mem == nullptr), "superlu::malloc(): out of memory" ); @@ -2563,12 +2563,166 @@ template inline +void +superlu_array_wrangler::reset() + { + arma_extra_debug_sigprint(); + + if(mem != nullptr) + { + superlu::free(mem); + mem = nullptr; + } + } + +template +inline eT* superlu_array_wrangler::get_ptr() { return mem; } + +// + + +template +inline +superlu_worker::~superlu_worker() + { + arma_extra_debug_sigprint_this(this); + + if(l != nullptr) { delete l; l = nullptr; } + if(u != nullptr) { delete u; u = nullptr; } + } + + +template +inline +superlu_worker::superlu_worker() + { + arma_extra_debug_sigprint_this(this); + } + + +template +inline +bool +superlu_worker::factorise(typename get_pod_type::result& out_rcond, const SpMat& A, const superlu_opts& user_opts) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + factorisation_valid = false; + + if(l != nullptr) { delete l; l = nullptr; } + if(u != nullptr) { delete u; u = nullptr; } + + l = new(std::nothrow) superlu_supermatrix_wrangler; + u = new(std::nothrow) superlu_supermatrix_wrangler; + + if( (l == nullptr) || (u == nullptr) ) + { + arma_debug_warn_level(3, "superlu_worker()::factorise(): could not construct SuperLU matrix"); + return false; + } + + superlu_supermatrix_wrangler& l_ref = (*l); + superlu_supermatrix_wrangler& u_ref = (*u); + + superlu::superlu_options_t options; + sp_auxlib::set_superlu_opts(options, user_opts); + + superlu_supermatrix_wrangler AA; + superlu_supermatrix_wrangler AAc; + + const bool status_AA = sp_auxlib::copy_to_supermatrix(AA.get_ref(), A); + + if(status_AA == false) + { + arma_debug_warn_level(3, "superlu_worker()::factorise(): could not construct SuperLU matrix"); + return false; + } + + (*this).perm_c.set_size(A.n_cols+1); // paranoia: increase array length by 1 + (*this).perm_r.set_size(A.n_rows+1); + + superlu_array_wrangler etree(A.n_cols+1); + + superlu::GlobalLU_t Glu; + arrayops::fill_zeros(reinterpret_cast(&Glu), sizeof(superlu::GlobalLU_t)); + + int panel_size = superlu::sp_ispec_environ(1); + int relax = superlu::sp_ispec_environ(2); + int lwork = 0; + int info = 0; + + arma_extra_debug_print("superlu::superlu::get_permutation_c()"); + superlu::get_permutation_c(options.ColPerm, AA.get_ptr(), perm_c.get_ptr()); + + arma_extra_debug_print("superlu::superlu::sp_preorder_mat()"); + superlu::sp_preorder_mat(&options, AA.get_ptr(), perm_c.get_ptr(), etree.get_ptr(), AAc.get_ptr()); + + arma_extra_debug_print("superlu::gstrf()"); + superlu::gstrf(&options, AAc.get_ptr(), relax, panel_size, etree.get_ptr(), NULL, lwork, perm_c.get_ptr(), perm_r.get_ptr(), l_ref.get_ptr(), u_ref.get_ptr(), &Glu, stat.get_ptr(), &info); + + if(info != 0) + { + arma_debug_warn_level(3, "superlu_worker()::factorise(): LU factorisation failed"); + return false; + } + + const T AA_norm = sp_auxlib::norm1(AA.get_ptr()); + const T AA_rcond = sp_auxlib::lu_rcond(l_ref.get_ptr(), u_ref.get_ptr(), AA_norm); + + out_rcond = AA_rcond; + + if(arma_isnan(AA_rcond)) { return false; } + // if(AA_rcond == T(0)) { return false; } + + factorisation_valid = true; + + return true; + } + + +template +inline +bool +superlu_worker::solve(Mat& X, const Mat& B) + { + arma_extra_debug_sigprint(); + + if(factorisation_valid == false) { return false; } + if( (l == nullptr) || (u == nullptr) ) { return false; } + + superlu_supermatrix_wrangler& l_ref = (*l); + superlu_supermatrix_wrangler& u_ref = (*u); + + X = B; + + superlu_supermatrix_wrangler XX; + + const bool status_XX = sp_auxlib::wrap_to_supermatrix(XX.get_ref(), X); + + if(status_XX == false) + { + arma_debug_warn_level(3, "superlu_worker()::solve(): could not construct SuperLU matrix"); + return false; + } + + superlu::trans_t trans = superlu::NOTRANS; + int info = 0; + + arma_extra_debug_print("superlu::gstrs()"); + superlu::gstrs(trans, l_ref.get_ptr(), u_ref.get_ptr(), perm_c.get_ptr(), perm_r.get_ptr(), XX.get_ptr(), stat.get_ptr(), &info); + + return (info == 0); + } + + #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpBase_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpBase_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpBase_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpBase_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -24,14 +24,14 @@ template struct SpBase_eval_SpMat { - inline arma_warn_unused const derived& eval() const; + arma_warn_unused inline const derived& eval() const; }; template struct SpBase_eval_expr { - inline arma_warn_unused SpMat eval() const; //!< force the immediate evaluation of a delayed expression + arma_warn_unused inline SpMat eval() const; //!< force the immediate evaluation of a delayed expression }; @@ -54,9 +54,9 @@ arma_inline bool is_alias(const SpMat& X) const; - 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_warn_unused inline const SpOp t() const; //!< Hermitian transpose + arma_warn_unused inline const SpOp ht() const; //!< Hermitian transpose + arma_warn_unused inline 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; @@ -73,8 +73,8 @@ 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; + arma_warn_unused inline elem_type min() const; + arma_warn_unused inline elem_type max() const; inline elem_type min(uword& index_of_min_val) const; inline elem_type max(uword& index_of_max_val) const; @@ -82,31 +82,33 @@ inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const; inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const; - inline arma_warn_unused uword index_min() const; - inline arma_warn_unused uword index_max() const; + arma_warn_unused inline uword index_min() const; + arma_warn_unused inline uword index_max() const; - inline arma_warn_unused bool is_symmetric() const; - inline arma_warn_unused bool is_symmetric(const typename get_pod_type::result tol) const; + arma_warn_unused inline bool is_symmetric() const; + arma_warn_unused inline bool is_symmetric(const typename get_pod_type::result tol) const; - inline arma_warn_unused bool is_hermitian() const; - inline arma_warn_unused bool is_hermitian(const typename get_pod_type::result tol) const; + arma_warn_unused inline bool is_hermitian() const; + arma_warn_unused inline 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; - inline arma_warn_unused bool is_empty() const; - inline arma_warn_unused bool is_square() const; - inline arma_warn_unused bool is_vec() const; - inline arma_warn_unused bool is_colvec() const; - inline arma_warn_unused bool is_rowvec() const; - inline arma_warn_unused bool is_finite() const; - inline arma_warn_unused bool has_inf() const; - inline arma_warn_unused bool has_nan() const; + arma_warn_unused inline bool is_zero(const typename get_pod_type::result tol = 0) const; + + arma_warn_unused inline bool is_trimatu() const; + arma_warn_unused inline bool is_trimatl() const; + arma_warn_unused inline bool is_diagmat() const; + arma_warn_unused inline bool is_empty() const; + arma_warn_unused inline bool is_square() const; + arma_warn_unused inline bool is_vec() const; + arma_warn_unused inline bool is_colvec() const; + arma_warn_unused inline bool is_rowvec() const; + arma_warn_unused inline bool is_finite() const; + + arma_warn_unused inline bool has_inf() const; + arma_warn_unused inline bool has_nan() const; + arma_warn_unused inline bool has_nonfinite() const; - inline arma_warn_unused const SpOp as_col() const; - inline arma_warn_unused const SpOp as_row() const; + arma_warn_unused inline const SpOp as_col() const; + arma_warn_unused inline const SpOp as_row() const; }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpBase_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpBase_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpBase_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpBase_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -43,7 +43,6 @@ template inline -arma_warn_unused const SpOp SpBase::t() const { @@ -53,7 +52,6 @@ template inline -arma_warn_unused const SpOp SpBase::ht() const { @@ -64,7 +62,6 @@ template inline -arma_warn_unused const SpOp SpBase::st() const { @@ -74,7 +71,6 @@ template -arma_cold inline void SpBase::print(const std::string extra_text) const @@ -98,7 +94,6 @@ template -arma_cold inline void SpBase::print(std::ostream& user_stream, const std::string extra_text) const @@ -122,7 +117,6 @@ template -arma_cold inline void SpBase::raw_print(const std::string extra_text) const @@ -146,7 +140,6 @@ template -arma_cold inline void SpBase::raw_print(std::ostream& user_stream, const std::string extra_text) const @@ -170,7 +163,6 @@ template -arma_cold inline void SpBase::print_dense(const std::string extra_text) const @@ -194,7 +186,6 @@ template -arma_cold inline void SpBase::print_dense(std::ostream& user_stream, const std::string extra_text) const @@ -218,7 +209,6 @@ template -arma_cold inline void SpBase::raw_print_dense(const std::string extra_text) const @@ -242,7 +232,6 @@ template -arma_cold inline void SpBase::raw_print_dense(std::ostream& user_stream, const std::string extra_text) const @@ -266,7 +255,6 @@ template -arma_cold inline void SpBase::brief_print(const std::string extra_text) const @@ -290,7 +278,6 @@ template -arma_cold inline void SpBase::brief_print(std::ostream& user_stream, const std::string extra_text) const @@ -318,7 +305,6 @@ template inline -arma_warn_unused const derived& SpBase_eval_SpMat::eval() const { @@ -334,7 +320,6 @@ template inline -arma_warn_unused SpMat SpBase_eval_expr::eval() const { @@ -347,7 +332,6 @@ template inline -arma_warn_unused elem_type SpBase::min() const { @@ -358,7 +342,6 @@ template inline -arma_warn_unused elem_type SpBase::max() const { @@ -435,7 +418,6 @@ template inline -arma_warn_unused uword SpBase::index_min() const { @@ -459,7 +441,6 @@ template inline -arma_warn_unused uword SpBase::index_max() const { @@ -483,7 +464,6 @@ template inline -arma_warn_unused bool SpBase::is_symmetric() const { @@ -498,7 +478,6 @@ template inline -arma_warn_unused bool SpBase::is_symmetric(const typename get_pod_type::result tol) const { @@ -513,7 +492,6 @@ template inline -arma_warn_unused bool SpBase::is_hermitian() const { @@ -528,7 +506,6 @@ template inline -arma_warn_unused bool SpBase::is_hermitian(const typename get_pod_type::result tol) const { @@ -543,7 +520,6 @@ template inline -arma_warn_unused bool SpBase::is_zero(const typename get_pod_type::result tol) const { @@ -601,7 +577,6 @@ template inline -arma_warn_unused bool SpBase::is_trimatu() const { @@ -627,7 +602,6 @@ template inline -arma_warn_unused bool SpBase::is_trimatl() const { @@ -653,7 +627,6 @@ template inline -arma_warn_unused bool SpBase::is_diagmat() const { @@ -677,7 +650,6 @@ template inline -arma_warn_unused bool SpBase::is_empty() const { @@ -692,7 +664,6 @@ template inline -arma_warn_unused bool SpBase::is_square() const { @@ -707,7 +678,6 @@ template inline -arma_warn_unused bool SpBase::is_vec() const { @@ -724,7 +694,6 @@ template inline -arma_warn_unused bool SpBase::is_colvec() const { @@ -741,7 +710,6 @@ template inline -arma_warn_unused bool SpBase::is_rowvec() const { @@ -758,22 +726,23 @@ template inline -arma_warn_unused bool SpBase::is_finite() const { arma_extra_debug_sigprint(); - const SpProxy P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "is_finite(): detection of non-finite values is not reliable in fast math mode"); } if(is_SpMat::stored_type>::value) { - const unwrap_spmat::stored_type> U(P.Q); + const unwrap_spmat U( (*this).get_ref() ); - return U.M.is_finite(); + return U.M.internal_is_finite(); } else { + const SpProxy P( (*this).get_ref() ); + typename SpProxy::const_iterator_type it = P.begin(); typename SpProxy::const_iterator_type it_end = P.end(); @@ -791,22 +760,23 @@ template inline -arma_warn_unused bool SpBase::has_inf() const { arma_extra_debug_sigprint(); - const SpProxy P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_inf(): detection of non-finite values is not reliable in fast math mode"); } if(is_SpMat::stored_type>::value) { - const unwrap_spmat::stored_type> U(P.Q); + const unwrap_spmat U( (*this).get_ref() ); - return U.M.has_inf(); + return U.M.internal_has_inf(); } else { + const SpProxy P( (*this).get_ref() ); + typename SpProxy::const_iterator_type it = P.begin(); typename SpProxy::const_iterator_type it_end = P.end(); @@ -824,22 +794,23 @@ template inline -arma_warn_unused bool SpBase::has_nan() const { arma_extra_debug_sigprint(); - const SpProxy P( (*this).get_ref() ); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nan(): detection of non-finite values is not reliable in fast math mode"); } if(is_SpMat::stored_type>::value) { - const unwrap_spmat::stored_type> U(P.Q); + const unwrap_spmat U( (*this).get_ref() ); - return U.M.has_nan(); + return U.M.internal_has_nan(); } else { + const SpProxy P( (*this).get_ref() ); + typename SpProxy::const_iterator_type it = P.begin(); typename SpProxy::const_iterator_type it_end = P.end(); @@ -857,7 +828,40 @@ template inline -arma_warn_unused +bool +SpBase::has_nonfinite() const + { + arma_extra_debug_sigprint(); + + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nonfinite(): detection of non-finite values is not reliable in fast math mode"); } + + if(is_SpMat::stored_type>::value) + { + const unwrap_spmat U( (*this).get_ref() ); + + return U.M.internal_has_nonfinite(); + } + else + { + const SpProxy P( (*this).get_ref() ); + + typename SpProxy::const_iterator_type it = P.begin(); + typename SpProxy::const_iterator_type it_end = P.end(); + + while(it != it_end) + { + if(arma_isfinite(*it) == false) { return true; } + ++it; + } + } + + return false; + } + + + +template +inline const SpOp SpBase::as_col() const { @@ -868,7 +872,6 @@ template inline -arma_warn_unused const SpOp SpBase::as_row() const { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpCol_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpCol_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpCol_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpCol_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -56,9 +56,9 @@ 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; + arma_warn_unused inline const SpOp,spop_htrans> t() const; + arma_warn_unused inline const SpOp,spop_htrans> ht() const; + arma_warn_unused inline 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); @@ -76,7 +76,7 @@ inline const_row_iterator end_row (const uword row_num = 0) const; - #ifdef ARMA_EXTRA_SPCOL_PROTO + #if defined(ARMA_EXTRA_SPCOL_PROTO) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPCOL_PROTO) #endif }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpCol_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpCol_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpCol_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpCol_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -204,7 +204,6 @@ template inline -arma_warn_unused const SpOp,spop_htrans> SpCol::t() const { @@ -215,7 +214,6 @@ template inline -arma_warn_unused const SpOp,spop_htrans> SpCol::ht() const { @@ -226,7 +224,6 @@ template inline -arma_warn_unused const SpOp,spop_strans> SpCol::st() const { @@ -426,7 +423,7 @@ -#ifdef ARMA_EXTRA_SPCOL_MEAT +#if defined(ARMA_EXTRA_SPCOL_MEAT) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPCOL_MEAT) #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_merge_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_merge_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_merge_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_merge_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -26,16 +26,16 @@ public: template - arma_hot inline static void subview_merge(SpSubview& sv, const SpMat& B); + inline static void subview_merge(SpSubview& sv, const SpMat& B); template - arma_hot inline static void subview_merge(SpSubview& sv, const Mat& B); + inline static void subview_merge(SpSubview& sv, const Mat& B); template - arma_hot inline static void symmat_merge(SpMat& out, const SpMat& A, const SpMat& B); + inline static void symmat_merge(SpMat& out, const SpMat& A, const SpMat& B); template - arma_hot inline static void diagview_merge(SpMat& out, const SpMat& A, const SpMat& B); + inline static void diagview_merge(SpMat& out, const SpMat& A, const SpMat& B); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_merge_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_merge_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_merge_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_merge_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,7 +22,6 @@ template -arma_hot inline void spglue_merge::subview_merge(SpSubview& sv, const SpMat& B) @@ -195,7 +194,6 @@ template -arma_hot inline void spglue_merge::subview_merge(SpSubview& sv, const Mat& B) @@ -383,7 +381,6 @@ template -arma_hot inline void spglue_merge::symmat_merge(SpMat& out, const SpMat& A, const SpMat& B) @@ -468,7 +465,6 @@ template -arma_hot inline void spglue_merge::diagview_merge(SpMat& out, const SpMat& A, const SpMat& B) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_minus_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_minus_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_minus_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_minus_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -27,13 +27,13 @@ public: template - arma_hot inline static void apply(SpMat& out, const SpGlue& X); + inline static void apply(SpMat& out, const SpGlue& X); template - arma_hot inline static void apply_noalias(SpMat& result, const SpProxy& pa, const SpProxy& pb); + inline static void apply_noalias(SpMat& result, const SpProxy& pa, const SpProxy& pb); template - arma_hot inline static void apply_noalias(SpMat& out, const SpMat& A, const SpMat& B); + inline static void apply_noalias(SpMat& out, const SpMat& A, const SpMat& B); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_minus_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_minus_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_minus_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_minus_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,7 +22,6 @@ template -arma_hot inline void spglue_minus::apply(SpMat& out, const SpGlue& X) @@ -53,7 +52,6 @@ template -arma_hot inline void spglue_minus::apply_noalias(SpMat& out, const SpProxy& pa, const SpProxy& pb) @@ -160,7 +158,6 @@ template -arma_hot inline void spglue_minus::apply_noalias(SpMat& out, const SpMat& A, const SpMat& B) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_plus_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_plus_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_plus_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_plus_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -27,13 +27,13 @@ public: template - arma_hot inline static void apply(SpMat& out, const SpGlue& X); + inline static void apply(SpMat& out, const SpGlue& X); template - arma_hot inline static void apply_noalias(SpMat& out, const SpProxy& pa, const SpProxy& pb); + inline static void apply_noalias(SpMat& out, const SpProxy& pa, const SpProxy& pb); template - arma_hot inline static void apply_noalias(SpMat& out, const SpMat& A, const SpMat& B); + inline static void apply_noalias(SpMat& out, const SpMat& A, const SpMat& B); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_plus_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_plus_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_plus_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_plus_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,7 +22,6 @@ template -arma_hot inline void spglue_plus::apply(SpMat& out, const SpGlue& X) @@ -53,7 +52,6 @@ template -arma_hot inline void spglue_plus::apply_noalias(SpMat& out, const SpProxy& pa, const SpProxy& pb) @@ -160,7 +158,6 @@ template -arma_hot inline void spglue_plus::apply_noalias(SpMat& out, const SpMat& A, const SpMat& B) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_schur_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_schur_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_schur_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_schur_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -27,13 +27,13 @@ public: template - arma_hot inline static void apply(SpMat& out, const SpGlue& X); + inline static void apply(SpMat& out, const SpGlue& X); template - arma_hot inline static void apply_noalias(SpMat& out, const SpProxy& pa, const SpProxy& pb); + inline static void apply_noalias(SpMat& out, const SpProxy& pa, const SpProxy& pb); template - arma_hot inline static void apply_noalias(SpMat& out, const SpMat& A, const SpMat& B); + inline static void apply_noalias(SpMat& out, const SpMat& A, const SpMat& B); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_schur_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_schur_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_schur_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_schur_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,7 +22,6 @@ template -arma_hot inline void spglue_schur::apply(SpMat& out, const SpGlue& X) @@ -53,7 +52,6 @@ template -arma_hot inline void spglue_schur::apply_noalias(SpMat& out, const SpProxy& pa, const SpProxy& pb) @@ -150,7 +148,6 @@ template -arma_hot inline void spglue_schur::apply_noalias(SpMat& out, const SpMat& A, const SpMat& B) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_times_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_times_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_times_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_times_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -40,28 +40,7 @@ inline static void apply(SpMat& out, const SpGlue,T2,spglue_times>& X); template - arma_hot inline static void apply_noalias(SpMat& c, const SpMat& x, const SpMat& y); - }; - - - -class spglue_times_misc - { - public: - - template - struct traits - { - static constexpr bool is_row = T1::is_row; - static constexpr bool is_col = T2::is_col; - static constexpr bool is_xvec = false; - }; - - template - inline static void sparse_times_dense(Mat& out, const T1& x, const T2& y); - - template - inline static void dense_times_sparse(Mat& out, const T1& x, const T2& y); + inline static void apply_noalias(SpMat& c, const SpMat& x, const SpMat& y); }; @@ -80,12 +59,6 @@ template inline static void apply(SpMat::eT>& out, const mtSpGlue::eT, T1, T2, spglue_times_mixed>& expr); - - template - inline static void sparse_times_dense(Mat< typename promote_type::result >& out, const T1& X, const T2& Y); - - template - inline static void dense_times_sparse(Mat< typename promote_type::result >& out, const T1& X, const T2& Y); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_times_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_times_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spglue_times_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spglue_times_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -84,7 +84,6 @@ template -arma_hot inline void spglue_times::apply_noalias(SpMat& c, const SpMat& x, const SpMat& y) @@ -95,9 +94,9 @@ const uword x_n_cols = x.n_cols; const uword y_n_rows = y.n_rows; const uword y_n_cols = y.n_cols; - + arma_debug_assert_mul_size(x_n_rows, x_n_cols, y_n_rows, y_n_cols, "matrix multiplication"); - + // First we must determine the structure of the new matrix (column pointers). // This follows the algorithm described in 'Sparse Matrix Multiplication // Package (SMMP)' (R.E. Bank and C.C. Douglas, 2001). Their description of @@ -119,7 +118,7 @@ typename SpMat::const_iterator y_it = y.begin(); typename SpMat::const_iterator y_end = y.end(); - + // SYMBMM: calculate column pointers for resultant matrix to obtain a good // upper bound on the number of nonzero elements. uword cur_col_length = 0; @@ -142,20 +141,20 @@ last_ind = x_it_row; ++cur_col_length; } - + ++x_it; } - + const uword old_col = y_it.col(); ++y_it; - + // See if column incremented. if(old_col != y_it.col()) { // Set column pointer (this is not a cumulative count; that is done later). access::rw(c.col_ptrs[old_col + 1]) = cur_col_length; cur_col_length = 0; - + // Return index markers to zero. Use last_ind for traversal. while(last_ind != x_n_rows + 1) { @@ -166,17 +165,20 @@ } } while(y_it != y_end); - + // Accumulate column pointers. for(uword i = 0; i < c.n_cols; ++i) { access::rw(c.col_ptrs[i + 1]) += c.col_ptrs[i]; } - - // Now that we know a decent bound on the number of nonzero elements, allocate - // the memory and fill it. - c.mem_resize(c.col_ptrs[c.n_cols]); - + + // Now that we know a decent bound on the number of nonzero elements, + // allocate the memory and fill it. + + const uword max_n_nonzero = c.col_ptrs[c.n_cols]; + + c.mem_resize(max_n_nonzero); + // Now the implementation of the NUMBMM algorithm. uword cur_pos = 0; // Current position in c matrix. podarray sums(x_n_rows); // Partial sums. @@ -197,15 +199,12 @@ access::rw(c.col_ptrs[cur_col]) = cur_pos; ++cur_col; } - - if(cur_col == c.n_cols) - { - break; - } - + + if(cur_col == c.n_cols) { break; } + // Update current column pointer. access::rw(c.col_ptrs[cur_col]) = cur_pos; - + // Check all elements in this column. typename SpMat::const_iterator y_col_it = y.begin_col_no_sync(cur_col); @@ -216,9 +215,9 @@ // Check all elements in the column of the other matrix corresponding to // the row of this column. typename SpMat::const_iterator x_col_it = x.begin_col_no_sync(y_col_it_row); - + const eT y_value = (*y_col_it); - + while(x_col_it.col() == y_col_it_row) { const uword x_col_it_row = x_col_it.row(); @@ -227,26 +226,26 @@ // Add to partial sum. const eT x_value = (*x_col_it); sums[x_col_it_row] += (x_value * y_value); - + // Add point if it hasn't already been marked. if(index[x_col_it_row] == x_n_rows) { index[x_col_it_row] = last_ind; last_ind = x_col_it_row; } - + ++x_col_it; } - + ++y_col_it; } - + // Now sort the indices that were used in this column. uword cur_index = 0; while(last_ind != x_n_rows + 1) { const uword tmp = last_ind; - + // Check that it wasn't a "fake" nonzero element. if(sums[tmp] != eT(0)) { @@ -258,7 +257,7 @@ last_ind = index[tmp]; index[tmp] = x_n_rows; } - + // Now sort the indices. if(cur_index != 0) { @@ -277,205 +276,22 @@ // Move to next column. ++cur_col; } - - // Update last column pointer and resize to actual memory size. - access::rw(c.col_ptrs[c.n_cols]) = cur_pos; - c.mem_resize(cur_pos); - } - - - -// -// -// - - - -template -inline -void -spglue_times_misc::sparse_times_dense(Mat& out, const T1& x, const T2& y) - { - arma_extra_debug_sigprint(); - typedef typename T1::elem_type eT; + // Update last column pointer and resize to actual memory size. - if(is_op_diagmat::value) - { - const SpMat tmp(y); - - out = x * tmp; - } - else - { - const unwrap_spmat UA(x); - const quasi_unwrap UB(y); - - 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; - - const uword B_n_rows = B.n_rows; - const uword B_n_cols = B.n_cols; - - arma_debug_assert_mul_size(A_n_rows, A_n_cols, B_n_rows, B_n_cols, "matrix multiplication"); - - if(B_n_cols >= (B_n_rows / uword(100))) - { - arma_extra_debug_print("using transpose-based multiplication"); - - const SpMat At = A.st(); - const Mat Bt = B.st(); - - if(A_n_rows == B_n_cols) - { - spglue_times_misc::dense_times_sparse(out, Bt, At); - - op_strans::apply_mat(out, out); // since 'out' is square-sized, this will do an inplace transpose - } - else - { - Mat tmp; - - spglue_times_misc::dense_times_sparse(tmp, Bt, At); - - op_strans::apply_mat(out, tmp); - } - } - else - { - arma_extra_debug_print("using standard multiplication"); - - out.zeros(A_n_rows, B_n_cols); - - typename SpMat::const_iterator A_it = A.begin(); - typename SpMat::const_iterator A_it_end = A.end(); - - while(A_it != A_it_end) - { - const eT A_it_val = (*A_it); - const uword A_it_row = A_it.row(); - const uword A_it_col = A_it.col(); - - for(uword col = 0; col < B_n_cols; ++col) - { - out.at(A_it_row, col) += A_it_val * B.at(A_it_col, col); - } - - ++A_it; - } - } - } - } - - - -template -inline -void -spglue_times_misc::dense_times_sparse(Mat& out, const T1& x, const T2& y) - { - arma_extra_debug_sigprint(); + // access::rw(c.col_ptrs[c.n_cols]) = cur_pos; + // c.mem_resize(cur_pos); - typedef typename T1::elem_type eT; + access::rw(c.col_ptrs[c.n_cols]) = cur_pos; - if(is_op_diagmat::value) - { - const SpMat tmp(x); - - out = tmp * y; - } - else - { - const quasi_unwrap UA(x); - const unwrap_spmat UB(y); - - const Mat& A = UA.M; - const SpMat& B = UB.M; - - if( (resolves_to_vector::no) && (A.is_vec() == false) && A.is_diagmat() ) - { - const SpMat tmp(diagmat(A)); - - out = tmp * B; - - return; - } - - 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) && (A.n_rows <= (A.n_cols / uword(100))) ) - { - #if defined(ARMA_USE_OPENMP) - { - arma_extra_debug_print("using parallelised multiplication"); - - 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 < B_n_cols; ++i) - { - 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(&(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) = A.cols(indices) * B_col; - } - } - #endif - } - else - { - arma_extra_debug_print("using standard multiplication"); - - 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(B_it != B_it_end) - { - 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(B_it_col); - - for(uword row = 0; row < out_n_rows; ++row) - { - out_col[row] += A.at(row, B_it_row) * B_it_val; - } - - ++B_it; - } - } - } - } + if(cur_pos < max_n_nonzero) { c.mem_resize(cur_pos); } } // +// +// @@ -548,148 +364,6 @@ } } - - -template -inline -void -spglue_times_mixed::sparse_times_dense(Mat< typename promote_type::result >& out, const T1& X, const T2& Y) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT1; - typedef typename T2::elem_type eT2; - - typedef typename promote_type::result out_eT; - - promote_type::check(); - - if( (is_same_type::no) && (is_same_type::yes) ) - { - // upgrade T1 - - const unwrap_spmat UA(X); - const quasi_unwrap UB(Y); - - const SpMat& A = UA.M; - const Mat& B = UB.M; - - SpMat AA(arma_layout_indicator(), A); - - for(uword i=0; i < A.n_nonzero; ++i) { access::rw(AA.values[i]) = out_eT(A.values[i]); } - - const Mat& BB = reinterpret_cast< const Mat& >(B); - - spglue_times_misc::sparse_times_dense(out, AA, BB); - } - else - if( (is_same_type::yes) && (is_same_type::no) ) - { - // upgrade T2 - - const unwrap_spmat UA(X); - const quasi_unwrap UB(Y); - - const SpMat& A = UA.M; - const Mat& B = UB.M; - - const SpMat& AA = reinterpret_cast< const SpMat& >(A); - - const Mat BB = conv_to< Mat >::from(B); - - spglue_times_misc::sparse_times_dense(out, AA, BB); - } - else - { - // upgrade T1 and T2 - - const unwrap_spmat UA(X); - const quasi_unwrap UB(Y); - - const SpMat& A = UA.M; - const Mat& B = UB.M; - - SpMat AA(arma_layout_indicator(), A); - - for(uword i=0; i < A.n_nonzero; ++i) { access::rw(AA.values[i]) = out_eT(A.values[i]); } - - const Mat BB = conv_to< Mat >::from(B); - - spglue_times_misc::sparse_times_dense(out, AA, BB); - } - } - - - -template -inline -void -spglue_times_mixed::dense_times_sparse(Mat< typename promote_type::result >& out, const T1& X, const T2& Y) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT1; - typedef typename T2::elem_type eT2; - - typedef typename promote_type::result out_eT; - - promote_type::check(); - - if( (is_same_type::no) && (is_same_type::yes) ) - { - // upgrade T1 - - const quasi_unwrap UA(X); - const unwrap_spmat UB(Y); - - const Mat& A = UA.M; - const SpMat& B = UB.M; - - const Mat AA = conv_to< Mat >::from(A); - - const SpMat& BB = reinterpret_cast< const SpMat& >(B); - - spglue_times_misc::dense_times_sparse(out, AA, BB); - } - else - if( (is_same_type::yes) && (is_same_type::no) ) - { - // upgrade T2 - - const quasi_unwrap UA(X); - const unwrap_spmat UB(Y); - - const Mat& A = UA.M; - const SpMat& B = UB.M; - - const Mat& AA = reinterpret_cast< const Mat& >(A); - - SpMat BB(arma_layout_indicator(), B); - - for(uword i=0; i < B.n_nonzero; ++i) { access::rw(BB.values[i]) = out_eT(B.values[i]); } - - spglue_times_misc::dense_times_sparse(out, AA, BB); - } - else - { - // upgrade T1 and T2 - - const quasi_unwrap UA(X); - const unwrap_spmat UB(Y); - - const Mat& A = UA.M; - const SpMat& B = UB.M; - - const Mat AA = conv_to< Mat >::from(A); - - SpMat BB(arma_layout_indicator(), B); - - for(uword i=0; i < B.n_nonzero; ++i) { access::rw(BB.values[i]) = out_eT(B.values[i]); } - - spglue_times_misc::dense_times_sparse(out, AA, BB); - } - } - //! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpMat_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpMat_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -101,7 +101,7 @@ 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); + inline SpMat(const Base& rowind, const Base& colptr, const Base& values, const uword n_rows, const uword n_cols, const bool check_for_zeros = true); template inline SpMat(const Base& locations, const Base& values, const bool sort_locations = true); @@ -274,92 +274,101 @@ // access the i-th element; if there is nothing at element i, 0 is returned - arma_inline arma_warn_unused SpMat_MapMat_val operator[] (const uword i); - arma_inline arma_warn_unused eT operator[] (const uword i) const; - arma_inline arma_warn_unused SpMat_MapMat_val at (const uword i); - arma_inline arma_warn_unused eT at (const uword i) const; - arma_inline arma_warn_unused SpMat_MapMat_val operator() (const uword i); - arma_inline arma_warn_unused eT operator() (const uword i) const; + arma_warn_unused arma_inline SpMat_MapMat_val operator[] (const uword i); + arma_warn_unused arma_inline eT operator[] (const uword i) const; + + arma_warn_unused arma_inline SpMat_MapMat_val at (const uword i); + arma_warn_unused arma_inline eT at (const uword i) const; + + arma_warn_unused arma_inline SpMat_MapMat_val operator() (const uword i); + arma_warn_unused arma_inline eT operator() (const uword i) const; // access the element at the given row and column; if there is nothing at that position, 0 is returned - arma_inline arma_warn_unused SpMat_MapMat_val at (const uword in_row, const uword in_col); - arma_inline arma_warn_unused eT at (const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused SpMat_MapMat_val operator() (const uword in_row, const uword in_col); - arma_inline arma_warn_unused eT operator() (const uword in_row, const uword in_col) const; + #if defined(__cpp_multidimensional_subscript) + arma_warn_unused arma_inline SpMat_MapMat_val operator[] (const uword in_row, const uword in_col); + arma_warn_unused arma_inline eT operator[] (const uword in_row, const uword in_col) const; + #endif + + arma_warn_unused arma_inline SpMat_MapMat_val at (const uword in_row, const uword in_col); + arma_warn_unused arma_inline eT at (const uword in_row, const uword in_col) const; + + arma_warn_unused arma_inline SpMat_MapMat_val operator() (const uword in_row, const uword in_col); + arma_warn_unused arma_inline eT operator() (const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused bool is_empty() const; - arma_inline arma_warn_unused bool is_vec() const; - arma_inline arma_warn_unused bool is_rowvec() const; - arma_inline arma_warn_unused bool is_colvec() const; - arma_inline arma_warn_unused bool is_square() const; - inline arma_warn_unused bool is_finite() const; + arma_warn_unused arma_inline bool is_empty() const; + arma_warn_unused arma_inline bool is_vec() const; + arma_warn_unused arma_inline bool is_rowvec() const; + arma_warn_unused arma_inline bool is_colvec() const; + arma_warn_unused arma_inline bool is_square() const; - inline arma_warn_unused bool is_symmetric() const; - inline arma_warn_unused bool is_symmetric(const typename get_pod_type::result tol) const; + arma_warn_unused inline bool is_symmetric() const; + arma_warn_unused inline bool is_symmetric(const typename get_pod_type::result tol) const; - inline arma_warn_unused bool is_hermitian() const; - inline arma_warn_unused bool is_hermitian(const typename get_pod_type::result tol) const; + arma_warn_unused inline bool is_hermitian() const; + arma_warn_unused inline bool is_hermitian(const typename get_pod_type::result tol) const; - inline arma_warn_unused bool has_inf() const; - inline arma_warn_unused bool has_nan() const; + arma_warn_unused inline bool internal_is_finite() const; + arma_warn_unused inline bool internal_has_inf() const; + arma_warn_unused inline bool internal_has_nan() const; + arma_warn_unused inline bool internal_has_nonfinite() const; - arma_inline arma_warn_unused bool in_range(const uword i) const; - arma_inline arma_warn_unused bool in_range(const span& x) const; + arma_warn_unused arma_inline bool in_range(const uword i) const; + arma_warn_unused arma_inline bool in_range(const span& x) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col) const; - arma_inline arma_warn_unused bool in_range(const span& row_span, const uword in_col) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const span& col_span) const; - arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const uword in_col) const; + arma_warn_unused arma_inline bool in_range(const span& row_span, const uword in_col) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const span& col_span) const; + arma_warn_unused arma_inline bool in_range(const span& row_span, const span& col_span) const; - arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; + arma_warn_unused arma_inline bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; - template inline void copy_size(const SpMat& m); - template inline void copy_size(const Mat& m); + template inline SpMat& copy_size(const SpMat& m); + template inline SpMat& copy_size(const Mat& m); - 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 SizeMat& s); + inline SpMat& set_size(const uword in_elem); + inline SpMat& set_size(const uword in_rows, const uword in_cols); + inline SpMat& set_size(const SizeMat& s); - inline void resize(const uword in_rows, const uword in_cols); - inline void resize(const SizeMat& s); + inline SpMat& resize(const uword in_rows, const uword in_cols); + inline SpMat& resize(const SizeMat& s); - inline void reshape(const uword in_rows, const uword in_cols); - inline void reshape(const SizeMat& s); + inline SpMat& reshape(const uword in_rows, const uword in_cols); + inline SpMat& reshape(const SizeMat& s); inline void reshape_helper_generic(const uword in_rows, const uword in_cols); //! internal use only inline void reshape_helper_intovec(); //! internal use only - template inline const SpMat& for_each(functor F); + template inline SpMat& for_each(functor F); template inline const SpMat& for_each(functor F) const; - template inline const SpMat& transform(functor F); + template inline SpMat& transform(functor F); - inline const SpMat& replace(const eT old_val, const eT new_val); + inline SpMat& replace(const eT old_val, const eT new_val); - inline const SpMat& clean(const pod_type threshold); + inline SpMat& clean(const pod_type threshold); - inline const SpMat& clamp(const eT min_val, const eT max_val); + inline 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); - inline const SpMat& zeros(const SizeMat& s); + inline SpMat& zeros(); + inline SpMat& zeros(const uword in_elem); + inline SpMat& zeros(const uword in_rows, const uword in_cols); + inline SpMat& zeros(const SizeMat& s); - inline const SpMat& eye(); - inline const SpMat& eye(const uword in_rows, const uword in_cols); - inline const SpMat& eye(const SizeMat& s); + inline SpMat& eye(); + inline SpMat& eye(const uword in_rows, const uword in_cols); + inline SpMat& eye(const SizeMat& s); - inline const SpMat& speye(); - inline const SpMat& speye(const uword in_rows, const uword in_cols); - inline const SpMat& speye(const SizeMat& s); + inline SpMat& speye(); + inline SpMat& speye(const uword in_rows, const uword in_cols); + inline SpMat& speye(const SizeMat& s); - inline const SpMat& sprandu(const uword in_rows, const uword in_cols, const double density); - inline const SpMat& sprandu(const SizeMat& s, const double density); + inline SpMat& sprandu(const uword in_rows, const uword in_cols, const double density); + inline SpMat& sprandu(const SizeMat& s, const double density); - inline const SpMat& sprandn(const uword in_rows, const uword in_cols, const double density); - inline const SpMat& sprandn(const SizeMat& s, const double density); + inline SpMat& sprandn(const uword in_rows, const uword in_cols, const double density); + inline SpMat& sprandn(const SizeMat& s, const double density); inline void reset(); inline void reset_cache(); @@ -381,21 +390,19 @@ // 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; - 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); + arma_cold inline bool save(const std::string name, const file_type type = arma_binary) const; + arma_cold inline bool save(const csv_name& spec, const file_type type = csv_ascii) const; + arma_cold inline bool save( std::ostream& os, const file_type type = arma_binary) const; + + arma_cold inline bool load(const std::string name, const file_type type = arma_binary); + arma_cold inline bool load(const csv_name& spec, const file_type type = csv_ascii); + arma_cold inline bool load( std::istream& is, const file_type type = arma_binary); + + arma_deprecated inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; + arma_deprecated inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; + + arma_deprecated inline bool quiet_load(const std::string name, const file_type type = arma_binary); + arma_deprecated inline bool quiet_load( std::istream& is, const file_type type = arma_binary); @@ -438,30 +445,31 @@ public: inline const_iterator(); - inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // assumes initial_pos is valid - //! once initialised, will be at the first nonzero value after the given position (using forward columnwise traversal) - inline const_iterator(const SpMat& in_M, uword in_row, uword in_col); - //! if you know the exact position of the iterator; in_row is a dummy argument - inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uword in_pos); - inline const_iterator(const const_iterator& other); - - 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 SpSubview::const_iterator& rhs) const; - inline arma_hot bool operator!=(const typename SpSubview::const_iterator& rhs) const; + inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // assumes initial_pos is valid + inline const_iterator(const SpMat& in_M, uword in_row, uword in_col); // iterator will be at the first nonzero value after the given position (using forward columnwise traversal) + inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uword in_pos); // if the exact position of the iterator is known; in_row is a dummy argument + + inline const_iterator(const const_iterator& other); + inline const_iterator& operator= (const const_iterator& other) = default; + + arma_hot inline const_iterator& operator++(); + arma_warn_unused inline const_iterator operator++(int); - inline arma_hot bool operator==(const const_row_iterator& rhs) const; - inline arma_hot bool operator!=(const const_row_iterator& rhs) const; + arma_hot inline const_iterator& operator--(); + arma_warn_unused inline const_iterator operator--(int); - inline arma_hot bool operator==(const typename SpSubview::const_row_iterator& rhs) const; - inline arma_hot bool operator!=(const typename SpSubview::const_row_iterator& rhs) const; + arma_hot inline bool operator==(const const_iterator& rhs) const; + arma_hot inline bool operator!=(const const_iterator& rhs) const; + + arma_hot inline bool operator==(const typename SpSubview::const_iterator& rhs) const; + arma_hot inline bool operator!=(const typename SpSubview::const_iterator& rhs) const; + + arma_hot inline bool operator==(const const_row_iterator& rhs) const; + arma_hot inline bool operator!=(const const_row_iterator& rhs) const; + + arma_hot inline bool operator==(const typename SpSubview::const_row_iterator& rhs) const; + arma_hot inline bool operator!=(const typename SpSubview::const_row_iterator& rhs) const; }; /** @@ -474,19 +482,22 @@ public: inline iterator() : const_iterator() { } - inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in_M, initial_pos) { } - inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterator(in_M, in_row, in_col) { } + + inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in_M, initial_pos) { } + inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterator(in_M, in_row, in_col) { } 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< SpMat > operator*(); + inline iterator (const iterator& other) : const_iterator(other) { } + inline iterator& operator=(const iterator& other) = default; + + arma_hot inline SpValProxy< SpMat > operator*(); // overloads needed for return type correctness - inline arma_hot iterator& operator++(); - inline arma_warn_unused iterator operator++(int); + arma_hot inline iterator& operator++(); + arma_warn_unused inline iterator operator++(int); - inline arma_hot iterator& operator--(); - inline arma_warn_unused iterator operator--(int); + arma_hot inline iterator& operator--(); + arma_warn_unused inline iterator operator--(int); // this has a different value_type than iterator_base typedef SpValProxy< SpMat > value_type; @@ -500,34 +511,35 @@ inline const_row_iterator(); inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0); - //! once initialised, will be at the first nonzero value after the given position (using forward row-wise traversal) inline const_row_iterator(const SpMat& 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 const_row_iterator(const const_row_iterator& other); + inline const_row_iterator& operator= (const const_row_iterator& other) = default; + + arma_hot inline const_row_iterator& operator++(); + arma_warn_unused inline const_row_iterator operator++(int); - inline arma_hot const_row_iterator& operator--(); - inline arma_warn_unused const_row_iterator operator--(int); + arma_hot inline const_row_iterator& operator--(); + arma_warn_unused inline const_row_iterator operator--(int); uword internal_row; // hold row internally - uword actual_pos; // this holds the true position we are at in the matrix, as column-major indexing + uword actual_pos; // hold the true position we are at in the matrix, as column-major indexing arma_inline eT operator*() const { return iterator_base::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; + arma_hot inline bool operator==(const const_iterator& rhs) const; + arma_hot inline bool operator!=(const const_iterator& rhs) const; - inline arma_hot bool operator==(const typename SpSubview::const_iterator& rhs) const; - inline arma_hot bool operator!=(const typename SpSubview::const_iterator& rhs) const; + arma_hot inline bool operator==(const typename SpSubview::const_iterator& rhs) const; + arma_hot inline bool operator!=(const typename SpSubview::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; + arma_hot inline bool operator==(const const_row_iterator& rhs) const; + arma_hot inline bool operator!=(const const_row_iterator& rhs) const; - inline arma_hot bool operator==(const typename SpSubview::const_row_iterator& rhs) const; - inline arma_hot bool operator!=(const typename SpSubview::const_row_iterator& rhs) const; + arma_hot inline bool operator==(const typename SpSubview::const_row_iterator& rhs) const; + arma_hot inline bool operator!=(const typename SpSubview::const_row_iterator& rhs) const; }; class row_iterator : public const_row_iterator @@ -535,19 +547,21 @@ public: inline row_iterator() : const_row_iterator() {} - inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { } - //! once initialised, will be at the first nonzero value after the given position (using forward row-wise traversal) + + inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { } 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< SpMat > operator*(); + inline row_iterator(const row_iterator& other) : const_row_iterator(other) { } + inline row_iterator& operator= (const row_iterator& other) = default; + + arma_hot inline SpValProxy< SpMat > operator*(); // overloads required for return type correctness - inline arma_hot row_iterator& operator++(); - inline arma_warn_unused row_iterator operator++(int); + arma_hot inline row_iterator& operator++(); + arma_warn_unused inline row_iterator operator++(int); - inline arma_hot row_iterator& operator--(); - inline arma_warn_unused row_iterator operator--(int); + arma_hot inline row_iterator& operator--(); + arma_warn_unused inline row_iterator operator--(int); // this has a different value_type than iterator_base typedef SpValProxy< SpMat > value_type; @@ -603,11 +617,11 @@ 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_warn_unused arma_inline SpMat_MapMat_val front(); + arma_warn_unused arma_inline eT front() const; - arma_inline arma_warn_unused SpMat_MapMat_val back(); - arma_inline arma_warn_unused eT back() const; + arma_warn_unused arma_inline SpMat_MapMat_val back(); + arma_warn_unused arma_inline eT back() const; // Resize memory. // If the new size is larger, the column pointers and new memory still need to be correctly set. @@ -637,8 +651,8 @@ protected: - inline void init(uword in_rows, uword in_cols, const uword new_n_nonzero = 0); - inline void arma_cold init_cold(uword in_rows, uword in_cols, const uword new_n_nonzero = 0); + inline void init(uword in_rows, uword in_cols, const uword new_n_nonzero = 0); + arma_cold inline void init_cold(uword in_rows, uword in_cols, const uword new_n_nonzero = 0); inline void init(const std::string& text); inline void init(const SpMat& x); @@ -655,22 +669,22 @@ private: - inline arma_hot arma_warn_unused const eT* find_value_csc(const uword in_row, const uword in_col) const; + arma_warn_unused arma_hot inline const eT* find_value_csc(const uword in_row, const uword in_col) const; - inline arma_hot arma_warn_unused eT get_value(const uword i ) const; - inline arma_hot arma_warn_unused eT get_value(const uword in_row, const uword in_col) const; + arma_warn_unused arma_hot inline eT get_value(const uword i ) const; + arma_warn_unused arma_hot inline eT get_value(const uword in_row, const uword in_col) const; - inline arma_hot arma_warn_unused eT get_value_csc(const uword i ) const; - inline arma_hot arma_warn_unused eT get_value_csc(const uword in_row, const uword in_col) const; + arma_warn_unused arma_hot inline eT get_value_csc(const uword i ) const; + arma_warn_unused arma_hot inline eT get_value_csc(const uword in_row, const uword in_col) const; - inline arma_hot arma_warn_unused bool try_set_value_csc(const uword in_row, const uword in_col, const eT in_val); - inline arma_hot arma_warn_unused bool try_add_value_csc(const uword in_row, const uword in_col, const eT in_val); - inline arma_hot arma_warn_unused bool try_sub_value_csc(const uword in_row, const uword in_col, const eT in_val); - inline arma_hot arma_warn_unused bool try_mul_value_csc(const uword in_row, const uword in_col, const eT in_val); - inline arma_hot arma_warn_unused bool try_div_value_csc(const uword in_row, const uword in_col, const eT in_val); + arma_warn_unused arma_hot inline bool try_set_value_csc(const uword in_row, const uword in_col, const eT in_val); + arma_warn_unused arma_hot inline bool try_add_value_csc(const uword in_row, const uword in_col, const eT in_val); + arma_warn_unused arma_hot inline bool try_sub_value_csc(const uword in_row, const uword in_col, const eT in_val); + arma_warn_unused arma_hot inline bool try_mul_value_csc(const uword in_row, const uword in_col, const eT in_val); + arma_warn_unused arma_hot inline bool try_div_value_csc(const uword in_row, const uword in_col, const eT in_val); - 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); + arma_warn_unused inline 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); // cache related @@ -706,7 +720,7 @@ public: - #ifdef ARMA_EXTRA_SPMAT_PROTO + #if defined(ARMA_EXTRA_SPMAT_PROTO) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPMAT_PROTO) #endif }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_iterators_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpMat_iterators_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_iterators_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpMat_iterators_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -150,7 +150,6 @@ template inline -arma_hot typename SpMat::const_iterator& SpMat::const_iterator::operator++() { @@ -175,7 +174,6 @@ template inline -arma_warn_unused typename SpMat::const_iterator SpMat::const_iterator::operator++(int) { @@ -190,7 +188,6 @@ template inline -arma_hot typename SpMat::const_iterator& SpMat::const_iterator::operator--() { @@ -209,7 +206,6 @@ template inline -arma_warn_unused typename SpMat::const_iterator SpMat::const_iterator::operator--(int) { @@ -224,7 +220,6 @@ template inline -arma_hot bool SpMat::const_iterator::operator==(const const_iterator& rhs) const { @@ -235,7 +230,6 @@ template inline -arma_hot bool SpMat::const_iterator::operator!=(const const_iterator& rhs) const { @@ -246,7 +240,6 @@ template inline -arma_hot bool SpMat::const_iterator::operator==(const typename SpSubview::const_iterator& rhs) const { @@ -257,7 +250,6 @@ template inline -arma_hot bool SpMat::const_iterator::operator!=(const typename SpSubview::const_iterator& rhs) const { @@ -268,7 +260,6 @@ template inline -arma_hot bool SpMat::const_iterator::operator==(const const_row_iterator& rhs) const { @@ -279,7 +270,6 @@ template inline -arma_hot bool SpMat::const_iterator::operator!=(const const_row_iterator& rhs) const { @@ -290,7 +280,6 @@ template inline -arma_hot bool SpMat::const_iterator::operator==(const typename SpSubview::const_row_iterator& rhs) const { @@ -301,7 +290,6 @@ template inline -arma_hot bool SpMat::const_iterator::operator!=(const typename SpSubview::const_row_iterator& rhs) const { @@ -316,7 +304,6 @@ template inline -arma_hot SpValProxy< SpMat > SpMat::iterator::operator*() { @@ -331,7 +318,6 @@ template inline -arma_hot typename SpMat::iterator& SpMat::iterator::operator++() { @@ -344,7 +330,6 @@ template inline -arma_warn_unused typename SpMat::iterator SpMat::iterator::operator++(int) { @@ -359,7 +344,6 @@ template inline -arma_hot typename SpMat::iterator& SpMat::iterator::operator--() { @@ -372,7 +356,6 @@ template inline -arma_warn_unused typename SpMat::iterator SpMat::iterator::operator--(int) { @@ -573,7 +556,6 @@ */ template inline -arma_hot typename SpMat::const_row_iterator& SpMat::const_row_iterator::operator++() { @@ -699,7 +681,6 @@ */ template inline -arma_warn_unused typename SpMat::const_row_iterator SpMat::const_row_iterator::operator++(int) { @@ -717,7 +698,6 @@ */ template inline -arma_hot typename SpMat::const_row_iterator& SpMat::const_row_iterator::operator--() { @@ -820,7 +800,6 @@ */ template inline -arma_warn_unused typename SpMat::const_row_iterator SpMat::const_row_iterator::operator--(int) { @@ -835,7 +814,6 @@ template inline -arma_hot bool SpMat::const_row_iterator::operator==(const const_iterator& rhs) const { @@ -846,7 +824,6 @@ template inline -arma_hot bool SpMat::const_row_iterator::operator!=(const const_iterator& rhs) const { @@ -857,7 +834,6 @@ template inline -arma_hot bool SpMat::const_row_iterator::operator==(const typename SpSubview::const_iterator& rhs) const { @@ -868,7 +844,6 @@ template inline -arma_hot bool SpMat::const_row_iterator::operator!=(const typename SpSubview::const_iterator& rhs) const { @@ -879,7 +854,6 @@ template inline -arma_hot bool SpMat::const_row_iterator::operator==(const const_row_iterator& rhs) const { @@ -890,7 +864,6 @@ template inline -arma_hot bool SpMat::const_row_iterator::operator!=(const const_row_iterator& rhs) const { @@ -901,7 +874,6 @@ template inline -arma_hot bool SpMat::const_row_iterator::operator==(const typename SpSubview::const_row_iterator& rhs) const { @@ -912,7 +884,6 @@ template inline -arma_hot bool SpMat::const_row_iterator::operator!=(const typename SpSubview::const_row_iterator& rhs) const { @@ -927,7 +898,6 @@ template inline -arma_hot SpValProxy< SpMat > SpMat::row_iterator::operator*() { @@ -942,7 +912,6 @@ template inline -arma_hot typename SpMat::row_iterator& SpMat::row_iterator::operator++() { @@ -955,7 +924,6 @@ template inline -arma_warn_unused typename SpMat::row_iterator SpMat::row_iterator::operator++(int) { @@ -970,7 +938,6 @@ template inline -arma_hot typename SpMat::row_iterator& SpMat::row_iterator::operator--() { @@ -983,7 +950,6 @@ template inline -arma_warn_unused typename SpMat::row_iterator SpMat::row_iterator::operator--(int) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpMat_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpMat_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpMat_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -320,8 +320,8 @@ { arma_extra_debug_sigprint_this(this); - const unwrap locs_tmp( locations_expr.get_ref() ); - const unwrap vals_tmp( vals_expr.get_ref() ); + const quasi_unwrap locs_tmp( locations_expr.get_ref() ); + const quasi_unwrap vals_tmp( vals_expr.get_ref() ); const Mat& locs = locs_tmp.M; const Mat& vals = vals_tmp.M; @@ -393,8 +393,8 @@ { arma_extra_debug_sigprint_this(this); - const unwrap locs_tmp( locations_expr.get_ref() ); - const unwrap vals_tmp( vals_expr.get_ref() ); + const quasi_unwrap locs_tmp( locations_expr.get_ref() ); + const quasi_unwrap vals_tmp( vals_expr.get_ref() ); const Mat& locs = locs_tmp.M; const Mat& vals = vals_tmp.M; @@ -462,8 +462,8 @@ { arma_extra_debug_sigprint_this(this); - const unwrap locs_tmp( locations_expr.get_ref() ); - const unwrap vals_tmp( vals_expr.get_ref() ); + const quasi_unwrap locs_tmp( locations_expr.get_ref() ); + const quasi_unwrap vals_tmp( vals_expr.get_ref() ); const Mat& locs = locs_tmp.M; const Mat& vals = vals_tmp.M; @@ -532,7 +532,8 @@ const Base& colptr_expr, const Base& values_expr, const uword in_n_rows, - const uword in_n_cols + const uword in_n_cols, + const bool check_for_zeros ) : n_rows(0) , n_cols(0) @@ -545,9 +546,9 @@ { arma_extra_debug_sigprint_this(this); - const unwrap rowind_tmp( rowind_expr.get_ref() ); - const unwrap colptr_tmp( colptr_expr.get_ref() ); - const unwrap vals_tmp( values_expr.get_ref() ); + const quasi_unwrap rowind_tmp( rowind_expr.get_ref() ); + const quasi_unwrap colptr_tmp( colptr_expr.get_ref() ); + const quasi_unwrap vals_tmp( values_expr.get_ref() ); const Mat& rowind = rowind_tmp.M; const Mat& colptr = colptr_tmp.M; @@ -572,7 +573,7 @@ access::rw(col_ptrs[n_cols + 1]) = std::numeric_limits::max(); // make sure no zeros are stored - remove_zeros(); + if(check_for_zeros) { remove_zeros(); } } @@ -1032,93 +1033,13 @@ template inline SpMat& -SpMat::operator*=(const Base& y) +SpMat::operator*=(const Base& x) { 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 - // matrix) implies an entire nonzero column. Therefore, we iterate over all - // the row_indices and count the number of rows with any elements in them - // (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) - { - if(index[row_indices[i]] == n_rows) - { - index[row_indices[i]] = last_index; - 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) - { - ++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) - { - if(partial_sums[i] != eT(0)) - { - access::rw(z.values[cur_pos]) = partial_sums[i]; - access::rw(z.row_indices[cur_pos]) = i; - ++access::rw(z.col_ptrs[lcol + 1]); - //printf("colptr %d now %d\n", lcol + 1, z.col_ptrs[lcol + 1]); - ++cur_pos; - partial_sums[i] = 0; // Would it be faster to do this in batch later? - } - } - } - - // 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]); - - // Now take the memory of the temporary matrix. - steal_mem(z); - - return *this; + return (*this).operator=( (*this) * x.get_ref() ); } @@ -1151,13 +1072,38 @@ { arma_extra_debug_sigprint(); - SpMat tmp; + const quasi_unwrap U(x.get_ref()); + const Mat& B = U.M; - // 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)); + arma_debug_assert_same_size(n_rows, n_cols, B.n_rows, B.n_cols, "element-wise multiplication"); - steal_mem(tmp); + sync_csc(); + invalidate_cache(); + + constexpr eT zero = eT(0); + + bool has_zero = false; + + for(uword c=0; c < n_cols; ++c) + { + const uword index_start = col_ptrs[c ]; + const uword index_end = col_ptrs[c + 1]; + + for(uword i=index_start; i < index_end; ++i) + { + const uword r = row_indices[i]; + + eT& val = access::rw(values[i]); + + const eT result = val * B.at(r,c); + + val = result; + + if(result == zero) { has_zero = true; } + } + } + + if(has_zero) { remove_zeros(); } return *this; } @@ -1355,8 +1301,8 @@ 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); + typename SpMat::const_col_iterator m_it = X.m.begin_col_no_sync(sv_col_start); + typename SpMat::const_col_iterator m_it_end = X.m.end_col_no_sync(sv_col_end); uword count = 0; @@ -3110,8 +3056,8 @@ // Now, copy over the elements. // i is the index in the old matrix; j is the index in the new matrix. - const_iterator it = begin(); - const_iterator it_end = end(); + const_iterator it = cbegin(); + const_iterator it_end = cend(); uword j = 0; // The index in the new matrix. while(it != it_end) @@ -3181,8 +3127,8 @@ if(diff > 0) { - eT* new_values = memory::acquire (n_nonzero - diff); - uword* new_row_indices = memory::acquire(n_nonzero - diff); + eT* new_values = memory::acquire (n_nonzero + 1 - diff); + uword* new_row_indices = memory::acquire(n_nonzero + 1 - diff); // Copy first part. if(col_beg != 0) @@ -3197,6 +3143,10 @@ 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); } + + // Copy sentry element. + new_values[n_nonzero - diff] = values[n_nonzero]; + new_row_indices[n_nonzero - diff] = row_indices[n_nonzero]; if(values) { memory::release(access::rw(values)); } if(row_indices) { memory::release(access::rw(row_indices)); } @@ -3244,7 +3194,6 @@ template arma_inline -arma_warn_unused SpMat_MapMat_val SpMat::operator[](const uword i) { @@ -3258,7 +3207,6 @@ template arma_inline -arma_warn_unused eT SpMat::operator[](const uword i) const { @@ -3269,7 +3217,6 @@ template arma_inline -arma_warn_unused SpMat_MapMat_val SpMat::at(const uword i) { @@ -3283,7 +3230,6 @@ template arma_inline -arma_warn_unused eT SpMat::at(const uword i) const { @@ -3294,7 +3240,6 @@ template arma_inline -arma_warn_unused SpMat_MapMat_val SpMat::operator()(const uword i) { @@ -3310,7 +3255,6 @@ template arma_inline -arma_warn_unused eT SpMat::operator()(const uword i) const { @@ -3326,9 +3270,32 @@ * If there is nothing at that position, 0 is returned. */ +#if defined(__cpp_multidimensional_subscript) + + template + arma_inline + SpMat_MapMat_val + SpMat::operator[] (const uword in_row, const uword in_col) + { + return SpMat_MapMat_val((*this), cache, in_row, in_col); + } + + + + template + arma_inline + eT + SpMat::operator[] (const uword in_row, const uword in_col) const + { + return get_value(in_row, in_col); + } + +#endif + + + template arma_inline -arma_warn_unused SpMat_MapMat_val SpMat::at(const uword in_row, const uword in_col) { @@ -3339,7 +3306,6 @@ template arma_inline -arma_warn_unused eT SpMat::at(const uword in_row, const uword in_col) const { @@ -3350,7 +3316,6 @@ template arma_inline -arma_warn_unused SpMat_MapMat_val SpMat::operator()(const uword in_row, const uword in_col) { @@ -3363,7 +3328,6 @@ template arma_inline -arma_warn_unused eT SpMat::operator()(const uword in_row, const uword in_col) const { @@ -3379,7 +3343,6 @@ */ template arma_inline -arma_warn_unused bool SpMat::is_empty() const { @@ -3391,7 +3354,6 @@ //! returns true if the object can be interpreted as a column or row vector template arma_inline -arma_warn_unused bool SpMat::is_vec() const { @@ -3403,7 +3365,6 @@ //! returns true if the object can be interpreted as a row vector template arma_inline -arma_warn_unused bool SpMat::is_rowvec() const { @@ -3415,7 +3376,6 @@ //! returns true if the object can be interpreted as a column vector template arma_inline -arma_warn_unused bool SpMat::is_colvec() const { @@ -3427,7 +3387,6 @@ //! returns true if the object has the same number of non-zero rows and columnns template arma_inline -arma_warn_unused bool SpMat::is_square() const { @@ -3436,25 +3395,8 @@ -//! returns true if all of the elements are finite -template -inline -arma_warn_unused -bool -SpMat::is_finite() const - { - arma_extra_debug_sigprint(); - - sync_csc(); - - return arrayops::is_finite(values, n_nonzero); - } - - - template inline -arma_warn_unused bool SpMat::is_symmetric() const { @@ -3473,7 +3415,6 @@ template inline -arma_warn_unused bool SpMat::is_symmetric(const typename get_pod_type::result tol) const { @@ -3502,7 +3443,6 @@ template inline -arma_warn_unused bool SpMat::is_hermitian() const { @@ -3521,7 +3461,6 @@ template inline -arma_warn_unused bool SpMat::is_hermitian(const typename get_pod_type::result tol) const { @@ -3550,9 +3489,22 @@ template inline -arma_warn_unused bool -SpMat::has_inf() const +SpMat::internal_is_finite() const + { + arma_extra_debug_sigprint(); + + sync_csc(); + + return arrayops::is_finite(values, n_nonzero); + } + + + +template +inline +bool +SpMat::internal_has_inf() const { arma_extra_debug_sigprint(); @@ -3565,9 +3517,8 @@ template inline -arma_warn_unused bool -SpMat::has_nan() const +SpMat::internal_has_nan() const { arma_extra_debug_sigprint(); @@ -3578,10 +3529,23 @@ +template +inline +bool +SpMat::internal_has_nonfinite() const + { + arma_extra_debug_sigprint(); + + sync_csc(); + + return (arrayops::is_finite(values, n_nonzero) == false); + } + + + //! returns true if the given index is currently in range template arma_inline -arma_warn_unused bool SpMat::in_range(const uword i) const { @@ -3592,7 +3556,6 @@ //! returns true if the given start and end indices are currently in range template arma_inline -arma_warn_unused bool SpMat::in_range(const span& x) const { @@ -3616,7 +3579,6 @@ //! returns true if the given location is currently in range template arma_inline -arma_warn_unused bool SpMat::in_range(const uword in_row, const uword in_col) const { @@ -3627,7 +3589,6 @@ template arma_inline -arma_warn_unused bool SpMat::in_range(const span& row_span, const uword in_col) const { @@ -3650,7 +3611,6 @@ template arma_inline -arma_warn_unused bool SpMat::in_range(const uword in_row, const span& col_span) const { @@ -3673,7 +3633,6 @@ template arma_inline -arma_warn_unused bool SpMat::in_range(const span& row_span, const span& col_span) const { @@ -3695,7 +3654,6 @@ template arma_inline -arma_warn_unused bool SpMat::in_range(const uword in_row, const uword in_col, const SizeMat& s) const { @@ -3718,12 +3676,12 @@ template template inline -void +SpMat& SpMat::copy_size(const SpMat& m) { arma_extra_debug_sigprint(); - set_size(m.n_rows, m.n_cols); + return set_size(m.n_rows, m.n_cols); } @@ -3731,19 +3689,19 @@ template template inline -void +SpMat& SpMat::copy_size(const Mat& m) { arma_extra_debug_sigprint(); - set_size(m.n_rows, m.n_cols); + return set_size(m.n_rows, m.n_cols); } template inline -void +SpMat& SpMat::set_size(const uword in_elem) { arma_extra_debug_sigprint(); @@ -3757,60 +3715,52 @@ { set_size(in_elem, 1); } + + return *this; } template inline -void +SpMat& SpMat::set_size(const uword in_rows, const uword in_cols) { arma_extra_debug_sigprint(); invalidate_cache(); // placed here, as set_size() is used during matrix modification - if( (n_rows == in_rows) && (n_cols == in_cols) ) - { - return; - } - else - { - init(in_rows, in_cols); - } + if( (n_rows == in_rows) && (n_cols == in_cols) ) { return *this; } + + init(in_rows, in_cols); + + return *this; } template inline -void +SpMat& SpMat::set_size(const SizeMat& s) { arma_extra_debug_sigprint(); - (*this).set_size(s.n_rows, s.n_cols); + return (*this).set_size(s.n_rows, s.n_cols); } template inline -void +SpMat& SpMat::resize(const uword in_rows, const uword in_cols) { arma_extra_debug_sigprint(); - if( (n_rows == in_rows) && (n_cols == in_cols) ) - { - return; - } + if( (n_rows == in_rows) && (n_cols == in_cols) ) { return *this; } - if( (n_elem == 0) || (n_nonzero == 0) ) - { - set_size(in_rows, in_cols); - return; - } + if( (n_elem == 0) || (n_nonzero == 0) ) { return set_size(in_rows, in_cols); } SpMat tmp(in_rows, in_cols); @@ -3825,41 +3775,39 @@ } steal_mem(tmp); + + return *this; } template inline -void +SpMat& SpMat::resize(const SizeMat& s) { arma_extra_debug_sigprint(); - (*this).resize(s.n_rows, s.n_cols); + return (*this).resize(s.n_rows, s.n_cols); } template inline -void +SpMat& SpMat::reshape(const uword in_rows, const uword in_cols) { arma_extra_debug_sigprint(); arma_check( ((in_rows*in_cols) != n_elem), "SpMat::reshape(): changing the number of elements in a sparse matrix is currently not supported" ); - if( (n_rows == in_rows) && (n_cols == in_cols) ) { return; } + if( (n_rows == in_rows) && (n_cols == in_cols) ) { return *this; } if(vec_state == 1) { arma_debug_check( (in_cols != 1), "SpMat::reshape(): object is a column vector; requested size is not compatible" ); } if(vec_state == 2) { arma_debug_check( (in_rows != 1), "SpMat::reshape(): object is a row vector; requested size is not compatible" ); } - if(n_nonzero == 0) - { - (*this).zeros(in_rows, in_cols); - return; - } + if(n_nonzero == 0) { return (*this).zeros(in_rows, in_cols); } if(in_cols == 1) { @@ -3869,18 +3817,20 @@ { (*this).reshape_helper_generic(in_rows, in_cols); } + + return *this; } template inline -void +SpMat& SpMat::reshape(const SizeMat& s) { arma_extra_debug_sigprint(); - (*this).reshape(s.n_rows, s.n_cols); + return (*this).reshape(s.n_rows, s.n_cols); } @@ -3906,8 +3856,8 @@ arrayops::fill_zeros(new_col_ptrs, in_cols + 1); - const_iterator it = begin(); - const_iterator it_end = end(); + const_iterator it = cbegin(); + const_iterator it_end = cend(); for(; it != it_end; ++it) { @@ -3946,7 +3896,7 @@ sync_csc(); invalidate_cache(); - const_iterator it = begin(); + const_iterator it = cbegin(); const uword t_n_rows = n_rows; const uword t_n_nonzero = n_nonzero; @@ -3978,7 +3928,7 @@ template template inline -const SpMat& +SpMat& SpMat::for_each(functor F) { arma_extra_debug_sigprint(); @@ -4023,10 +3973,7 @@ const uword N = (*this).n_nonzero; - for(uword i=0; i < N; ++i) - { - F(values[i]); - } + for(uword i=0; i < N; ++i) { F(values[i]); } return *this; } @@ -4037,7 +3984,7 @@ template template inline -const SpMat& +SpMat& SpMat::transform(functor F) { arma_extra_debug_sigprint(); @@ -4069,7 +4016,7 @@ template inline -const SpMat& +SpMat& SpMat::replace(const eT old_val, const eT new_val) { arma_extra_debug_sigprint(); @@ -4095,7 +4042,7 @@ template inline -const SpMat& +SpMat& SpMat::clean(const typename get_pod_type::result threshold) { arma_extra_debug_sigprint(); @@ -4116,7 +4063,7 @@ template inline -const SpMat& +SpMat& SpMat::clamp(const eT min_val, const eT max_val) { arma_extra_debug_sigprint(); @@ -4147,17 +4094,14 @@ template inline -const SpMat& +SpMat& SpMat::zeros() { arma_extra_debug_sigprint(); const bool already_done = ( (sync_state != 1) && (n_nonzero == 0) ); - if(already_done == false) - { - init(n_rows, n_cols); - } + if(already_done == false) { init(n_rows, n_cols); } return *this; } @@ -4166,7 +4110,7 @@ template inline -const SpMat& +SpMat& SpMat::zeros(const uword in_elem) { arma_extra_debug_sigprint(); @@ -4187,17 +4131,14 @@ template inline -const SpMat& +SpMat& SpMat::zeros(const uword in_rows, const uword in_cols) { arma_extra_debug_sigprint(); const bool already_done = ( (sync_state != 1) && (n_nonzero == 0) && (n_rows == in_rows) && (n_cols == in_cols) ); - if(already_done == false) - { - init(in_rows, in_cols); - } + if(already_done == false) { init(in_rows, in_cols); } return *this; } @@ -4206,7 +4147,7 @@ template inline -const SpMat& +SpMat& SpMat::zeros(const SizeMat& s) { arma_extra_debug_sigprint(); @@ -4218,7 +4159,7 @@ template inline -const SpMat& +SpMat& SpMat::eye() { arma_extra_debug_sigprint(); @@ -4230,7 +4171,7 @@ template inline -const SpMat& +SpMat& SpMat::eye(const uword in_rows, const uword in_cols) { arma_extra_debug_sigprint(); @@ -4257,7 +4198,7 @@ template inline -const SpMat& +SpMat& SpMat::eye(const SizeMat& s) { arma_extra_debug_sigprint(); @@ -4269,7 +4210,7 @@ template inline -const SpMat& +SpMat& SpMat::speye() { arma_extra_debug_sigprint(); @@ -4281,7 +4222,7 @@ template inline -const SpMat& +SpMat& SpMat::speye(const uword in_n_rows, const uword in_n_cols) { arma_extra_debug_sigprint(); @@ -4293,7 +4234,7 @@ template inline -const SpMat& +SpMat& SpMat::speye(const SizeMat& s) { arma_extra_debug_sigprint(); @@ -4305,7 +4246,7 @@ template inline -const SpMat& +SpMat& SpMat::sprandu(const uword in_rows, const uword in_cols, const double density) { arma_extra_debug_sigprint(); @@ -4379,7 +4320,7 @@ template inline -const SpMat& +SpMat& SpMat::sprandu(const SizeMat& s, const double density) { arma_extra_debug_sigprint(); @@ -4391,7 +4332,7 @@ template inline -const SpMat& +SpMat& SpMat::sprandn(const uword in_rows, const uword in_cols, const double density) { arma_extra_debug_sigprint(); @@ -4465,7 +4406,7 @@ template inline -const SpMat& +SpMat& SpMat::sprandn(const SizeMat& s, const double density) { arma_extra_debug_sigprint(); @@ -4481,20 +4422,12 @@ SpMat::reset() { arma_extra_debug_sigprint(); - + switch(vec_state) { - default: - init(0, 0); - break; - - case 1: - init(0, 1); - break; - - case 2: - init(1, 0); - break; + default: init(0, 0); break; + case 1: init(0, 1); break; + case 2: init(1, 0); break; } } @@ -4520,13 +4453,11 @@ } #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) { - cache_mutex.lock(); + const std::lock_guard lock(cache_mutex); cache.reset(); sync_state = 0; - - cache_mutex.unlock(); } #else { @@ -4580,7 +4511,6 @@ //! save the matrix to a file template inline -arma_cold bool SpMat::save(const std::string name, const file_type type) const { @@ -4613,7 +4543,7 @@ save_okay = false; } - if(save_okay == false) { arma_debug_warn_level(3, "SpMat::save(): couldn't write; file: ", name); } + if(save_okay == false) { arma_debug_warn_level(3, "SpMat::save(): write failed; file: ", name); } return save_okay; } @@ -4622,7 +4552,6 @@ template inline -arma_cold bool SpMat::save(const csv_name& spec, const file_type type) const { @@ -4634,10 +4563,10 @@ 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); + 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 ); + const bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header) && (no_header == false); + 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:"); @@ -4648,8 +4577,6 @@ 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) ) @@ -4691,7 +4618,7 @@ 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); } + if(save_okay == false) { arma_debug_warn_level(3, "SpMat::save(): write failed; file: ", spec.filename); } return save_okay; } @@ -4701,7 +4628,6 @@ //! save the matrix to a stream template inline -arma_cold bool SpMat::save(std::ostream& os, const file_type type) const { @@ -4734,7 +4660,7 @@ save_okay = false; } - if(save_okay == false) { arma_debug_warn_level(3, "SpMat::save(): couldn't write to stream"); } + if(save_okay == false) { arma_debug_warn_level(3, "SpMat::save(): stream write failed"); } return save_okay; } @@ -4744,7 +4670,6 @@ //! load a matrix from a file template inline -arma_cold bool SpMat::load(const std::string name, const file_type type) { @@ -4790,7 +4715,7 @@ } else { - arma_debug_warn_level(3, "SpMat::load(): couldn't read; file: ", name); + arma_debug_warn_level(3, "SpMat::load(): read failed; file: ", name); } } @@ -4803,7 +4728,6 @@ template inline -arma_cold bool SpMat::load(const csv_name& spec, const file_type type) { @@ -4815,10 +4739,11 @@ 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); + 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 ); + const bool with_header = bool(spec.opts.flags & csv_opts::flag_with_header) && (no_header == false); + const bool use_semicolon = bool(spec.opts.flags & csv_opts::flag_semicolon ) || (type == ssv_ascii); + const bool strict = bool(spec.opts.flags & csv_opts::flag_strict ); arma_extra_debug_print("SpMat::load(csv_name): enabled flags:"); @@ -4826,10 +4751,11 @@ 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"); } + if(strict ) { arma_extra_debug_print("strict"); } - const char separator = (use_semicolon) ? char(';') : char(','); + if(strict) { arma_debug_warn_level(1, "SpMat::load(): option 'strict' not implemented for sparse matrices"); } - if(no_header) { with_header = false; } + const char separator = (use_semicolon) ? char(';') : char(','); bool load_okay = false; std::string err_msg; @@ -4864,7 +4790,7 @@ } else { - arma_debug_warn_level(3, "SpMat::load(): couldn't read; file: ", spec.filename); + arma_debug_warn_level(3, "SpMat::load(): read failed; file: ", spec.filename); } } else @@ -4892,7 +4818,6 @@ //! load a matrix from a stream template inline -arma_cold bool SpMat::load(std::istream& is, const file_type type) { @@ -4938,7 +4863,7 @@ } else { - arma_debug_warn_level(3, "SpMat::load(): couldn't load from stream"); + arma_debug_warn_level(3, "SpMat::load(): stream read failed"); } } @@ -4949,10 +4874,8 @@ -//! save the matrix to a file, without printing any error messages template inline -arma_cold bool SpMat::quiet_save(const std::string name, const file_type type) const { @@ -4963,10 +4886,8 @@ -//! save the matrix to a stream, without printing any error messages template inline -arma_cold bool SpMat::quiet_save(std::ostream& os, const file_type type) const { @@ -4977,10 +4898,8 @@ -//! load a matrix from a file, without printing any error messages template inline -arma_cold bool SpMat::quiet_load(const std::string name, const file_type type) { @@ -4991,10 +4910,8 @@ -//! load a matrix from a stream, without printing any error messages template inline -arma_cold bool SpMat::quiet_load(std::istream& is, const file_type type) { @@ -5039,7 +4956,6 @@ template inline void -arma_cold SpMat::init_cold(uword in_rows, uword in_cols, const uword new_n_nonzero) { arma_extra_debug_sigprint(); @@ -5155,13 +5071,13 @@ #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) if(x.sync_state == 1) { - x.cache_mutex.lock(); + const std::lock_guard lock(x.cache_mutex); + if(x.sync_state == 1) { (*this).init(x.cache); init_done = true; } - x.cache_mutex.unlock(); } #else if(x.sync_state == 1) @@ -5713,9 +5629,11 @@ const eT* old_values = values; + constexpr eT zero = eT(0); + for(uword i=0; i < old_n_nonzero; ++i) { - new_n_nonzero += (old_values[i] != eT(0)) ? uword(1) : uword(0); + new_n_nonzero += (old_values[i] != zero) ? uword(1) : uword(0); } if(new_n_nonzero != old_n_nonzero) @@ -5726,18 +5644,21 @@ uword new_index = 0; - const_iterator it = begin(); - const_iterator it_end = end(); + const_iterator it = cbegin(); + const_iterator it_end = cend(); for(; it != it_end; ++it) { const eT val = eT(*it); - if(val != eT(0)) + if(val != zero) { + const uword it_row = it.row(); + const uword it_col = it.col(); + access::rw(tmp.values[new_index]) = val; - access::rw(tmp.row_indices[new_index]) = it.row(); - access::rw(tmp.col_ptrs[it.col() + 1])++; + access::rw(tmp.row_indices[new_index]) = it_row; + access::rw(tmp.col_ptrs[it_col + 1])++; ++new_index; } } @@ -5777,6 +5698,8 @@ if(layout_ok) { + arma_extra_debug_print("SpMat::steal_mem(): stealing memory"); + x.sync_csc(); steal_mem_simple(x); @@ -5787,6 +5710,8 @@ } else { + arma_extra_debug_print("SpMat::steal_mem(): copying memory"); + (*this).operator=(x); } } @@ -6275,7 +6200,6 @@ template arma_inline -arma_warn_unused SpMat_MapMat_val SpMat::front() { @@ -6288,7 +6212,6 @@ template arma_inline -arma_warn_unused eT SpMat::front() const { @@ -6301,7 +6224,6 @@ template arma_inline -arma_warn_unused SpMat_MapMat_val SpMat::back() { @@ -6314,7 +6236,6 @@ template arma_inline -arma_warn_unused eT SpMat::back() const { @@ -6327,8 +6248,6 @@ template inline -arma_hot -arma_warn_unused eT SpMat::get_value(const uword i) const { @@ -6343,8 +6262,6 @@ template inline -arma_hot -arma_warn_unused eT SpMat::get_value(const uword in_row, const uword in_col) const { @@ -6359,8 +6276,6 @@ template inline -arma_hot -arma_warn_unused eT SpMat::get_value_csc(const uword i) const { @@ -6375,8 +6290,6 @@ template inline -arma_hot -arma_warn_unused const eT* SpMat::find_value_csc(const uword in_row, const uword in_col) const { @@ -6403,8 +6316,6 @@ template inline -arma_hot -arma_warn_unused eT SpMat::get_value_csc(const uword in_row, const uword in_col) const { @@ -6417,8 +6328,6 @@ template inline -arma_hot -arma_warn_unused bool SpMat::try_set_value_csc(const uword in_row, const uword in_col, const eT in_val) { @@ -6441,8 +6350,6 @@ template inline -arma_hot -arma_warn_unused bool SpMat::try_add_value_csc(const uword in_row, const uword in_col, const eT in_val) { @@ -6467,8 +6374,6 @@ template inline -arma_hot -arma_warn_unused bool SpMat::try_sub_value_csc(const uword in_row, const uword in_col, const eT in_val) { @@ -6493,8 +6398,6 @@ template inline -arma_hot -arma_warn_unused bool SpMat::try_mul_value_csc(const uword in_row, const uword in_col, const eT in_val) { @@ -6519,8 +6422,6 @@ template inline -arma_hot -arma_warn_unused bool SpMat::try_div_value_csc(const uword in_row, const uword in_col, const eT in_val) { @@ -6550,7 +6451,6 @@ */ template inline -arma_warn_unused eT& SpMat::insert_element(const uword in_row, const uword in_col, const eT val) { @@ -6759,11 +6659,9 @@ { if(sync_state == 0) { - cache_mutex.lock(); + const std::lock_guard lock(cache_mutex); sync_cache_simple(); - - cache_mutex.unlock(); } } #else @@ -6811,11 +6709,9 @@ #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) if(sync_state == 1) { - cache_mutex.lock(); + const std::lock_guard lock(cache_mutex); sync_csc_simple(); - - cache_mutex.unlock(); } #else { @@ -6931,7 +6827,7 @@ -#ifdef ARMA_EXTRA_SPMAT_MEAT +#if defined(ARMA_EXTRA_SPMAT_MEAT) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPMAT_MEAT) #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spop_mean_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spop_mean_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spop_mean_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spop_mean_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -125,7 +125,7 @@ out = acc; } - if(out.is_finite() == false) + if(out.internal_has_nonfinite()) { spop_mean::apply_noalias_slow(out, p, dim); } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spop_normalise_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spop_normalise_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spop_normalise_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spop_normalise_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -33,8 +33,8 @@ const uword p = expr.aux_uword_a; const uword dim = expr.aux_uword_b; - arma_debug_check( (p == 0), "normalise(): parameter 'p' must be greater than zero" ); - arma_debug_check( (dim > 1), "normalise(): parameter 'dim' must be 0 or 1" ); + arma_debug_check( (p == 0), "normalise(): unsupported vector norm type" ); + arma_debug_check( (dim > 1), "normalise(): parameter 'dim' must be 0 or 1" ); const unwrap_spmat U(expr.m); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spop_norm_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spop_norm_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spop_norm_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spop_norm_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -31,6 +31,8 @@ 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); + + template inline static typename get_pod_type::result vec_norm_k(const eT* mem, const uword N, const uword k); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spop_norm_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spop_norm_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spop_norm_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spop_norm_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -104,4 +104,26 @@ +template +inline +typename get_pod_type::result +spop_norm::vec_norm_k(const eT* mem, const uword N, const uword k) + { + arma_extra_debug_sigprint(); + + arma_debug_check( (k == 0), "norm(): unsupported vector norm type" ); + + // create a fake dense vector to allow reuse of code for dense vectors + Col fake_vector( access::rwp(mem), N, false ); + + const Proxy< Col > P_fake_vector(fake_vector); + + 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); } + + return op_norm::vec_norm_k(P_fake_vector, int(k)); + } + + + //! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spop_sum_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spop_sum_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spop_sum_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spop_sum_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -26,7 +26,7 @@ public: template - arma_hot inline static void apply(SpMat& out, const SpOp& in); + inline static void apply(SpMat& out, const SpOp& in); }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spop_sum_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spop_sum_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spop_sum_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spop_sum_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -22,7 +22,6 @@ template -arma_hot inline void spop_sum::apply(SpMat& out, const SpOp& in) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spop_vecnorm_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spop_vecnorm_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spop_vecnorm_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spop_vecnorm_bones.hpp 2016-06-16 16:27:01.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 spop_vecnorm +//! @{ + + +class spop_vecnorm + : public traits_op_xvec + { + public: + + template + inline static void apply(SpMat& out, const mtSpOp& expr); + + template + inline static void apply_direct(Mat< typename get_pod_type::result >& out, const SpMat& X, const uword k); + }; + + +// + + +class spop_vecnorm_ext + : public traits_op_xvec + { + public: + + template + inline static void apply(SpMat& out, const mtSpOp& expr); + + template + inline static void apply_direct(Mat< typename get_pod_type::result >& out, const SpMat& X, const uword method_id); + }; + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spop_vecnorm_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spop_vecnorm_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spop_vecnorm_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spop_vecnorm_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,209 @@ +// 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_vecnorm +//! @{ + + + +template +inline +void +spop_vecnorm::apply(SpMat& out, const mtSpOp& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + const uword k = expr.aux_uword_a; + const uword dim = expr.aux_uword_b; + + arma_debug_check( (k == 0), "vecnorm(): unsupported vector norm type" ); + arma_debug_check( (dim > 1), "vecnorm(): parameter 'dim' must be 0 or 1" ); + + const unwrap_spmat U(expr.m); + const SpMat& X = U.M; + + X.sync(); + + if(dim == 0) + { + Mat tmp; + + spop_vecnorm::apply_direct(tmp, X, k); + + out = tmp; + } + else + if(dim == 1) + { + Mat< T> tmp; + SpMat Xt; + + spop_strans::apply_noalias(Xt, X); + + spop_vecnorm::apply_direct(tmp, Xt, k); + + out = tmp.t(); + } + } + + + +template +inline +void +spop_vecnorm::apply_direct(Mat< typename get_pod_type::result >& out, const SpMat& X, const uword k) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + out.zeros(1, X.n_cols); + + T* out_mem = out.memptr(); + + for(uword col=0; col < X.n_cols; ++col) + { + const uword col_offset = X.col_ptrs[col ]; + const uword next_col_offset = X.col_ptrs[col + 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; + + T out_val = T(0); + + if(n_elem > 0) + { + const Col tmp(const_cast(start_ptr), n_elem, false, false); + + const Proxy< Col > P(tmp); + + if(k == uword(1)) { out_val = op_norm::vec_norm_1(P); } + if(k == uword(2)) { out_val = op_norm::vec_norm_2(P); } + } + + out_mem[col] = out_val; + } + } + + + +// + + + +template +inline +void +spop_vecnorm_ext::apply(SpMat& out, const mtSpOp& expr) + { + arma_extra_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + const uword method_id = expr.aux_uword_a; + const uword dim = expr.aux_uword_b; + + arma_debug_check( (method_id == 0), "vecnorm(): unsupported vector norm type" ); + arma_debug_check( (dim > 1), "vecnorm(): parameter 'dim' must be 0 or 1" ); + + const unwrap_spmat U(expr.m); + const SpMat& X = U.M; + + X.sync(); + + if(dim == 0) + { + Mat tmp; + + spop_vecnorm_ext::apply_direct(tmp, X, method_id); + + out = tmp; + } + else + if(dim == 1) + { + Mat< T> tmp; + SpMat Xt; + + spop_strans::apply_noalias(Xt, X); + + spop_vecnorm_ext::apply_direct(tmp, Xt, method_id); + + out = tmp.t(); + } + } + + + +template +inline +void +spop_vecnorm_ext::apply_direct(Mat< typename get_pod_type::result >& out, const SpMat& X, const uword method_id) + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type::result T; + + out.zeros(1, X.n_cols); + + T* out_mem = out.memptr(); + + for(uword col=0; col < X.n_cols; ++col) + { + const uword col_offset = X.col_ptrs[col ]; + const uword next_col_offset = X.col_ptrs[col + 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; + + T out_val = T(0); + + if(n_elem > 0) + { + const Col tmp(const_cast(start_ptr), n_elem, false, false); + + const Proxy< Col > P(tmp); + + if(method_id == uword(1)) + { + out_val = op_norm::vec_norm_max(P); + } + else + if(method_id == uword(2)) + { + const T tmp_val = op_norm::vec_norm_min(P); + + out_val = (n_elem < X.n_rows) ? T((std::min)(T(0), tmp_val)) : T(tmp_val); + } + } + + out_mem[col] = out_val; + } + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpProxy.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpProxy.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpProxy.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpProxy.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -144,7 +144,7 @@ } 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 uword get_n_nonzero() const { return Q.n_nonzero; } @@ -195,7 +195,7 @@ Q.sync(); } - 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 uword get_n_nonzero() const { return Q.n_nonzero; } @@ -300,7 +300,7 @@ } 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 uword get_n_nonzero() const { return Q.n_nonzero; } @@ -402,7 +402,7 @@ Q.m.sync(); } - 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 uword get_n_nonzero() const { return Q.n_nonzero; } @@ -454,7 +454,7 @@ } 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 uword get_n_nonzero() const { return Q.n_nonzero; } diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpRow_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpRow_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpRow_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpRow_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -56,9 +56,9 @@ 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; + arma_warn_unused inline const SpOp,spop_htrans> t() const; + arma_warn_unused inline const SpOp,spop_htrans> ht() const; + arma_warn_unused inline 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); @@ -75,7 +75,7 @@ inline row_iterator end_row(const uword row_num = 0); inline const_row_iterator end_row(const uword row_num = 0) const; - #ifdef ARMA_EXTRA_SPROW_PROTO + #if defined(ARMA_EXTRA_SPROW_PROTO) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPROW_PROTO) #endif }; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpRow_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpRow_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpRow_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpRow_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -204,7 +204,6 @@ template inline -arma_warn_unused const SpOp,spop_htrans> SpRow::t() const { @@ -215,7 +214,6 @@ template inline -arma_warn_unused const SpOp,spop_htrans> SpRow::ht() const { @@ -226,7 +224,6 @@ template inline -arma_warn_unused const SpOp,spop_strans> SpRow::st() const { @@ -427,7 +424,7 @@ -#ifdef ARMA_EXTRA_SPROW_MEAT +#if defined(ARMA_EXTRA_SPROW_MEAT) #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPROW_MEAT) #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spsolve_factoriser_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spsolve_factoriser_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spsolve_factoriser_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spsolve_factoriser_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,57 @@ +// 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 spsolve_factoriser +//! @{ + + + +class spsolve_factoriser + { + private: + + void_ptr worker_ptr = nullptr; + uword elem_type_indicator = 0; + uword n_rows = 0; + double rcond_value = double(0); + + template inline void delete_worker(); + + inline void cleanup(); + + + public: + + inline ~spsolve_factoriser(); + inline spsolve_factoriser(); + + inline void reset(); + + inline double rcond() const; + + template inline bool factorise(const SpBase& A_expr, const spsolve_opts_base& settings = spsolve_opts_none(), const typename arma_blas_type_only::result* junk = nullptr); + + template inline bool solve(Mat& X, const Base& B_expr, const typename arma_blas_type_only::result* junk = nullptr); + + inline spsolve_factoriser(const spsolve_factoriser&) = delete; + inline void operator= (const spsolve_factoriser&) = delete; + }; + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/spsolve_factoriser_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/spsolve_factoriser_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/spsolve_factoriser_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/spsolve_factoriser_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,289 @@ +// 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 spsolve_factoriser +//! @{ + + + +template +inline +void +spsolve_factoriser::delete_worker() + { + arma_extra_debug_sigprint(); + + if(worker_ptr != nullptr) + { + worker_type* ptr = reinterpret_cast(worker_ptr); + + delete ptr; + + worker_ptr = nullptr; + } + } + + + +inline +void +spsolve_factoriser::cleanup() + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_SUPERLU) + { + if(elem_type_indicator == 1) { delete_worker< superlu_worker< float> >(); } + else if(elem_type_indicator == 2) { delete_worker< superlu_worker< double> >(); } + else if(elem_type_indicator == 3) { delete_worker< superlu_worker< cx_float> >(); } + else if(elem_type_indicator == 4) { delete_worker< superlu_worker >(); } + } + #endif + + worker_ptr = nullptr; + elem_type_indicator = 0; + n_rows = 0; + rcond_value = double(0); + } + + + +inline +spsolve_factoriser::~spsolve_factoriser() + { + arma_extra_debug_sigprint_this(this); + + cleanup(); + } + + + +inline +spsolve_factoriser::spsolve_factoriser() + { + arma_extra_debug_sigprint_this(this); + } + + + +inline +void +spsolve_factoriser::reset() + { + arma_extra_debug_sigprint(); + + cleanup(); + } + + + +inline +double +spsolve_factoriser::rcond() const + { + arma_extra_debug_sigprint(); + + return rcond_value; + } + + + +template +inline +bool +spsolve_factoriser::factorise + ( + const SpBase& A_expr, + const spsolve_opts_base& settings, + const typename arma_blas_type_only::result* junk + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + #if defined(ARMA_USE_SUPERLU) + { + typedef typename T1::elem_type eT; + typedef typename get_pod_type::result T; + + typedef superlu_worker worker_type; + + // + + cleanup(); + + // + + const unwrap_spmat U(A_expr.get_ref()); + const SpMat& A = U.M; + + if(A.is_square() == false) + { + arma_debug_warn_level(1, "spsolve_factoriser::factorise(): solving under-determined / over-determined systems is currently not supported"); + return false; + } + + n_rows = A.n_rows; + + // + + superlu_opts superlu_opts_default; + + const superlu_opts& opts = (settings.id == 1) ? static_cast(settings) : superlu_opts_default; + + if( (opts.pivot_thresh < double(0)) || (opts.pivot_thresh > double(1)) ) + { + arma_debug_warn_level(1, "spsolve_factoriser::factorise(): pivot_thresh must be in the [0,1] interval" ); + return false; + } + + // + + worker_ptr = new(std::nothrow) worker_type; + + if(worker_ptr == nullptr) + { + arma_debug_warn_level(3, "spsolve_factoriser::factorise(): could not construct worker object"); + return false; + } + + // + + if( is_float::value) { elem_type_indicator = 1; } + else if( is_double::value) { elem_type_indicator = 2; } + else if( is_cx_float::value) { elem_type_indicator = 3; } + else if(is_cx_double::value) { elem_type_indicator = 4; } + + // + + worker_type* local_worker_ptr = reinterpret_cast(worker_ptr); + worker_type& local_worker_ref = (*local_worker_ptr); + + // + + T local_rcond_value = T(0); + + const bool status = local_worker_ref.factorise(local_rcond_value, A, opts); + + rcond_value = double(local_rcond_value); + + if( (status == false) || arma_isnan(local_rcond_value) || ((opts.allow_ugly == false) && (local_rcond_value < std::numeric_limits::epsilon())) ) + { + arma_debug_warn_level(3, "spsolve_factoriser::factorise(): factorisation failed; rcond: ", local_rcond_value); + delete_worker(); + return false; + } + + return true; + } + #else + { + arma_ignore(A_expr); + arma_ignore(settings); + arma_stop_logic_error("spsolve_factoriser::factorise(): use of SuperLU must be enabled"); + return false; + } + #endif + } + + + +template +inline +bool +spsolve_factoriser::solve + ( + Mat& X, + const Base& B_expr, + const typename arma_blas_type_only::result* junk + ) + { + arma_extra_debug_sigprint(); + arma_ignore(junk); + + #if defined(ARMA_USE_SUPERLU) + { + typedef typename T1::elem_type eT; + + typedef superlu_worker worker_type; + + if(worker_ptr == nullptr) + { + arma_debug_warn_level(2, "spsolve_factoriser::solve(): no factorisation available"); + X.soft_reset(); + return false; + } + + bool type_mismatch = false; + + if( (is_float::value) && (elem_type_indicator != 1) ) { type_mismatch = true; } + else if( (is_double::value) && (elem_type_indicator != 2) ) { type_mismatch = true; } + else if( (is_cx_float::value) && (elem_type_indicator != 3) ) { type_mismatch = true; } + else if((is_cx_double::value) && (elem_type_indicator != 4) ) { type_mismatch = true; } + + if(type_mismatch) + { + arma_debug_warn_level(1, "spsolve_factoriser::solve(): matrix type mismatch"); + X.soft_reset(); + return false; + } + + const quasi_unwrap U(B_expr.get_ref()); + const Mat& B = U.M; + + if(n_rows != B.n_rows) + { + arma_debug_warn_level(1, "spsolve_factoriser::solve(): matrix size mismatch"); + X.soft_reset(); + return false; + } + + const bool is_alias = U.is_alias(X); + + Mat tmp; + Mat& out = is_alias ? tmp : X; + + worker_type* local_worker_ptr = reinterpret_cast(worker_ptr); + worker_type& local_worker_ref = (*local_worker_ptr); + + const bool status = local_worker_ref.solve(out,B); + + if(is_alias) { X.steal_mem(tmp); } + + if(status == false) + { + arma_debug_warn_level(3, "spsolve_factoriser::solve(): solution not found"); + X.soft_reset(); + return false; + } + + return true; + } + #else + { + arma_ignore(X); + arma_ignore(B_expr); + arma_stop_logic_error("spsolve_factoriser::solve(): use of SuperLU must be enabled"); + return false; + } + #endif + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpSubview_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpSubview_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -197,23 +197,23 @@ // 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); + arma_hot inline const_iterator& operator++(); + arma_warn_unused inline const_iterator operator++(int); - inline arma_hot const_iterator& operator--(); - inline arma_warn_unused const_iterator operator--(int); + arma_hot inline const_iterator& operator--(); + arma_warn_unused inline const_iterator operator--(int); - inline arma_hot bool operator!=(const const_iterator& rhs) const; - inline arma_hot bool operator==(const const_iterator& rhs) const; + arma_hot inline bool operator!=(const const_iterator& rhs) const; + arma_hot inline 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; + arma_hot inline bool operator!=(const typename SpMat::const_iterator& rhs) const; + arma_hot inline 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; + arma_hot inline bool operator!=(const const_row_iterator& rhs) const; + arma_hot inline 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_hot inline bool operator!=(const typename SpMat::const_row_iterator& rhs) const; + arma_hot inline bool operator==(const typename SpMat::const_row_iterator& rhs) const; arma_aligned uword skip_pos; // not used in row_iterator or const_row_iterator }; @@ -227,14 +227,14 @@ 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< SpSubview > operator*(); + arma_hot inline SpValProxy< SpSubview > operator*(); // overloads needed for return type correctness - inline arma_hot iterator& operator++(); - inline arma_warn_unused iterator operator++(int); + arma_hot inline iterator& operator++(); + arma_warn_unused inline iterator operator++(int); - inline arma_hot iterator& operator--(); - inline arma_warn_unused iterator operator--(int); + arma_hot inline iterator& operator--(); + arma_warn_unused inline iterator operator--(int); // This has a different value_type than iterator_base. typedef SpValProxy< SpSubview > value_type; @@ -251,11 +251,11 @@ 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); + arma_hot inline const_row_iterator& operator++(); + arma_warn_unused inline const_row_iterator operator++(int); - inline arma_hot const_row_iterator& operator--(); - inline arma_warn_unused const_row_iterator operator--(int); + arma_hot inline const_row_iterator& operator--(); + arma_warn_unused inline 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. @@ -264,17 +264,17 @@ 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; + arma_hot inline bool operator!=(const const_iterator& rhs) const; + arma_hot inline 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; + arma_hot inline bool operator!=(const typename SpMat::const_iterator& rhs) const; + arma_hot inline 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; + arma_hot inline bool operator!=(const const_row_iterator& rhs) const; + arma_hot inline 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_hot inline bool operator!=(const typename SpMat::const_row_iterator& rhs) const; + arma_hot inline bool operator==(const typename SpMat::const_row_iterator& rhs) const; }; class row_iterator : public const_row_iterator @@ -285,14 +285,14 @@ 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< SpSubview > operator*(); + arma_hot inline SpValProxy< SpSubview > operator*(); // overloads needed for return type correctness - inline arma_hot row_iterator& operator++(); - inline arma_warn_unused row_iterator operator++(int); + arma_hot inline row_iterator& operator++(); + arma_warn_unused inline row_iterator operator++(int); - inline arma_hot row_iterator& operator--(); - inline arma_warn_unused row_iterator operator--(int); + arma_hot inline row_iterator& operator--(); + arma_warn_unused inline row_iterator operator--(int); // This has a different value_type than iterator_base. typedef SpValProxy< SpSubview > value_type; @@ -331,8 +331,8 @@ 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); + arma_warn_unused inline 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); inline void invalidate_cache() const; }; @@ -357,9 +357,9 @@ 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; + arma_warn_unused inline const SpOp,spop_htrans> t() const; + arma_warn_unused inline const SpOp,spop_htrans> ht() const; + arma_warn_unused inline const SpOp,spop_strans> st() const; protected: @@ -395,9 +395,9 @@ 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; + arma_warn_unused inline const SpOp,spop_htrans> t() const; + arma_warn_unused inline const SpOp,spop_htrans> ht() const; + arma_warn_unused inline const SpOp,spop_strans> st() const; protected: diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_iterators_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpSubview_iterators_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_iterators_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpSubview_iterators_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -280,7 +280,6 @@ template inline -arma_hot typename SpSubview::const_iterator& SpSubview::const_iterator::operator++() { @@ -339,7 +338,6 @@ template inline -arma_warn_unused typename SpSubview::const_iterator SpSubview::const_iterator::operator++(int) { @@ -354,7 +352,6 @@ template inline -arma_hot typename SpSubview::const_iterator& SpSubview::const_iterator::operator--() { @@ -410,7 +407,6 @@ template inline -arma_warn_unused typename SpSubview::const_iterator SpSubview::const_iterator::operator--(int) { @@ -425,7 +421,6 @@ template inline -arma_hot bool SpSubview::const_iterator::operator==(const const_iterator& rhs) const { @@ -436,7 +431,6 @@ template inline -arma_hot bool SpSubview::const_iterator::operator!=(const const_iterator& rhs) const { @@ -447,7 +441,6 @@ template inline -arma_hot bool SpSubview::const_iterator::operator==(const typename SpMat::const_iterator& rhs) const { @@ -458,7 +451,6 @@ template inline -arma_hot bool SpSubview::const_iterator::operator!=(const typename SpMat::const_iterator& rhs) const { @@ -469,7 +461,6 @@ template inline -arma_hot bool SpSubview::const_iterator::operator==(const const_row_iterator& rhs) const { @@ -480,7 +471,6 @@ template inline -arma_hot bool SpSubview::const_iterator::operator!=(const const_row_iterator& rhs) const { @@ -491,7 +481,6 @@ template inline -arma_hot bool SpSubview::const_iterator::operator==(const typename SpMat::const_row_iterator& rhs) const { @@ -502,7 +491,6 @@ template inline -arma_hot bool SpSubview::const_iterator::operator!=(const typename SpMat::const_row_iterator& rhs) const { @@ -517,7 +505,6 @@ template inline -arma_hot SpValProxy< SpSubview > SpSubview::iterator::operator*() { @@ -532,7 +519,6 @@ template inline -arma_hot typename SpSubview::iterator& SpSubview::iterator::operator++() { @@ -544,7 +530,6 @@ template inline -arma_warn_unused typename SpSubview::iterator SpSubview::iterator::operator++(int) { @@ -559,7 +544,6 @@ template inline -arma_hot typename SpSubview::iterator& SpSubview::iterator::operator--() { @@ -571,7 +555,6 @@ template inline -arma_warn_unused typename SpSubview::iterator SpSubview::iterator::operator--(int) { @@ -770,7 +753,6 @@ template inline -arma_hot typename SpSubview::const_row_iterator& SpSubview::const_row_iterator::operator++() { @@ -897,7 +879,6 @@ template inline -arma_warn_unused typename SpSubview::const_row_iterator SpSubview::const_row_iterator::operator++(int) { @@ -912,7 +893,6 @@ template inline -arma_hot typename SpSubview::const_row_iterator& SpSubview::const_row_iterator::operator--() { @@ -1012,7 +992,6 @@ template inline -arma_warn_unused typename SpSubview::const_row_iterator SpSubview::const_row_iterator::operator--(int) { @@ -1027,7 +1006,6 @@ template inline -arma_hot bool SpSubview::const_row_iterator::operator==(const const_iterator& rhs) const { @@ -1038,7 +1016,6 @@ template inline -arma_hot bool SpSubview::const_row_iterator::operator!=(const const_iterator& rhs) const { @@ -1049,7 +1026,6 @@ template inline -arma_hot bool SpSubview::const_row_iterator::operator==(const typename SpMat::const_iterator& rhs) const { @@ -1060,7 +1036,6 @@ template inline -arma_hot bool SpSubview::const_row_iterator::operator!=(const typename SpMat::const_iterator& rhs) const { @@ -1071,7 +1046,6 @@ template inline -arma_hot bool SpSubview::const_row_iterator::operator==(const const_row_iterator& rhs) const { @@ -1082,7 +1056,6 @@ template inline -arma_hot bool SpSubview::const_row_iterator::operator!=(const const_row_iterator& rhs) const { @@ -1093,7 +1066,6 @@ template inline -arma_hot bool SpSubview::const_row_iterator::operator==(const typename SpMat::const_row_iterator& rhs) const { @@ -1104,7 +1076,6 @@ template inline -arma_hot bool SpSubview::const_row_iterator::operator!=(const typename SpMat::const_row_iterator& rhs) const { @@ -1119,7 +1090,6 @@ template inline -arma_hot SpValProxy< SpSubview > SpSubview::row_iterator::operator*() { @@ -1134,7 +1104,6 @@ template inline -arma_hot typename SpSubview::row_iterator& SpSubview::row_iterator::operator++() { @@ -1146,7 +1115,6 @@ template inline -arma_warn_unused typename SpSubview::row_iterator SpSubview::row_iterator::operator++(int) { @@ -1161,7 +1129,6 @@ template inline -arma_hot typename SpSubview::row_iterator& SpSubview::row_iterator::operator--() { @@ -1173,7 +1140,6 @@ template inline -arma_warn_unused typename SpSubview::row_iterator SpSubview::row_iterator::operator--(int) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpSubview_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpSubview_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpSubview_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -354,7 +354,60 @@ { arma_extra_debug_sigprint(); - return (*this).operator=( (*this) % x.get_ref() ); + SpSubview& sv = (*this); + + const quasi_unwrap U(x.get_ref()); + const Mat& B = U.M; + + arma_debug_assert_same_size(sv.n_rows, sv.n_cols, B.n_rows, B.n_cols, "element-wise multiplication"); + + SpMat& sv_m = access::rw(sv.m); + + sv_m.sync_csc(); + sv_m.invalidate_cache(); + + const uword m_row_start = sv.aux_row1; + const uword m_row_end = sv.aux_row1 + sv.n_rows - 1; + + const uword m_col_start = sv.aux_col1; + const uword m_col_end = sv.aux_col1 + sv.n_cols - 1; + + constexpr eT zero = eT(0); + + bool has_zero = false; + uword count = 0; + + for(uword m_col = m_col_start; m_col <= m_col_end; ++m_col) + { + const uword sv_col = m_col - m_col_start; + + const uword index_start = sv_m.col_ptrs[m_col ]; + const uword index_end = sv_m.col_ptrs[m_col + 1]; + + for(uword i=index_start; i < index_end; ++i) + { + const uword m_row = sv_m.row_indices[i]; + + if(m_row < m_row_start) { continue; } + if(m_row > m_row_end ) { break; } + + const uword sv_row = m_row - m_row_start; + + eT& m_val = access::rw(sv_m.values[i]); + + const eT result = m_val * B.at(sv_row, sv_col); + + m_val = result; + + if(result == zero) { has_zero = true; } else { ++count; } + } + } + + if(has_zero) { sv_m.remove_zeros(); } + + access::rw(sv.n_nonzero) = count; + + return (*this); } @@ -367,7 +420,68 @@ { arma_extra_debug_sigprint(); - return (*this).operator=( (*this) / x.get_ref() ); + const SpSubview& A = (*this); + + const quasi_unwrap U(x.get_ref()); + const Mat& B = U.M; + + arma_debug_assert_same_size(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "element-wise division"); + + bool result_ok = true; + + constexpr eT zero = eT(0); + + const uword B_n_rows = B.n_rows; + const uword B_n_cols = B.n_cols; + + for(uword c=0; c < B_n_cols; ++c) + { + for(uword r=0; r < B_n_rows; ++r) + { + // a zero in B and A at the same location implies the division result is NaN; + // hence a zero in A (not stored) needs to be changed into a non-zero + + // for efficiency, an element in B is checked before checking the corresponding element in A + + if((B.at(r,c) == zero) && (A.at(r,c) == zero)) { result_ok = false; break; } + } + + if(result_ok == false) { break; } + } + + if(result_ok) + { + const_iterator cit = A.begin(); + const_iterator cit_end = A.end(); + + while(cit != cit_end) + { + const eT tmp = (*cit) / B.at(cit.row(), cit.col()); + + if(tmp == zero) { result_ok = false; break; } + + ++cit; + } + } + + if(result_ok) + { + iterator it = (*this).begin(); + iterator it_end = (*this).end(); + + while(it != it_end) + { + (*it) /= B.at(it.row(), it.col()); + + ++it; + } + } + else + { + (*this).operator=( (*this) / B ); + } + + return (*this); } @@ -941,7 +1055,6 @@ template -arma_hot inline SpSubview_MapMat_val SpSubview::operator[](const uword i) @@ -955,7 +1068,6 @@ template -arma_hot inline eT SpSubview::operator[](const uword i) const @@ -969,7 +1081,6 @@ template -arma_hot inline SpSubview_MapMat_val SpSubview::operator()(const uword i) @@ -985,7 +1096,6 @@ template -arma_hot inline eT SpSubview::operator()(const uword i) const @@ -1001,7 +1111,6 @@ template -arma_hot inline SpSubview_MapMat_val SpSubview::operator()(const uword in_row, const uword in_col) @@ -1014,7 +1123,6 @@ template -arma_hot inline eT SpSubview::operator()(const uword in_row, const uword in_col) const @@ -1027,7 +1135,6 @@ template -arma_hot inline SpSubview_MapMat_val SpSubview::at(const uword i) @@ -1041,7 +1148,6 @@ template -arma_hot inline eT SpSubview::at(const uword i) const @@ -1055,7 +1161,6 @@ template -arma_hot inline SpSubview_MapMat_val SpSubview::at(const uword in_row, const uword in_col) @@ -1066,7 +1171,6 @@ template -arma_hot inline eT SpSubview::at(const uword in_row, const uword in_col) const @@ -1470,6 +1574,8 @@ typename SpSubview::iterator SpSubview::begin() { + m.sync_csc(); + return iterator(*this); } @@ -1642,7 +1748,6 @@ template inline -arma_warn_unused eT& SpSubview::insert_element(const uword in_row, const uword in_col, const eT in_val) { @@ -1764,7 +1869,6 @@ template inline -arma_warn_unused const SpOp,spop_htrans> SpSubview_col::t() const { @@ -1775,7 +1879,6 @@ template inline -arma_warn_unused const SpOp,spop_htrans> SpSubview_col::ht() const { @@ -1786,7 +1889,6 @@ template inline -arma_warn_unused const SpOp,spop_strans> SpSubview_col::st() const { @@ -1873,7 +1975,6 @@ template inline -arma_warn_unused const SpOp,spop_htrans> SpSubview_row::t() const { @@ -1884,7 +1985,6 @@ template inline -arma_warn_unused const SpOp,spop_htrans> SpSubview_row::ht() const { @@ -1895,7 +1995,6 @@ template inline -arma_warn_unused const SpOp,spop_strans> SpSubview_row::st() const { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpToDGlue_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpToDGlue_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpToDGlue_bones.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpToDGlue_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,45 @@ +// 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 SpToDGlue +//! @{ + + + +template +class SpToDGlue : public Base< typename T1::elem_type, SpToDGlue > + { + public: + + typedef typename T1::elem_type elem_type; + typedef typename get_pod_type::result pod_type; + + inline explicit SpToDGlue(const T1& in_A, const T2& in_B); + inline ~SpToDGlue(); + + const T1& A; //!< first operand; must be derived from Base or SpBase + const T2& B; //!< second operand; must be derived from Base or SpBase + + 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; + }; + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/SpToDGlue_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/SpToDGlue_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/SpToDGlue_meat.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/SpToDGlue_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,44 @@ +// 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 SpToDGlue +//! @{ + + + +template +inline +SpToDGlue::SpToDGlue(const T1& in_A, const T2& in_B) + : A(in_A) + , B(in_B) + { + arma_extra_debug_sigprint(); + } + + + +template +inline +SpToDGlue::~SpToDGlue() + { + arma_extra_debug_sigprint(); + } + + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/strip.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/strip.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/strip.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/strip.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -73,19 +73,19 @@ const T1& M; - static constexpr bool do_inv = false; - static constexpr bool do_inv_sympd = false; + static constexpr bool do_inv_gen = false; + static constexpr bool do_inv_spd = false; }; template -struct strip_inv< Op > +struct strip_inv< Op > { typedef T1 stored_type; inline - strip_inv(const Op& X) + strip_inv(const Op& X) : M(X.m) { arma_extra_debug_sigprint(); @@ -93,19 +93,19 @@ const T1& M; - static constexpr bool do_inv = true; - static constexpr bool do_inv_sympd = false; + static constexpr bool do_inv_gen = true; + static constexpr bool do_inv_spd = false; }; template -struct strip_inv< Op > +struct strip_inv< Op > { typedef T1 stored_type; inline - strip_inv(const Op& X) + strip_inv(const Op& X) : M(X.m) { arma_extra_debug_sigprint(); @@ -113,8 +113,8 @@ const T1& M; - static constexpr bool do_inv = true; - static constexpr bool do_inv_sympd = true; + static constexpr bool do_inv_gen = false; + static constexpr bool do_inv_spd = true; }; @@ -163,5 +163,69 @@ }; + +// + + + +template +struct sp_strip_trans + { + typedef T1 stored_type; + + inline + sp_strip_trans(const T1& X) + : M(X) + { + arma_extra_debug_sigprint(); + } + + static constexpr bool do_htrans = false; + static constexpr bool do_strans = false; + + const T1& M; + }; + + + +template +struct sp_strip_trans< SpOp > + { + typedef T1 stored_type; + + inline + sp_strip_trans(const SpOp& X) + : M(X.m) + { + arma_extra_debug_sigprint(); + } + + static constexpr bool do_htrans = true; + static constexpr bool do_strans = false; + + const T1& M; + }; + + + +template +struct sp_strip_trans< SpOp > + { + typedef T1 stored_type; + + inline + sp_strip_trans(const SpOp& X) + : M(X.m) + { + arma_extra_debug_sigprint(); + } + + static constexpr bool do_htrans = false; + static constexpr bool do_strans = true; + + const T1& M; + }; + + //! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -119,25 +119,25 @@ inline void randu(); inline void randn(); - inline arma_warn_unused eT at_alt (const uword ii) const; + arma_warn_unused inline 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; + arma_warn_unused inline eT& operator[](const uword ii); + arma_warn_unused 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; + arma_warn_unused inline eT& operator()(const uword ii); + arma_warn_unused inline 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; + arma_warn_unused inline eT& operator()(const uword in_row, const uword in_col); + arma_warn_unused inline 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_warn_unused inline eT& at(const uword in_row, const uword in_col); + arma_warn_unused inline eT at(const uword in_row, const uword in_col) const; - inline arma_warn_unused eT& front(); - inline arma_warn_unused eT front() const; + arma_warn_unused inline eT& front(); + arma_warn_unused inline eT front() const; - inline arma_warn_unused eT& back(); - inline arma_warn_unused eT back() const; + arma_warn_unused inline eT& back(); + arma_warn_unused inline eT back() const; arma_inline eT* colptr(const uword in_col); arma_inline const eT* colptr(const uword in_col) const; @@ -145,12 +145,13 @@ template inline bool check_overlap(const subview& x) const; - 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; + arma_warn_unused inline bool is_vec() const; + arma_warn_unused inline bool is_finite() const; + arma_warn_unused inline bool is_zero(const pod_type tol = 0) const; + + arma_warn_unused inline bool has_inf() const; + arma_warn_unused inline bool has_nan() const; + arma_warn_unused inline bool has_nonfinite() const; inline subview_row row(const uword row_num); inline const subview_row row(const uword row_num) const; @@ -211,15 +212,15 @@ inline iterator(const iterator& X); inline iterator(subview& in_sv, const uword in_row, const uword in_col); - inline arma_warn_unused eT& operator*(); + arma_warn_unused inline eT& operator*(); - inline iterator& operator++(); - inline arma_warn_unused iterator operator++(int); + inline iterator& operator++(); + arma_warn_unused inline iterator operator++(int); - inline arma_warn_unused bool operator==(const iterator& rhs) const; - inline arma_warn_unused bool operator!=(const iterator& rhs) const; - inline arma_warn_unused bool operator==(const const_iterator& rhs) const; - inline arma_warn_unused bool operator!=(const const_iterator& rhs) const; + arma_warn_unused inline bool operator==(const iterator& rhs) const; + arma_warn_unused inline bool operator!=(const iterator& rhs) const; + arma_warn_unused inline bool operator==(const const_iterator& rhs) const; + arma_warn_unused inline bool operator!=(const const_iterator& rhs) const; typedef std::forward_iterator_tag iterator_category; typedef eT value_type; @@ -246,15 +247,15 @@ inline const_iterator(const const_iterator& X); inline const_iterator(const subview& in_sv, const uword in_row, const uword in_col); - inline arma_warn_unused const eT& operator*(); + arma_warn_unused inline const eT& operator*(); - inline const_iterator& operator++(); - inline arma_warn_unused const_iterator operator++(int); + inline const_iterator& operator++(); + arma_warn_unused inline const_iterator operator++(int); - inline arma_warn_unused bool operator==(const iterator& rhs) const; - inline arma_warn_unused bool operator!=(const iterator& rhs) const; - inline arma_warn_unused bool operator==(const const_iterator& rhs) const; - inline arma_warn_unused bool operator!=(const const_iterator& rhs) const; + arma_warn_unused inline bool operator==(const iterator& rhs) const; + arma_warn_unused inline bool operator!=(const iterator& rhs) const; + arma_warn_unused inline bool operator==(const const_iterator& rhs) const; + arma_warn_unused inline bool operator!=(const const_iterator& rhs) const; // So that we satisfy the STL iterator types. typedef std::forward_iterator_tag iterator_category; @@ -283,15 +284,15 @@ inline row_iterator(const row_iterator& X); inline row_iterator(subview& in_sv, const uword in_row, const uword in_col); - inline arma_warn_unused eT& operator* (); + arma_warn_unused inline eT& operator* (); - inline row_iterator& operator++(); - inline arma_warn_unused row_iterator operator++(int); + inline row_iterator& operator++(); + arma_warn_unused inline row_iterator operator++(int); - inline arma_warn_unused bool operator!=(const row_iterator& X) const; - inline arma_warn_unused bool operator==(const row_iterator& X) const; - inline arma_warn_unused bool operator!=(const const_row_iterator& X) const; - inline arma_warn_unused bool operator==(const const_row_iterator& X) const; + arma_warn_unused inline bool operator!=(const row_iterator& X) const; + arma_warn_unused inline bool operator==(const row_iterator& X) const; + arma_warn_unused inline bool operator!=(const const_row_iterator& X) const; + arma_warn_unused inline bool operator==(const const_row_iterator& X) const; typedef std::forward_iterator_tag iterator_category; typedef eT value_type; @@ -317,15 +318,15 @@ inline const_row_iterator(const const_row_iterator& X); inline const_row_iterator(const subview& in_sv, const uword in_row, const uword in_col); - inline arma_warn_unused const eT& operator*() const; + arma_warn_unused inline const eT& operator*() const; - inline const_row_iterator& operator++(); - inline arma_warn_unused const_row_iterator operator++(int); + inline const_row_iterator& operator++(); + arma_warn_unused inline const_row_iterator operator++(int); - inline arma_warn_unused bool operator!=(const row_iterator& X) const; - inline arma_warn_unused bool operator==(const row_iterator& X) const; - inline arma_warn_unused bool operator!=(const const_row_iterator& X) const; - inline arma_warn_unused bool operator==(const const_row_iterator& X) const; + arma_warn_unused inline bool operator!=(const row_iterator& X) const; + arma_warn_unused inline bool operator==(const row_iterator& X) const; + arma_warn_unused inline bool operator!=(const const_row_iterator& X) const; + arma_warn_unused inline bool operator==(const const_row_iterator& X) const; typedef std::forward_iterator_tag iterator_category; typedef eT value_type; @@ -382,11 +383,11 @@ 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_warn_unused arma_inline const Op,op_htrans> t() const; + arma_warn_unused arma_inline const Op,op_htrans> ht() const; + arma_warn_unused arma_inline const Op,op_strans> st() const; - arma_inline arma_warn_unused const Op,op_strans> as_row() const; + arma_warn_unused arma_inline const Op,op_strans> as_row() const; inline void fill(const eT val); inline void zeros(); @@ -424,14 +425,14 @@ inline subview_col tail(const uword N); inline const subview_col tail(const uword N) const; - inline arma_warn_unused eT min() const; - inline arma_warn_unused eT max() const; + arma_warn_unused inline eT min() const; + arma_warn_unused inline eT max() const; inline eT min(uword& index_of_min_val) const; inline eT max(uword& index_of_max_val) const; - inline arma_warn_unused uword index_min() const; - inline arma_warn_unused uword index_max() const; + arma_warn_unused inline uword index_min() const; + arma_warn_unused inline uword index_max() const; inline subview_col(const subview_col& in); inline subview_col( subview_col&& in); @@ -478,25 +479,25 @@ 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_warn_unused arma_inline const Op,op_htrans> t() const; + arma_warn_unused arma_inline const Op,op_htrans> ht() const; + arma_warn_unused arma_inline const Op,op_strans> st() const; - arma_inline arma_warn_unused const Op,op_vectorise_col> as_col() const; + arma_warn_unused arma_inline const Op,op_vectorise_col> as_col() const; - inline arma_warn_unused eT at_alt (const uword ii) const; + arma_warn_unused inline 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; + arma_warn_unused inline eT& operator[](const uword ii); + arma_warn_unused 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; + arma_warn_unused inline eT& operator()(const uword ii); + arma_warn_unused inline 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; + arma_warn_unused inline eT& operator()(const uword in_row, const uword in_col); + arma_warn_unused inline 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_warn_unused inline eT& at(const uword in_row, const uword in_col); + arma_warn_unused inline 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; @@ -535,11 +536,11 @@ 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_warn_unused arma_inline const Op,op_htrans> t() const; + arma_warn_unused arma_inline const Op,op_htrans> ht() const; + arma_warn_unused arma_inline const Op,op_strans> st() const; - arma_inline arma_warn_unused const Op,op_strans> as_col() const; + arma_warn_unused arma_inline const Op,op_strans> as_col() const; inline eT at_alt (const uword i) const; @@ -570,8 +571,8 @@ inline subview_row tail(const uword N); inline const subview_row tail(const uword N) const; - inline arma_warn_unused uword index_min() const; - inline arma_warn_unused uword index_max() const; + arma_warn_unused inline uword index_min() const; + arma_warn_unused inline uword index_max() const; inline typename subview::row_iterator begin(); inline typename subview::const_row_iterator begin() const; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_cube_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_cube_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -120,11 +120,12 @@ inline void randu(); inline void randn(); - inline arma_warn_unused bool is_finite() const; - inline arma_warn_unused bool is_zero(const pod_type tol = 0) const; + arma_warn_unused inline bool is_finite() const; + arma_warn_unused inline 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; + arma_warn_unused inline bool has_inf() const; + arma_warn_unused inline bool has_nan() const; + arma_warn_unused inline bool has_nonfinite() const; inline eT at_alt (const uword i) const; @@ -159,15 +160,15 @@ inline iterator(const iterator& X); inline iterator(subview_cube& in_sv, const uword in_row, const uword in_col, const uword in_slice); - inline arma_warn_unused eT& operator*(); + arma_warn_unused inline eT& operator*(); - inline iterator& operator++(); - inline arma_warn_unused iterator operator++(int); + inline iterator& operator++(); + arma_warn_unused inline iterator operator++(int); - inline arma_warn_unused bool operator==(const iterator& rhs) const; - inline arma_warn_unused bool operator!=(const iterator& rhs) const; - inline arma_warn_unused bool operator==(const const_iterator& rhs) const; - inline arma_warn_unused bool operator!=(const const_iterator& rhs) const; + arma_warn_unused inline bool operator==(const iterator& rhs) const; + arma_warn_unused inline bool operator!=(const iterator& rhs) const; + arma_warn_unused inline bool operator==(const const_iterator& rhs) const; + arma_warn_unused inline bool operator!=(const const_iterator& rhs) const; typedef std::forward_iterator_tag iterator_category; typedef eT value_type; @@ -198,15 +199,15 @@ inline const_iterator(const const_iterator& X); inline const_iterator(const subview_cube& in_sv, const uword in_row, const uword in_col, const uword in_slice); - inline arma_warn_unused const eT& operator*(); + arma_warn_unused inline const eT& operator*(); - inline const_iterator& operator++(); - inline arma_warn_unused const_iterator operator++(int); + inline const_iterator& operator++(); + arma_warn_unused inline const_iterator operator++(int); - inline arma_warn_unused bool operator==(const iterator& rhs) const; - inline arma_warn_unused bool operator!=(const iterator& rhs) const; - inline arma_warn_unused bool operator==(const const_iterator& rhs) const; - inline arma_warn_unused bool operator!=(const const_iterator& rhs) const; + arma_warn_unused inline bool operator==(const iterator& rhs) const; + arma_warn_unused inline bool operator!=(const iterator& rhs) const; + arma_warn_unused inline bool operator==(const const_iterator& rhs) const; + arma_warn_unused inline bool operator!=(const const_iterator& rhs) const; // So that we satisfy the STL iterator types. typedef std::forward_iterator_tag iterator_category; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_each_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_cube_each_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_each_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_cube_each_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -28,7 +28,8 @@ const Cube& P; - inline void check_size(const Mat& A) const; + template + inline void check_size(const Mat& A) const; protected: @@ -36,7 +37,8 @@ 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; + template + arma_cold inline const std::string incompat_size_string(const Mat& A) const; }; @@ -104,7 +106,7 @@ template static inline Cube operator_plus(const subview_cube_each1& X, const Base& Y); - + template static inline Cube operator_minus(const subview_cube_each1& X, const Base& Y); @@ -135,7 +137,7 @@ template static inline Cube operator_plus(const subview_cube_each2& X, const Base& Y); - + template static inline Cube operator_minus(const subview_cube_each2& X, const Base& Y); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_each_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_cube_each_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_each_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_cube_each_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -35,9 +35,10 @@ template +template inline void -subview_cube_each_common::check_size(const Mat& A) const +subview_cube_each_common::check_size(const Mat& A) const { if(arma_config::debug) { @@ -51,10 +52,10 @@ template -arma_cold +template inline const std::string -subview_cube_each_common::incompat_size_string(const Mat& A) const +subview_cube_each_common::incompat_size_string(const Mat& A) const { std::ostringstream tmp; @@ -134,7 +135,7 @@ const uword p_n_elem_slice = p.n_elem_slice; const eT* A_mem = A.memptr(); - + for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_plus( p.slice_memptr(i), A_mem, p_n_elem_slice ); } } @@ -287,7 +288,7 @@ const uword p_n_slices = p.n_slices; const uword p_n_elem_slice = p.n_elem_slice; - + const uword* indices_mem = U.M.memptr(); const uword N = U.M.n_elem; @@ -326,7 +327,7 @@ const uword p_n_slices = p.n_slices; const uword p_n_elem_slice = p.n_elem_slice; - + const uword* indices_mem = U.M.memptr(); const uword N = U.M.n_elem; @@ -365,7 +366,7 @@ const uword p_n_slices = p.n_slices; const uword p_n_elem_slice = p.n_elem_slice; - + const uword* indices_mem = U.M.memptr(); const uword N = U.M.n_elem; @@ -404,7 +405,7 @@ const uword p_n_slices = p.n_slices; const uword p_n_elem_slice = p.n_elem_slice; - + const uword* indices_mem = U.M.memptr(); const uword N = U.M.n_elem; @@ -443,7 +444,7 @@ const uword p_n_slices = p.n_slices; const uword p_n_elem_slice = p.n_elem_slice; - + const uword* indices_mem = U.M.memptr(); const uword N = U.M.n_elem; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_cube_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_cube_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_cube_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -1341,12 +1341,13 @@ template inline -arma_warn_unused bool subview_cube::is_finite() const { arma_extra_debug_sigprint(); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "is_finite(): detection of non-finite values is not reliable in fast math mode"); } + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; const uword local_n_slices = n_slices; @@ -1366,7 +1367,6 @@ template inline -arma_warn_unused bool subview_cube::is_zero(const typename get_pod_type::result tol) const { @@ -1391,12 +1391,13 @@ template inline -arma_warn_unused bool subview_cube::has_inf() const { arma_extra_debug_sigprint(); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_inf(): detection of non-finite values is not reliable in fast math mode"); } + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; const uword local_n_slices = n_slices; @@ -1416,12 +1417,13 @@ template inline -arma_warn_unused bool subview_cube::has_nan() const { arma_extra_debug_sigprint(); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nan(): detection of non-finite values is not reliable in fast math mode"); } + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; const uword local_n_slices = n_slices; @@ -1441,6 +1443,32 @@ template inline +bool +subview_cube::has_nonfinite() const + { + arma_extra_debug_sigprint(); + + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nonfinite(): detection of non-finite values is not reliable in fast math mode"); } + + 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_finite(slice_colptr(slice,col), local_n_rows) == false) { return true; } + } + } + + return false; + } + + + +template +inline eT subview_cube::at_alt(const uword i) const { @@ -1684,7 +1712,7 @@ const uword n_cols = in.n_cols; const uword n_slices = in.n_slices; - 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); + arma_extra_debug_print(arma_str::format("out.n_rows = %u out.n_cols = %u out.n_slices = %u in.m.n_rows = %u in.m.n_cols = %u in.m.n_slices = %u") % out.n_rows % out.n_cols % out.n_slices % in.m.n_rows % in.m.n_cols % in.m.n_slices); if( (in.aux_row1 == 0) && (n_rows == in.m.n_rows) ) { @@ -2426,7 +2454,6 @@ template inline -arma_warn_unused eT& subview_cube::iterator::operator*() { @@ -2467,7 +2494,6 @@ template inline -arma_warn_unused typename subview_cube::iterator subview_cube::iterator::operator++(int) { @@ -2482,7 +2508,6 @@ template inline -arma_warn_unused bool subview_cube::iterator::operator==(const iterator& rhs) const { @@ -2493,7 +2518,6 @@ template inline -arma_warn_unused bool subview_cube::iterator::operator!=(const iterator& rhs) const { @@ -2504,7 +2528,6 @@ template inline -arma_warn_unused bool subview_cube::iterator::operator==(const const_iterator& rhs) const { @@ -2515,7 +2538,6 @@ template inline -arma_warn_unused bool subview_cube::iterator::operator!=(const const_iterator& rhs) const { @@ -2605,7 +2627,6 @@ template inline -arma_warn_unused const eT& subview_cube::const_iterator::operator*() { @@ -2646,7 +2667,6 @@ template inline -arma_warn_unused typename subview_cube::const_iterator subview_cube::const_iterator::operator++(int) { @@ -2661,7 +2681,6 @@ template inline -arma_warn_unused bool subview_cube::const_iterator::operator==(const iterator& rhs) const { @@ -2672,7 +2691,6 @@ template inline -arma_warn_unused bool subview_cube::const_iterator::operator!=(const iterator& rhs) const { @@ -2683,7 +2701,6 @@ template inline -arma_warn_unused bool subview_cube::const_iterator::operator==(const const_iterator& rhs) const { @@ -2694,7 +2711,6 @@ template inline -arma_warn_unused bool subview_cube::const_iterator::operator!=(const const_iterator& rhs) const { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_each_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_each_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_each_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_each_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -30,7 +30,8 @@ const parent& P; - inline void check_size(const Mat& A) const; + template + inline void check_size(const Mat& A) const; protected: @@ -43,7 +44,8 @@ arma_inline const Mat& get_mat_ref() const; - arma_cold inline const std::string incompat_size_string(const Mat& A) const; + template + arma_cold inline const std::string incompat_size_string(const Mat& A) const; }; @@ -117,7 +119,7 @@ template static inline Mat operator_plus(const subview_each1& X, const Base& Y); - + template static inline Mat operator_minus(const subview_each1& X, const Base& Y); @@ -142,7 +144,7 @@ template static inline Mat operator_plus(const subview_each2& X, const Base& Y); - + template static inline Mat operator_minus(const subview_each2& X, const Base& Y); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_each_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_each_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_each_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_each_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -65,11 +65,12 @@ template +template inline void -subview_each_common::check_size(const Mat& A) const +subview_each_common::check_size(const Mat& A) const { - if(arma_config::debug == true) + if(arma_config::debug) { if(mode == 0) { @@ -91,10 +92,10 @@ template -arma_cold +template inline const std::string -subview_each_common::incompat_size_string(const Mat& A) const +subview_each_common::incompat_size_string(const Mat& A) const { std::ostringstream tmp; @@ -192,7 +193,7 @@ const eT* A_mem = A.memptr(); const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; - + if(mode == 0) // each column { for(uword i=0; i < p_n_cols; ++i) @@ -229,7 +230,7 @@ const eT* A_mem = A.memptr(); const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; - + if(mode == 0) // each column { for(uword i=0; i < p_n_cols; ++i) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem1_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_elem1_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem1_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_elem1_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -806,7 +806,7 @@ if(alias) { arma_extra_debug_print("subview_elem1::extract(): aliasing detected"); } - Mat* tmp_out = alias ? new Mat() : 0; + Mat* tmp_out = alias ? new Mat() : nullptr; Mat& out = alias ? *tmp_out : actual_out; out.set_size(aa_n_elem, 1); diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem2_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_elem2_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_elem2_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_elem2_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -699,7 +699,7 @@ if(alias) { arma_extra_debug_print("subview_elem2::extract(): aliasing detected"); } - Mat* tmp_out = alias ? new Mat() : 0; + Mat* tmp_out = alias ? new Mat() : nullptr; Mat& out = alias ? *tmp_out : actual_out; if( (in.all_rows == false) && (in.all_cols == false) ) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_field_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_field_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_field_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_field_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -514,7 +514,7 @@ // const bool alias = (&actual_out == &in.f); - field* tmp = (alias) ? new field : 0; + field* tmp = (alias) ? new field : nullptr; field& out = (alias) ? (*tmp) : actual_out; // @@ -525,7 +525,7 @@ out.set_size(n_rows, n_cols, n_slices); - 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.f.n_rows % in.f.n_cols % in.f.n_slices); + arma_extra_debug_print(arma_str::format("out.n_rows = %u out.n_cols = %u out.n_slices = %u in.m.n_rows = %u in.m.n_cols = %u in.m.n_slices = %u") % out.n_rows % out.n_cols % out.n_slices % in.f.n_rows % in.f.n_cols % in.f.n_slices); if(n_slices == 1) { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/subview_meat.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/subview_meat.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/subview_meat.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/subview_meat.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -1234,7 +1234,6 @@ template inline -arma_warn_unused eT subview::at_alt(const uword ii) const { @@ -1245,7 +1244,6 @@ template inline -arma_warn_unused eT& subview::operator[](const uword ii) { @@ -1261,7 +1259,6 @@ template inline -arma_warn_unused eT subview::operator[](const uword ii) const { @@ -1277,7 +1274,6 @@ template inline -arma_warn_unused eT& subview::operator()(const uword ii) { @@ -1295,7 +1291,6 @@ template inline -arma_warn_unused eT subview::operator()(const uword ii) const { @@ -1313,7 +1308,6 @@ template inline -arma_warn_unused eT& subview::operator()(const uword in_row, const uword in_col) { @@ -1328,7 +1322,6 @@ template inline -arma_warn_unused eT subview::operator()(const uword in_row, const uword in_col) const { @@ -1343,7 +1336,6 @@ template inline -arma_warn_unused eT& subview::at(const uword in_row, const uword in_col) { @@ -1356,7 +1348,6 @@ template inline -arma_warn_unused eT subview::at(const uword in_row, const uword in_col) const { @@ -1369,7 +1360,6 @@ template inline -arma_warn_unused eT& subview::front() { @@ -1382,7 +1372,6 @@ template inline -arma_warn_unused eT subview::front() const { @@ -1395,7 +1384,6 @@ template inline -arma_warn_unused eT& subview::back() { @@ -1411,7 +1399,6 @@ template inline -arma_warn_unused eT subview::back() const { @@ -1483,7 +1470,6 @@ template inline -arma_warn_unused bool subview::is_vec() const { @@ -1494,12 +1480,13 @@ template inline -arma_warn_unused bool subview::is_finite() const { arma_extra_debug_sigprint(); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "is_finite(): detection of non-finite values is not reliable in fast math mode"); } + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; @@ -1515,7 +1502,6 @@ template inline -arma_warn_unused bool subview::is_zero(const typename get_pod_type::result tol) const { @@ -1536,12 +1522,13 @@ template inline -arma_warn_unused bool subview::has_inf() const { arma_extra_debug_sigprint(); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_inf(): detection of non-finite values is not reliable in fast math mode"); } + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; @@ -1557,12 +1544,13 @@ template inline -arma_warn_unused bool subview::has_nan() const { arma_extra_debug_sigprint(); + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nan(): detection of non-finite values is not reliable in fast math mode"); } + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; @@ -1576,6 +1564,28 @@ +template +inline +bool +subview::has_nonfinite() const + { + arma_extra_debug_sigprint(); + + if(arma_config::fast_math_warn) { arma_debug_warn_level(1, "has_nonfinite(): detection of non-finite values is not reliable in fast math mode"); } + + const uword local_n_rows = n_rows; + const uword local_n_cols = n_cols; + + for(uword ii=0; ii inline @@ -1590,7 +1600,7 @@ const uword n_rows = in.n_rows; // number of rows in the subview const uword n_cols = in.n_cols; // number of columns in the subview - 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 ); + arma_extra_debug_print(arma_str::format("out.n_rows = %u out.n_cols = %u in.m.n_rows = %u in.m.n_cols = %u") % out.n_rows % out.n_cols % in.m.n_rows % in.m.n_cols ); if(in.is_vec()) @@ -1602,7 +1612,8 @@ // in.colptr(0) the first column of the subview, taking into account any row offset arrayops::copy( out.memptr(), in.colptr(0), n_rows ); } - else // a row vector (possibly empty) + else + if(n_rows == 1) // a row vector { arma_extra_debug_print("subview::extract(): copying row (going across columns)"); @@ -2720,7 +2731,6 @@ template inline -arma_warn_unused eT& subview::iterator::operator*() { @@ -2755,7 +2765,6 @@ template inline -arma_warn_unused typename subview::iterator subview::iterator::operator++(int) { @@ -2770,7 +2779,6 @@ template inline -arma_warn_unused bool subview::iterator::operator==(const iterator& rhs) const { @@ -2781,7 +2789,6 @@ template inline -arma_warn_unused bool subview::iterator::operator!=(const iterator& rhs) const { @@ -2792,7 +2799,6 @@ template inline -arma_warn_unused bool subview::iterator::operator==(const const_iterator& rhs) const { @@ -2803,7 +2809,6 @@ template inline -arma_warn_unused bool subview::iterator::operator!=(const const_iterator& rhs) const { @@ -2881,7 +2886,6 @@ template inline -arma_warn_unused const eT& subview::const_iterator::operator*() { @@ -2916,7 +2920,6 @@ template inline -arma_warn_unused typename subview::const_iterator subview::const_iterator::operator++(int) { @@ -2931,7 +2934,6 @@ template inline -arma_warn_unused bool subview::const_iterator::operator==(const iterator& rhs) const { @@ -2942,7 +2944,6 @@ template inline -arma_warn_unused bool subview::const_iterator::operator!=(const iterator& rhs) const { @@ -2953,7 +2954,6 @@ template inline -arma_warn_unused bool subview::const_iterator::operator==(const const_iterator& rhs) const { @@ -2964,7 +2964,6 @@ template inline -arma_warn_unused bool subview::const_iterator::operator!=(const const_iterator& rhs) const { @@ -3024,7 +3023,6 @@ template inline -arma_warn_unused eT& subview::row_iterator::operator*() { @@ -3053,7 +3051,6 @@ template inline -arma_warn_unused typename subview::row_iterator subview::row_iterator::operator++(int) { @@ -3068,7 +3065,6 @@ template inline -arma_warn_unused bool subview::row_iterator::operator==(const row_iterator& rhs) const { @@ -3079,7 +3075,6 @@ template inline -arma_warn_unused bool subview::row_iterator::operator!=(const row_iterator& rhs) const { @@ -3090,7 +3085,6 @@ template inline -arma_warn_unused bool subview::row_iterator::operator==(const const_row_iterator& rhs) const { @@ -3101,7 +3095,6 @@ template inline -arma_warn_unused bool subview::row_iterator::operator!=(const const_row_iterator& rhs) const { @@ -3175,7 +3168,6 @@ template inline -arma_warn_unused const eT& subview::const_row_iterator::operator*() const { @@ -3204,7 +3196,6 @@ template inline -arma_warn_unused typename subview::const_row_iterator subview::const_row_iterator::operator++(int) { @@ -3219,7 +3210,6 @@ template inline -arma_warn_unused bool subview::const_row_iterator::operator==(const row_iterator& rhs) const { @@ -3230,7 +3220,6 @@ template inline -arma_warn_unused bool subview::const_row_iterator::operator!=(const row_iterator& rhs) const { @@ -3241,7 +3230,6 @@ template inline -arma_warn_unused bool subview::const_row_iterator::operator==(const const_row_iterator& rhs) const { @@ -3252,7 +3240,6 @@ template inline -arma_warn_unused bool subview::const_row_iterator::operator!=(const const_row_iterator& rhs) const { @@ -3413,7 +3400,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> subview_col::t() const { @@ -3424,7 +3410,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> subview_col::ht() const { @@ -3435,7 +3420,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> subview_col::st() const { @@ -3446,7 +3430,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> subview_col::as_row() const { @@ -3780,7 +3763,6 @@ template inline -arma_warn_unused eT subview_col::min() const { @@ -3800,7 +3782,6 @@ template inline -arma_warn_unused eT subview_col::max() const { @@ -3866,7 +3847,6 @@ template inline -arma_warn_unused uword subview_col::index_min() const { @@ -3890,7 +3870,6 @@ template inline -arma_warn_unused uword subview_col::index_max() const { @@ -4048,7 +4027,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> subview_cols::t() const { @@ -4059,7 +4037,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> subview_cols::ht() const { @@ -4070,7 +4047,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> subview_cols::st() const { @@ -4081,7 +4057,6 @@ template arma_inline -arma_warn_unused const Op,op_vectorise_col> subview_cols::as_col() const { @@ -4092,7 +4067,6 @@ template inline -arma_warn_unused eT subview_cols::at_alt(const uword ii) const { @@ -4103,7 +4077,6 @@ template inline -arma_warn_unused eT& subview_cols::operator[](const uword ii) { @@ -4116,7 +4089,6 @@ template inline -arma_warn_unused eT subview_cols::operator[](const uword ii) const { @@ -4129,7 +4101,6 @@ template inline -arma_warn_unused eT& subview_cols::operator()(const uword ii) { @@ -4144,7 +4115,6 @@ template inline -arma_warn_unused eT subview_cols::operator()(const uword ii) const { @@ -4159,7 +4129,6 @@ template inline -arma_warn_unused eT& subview_cols::operator()(const uword in_row, const uword in_col) { @@ -4174,7 +4143,6 @@ template inline -arma_warn_unused eT subview_cols::operator()(const uword in_row, const uword in_col) const { @@ -4189,7 +4157,6 @@ template inline -arma_warn_unused eT& subview_cols::at(const uword in_row, const uword in_col) { @@ -4202,7 +4169,6 @@ template inline -arma_warn_unused eT subview_cols::at(const uword in_row, const uword in_col) const { @@ -4380,7 +4346,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> subview_row::t() const { @@ -4391,7 +4356,6 @@ template arma_inline -arma_warn_unused const Op,op_htrans> subview_row::ht() const { @@ -4402,7 +4366,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> subview_row::st() const { @@ -4413,7 +4376,6 @@ template arma_inline -arma_warn_unused const Op,op_strans> subview_row::as_col() const { @@ -4708,7 +4670,6 @@ template inline -arma_warn_unused uword subview_row::index_min() const { @@ -4732,7 +4693,6 @@ template inline -arma_warn_unused uword subview_row::index_max() const { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/sym_helper.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/sym_helper.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/sym_helper.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/sym_helper.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,485 @@ +// 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 sym_helper +//! @{ + + +namespace sym_helper +{ + +// computationally inexpensive algorithm to guess whether a matrix is positive definite: +// (1) ensure the matrix is symmetric/hermitian (within a tolerance) +// (2) ensure the diagonal entries are real and greater than zero +// (3) ensure that the value with largest modulus is on the main diagonal +// (4) ensure rudimentary diagonal dominance: (real(A_ii) + real(A_jj)) > 2*abs(real(A_ij)) +// the above conditions are necessary, but not sufficient; +// doing it properly would be too computationally expensive for our purposes +// more info: +// http://mathworld.wolfram.com/PositiveDefiniteMatrix.html +// http://mathworld.wolfram.com/DiagonallyDominantMatrix.html + +template +inline +typename enable_if2::no, bool>::result +guess_sympd_worker(const Mat& A) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming A is square-sized + + 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)) { return 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); + + // if( (A_ij_abs >= max_diag) || (A_ji_abs >= max_diag) ) { return false; } + if(A_ij_abs >= max_diag) { return false; } + + 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)) ) { return false; } + + const eT A_ii = (*A_ii_ptr); + + if( (A_ij_abs + A_ij_abs) >= (A_ii + A_jj) ) { return false; } + + A_ji_ptr += N; + A_ii_ptr += Np1; + } + + A_col += N; + } + + return true; + } + + + +template +inline +typename enable_if2::yes, bool>::result +guess_sympd_worker(const Mat& A) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming A is square-sized + + typedef typename get_pod_type::result T; + + 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) ) { return 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) { return 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); + + // 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) { return false; } + + if(square_A_ij_abs >= square_max_diag) { return false; } + + 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)) ) { return false; } + + + const T A_imag_delta = (std::abs)(A_ij_imag + A_ji_imag); // take into account complex conjugate + const T A_imag_abs_max = (std::max)(A_ij_imag_abs, A_ji_imag_abs); + + if( (A_imag_delta > tol) && (A_imag_delta > (A_imag_abs_max*tol)) ) { return false; } + + + 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) ) { return false; } + + A_ji_ptr += N; + A_ii_ptr += Np1; + } + + A_col += N; + } + + return true; + } + + + +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; } + } + + + +template +inline +bool +check_diag_imag(const Mat& A) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming matrix A is square-sized + + typedef typename get_pod_type::result T; + + const T tol = T(10000) * std::numeric_limits::epsilon(); // allow some leeway + + const eT* colmem = A.memptr(); + + const uword N = A.n_rows; + + for(uword i=0; i tol) { return false; } + + colmem += N; + } + + return true; + } + + + +} // end of namespace sym_helper + + +//! @} diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/sympd_helper.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/sympd_helper.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/sympd_helper.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/sympd_helper.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,453 +0,0 @@ -// 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 sympd_helper -//! @{ - - -namespace sympd_helper -{ - -// computationally inexpensive algorithm to guess whether a matrix is positive definite: -// (1) ensure the matrix is symmetric/hermitian (within a tolerance) -// (2) ensure the diagonal entries are real and greater than zero -// (3) ensure that the value with largest modulus is on the main diagonal -// (4) ensure rudimentary diagonal dominance: (real(A_ii) + real(A_jj)) > 2*abs(real(A_ij)) -// the above conditions are necessary, but not sufficient; -// doing it properly would be too computationally expensive for our purposes -// more info: -// http://mathworld.wolfram.com/PositiveDefiniteMatrix.html -// http://mathworld.wolfram.com/DiagonallyDominantMatrix.html - -template -inline -typename enable_if2::no, bool>::result -guess_sympd_worker(const Mat& A) - { - arma_extra_debug_sigprint(); - - // NOTE: assuming A is square-sized - - 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)) { return 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); - - // if( (A_ij_abs >= max_diag) || (A_ji_abs >= max_diag) ) { return false; } - if(A_ij_abs >= max_diag) { return false; } - - 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)) ) { return false; } - - const eT A_ii = (*A_ii_ptr); - - if( (A_ij_abs + A_ij_abs) >= (A_ii + A_jj) ) { return false; } - - A_ji_ptr += N; - A_ii_ptr += Np1; - } - - A_col += N; - } - - return true; - } - - - -template -inline -typename enable_if2::yes, bool>::result -guess_sympd_worker(const Mat& A) - { - arma_extra_debug_sigprint(); - - // NOTE: assuming A is square-sized - - typedef typename get_pod_type::result T; - - 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) ) { return 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) { return 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); - - // 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) { return false; } - - if(square_A_ij_abs >= square_max_diag) { return false; } - - 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)) ) { return false; } - - - const T A_imag_delta = (std::abs)(A_ij_imag + A_ji_imag); // take into account complex conjugate - const T A_imag_abs_max = (std::max)(A_ij_imag_abs, A_ji_imag_abs); - - if( (A_imag_delta > tol) && (A_imag_delta > (A_imag_abs_max*tol)) ) { return false; } - - - 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) ) { return false; } - - A_ji_ptr += N; - A_ii_ptr += Np1; - } - - A_col += N; - } - - return true; - } - - - -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-10.8.2+dfsg/include/armadillo_bits/traits.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/traits.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/traits.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/traits.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -343,6 +343,19 @@ template +struct is_SpToDGlue + { static constexpr bool value = false; }; + +template +struct is_SpToDGlue< SpToDGlue > + { static constexpr bool value = true; }; + +template +struct is_SpToDGlue< const SpToDGlue > + { static constexpr bool value = true; }; + + +template struct is_eOp { static constexpr bool value = false; }; @@ -546,8 +559,6 @@ = is_Mat::value || is_Gen::value || is_Op::value - || is_CubeToMatOp::value - || is_SpToDOp::value || is_Glue::value || is_eOp::value || is_eGlue::value @@ -560,6 +571,9 @@ || is_subview_cols::value || is_subview_elem1::value || is_subview_elem2::value + || is_CubeToMatOp::value + || is_SpToDOp::value + || is_SpToDGlue::value ; }; @@ -1207,41 +1221,60 @@ template -struct has_op_inv +struct has_op_inv_any { static constexpr bool value = false; }; template -struct has_op_inv< Op > +struct has_op_inv_any< Op > + { static constexpr bool value = true; }; + +template +struct has_op_inv_any< Op > + { static constexpr bool value = true; }; + +template +struct has_op_inv_any< Op > + { static constexpr bool value = true; }; + +template +struct has_op_inv_any< Op > { static constexpr bool value = true; }; template -struct has_op_inv< Glue, T2, glue_times> > +struct has_op_inv_any< Glue, T2, glue_times> > { static constexpr bool value = true; }; template -struct has_op_inv< Glue, glue_times> > +struct has_op_inv_any< Glue, T2, glue_times> > { static constexpr bool value = true; }; +template +struct has_op_inv_any< Glue, T2, glue_times> > + { static constexpr bool value = true; }; +template +struct has_op_inv_any< Glue, T2, glue_times> > + { static constexpr bool value = true; }; -template -struct has_op_inv_sympd - { static constexpr bool value = false; }; +template +struct has_op_inv_any< Glue, glue_times> > + { static constexpr bool value = true; }; -template -struct has_op_inv_sympd< Op > +template +struct has_op_inv_any< Glue, glue_times> > { static constexpr bool value = true; }; template -struct has_op_inv_sympd< Glue, T2, glue_times> > +struct has_op_inv_any< Glue, glue_times> > { static constexpr bool value = true; }; template -struct has_op_inv_sympd< Glue, glue_times> > +struct has_op_inv_any< Glue, glue_times> > { static constexpr bool value = true; }; + template struct has_nested_op_traits { diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/translate_arpack.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/translate_arpack.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/translate_arpack.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/translate_arpack.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -17,7 +17,7 @@ -#ifdef ARMA_USE_ARPACK +#if defined(ARMA_USE_ARPACK) //! \namespace arpack namespace for ARPACK functions namespace arpack diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/translate_atlas.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/translate_atlas.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/translate_atlas.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/translate_atlas.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -16,10 +16,12 @@ // ------------------------------------------------------------------------ -#ifdef ARMA_USE_ATLAS +#if defined(ARMA_USE_ATLAS) -//! \namespace atlas namespace for ATLAS functions (imported from the global namespace) +// TODO: remove support for ATLAS in next major version + +//! \namespace atlas namespace for ATLAS functions namespace atlas { @@ -140,7 +142,7 @@ void cblas_gemv ( - const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, + const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const eT alpha, const eT *A, const int lda, @@ -154,25 +156,25 @@ if(is_float::value) { typedef float T; - arma_wrapper(cblas_sgemv)(Order, TransA, M, N, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)X, incX, (const T)tmp_real(beta), (T*)Y, incY); + arma_wrapper(cblas_sgemv)(layout, TransA, M, N, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)X, incX, (const T)tmp_real(beta), (T*)Y, incY); } else if(is_double::value) { typedef double T; - arma_wrapper(cblas_dgemv)(Order, TransA, M, N, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)X, incX, (const T)tmp_real(beta), (T*)Y, incY); + arma_wrapper(cblas_dgemv)(layout, TransA, M, N, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)X, incX, (const T)tmp_real(beta), (T*)Y, incY); } else if(is_cx_float::value) { typedef std::complex T; - arma_wrapper(cblas_cgemv)(Order, TransA, M, N, (const T*)&alpha, (const T*)A, lda, (const T*)X, incX, (const T*)&beta, (T*)Y, incY); + arma_wrapper(cblas_cgemv)(layout, TransA, M, N, (const T*)&alpha, (const T*)A, lda, (const T*)X, incX, (const T*)&beta, (T*)Y, incY); } else if(is_cx_double::value) { typedef std::complex T; - arma_wrapper(cblas_zgemv)(Order, TransA, M, N, (const T*)&alpha, (const T*)A, lda, (const T*)X, incX, (const T*)&beta, (T*)Y, incY); + arma_wrapper(cblas_zgemv)(layout, TransA, M, N, (const T*)&alpha, (const T*)A, lda, (const T*)X, incX, (const T*)&beta, (T*)Y, incY); } } @@ -183,8 +185,8 @@ void cblas_gemm ( - const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, - const enum CBLAS_TRANSPOSE TransB, const int M, const int N, + const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, + const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const eT alpha, const eT *A, const int lda, const eT *B, const int ldb, const eT beta, eT *C, const int ldc @@ -195,25 +197,25 @@ if(is_float::value) { typedef float T; - arma_wrapper(cblas_sgemm)(Order, TransA, TransB, M, N, K, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)B, ldb, (const T)tmp_real(beta), (T*)C, ldc); + arma_wrapper(cblas_sgemm)(layout, TransA, TransB, M, N, K, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)B, ldb, (const T)tmp_real(beta), (T*)C, ldc); } else if(is_double::value) { typedef double T; - arma_wrapper(cblas_dgemm)(Order, TransA, TransB, M, N, K, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)B, ldb, (const T)tmp_real(beta), (T*)C, ldc); + arma_wrapper(cblas_dgemm)(layout, TransA, TransB, M, N, K, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)B, ldb, (const T)tmp_real(beta), (T*)C, ldc); } else if(is_cx_float::value) { typedef std::complex T; - arma_wrapper(cblas_cgemm)(Order, TransA, TransB, M, N, K, (const T*)&alpha, (const T*)A, lda, (const T*)B, ldb, (const T*)&beta, (T*)C, ldc); + arma_wrapper(cblas_cgemm)(layout, TransA, TransB, M, N, K, (const T*)&alpha, (const T*)A, lda, (const T*)B, ldb, (const T*)&beta, (T*)C, ldc); } else if(is_cx_double::value) { typedef std::complex T; - arma_wrapper(cblas_zgemm)(Order, TransA, TransB, M, N, K, (const T*)&alpha, (const T*)A, lda, (const T*)B, ldb, (const T*)&beta, (T*)C, ldc); + arma_wrapper(cblas_zgemm)(layout, TransA, TransB, M, N, K, (const T*)&alpha, (const T*)A, lda, (const T*)B, ldb, (const T*)&beta, (T*)C, ldc); } } @@ -224,7 +226,7 @@ void cblas_syrk ( - const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, + const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const eT alpha, const eT* A, const int lda, const eT beta, eT* C, const int ldc ) @@ -234,13 +236,13 @@ if(is_float::value) { typedef float T; - arma_wrapper(cblas_ssyrk)(Order, Uplo, Trans, N, K, (const T)alpha, (const T*)A, lda, (const T)beta, (T*)C, ldc); + arma_wrapper(cblas_ssyrk)(layout, Uplo, Trans, N, K, (const T)alpha, (const T*)A, lda, (const T)beta, (T*)C, ldc); } else if(is_double::value) { typedef double T; - arma_wrapper(cblas_dsyrk)(Order, Uplo, Trans, N, K, (const T)alpha, (const T*)A, lda, (const T)beta, (T*)C, ldc); + arma_wrapper(cblas_dsyrk)(layout, Uplo, Trans, N, K, (const T)alpha, (const T*)A, lda, (const T)beta, (T*)C, ldc); } } @@ -251,7 +253,7 @@ void cblas_herk ( - const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, + const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const T alpha, const std::complex* A, const int lda, const T beta, std::complex* C, const int ldc ) @@ -263,7 +265,7 @@ typedef float TT; typedef std::complex cx_TT; - arma_wrapper(cblas_cherk)(Order, Uplo, Trans, N, K, (const TT)alpha, (const cx_TT*)A, lda, (const TT)beta, (cx_TT*)C, ldc); + arma_wrapper(cblas_cherk)(layout, Uplo, Trans, N, K, (const TT)alpha, (const cx_TT*)A, lda, (const TT)beta, (cx_TT*)C, ldc); } else if(is_double::value) @@ -271,239 +273,10 @@ typedef double TT; typedef std::complex cx_TT; - arma_wrapper(cblas_zherk)(Order, Uplo, Trans, N, K, (const TT)alpha, (const cx_TT*)A, lda, (const TT)beta, (cx_TT*)C, ldc); - } - } - - - - template - inline - int - clapack_getrf - ( - const enum CBLAS_ORDER Order, const int M, const int N, - eT *A, const int lda, int *ipiv - ) - { - arma_type_check((is_supported_blas_type::value == false)); - - if(is_float::value) - { - typedef float T; - return arma_wrapper(clapack_sgetrf)(Order, M, N, (T*)A, lda, ipiv); - } - else - if(is_double::value) - { - typedef double T; - return arma_wrapper(clapack_dgetrf)(Order, M, N, (T*)A, lda, ipiv); - } - else - if(is_cx_float::value) - { - typedef std::complex T; - return arma_wrapper(clapack_cgetrf)(Order, M, N, (T*)A, lda, ipiv); - } - else - if(is_cx_double::value) - { - typedef std::complex T; - return arma_wrapper(clapack_zgetrf)(Order, M, N, (T*)A, lda, ipiv); - } - - return -1; - } - - - - template - inline - int - clapack_getri - ( - const enum CBLAS_ORDER Order, const int N, eT *A, - const int lda, const int *ipiv - ) - { - arma_type_check((is_supported_blas_type::value == false)); - - if(is_float::value) - { - typedef float T; - return arma_wrapper(clapack_sgetri)(Order, N, (T*)A, lda, ipiv); - } - else - if(is_double::value) - { - typedef double T; - return arma_wrapper(clapack_dgetri)(Order, N, (T*)A, lda, ipiv); - } - else - if(is_cx_float::value) - { - typedef std::complex T; - return arma_wrapper(clapack_cgetri)(Order, N, (T*)A, lda, ipiv); - } - else - if(is_cx_double::value) - { - typedef std::complex T; - return arma_wrapper(clapack_zgetri)(Order, N, (T*)A, lda, ipiv); - } - - return -1; - } - - - - template - inline - int - clapack_gesv - ( - const enum CBLAS_ORDER Order, - const int N, const int NRHS, - eT* A, const int lda, int* ipiv, - eT* B, const int ldb - ) - { - arma_type_check((is_supported_blas_type::value == false)); - - if(is_float::value) - { - typedef float T; - return arma_wrapper(clapack_sgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb); - } - else - if(is_double::value) - { - typedef double T; - return arma_wrapper(clapack_dgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb); - } - else - if(is_cx_float::value) - { - typedef std::complex T; - return arma_wrapper(clapack_cgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb); - } - else - if(is_cx_double::value) - { - typedef std::complex T; - return arma_wrapper(clapack_zgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb); - } - - return -1; - } - - - - template - inline - int - clapack_potrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, eT *A, const int lda) - { - arma_type_check((is_supported_blas_type::value == false)); - - if(is_float::value) - { - typedef float T; - return arma_wrapper(clapack_spotrf)(Order, Uplo, N, (T*)A, lda); - } - else - if(is_double::value) - { - typedef double T; - return arma_wrapper(clapack_dpotrf)(Order, Uplo, N, (T*)A, lda); - } - else - if(is_cx_float::value) - { - typedef std::complex T; - return arma_wrapper(clapack_cpotrf)(Order, Uplo, N, (T*)A, lda); - } - else - if(is_cx_double::value) - { - typedef std::complex T; - return arma_wrapper(clapack_zpotrf)(Order, Uplo, N, (T*)A, lda); - } - - return -1; - } - - - - template - inline - int - clapack_potri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, eT *A, const int lda) - { - arma_type_check((is_supported_blas_type::value == false)); - - if(is_float::value) - { - typedef float T; - return arma_wrapper(clapack_spotri)(Order, Uplo, N, (T*)A, lda); - } - else - if(is_double::value) - { - typedef double T; - return arma_wrapper(clapack_dpotri)(Order, Uplo, N, (T*)A, lda); + arma_wrapper(cblas_zherk)(layout, Uplo, Trans, N, K, (const TT)alpha, (const cx_TT*)A, lda, (const TT)beta, (cx_TT*)C, ldc); } - else - if(is_cx_float::value) - { - typedef std::complex T; - return arma_wrapper(clapack_cpotri)(Order, Uplo, N, (T*)A, lda); - } - else - if(is_cx_double::value) - { - typedef std::complex T; - return arma_wrapper(clapack_zpotri)(Order, Uplo, N, (T*)A, lda); - } - - return -1; } - - - template - inline - int - clapack_posv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, eT *A, const int lda, eT *B, const int ldb) - { - arma_type_check((is_supported_blas_type::value == false)); - - if(is_float::value) - { - typedef float T; - return arma_wrapper(clapack_sposv)(Order, Uplo, N, NRHS, (T*)A, lda, (T*)B, ldb); - } - else - if(is_double::value) - { - typedef double T; - return arma_wrapper(clapack_dposv)(Order, Uplo, N, NRHS, (T*)A, lda, (T*)B, ldb); - } - else - if(is_cx_float::value) - { - typedef std::complex T; - return arma_wrapper(clapack_cposv)(Order, Uplo, N, NRHS, (T*)A, lda, (T*)B, ldb); - } - else - if(is_cx_double::value) - { - typedef std::complex T; - return arma_wrapper(clapack_zposv)(Order, Uplo, N, NRHS, (T*)A, lda, (T*)B, ldb); - } - - return -1; - } } #endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/translate_blas.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/translate_blas.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/translate_blas.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/translate_blas.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -17,7 +17,7 @@ -#ifdef ARMA_USE_BLAS +#if defined(ARMA_USE_BLAS) //! \namespace blas namespace for BLAS functions diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/translate_fftw3.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/translate_fftw3.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/translate_fftw3.hpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/translate_fftw3.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,106 @@ +// 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. +// ------------------------------------------------------------------------ + + +#if defined(ARMA_USE_FFTW3) + + +namespace fftw3 + { + template + arma_inline + void_ptr + plan_dft_1d(int N, eT* input, eT* output, int fftw3_sign, unsigned int fftw3_flags) + { + arma_type_check((is_cx::value == false)); + + if(is_cx_float::value) + { + return fftwf_plan_dft_1d(N, (cx_float*)input, (cx_float*)output, fftw3_sign, fftw3_flags); + } + else + if(is_cx_double::value) + { + return fftw_plan_dft_1d(N, (cx_double*)input, (cx_double*)output, fftw3_sign, fftw3_flags); + } + + return nullptr; + } + + + + template + arma_inline + void + execute(void_ptr plan) + { + arma_type_check((is_cx::value == false)); + + if(is_cx_float::value) + { + fftwf_execute(plan); + } + else + if(is_cx_double::value) + { + fftw_execute(plan); + } + } + + + + template + arma_inline + void + destroy_plan(void_ptr plan) + { + arma_type_check((is_cx::value == false)); + + if(is_cx_float::value) + { + fftwf_destroy_plan(plan); + } + else + if(is_cx_double::value) + { + fftw_destroy_plan(plan); + } + } + + + + template + arma_inline + void + cleanup() + { + arma_type_check((is_cx::value == false)); + + if(is_cx_float::value) + { + fftwf_cleanup(); + } + else + if(is_cx_double::value) + { + fftw_cleanup(); + } + } + } + + +#endif diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/translate_lapack.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/translate_lapack.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/translate_lapack.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/translate_lapack.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -17,7 +17,7 @@ -#ifdef ARMA_USE_LAPACK +#if defined(ARMA_USE_LAPACK) //! \namespace lapack namespace for LAPACK functions @@ -1306,18 +1306,6 @@ template - inline - void - larnv(blas_int* idist, blas_int* iseed, const blas_int* n, eT* x) - { - arma_type_check(( is_supported_blas_type::value == false )); - - if( is_float::value) { typedef float T; arma_fortran(arma_slarnv)(idist, iseed, n, (T*)x); } - else if(is_double::value) { typedef double T; arma_fortran(arma_dlarnv)(idist, iseed, n, (T*)x); } - } - - - template inline void gehrd(blas_int* n, blas_int* ilo, blas_int* ihi, eT* a, blas_int* lda, eT* tao, eT* work, blas_int* lwork, blas_int* info) diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/trimat_helper.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/trimat_helper.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/trimat_helper.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/trimat_helper.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -107,6 +107,58 @@ +template +inline +bool +has_nonfinite_tril(const Mat& A) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming that A has a square size + + const eT* colptr = A.memptr(); + const uword N = A.n_rows; + + for(uword i=0; i +inline +bool +has_nonfinite_triu(const Mat& A) + { + arma_extra_debug_sigprint(); + + // NOTE: assuming that A has a square size + + const eT* colptr = A.memptr(); + const uword N = A.n_rows; + + for(uword i=0; i= 0xffff @@ -123,7 +122,7 @@ // -#ifdef ARMA_USE_MKL_TYPES +#if defined(ARMA_USE_MKL_TYPES) // for compatibility with MKL typedef MKL_Complex8 blas_cxf; typedef MKL_Complex16 blas_cxd; diff -Nru armadillo-10.8.2+dfsg/include/armadillo_bits/wall_clock_bones.hpp armadillo-12.6.1+dfsg/include/armadillo_bits/wall_clock_bones.hpp --- armadillo-10.8.2+dfsg/include/armadillo_bits/wall_clock_bones.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/include/armadillo_bits/wall_clock_bones.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -28,8 +28,8 @@ inline wall_clock(); inline ~wall_clock(); - inline void tic(); //!< start the timer - inline arma_warn_unused double toc(); //!< return the number of seconds since the last call to tic() + inline void tic(); //!< start the timer + arma_warn_unused inline double toc(); //!< return the number of seconds since the last call to tic() private: diff -Nru armadillo-10.8.2+dfsg/index.html armadillo-12.6.1+dfsg/index.html --- armadillo-10.8.2+dfsg/index.html 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/index.html 2016-06-16 16:27:01.000000000 +0000 @@ -57,8 +57,8 @@ diff -Nru armadillo-10.8.2+dfsg/mex_interface/armaMex.hpp armadillo-12.6.1+dfsg/mex_interface/armaMex.hpp --- armadillo-10.8.2+dfsg/mex_interface/armaMex.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/mex_interface/armaMex.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -15,12 +15,12 @@ // Connector for Mex files to use Armadillo for calculation -// Version 0.5 +// Version 0.6 #include #include -#include +#include #include using namespace std; @@ -31,7 +31,7 @@ template inline Type -armaGetScalar(const mxArray *matlabScalar) +armaGetScalar(const mxArray* matlabScalar) { if(mxGetData(matlabScalar) != NULL) { @@ -48,7 +48,7 @@ // To keep with Matlab/Octave mex functions since functions for double are usually defined in conjunction with the general functions. inline double -armaGetDouble(const mxArray *matlabScalar) +armaGetDouble(const mxArray* matlabScalar) { return armaGetScalar(matlabScalar); } @@ -59,7 +59,7 @@ template inline Mat -armaGetData(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetData(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if(mxGetData(matlabMatrix) != NULL) { @@ -86,7 +86,7 @@ // Get double real matrix from Matlab/Octave. inline Mat -armaGetPr(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetPr(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if(mxGetData(matlabMatrix) != NULL) { @@ -115,7 +115,7 @@ template inline Mat -armaGetImagData(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetImagData(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if(mxGetImagData(matlabMatrix) != NULL) { @@ -142,7 +142,7 @@ // Get double imaginary matrix from Matlab/Octave. inline Mat -armaGetPi(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetPi(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if(mxGetImagData(matlabMatrix) != NULL) { @@ -169,7 +169,7 @@ // Get complex matrix from Matlab/Octave inline cx_mat -armaGetCx(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetCx(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if( (mxGetPr(matlabMatrix) != NULL) && (mxGetPi(matlabMatrix) != NULL) ) { @@ -195,7 +195,7 @@ template inline void -armaSetData(mxArray *matlabMatrix, const Mat& armaMatrix) +armaSetData(mxArray* matlabMatrix, const Mat& armaMatrix) { Type *dst_pointer = (Type*)mxGetData(matlabMatrix); const Type *src_pointer = (Type*)armaMatrix.memptr(); @@ -207,7 +207,7 @@ // Return double real valued matrix to Matlab/Octave inline void -armaSetPr(mxArray *matlabMatrix, const Mat& armaMatrix) +armaSetPr(mxArray* matlabMatrix, const Mat& armaMatrix) { double *dst_pointer = mxGetPr(matlabMatrix); const double *src_pointer = armaMatrix.memptr(); @@ -220,7 +220,7 @@ template inline void -armaSetImagData(mxArray *matlabMatrix, const Mat& armaMatrix) +armaSetImagData(mxArray* matlabMatrix, const Mat& armaMatrix) { Type *dst_pointer = (Type*)mxGetImagData(matlabMatrix); const Type *src_pointer = (Type*)armaMatrix.memptr(); @@ -232,7 +232,7 @@ // Return double complex valued matrix to Matlab/Octave inline void -armaSetPi(mxArray *matlabMatrix, const Mat& armaMatrix) +armaSetPi(mxArray* matlabMatrix, const Mat& armaMatrix) { double *dst_pointer = mxGetPi(matlabMatrix); const double *src_pointer = armaMatrix.memptr(); @@ -244,7 +244,7 @@ // Return complex matrix to Matlab/Octave. Requires Matlab/Octave matrix to be mxCOMPLEX inline void -armaSetCx(mxArray *matlabMatrix, const cx_mat& armaMatrix) +armaSetCx(mxArray* matlabMatrix, const cx_mat& armaMatrix) { armaSetPr(matlabMatrix, real(armaMatrix)); armaSetPi(matlabMatrix, imag(armaMatrix)); @@ -258,7 +258,7 @@ template inline Cube -armaGetCubeData(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetCubeData(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if(mxGetData(matlabMatrix) != NULL) { @@ -286,7 +286,7 @@ // Get double cube from Matlab/Octave. inline Cube -armaGetCubePr(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetCubePr(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if(mxGetData(matlabMatrix) != NULL) { @@ -316,7 +316,7 @@ template inline Cube -armaGetCubeImagData(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetCubeImagData(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if(mxGetImagData(matlabMatrix) != NULL) { @@ -344,7 +344,7 @@ // Get double cube from Matlab/Octave. inline Cube -armaGetCubePi(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetCubePi(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if(mxGetImagData(matlabMatrix) != NULL) { @@ -372,7 +372,7 @@ // Get complex cube from Matlab/Octave inline cx_cube -armaGetCubeCx(const mxArray *matlabMatrix, bool copy_aux_mem = false, bool strict = true) +armaGetCubeCx(const mxArray* matlabMatrix, bool copy_aux_mem = false, bool strict = true) { if( (mxGetPr(matlabMatrix) != NULL) && (mxGetPi(matlabMatrix) != NULL) ) { @@ -399,7 +399,7 @@ template inline void -armaSetCubeData(mxArray *matlabMatrix, const Cube& armaCube) +armaSetCubeData(mxArray* matlabMatrix, const Cube& armaCube) { Type *dst_pointer = (Type*)mxGetData(matlabMatrix); const Type *src_pointer = (Type*)armaCube.memptr(); @@ -411,7 +411,7 @@ // Return double real valued cube to Matlab/Octave inline void -armaSetCubePr(mxArray *matlabMatrix, const Cube& armaCube) +armaSetCubePr(mxArray* matlabMatrix, const Cube& armaCube) { double *dst_pointer = mxGetPr(matlabMatrix); const double *src_pointer = armaCube.memptr(); @@ -424,7 +424,7 @@ template inline void -armaSetImagCubeData(mxArray *matlabMatrix, const Cube& armaCube) +armaSetImagCubeData(mxArray* matlabMatrix, const Cube& armaCube) { Type *dst_pointer = (Type*)mxGetImagData(matlabMatrix); const Type *src_pointer = (Type*)armaCube.memptr(); @@ -436,7 +436,7 @@ // Return double imaginary valued matrix to Matlab/Octave inline void -armaSetCubePi(mxArray *matlabMatrix, const Cube& armaCube) +armaSetCubePi(mxArray* matlabMatrix, const Cube& armaCube) { double *dst_pointer = mxGetPi(matlabMatrix); const double *src_pointer = armaCube.memptr(); @@ -448,7 +448,7 @@ // Return double complex cube to Matlab/Octave. inline void -armaSetCubeCx(mxArray *matlabMatrix, const cx_cube& armaCube) +armaSetCubeCx(mxArray* matlabMatrix, const cx_cube& armaCube) { armaSetCubePr(matlabMatrix, real(armaCube)); armaSetCubePi(matlabMatrix, imag(armaCube)); @@ -462,7 +462,7 @@ template inline SpMat -armaGetSparseData(const mxArray *matlabMatrix, bool sort_locations = false) +armaGetSparseData(const mxArray* matlabMatrix, bool sort_locations = false) { if(!mxIsSparse(matlabMatrix)) { @@ -522,7 +522,7 @@ // Get double valued sparse matrix from Matlab/Octave. inline SpMat -armaGetSparseMatrix(const mxArray *matlabMatrix, bool sort_locations = false) +armaGetSparseMatrix(const mxArray* matlabMatrix, bool sort_locations = false) { if(!mxIsSparse(matlabMatrix)) { @@ -584,7 +584,7 @@ template inline SpMat -armaGetSparseImagData(const mxArray *matlabMatrix, bool sort_locations = false) +armaGetSparseImagData(const mxArray* matlabMatrix, bool sort_locations = false) { if(!mxIsSparse(matlabMatrix)) { @@ -643,7 +643,7 @@ // Get imaginary double valued sparse matrix from Matlab/Octave. inline SpMat -armaGetSparseImagMatrix(const mxArray *matlabMatrix, bool sort_locations = false) +armaGetSparseImagMatrix(const mxArray* matlabMatrix, bool sort_locations = false) { if(!mxIsSparse(matlabMatrix)) { @@ -703,12 +703,14 @@ // Return sparse matrix to matlab inline void -armaSetSparsePr(mxArray *matlabMatrix, const SpMat& armaMatrix) +armaSetSparsePr(mxArray* matlabMatrix, const SpMat& armaMatrix) { double *sr = mxGetPr(matlabMatrix); mwIndex *irs = mxGetIr(matlabMatrix); mwIndex *jcs = mxGetJc(matlabMatrix); - + + armaMatrix.sync(); + mwSize n_nonzero = armaMatrix.n_nonzero; mwSize n_cols = armaMatrix.n_cols; @@ -727,12 +729,14 @@ // Return sparse matrix to matlab as imaginary part inline void -armaSetSparsePi(mxArray *matlabMatrix, const SpMat& armaMatrix) +armaSetSparsePi(mxArray* matlabMatrix, const SpMat& armaMatrix) { double *si = mxGetPi(matlabMatrix); mwIndex *irs = mxGetIr(matlabMatrix); mwIndex *jcs = mxGetJc(matlabMatrix); - + + armaMatrix.sync(); + mwSize n_nonzero = armaMatrix.n_nonzero; mwSize n_cols = armaMatrix.n_cols; @@ -756,7 +760,7 @@ mxArray* armaCreateMxMatrix(const mwSize n_rows, const mwSize n_cols, const mxClassID mx_type = mxDOUBLE_CLASS, const mxComplexity mx_complexity = mxREAL) { - mxArray *temp = mxCreateNumericMatrix(n_rows, n_cols, mx_type, mx_complexity); + mxArray* temp = mxCreateNumericMatrix(n_rows, n_cols, mx_type, mx_complexity); if(temp == NULL) { @@ -779,7 +783,7 @@ const mwSize n_dim = 3; - mxArray *temp = mxCreateNumericArray(n_dim, dims, mx_type, mx_complexity); + mxArray* temp = mxCreateNumericArray(n_dim, dims, mx_type, mx_complexity); if(temp == NULL) { @@ -797,7 +801,7 @@ mxArray* armaCreateMxSparseMatrix(const mwSize n_rows,const mwSize n_cols,const mwSize n_nonzero,const mxComplexity mx_complexity = mxREAL) { - mxArray *temp = mxCreateSparse(n_rows, n_cols, n_nonzero, mx_complexity); + mxArray* temp = mxCreateSparse(n_rows, n_cols, n_nonzero, mx_complexity); if(temp == NULL) { @@ -811,219 +815,3 @@ } -//Functions to write MAT files -inline -int -armaWriteMatToFile(const char *filename, mat &armaMatrix, const char *name) - { - MATFile *file; - file = matOpen(filename,"wz"); - - int result; - - if(file == NULL) - { - mexErrMsgTxt("Could not create MAT file."); - return 0; - } - else - { - mxArray *temp = mxCreateDoubleMatrix(armaMatrix.n_rows, armaMatrix.n_cols, mxREAL); - armaSetPr(temp, armaMatrix); - result = matPutVariable(file, name, temp); - mxDestroyArray(temp); //Cleanup after writing MAT file - } - - matClose(file); - - return result; - } - - -inline -int -armaWriteCxMatToFile(const char *filename, cx_mat &armaMatrix, const char *name) - { - MATFile *file; - file = matOpen(filename,"wz"); - - int result; - - if(file == NULL) - { - mexErrMsgTxt("Could not create MAT file."); - return 0; - } - else - { - mxArray *temp = mxCreateDoubleMatrix(armaMatrix.n_rows, armaMatrix.n_cols, mxCOMPLEX); - armaSetCx(temp, armaMatrix); - result = matPutVariable(file, name, temp); - mxDestroyArray(temp); //Cleanup after writing MAT file - } - - matClose(file); - - return result; - } - - -inline -int -armaWriteCubeToFile(const char *filename, cube &armaCube, const char *name) - { - MATFile *file; - file = matOpen(filename,"wz"); - - int result; - - if(file == NULL) - { - mexErrMsgTxt("Could not create MAT file."); - return 0; - } - else - { - mxArray *temp = armaCreateMxMatrix(armaCube.n_rows, armaCube.n_cols, armaCube.n_slices, mxDOUBLE_CLASS, mxREAL); - armaSetCubePr(temp, armaCube); - result = matPutVariable(file, name, temp); - mxDestroyArray(temp); //Cleanup after writing MAT file - } - - matClose(file); - - return result; - } - - -inline -int -armaWriteCxCubeToFile(const char *filename, cx_cube &armaCube, const char *name) - { - MATFile *file; - file = matOpen(filename,"wz"); - - int result; - - if(file == NULL) - { - mexErrMsgTxt("Could not create MAT file."); - return 0; - } - else - { - mxArray *temp = armaCreateMxMatrix(armaCube.n_rows, armaCube.n_cols, armaCube.n_slices, mxDOUBLE_CLASS, mxCOMPLEX); - armaSetCubeCx(temp, armaCube); - result = matPutVariable(file, name, temp); - mxDestroyArray(temp); //Cleanup after writing MAT file - } - - matClose(file); - - return result; - } - - -//Functions to read and write matrices and cubes in MAT file format -inline -mat -armaReadMatFromFile(const char *filename) - { - MATFile *file; - file = matOpen(filename,"r"); - - char buffer[1024]; - const char *name; - name = buffer; - - if(file == NULL) - { - mexErrMsgTxt("Could not open MAT file."); - return mat(); - } - else - { - mat tmp = armaGetPr(matGetNextVariable(file,&name)); - matClose(file); - - return tmp; - } - } - - -inline -cx_mat -armaReadCxMatFromFile(const char *filename) - { - MATFile *file; - file = matOpen(filename,"r"); - - char buffer[1024]; - const char *name; - name = buffer; - - if(file == NULL) - { - mexErrMsgTxt("Could not open MAT file."); - return cx_mat(); - } - else - { - cx_mat tmp = armaGetCx(matGetNextVariable(file, &name)); - matClose(file); - - return tmp; - } - } - - -inline -cube -armaReadCubeFromFile(const char *filename) - { - MATFile *file; - file = matOpen(filename,"r"); - - char buffer[1024]; - const char *name; - name = buffer; - - if(file == NULL) - { - mexErrMsgTxt("Could not open MAT file."); - return cube(); - } - else - { - cube tmp = armaGetCubePr(matGetNextVariable(file,&name)); - matClose(file); - - return tmp; - } - } - - -inline -cx_cube -armaReadCxCubeFromFile(const char *filename) - { - MATFile *file; - file = matOpen(filename,"r"); - - char buffer[1024]; - const char *name; - name = buffer; - - if(file == NULL) - { - mexErrMsgTxt("Could not open MAT file."); - return cx_cube(); - } - else - { - cx_cube tmp = armaGetCubeCx(matGetNextVariable(file,&name)); - matClose(file); - - return tmp; - } - } diff -Nru armadillo-10.8.2+dfsg/mex_interface/readMatTest.cpp armadillo-12.6.1+dfsg/mex_interface/readMatTest.cpp --- armadillo-10.8.2+dfsg/mex_interface/readMatTest.cpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/mex_interface/readMatTest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -// Copyright 2014 Conrad Sanderson (http://conradsanderson.id.au) -// Copyright 2014 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. -// ------------------------------------------------------------------------ - - -// Demonstration of how to connect Armadillo with Matlab mex functions. -// Version 0.5 - - -#include "armaMex.hpp" - - -void -mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) - { - // Read the matrix from the file inData.mat - mat fromFile = armaReadMatFromFile("inData.mat"); - - fromFile.print(); - - mat tmp(4,6); - tmp.randu(); - - // Write the matrix tmp as outData in the file outData.mat - armaWriteMatToFile("outData.mat", tmp, "outData"); - } diff -Nru armadillo-10.8.2+dfsg/misc/armadillo.spec armadillo-12.6.1+dfsg/misc/armadillo.spec --- armadillo-10.8.2+dfsg/misc/armadillo.spec 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/misc/armadillo.spec 2016-06-16 16:27:01.000000000 +0000 @@ -1,5 +1,5 @@ Name: armadillo -Version: 10.1.x +Version: 11.1.x Release: 1%{?dist} Summary: Fast C++ matrix library with syntax similar to MATLAB and Octave @@ -7,7 +7,7 @@ URL: http://arma.sourceforge.net/ Source: http://sourceforge.net/projects/arma/files/%{name}-%{version}.tar.xz -BuildRequires: gcc-c++, cmake, lapack-devel, arpack-devel, hdf5-devel, zlib-devel +BuildRequires: gcc-c++, cmake, lapack-devel, arpack-devel %{!?openblas_arches:%global openblas_arches x86_64 %{ix86} armv7hl %{power64} aarch64} %ifarch %{openblas_arches} BuildRequires: openblas-devel @@ -36,7 +36,7 @@ %package devel Summary: Development headers and documentation for the Armadillo C++ library Requires: %{name} = %{version}-%{release} -Requires: lapack-devel, atlas-devel, arpack-devel, hdf5-devel, zlib-devel, libstdc++-devel +Requires: lapack-devel, arpack-devel, libstdc++-devel %ifarch %{openblas_arches} Requires: openblas-devel %endif @@ -97,5 +97,5 @@ %doc armadillo_nicta_2010.pdf %doc armadillo_solver_2020.pdf %doc armadillo_spcs_2017.pdf -%doc rcpp_armadillo_csda_2014.pdf +%doc armadillo_rcpp_2014.pdf %doc mex_interface diff -Nru armadillo-10.8.2+dfsg/NOTICE.txt armadillo-12.6.1+dfsg/NOTICE.txt --- armadillo-10.8.2+dfsg/NOTICE.txt 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/NOTICE.txt 2016-06-16 16:27:01.000000000 +0000 @@ -1,9 +1,21 @@ Armadillo C++ Linear Algebra Library -Copyright 2008-2022 Conrad Sanderson (http://conradsanderson.id.au) +Copyright 2008-2023 Conrad Sanderson (https://conradsanderson.id.au) Copyright 2008-2016 National ICT Australia (NICTA) -Copyright 2017-2022 Data61 / CSIRO +Copyright 2017-2023 Data61 / CSIRO -This product includes software developed by Conrad Sanderson (http://conradsanderson.id.au) +This product includes software developed by Conrad Sanderson (https://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 + +--- + +Attribution Notice. +As per UN General Assembly Resolution A/RES/ES-11/1 +adopted on 2 March 2022 with 141 votes in favour and 5 votes against, +we attribute the violation of the sovereignty and territorial integrity of Ukraine, +and subsequent destruction of many Ukrainian cities and civilian infrastructure, +to large-scale military aggression by the Russian Federation (aided by Belarus). +Further details: +https://undocs.org/A/RES/ES-11/1 +https://digitallibrary.un.org/record/3965290/files/A_RES_ES-11_1-EN.pdf +https://digitallibrary.un.org/record/3965290/files/A_RES_ES-11_1-RU.pdf diff -Nru armadillo-10.8.2+dfsg/README.md armadillo-12.6.1+dfsg/README.md --- armadillo-10.8.2+dfsg/README.md 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/README.md 2016-06-16 16:27:01.000000000 +0000 @@ -1,17 +1,17 @@ ### Armadillo: C++ Library for Linear Algebra & Scientific Computing -http://arma.sourceforge.net +https://arma.sourceforge.net -Copyright 2008-2022 Conrad Sanderson (http://conradsanderson.id.au) +Copyright 2008-2023 Conrad Sanderson (https://conradsanderson.id.au) Copyright 2008-2016 National ICT Australia (NICTA) -Copyright 2017-2022 Data61 / CSIRO +Copyright 2017-2023 Data61 / CSIRO --- ### Quick Links -- [download latest stable release](http://arma.sourceforge.net/download.html) -- [documentation for functions and classes](http://arma.sourceforge.net/docs.html) -- [bug reports & questions](http://arma.sourceforge.net/faq.html) +- [download latest stable release](https://arma.sourceforge.net/download.html) +- [documentation for functions and classes](https://arma.sourceforge.net/docs.html) +- [bug reports & questions](https://arma.sourceforge.net/faq.html) --- @@ -30,16 +30,15 @@ 8. [Windows: Compiling and Linking](#8-windows-compiling-and-linking) 9. [Support for OpenBLAS and Intel MKL](#9-support-for-openblas-and-intel-mkl) -10. [Support for ATLAS](#10-support-for-atlas) -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 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) +10. [Caveat on use of C++11 auto Keyword](#10-caveat-on-use-of-c11-auto-keyword) +11. [Support for OpenMP](#11-support-for-openmp) -16. [MEX Interface to Octave/Matlab](#16-mex-interface-to-octavematlab) -17. [Related Software Using Armadillo](#17-related-software-using-armadillo) +12. [Documentation of Functions and Classes](#12-documentation-of-functions-and-classes) +13. [API Stability and Version Policy](#13-api-stability-and-version-policy) +14. [Bug Reports and Frequently Asked Questions](#14-bug-reports-and-frequently-asked-questions) + +15. [MEX Interface to Octave/Matlab](#15-mex-interface-to-octavematlab) +16. [Related Software Using Armadillo](#16-related-software-using-armadillo) --- @@ -68,8 +67,8 @@ signal processing, bioinformatics, statistics, finance, etc. Authors: - * Conrad Sanderson - http://conradsanderson.id.au - * Ryan Curtin - http://ratml.org + * Conrad Sanderson - https://conradsanderson.id.au + * Ryan Curtin - https://ratml.org --- @@ -80,7 +79,7 @@ * Conrad Sanderson and Ryan Curtin. Armadillo: a template-based C++ library for linear algebra. - Journal of Open Source Software, Vol. 1, pp. 26, 2016. + Journal of Open Source Software, Vol. 1, No. 2, pp. 26, 2016. * Conrad Sanderson and Ryan Curtin. A User-Friendly Hybrid Sparse Matrix Class in C++. @@ -106,32 +105,40 @@ ### 4: Prerequisites and Dependencies The functionality of Armadillo is partly dependent on other libraries: -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. +- OpenBLAS (or standard BLAS) +- LAPACK +- ARPACK +- SuperLU + +Use of OpenBLAS (instead of standard BLAS) is strongly recommended on all systems. On macOS, the Accelerate framework can be used for BLAS and LAPACK functions. -Use of OpenBLAS is strongly recommended on all systems. -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. +If sparse matrices are not needed, ARPACK and SuperLU are not required. + +Armadillo requires a C++ compiler that supports at least the C++11 standard. On Linux-based systems, install the GCC C++ compiler, which is available as a pre-built package. The package name might be `g++` or `gcc-c++` depending on your system. -On macOS systems, a C++ compiler can be obtained by first installing Xcode (version 8 or later) +On macOS systems, a C++ compiler can be obtained by first installing Xcode (at least version 8) and then running the following command in a terminal window: xcode-select --install On Windows systems, the MinGW toolset or Visual Studio C++ 2019 (MSVC) can be used. +Caveats on the use of SuperLU: +- SuperLU must be available as a shared library +- Only the following SuperLU versions are supported: 5.2.x, 5.3.x, 6.0.x +- SuperLU 6.0.x must be compiled with default integer size (32 bits) + --- ### 5: Linux and macOS: Installation 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 +The cmake tool can be downloaded from https://www.cmake.org or (preferably) installed using the package manager on your system; on macOS systems, cmake can be installed through MacPorts or Homebrew. @@ -200,7 +207,7 @@ **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/`). +use a directory within your own home directory (eg. `/home/user/include/`). If required, modify `include/armadillo_bits/config.hpp` to indicate which libraries are currently available on your system. @@ -231,17 +238,17 @@ g++ prog.cpp -o prog -O2 -std=c++11 -lopenblas -llapack 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/` +such as `/home/user/include/`, you will need to make sure +that your C++ compiler searches `/home/user/include/` by explicitly specifying the directory as an argument/option. For example, using the `-I` switch in GCC and Clang: - g++ prog.cpp -o prog -O2 -std=c++11 -I /home/blah/include/ -lopenblas -llapack + g++ prog.cpp -o prog -O2 -std=c++11 -I /home/user/include/ -lopenblas -llapack If you're getting linking issues (unresolved symbols), enable the `ARMA_DONT_USE_WRAPPER` option: - g++ prog.cpp -o prog -O2 -std=c++11 -I /home/blah/include/ -DARMA_DONT_USE_WRAPPER -lopenblas -llapack + g++ prog.cpp -o prog -O2 -std=c++11 -I /home/user/include/ -DARMA_DONT_USE_WRAPPER -lopenblas -llapack If you don't have OpenBLAS, on Linux change `-lopenblas` to `-lblas`; on macOS change `-lopenblas -llapack` to `-framework Accelerate` @@ -254,7 +261,7 @@ 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 +https://arma.sourceforge.net/faq.html --- @@ -306,10 +313,10 @@ **Caveat:** for any high performance scientific/engineering workloads, -we strongly recommend using a Linux-based operating system: - * Fedora http://fedoraproject.org/ - * Ubuntu http://www.ubuntu.com/ - * CentOS http://centos.org/ +we strongly recommend using a Linux-based operating system, such as: + * Fedora https://fedoraproject.org/ + * Ubuntu https://www.ubuntu.com/ + * CentOS https://centos.org/ --- @@ -358,16 +365,7 @@ --- -### 10: Support for ATLAS - -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: Caveat on use of C++11 auto Keyword +### 10: Caveat on use of C++11 auto Keyword Use of the C++11 `auto` keyword is not recommended with Armadillo objects and expressions. @@ -376,28 +374,28 @@ --- -### 12: Support for OpenMP +### 11: Support for OpenMP Armadillo can use OpenMP to automatically speed up computationally expensive element-wise functions such as exp(), log(), cos(), etc. -This requires a C++11/C++14 compiler with OpenMP 3.1+ support. +This requires a C++ compiler with OpenMP 3.1+ support. -For GCC and Clang compilers, use the following options to enable both C++11 and OpenMP: -`-std=c++11 -fopenmp` +For GCC and Clang compilers, use the following option to enable OpenMP: +`-fopenmp` --- -### 13: Documentation of Functions and Classes +### 12: Documentation of Functions and Classes The documentation of Armadillo functions and classes is available at: -http://arma.sourceforge.net/docs.html +https://arma.sourceforge.net/docs.html The documentation is also in the `docs.html` file distributed with Armadillo. Use a web browser to view it. --- -### 14: API Stability and Versioning +### 13: API Stability and Version Policy Each release of Armadillo has its public API (functions, classes, constants) described in the accompanying API documentation (docs.html) specific @@ -406,33 +404,35 @@ Each release of Armadillo has its full version specified as A.B.C, where A is a major version number, B is a minor version number, and C is a patch level (indicating bug fixes). +The version specification has explicit meaning, +similar to [Semantic Versioning](https://semver.org/), as follows: -Within a major version (eg. 7), each minor version has a public API that -strongly strives to be backwards compatible (at the source level) with the -public API of preceding minor versions. For example, user code written for -version 7.100 should work with version 7.200, 7.300, 7.400, etc. However, -as later minor versions may have more features (API extensions) than -preceding minor versions, user code specifically written for version 7.400 -may not work with 7.300. - -An increase in the patch level, while the major and minor versions are retained, -indicates modifications to the code and/or documentation which aim to fix bugs -without altering the public API. - -We don't like changes to existing public API and strongly prefer not to break -any user software. However, to allow evolution, we reserve the right to -alter the public API in future major versions of Armadillo while remaining -backwards compatible in as many cases as possible (eg. major version 8 may -have slightly different public API than major version 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. -(In other words, don't use internal functionality). +* Within a major version (eg. 10), each minor version has a public API that + strongly strives to be backwards compatible (at the source level) with the + public API of preceding minor versions. For example, user code written for + version 10.0 should work with version 10.1, 10.2, etc. + However, later minor versions may have more features (API additions and extensions) + than preceding minor versions. As such, user code _specifically_ + written for version 10.2 may not work with 10.1. + +* An increase in the patch level, while the major and minor versions are retained, + indicates modifications to the code and/or documentation which aim to fix bugs + without altering the public API. + +* We don't like changes to existing public API and strongly prefer not to break + any user software. However, to allow evolution, the public API in future major versions + while remaining backwards compatible in as many cases as possible + (eg. major version 11 may have slightly different public API than major version 10). + +**CAVEAT:** +the above policy applies only to the public API described in the documentation. +Any functionality within Armadillo which is _not explicitly_ described +in the public API documentation is considered as internal implementation details, +and may be changed or removed without notice. --- -### 15: Bug Reports and Frequently Asked Questions +### 14: Bug Reports and Frequently Asked Questions Armadillo has gone through extensive testing and has been successfully used in production environments. However, as with almost all software, @@ -445,34 +445,34 @@ functions/classes from Armadillo and the standard C++ library (no other libraries). The contact details are at: -http://arma.sourceforge.net/contact.html +https://arma.sourceforge.net/contact.html Further information about Armadillo is on the frequently asked questions page: -http://arma.sourceforge.net/faq.html +https://arma.sourceforge.net/faq.html --- -### 16: MEX Interface to Octave/Matlab +### 15: MEX Interface to Octave/Matlab The `mex_interface` folder contains examples of how to interface Octave/Matlab with C++ code that uses Armadillo matrices. --- -### 17: Related Software Using Armadillo +### 16: Related Software Using Armadillo + +* Bandicoot: C++ library for accelerated linear algebra on GPUs + https://coot.sourceforge.io -* ensmallen: fast non-linear numerical optimisation library - http://ensmallen.org/ +* ensmallen: fast library for non-linear numerical optimisation + https://ensmallen.org/ * MLPACK: extensive library of machine learning algorithms - http://mlpack.org + https://mlpack.org + +* RcppArmadillo: integration of Armadillo with R + https://dirk.eddelbuettel.com/code/rcpp.armadillo.html * 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-10.8.2+dfsg/src/wrapper1.cpp armadillo-12.6.1+dfsg/src/wrapper1.cpp --- armadillo-10.8.2+dfsg/src/wrapper1.cpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/src/wrapper1.cpp 2016-06-16 16:27:01.000000000 +0000 @@ -27,7 +27,6 @@ #include "armadillo_bits/compiler_setup.hpp" #include "armadillo_bits/typedef_elem.hpp" -#include "armadillo_bits/include_atlas.hpp" #include "armadillo_bits/include_superlu.hpp" @@ -36,56 +35,21 @@ 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) - // #pragma message ("disabling use of HDF5 due to its incompatible configuration") - #undef ARMA_USE_HDF5_ALT - #endif - -#endif - namespace arma { #include "armadillo_bits/def_blas.hpp" +#include "armadillo_bits/def_atlas.hpp" #include "armadillo_bits/def_lapack.hpp" #include "armadillo_bits/def_arpack.hpp" #include "armadillo_bits/def_superlu.hpp" -// no need to include def_hdf5.hpp -- it only contains #defines for when ARMA_USE_HDF5_ALT is not defined. -#if defined(ARMA_USE_HDF5_ALT) - // Wrapper functions: arma::H5open() and arma::H5check_version() to hijack calls to H5open() and H5check_version() - herr_t H5open() - { - return ::H5open(); - } - - herr_t H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) - { - return ::H5check_version(majnum, minnum, relnum); - } -#endif - - - -// at this stage we have prototypes for the real blas, lapack and atlas functions +// at this stage we have prototypes for actual BLAS and LAPACK functions // now we make the wrapper functions @@ -200,6 +164,124 @@ + #if defined(ARMA_USE_ATLAS) + + float wrapper_cblas_sasum(const int N, const float *X, const int incX) + { + return cblas_sasum(N, X, incX); + } + + double wrapper_cblas_dasum(const int N, const double *X, const int incX) + { + return cblas_dasum(N, X, incX); + } + + + + float wrapper_cblas_snrm2(const int N, const float *X, const int incX) + { + return cblas_snrm2(N, X, incX); + } + + double wrapper_cblas_dnrm2(const int N, const double *X, const int incX) + { + return cblas_dnrm2(N, X, incX); + } + + + + float wrapper_cblas_sdot(const int N, const float *X, const int incX, const float *Y, const int incY) + { + return cblas_sdot(N, X, incX, Y, incY); + } + + double wrapper_cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY) + { + return cblas_ddot(N, X, incX, Y, incY); + } + + void wrapper_cblas_cdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu) + { + cblas_cdotu_sub(N, X, incX, Y, incY, dotu); + } + + void wrapper_cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu) + { + cblas_zdotu_sub(N, X, incX, Y, incY, dotu); + } + + + + void wrapper_cblas_sgemv(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY) + { + cblas_sgemv(layout, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); + } + + void wrapper_cblas_dgemv(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY) + { + cblas_dgemv(layout, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); + } + + void wrapper_cblas_cgemv(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) + { + cblas_cgemv(layout, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); + } + + void wrapper_cblas_zgemv(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const int M, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) + { + cblas_zgemv(layout, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); + } + + + + void wrapper_cblas_sgemm(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc) + { + cblas_sgemm(layout, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc); + } + + void wrapper_cblas_dgemm(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc) + { + cblas_dgemm(layout, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc); + } + + void wrapper_cblas_cgemm(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) + { + cblas_cgemm(layout, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc); + } + + void wrapper_cblas_zgemm(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_TRANS TransA, const atlas_CBLAS_TRANS TransB, const int M, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) + { + cblas_zgemm(layout, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc); + } + + + + void wrapper_cblas_ssyrk(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const float alpha, const float *A, const int lda, const float beta, float *C, const int ldc) + { + cblas_ssyrk(layout, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc); + } + + void wrapper_cblas_dsyrk(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double beta, double *C, const int ldc) + { + cblas_dsyrk(layout, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc); + } + + + + void wrapper_cblas_cherk(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const float alpha, const void *A, const int lda, const float beta, void *C, const int ldc) + { + cblas_cherk(layout, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc); + } + + void wrapper_cblas_zherk(const atlas_CBLAS_LAYOUT layout, const atlas_CBLAS_UPLO Uplo, const atlas_CBLAS_TRANS Trans, const int N, const int K, const double alpha, const void *A, const int lda, const double beta, void *C, const int ldc) + { + cblas_zherk(layout, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc); + } + + #endif + + + #if defined(ARMA_USE_LAPACK) void arma_fortran_with_prefix(arma_sgetrf)(const blas_int* m, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, blas_int* info) @@ -1166,18 +1248,6 @@ - void arma_fortran_with_prefix(arma_slarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, float* x) - { - arma_fortran_sans_prefix(arma_slarnv)(idist, iseed, n, x); - } - - void arma_fortran_with_prefix(arma_dlarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, double* x) - { - arma_fortran_sans_prefix(arma_dlarnv)(idist, iseed, n, x); - } - - - void arma_fortran_with_prefix(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_fortran_sans_prefix(arma_sgehrd)(n, ilo, ihi, a, lda, tao, work, lwork, info); @@ -1224,277 +1294,6 @@ - #if defined(ARMA_USE_ATLAS) - - float wrapper_cblas_sasum(const int N, const float *X, const int incX) - { - return cblas_sasum(N, X, incX); - } - - double wrapper_cblas_dasum(const int N, const double *X, const int incX) - { - return cblas_dasum(N, X, incX); - } - - - - float wrapper_cblas_snrm2(const int N, const float *X, const int incX) - { - return cblas_snrm2(N, X, incX); - } - - double wrapper_cblas_dnrm2(const int N, const double *X, const int incX) - { - return cblas_dnrm2(N, X, incX); - } - - - - float wrapper_cblas_sdot(const int N, const float *X, const int incX, const float *Y, const int incY) - { - return cblas_sdot(N, X, incX, Y, incY); - } - - double wrapper_cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY) - { - return cblas_ddot(N, X, incX, Y, incY); - } - - void wrapper_cblas_cdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu) - { - cblas_cdotu_sub(N, X, incX, Y, incY, dotu); - } - - void wrapper_cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu) - { - cblas_zdotu_sub(N, X, incX, Y, incY, dotu); - } - - - - void wrapper_cblas_sgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const float alpha, - const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY) - { - cblas_sgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); - } - - void wrapper_cblas_dgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha, - const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY) - { - cblas_dgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); - } - - void wrapper_cblas_cgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha, - const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) - { - cblas_cgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); - } - - void wrapper_cblas_zgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha, - const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) - { - cblas_zgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); - } - - - - void wrapper_cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, - const int M, const int N, const int K, const float alpha, - const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc) - { - cblas_sgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc); - } - - void wrapper_cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, - const int M, const int N, const int K, const double alpha, - const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc) - { - cblas_dgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc); - } - - void wrapper_cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, - const int M, const int N, const int K, const void *alpha, - const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) - { - cblas_cgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc); - } - - void wrapper_cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, - const int M, const int N, const int K, const void *alpha, - const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) - { - cblas_zgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc); - } - - - - void wrapper_cblas_ssyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, - const int N, const int K, const float alpha, - const float *A, const int lda, const float beta, float *C, const int ldc) - { - cblas_ssyrk(Order, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc); - } - - void wrapper_cblas_dsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, - const int N, const int K, const double alpha, - const double *A, const int lda, const double beta, double *C, const int ldc) - { - cblas_dsyrk(Order, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc); - } - - - - void wrapper_cblas_cherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, - const int N, const int K, const float alpha, - const void *A, const int lda, const float beta, void *C, const int ldc) - { - cblas_cherk(Order, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc); - } - - void wrapper_cblas_zherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, - const int N, const int K, const double alpha, - const void *A, const int lda, const double beta, void *C, const int ldc) - { - cblas_zherk(Order, Uplo, Trans, N, K, alpha, A, lda, beta, C, ldc); - } - - - - int wrapper_clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N, float *A, const int lda, int *ipiv) - { - return clapack_sgetrf(Order, M, N, A, lda, ipiv); - } - - int wrapper_clapack_dgetrf(const enum CBLAS_ORDER Order, const int M, const int N, double *A, const int lda, int *ipiv) - { - return clapack_dgetrf(Order, M, N, A, lda, ipiv); - } - - int wrapper_clapack_cgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void *A, const int lda, int *ipiv) - { - return clapack_cgetrf(Order, M, N, A, lda, ipiv); - } - - int wrapper_clapack_zgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void *A, const int lda, int *ipiv) - { - return clapack_zgetrf(Order, M, N, A, lda, ipiv); - } - - - - int wrapper_clapack_sgetri(const enum CBLAS_ORDER Order, const int N, float *A, const int lda, const int *ipiv) - { - return clapack_sgetri(Order, N, A, lda, ipiv); - } - - int wrapper_clapack_dgetri(const enum CBLAS_ORDER Order, const int N, double *A, const int lda, const int *ipiv) - { - return clapack_dgetri(Order, N, A, lda, ipiv); - } - - int wrapper_clapack_cgetri(const enum CBLAS_ORDER Order, const int N, void *A, const int lda, const int *ipiv) - { - return clapack_cgetri(Order, N, A, lda, ipiv); - } - - int wrapper_clapack_zgetri(const enum CBLAS_ORDER Order, const int N, void *A, const int lda, const int *ipiv) - { - return clapack_zgetri(Order, N, A, lda, ipiv); - } - - - - int wrapper_clapack_sgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, float *A, const int lda, int *ipiv, float *B, const int ldb) - { - return clapack_sgesv(Order, N, NRHS, A, lda, ipiv, B, ldb); - } - - int wrapper_clapack_dgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, double *A, const int lda, int *ipiv, double *B, const int ldb) - { - return clapack_dgesv(Order, N, NRHS, A, lda, ipiv, B, ldb); - } - - int wrapper_clapack_cgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void *A, const int lda, int *ipiv, void *B, const int ldb) - { - return clapack_cgesv(Order, N, NRHS, A, lda, ipiv, B, ldb); - } - - int wrapper_clapack_zgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void *A, const int lda, int *ipiv, void *B, const int ldb) - { - return clapack_zgesv(Order, N, NRHS, A, lda, ipiv, B, ldb); - } - - - - int wrapper_clapack_spotrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, float *A, const int lda) - { - return clapack_spotrf(Order, Uplo, N, A, lda); - } - - int wrapper_clapack_dpotrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, double *A, const int lda) - { - return clapack_dpotrf(Order, Uplo, N, A, lda); - } - - int wrapper_clapack_cpotrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, void *A, const int lda) - { - return clapack_cpotrf(Order, Uplo, N, A, lda); - } - - int wrapper_clapack_zpotrf(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, void *A, const int lda) - { - return clapack_zpotrf(Order, Uplo, N, A, lda); - } - - - - int wrapper_clapack_spotri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, float *A, const int lda) - { - return clapack_spotri(Order, Uplo, N, A, lda); - } - - int wrapper_clapack_dpotri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, double *A, const int lda) - { - return clapack_dpotri(Order, Uplo, N, A, lda); - } - - int wrapper_clapack_cpotri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, void *A, const int lda) - { - return clapack_cpotri(Order, Uplo, N, A, lda); - } - - int wrapper_clapack_zpotri(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, void *A, const int lda) - { - return clapack_zpotri(Order, Uplo, N, A, lda); - } - - - - int wrapper_clapack_sposv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, float *A, const int lda, float *B, const int ldb) - { - return clapack_sposv(Order, Uplo, N, NRHS, A, lda, B, ldb); - } - - int wrapper_clapack_dposv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, double *A, const int lda, double *B, const int ldb) - { - return clapack_dposv(Order, Uplo, N, NRHS, A, lda, B, ldb); - } - - int wrapper_clapack_cposv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, void *A, const int lda, void *B, const int ldb) - { - return clapack_cposv(Order, Uplo, N, NRHS, A, lda, B, ldb); - } - - int wrapper_clapack_zposv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N, const int NRHS, void *A, const int lda, void *B, const int ldb) - { - return clapack_zposv(Order, Uplo, N, NRHS, A, lda, B, ldb); - } - - - #endif - - - #if defined(ARMA_USE_ARPACK) void arma_fortran_with_prefix(arma_snaupd)(blas_int* ido, char* bmat, blas_int* n, char* which, blas_int* nev, float* tol, float* resid, blas_int* ncv, float* v, blas_int* ldv, blas_int* iparam, blas_int* ipntr, float* workd, float* workl, blas_int* lworkl, blas_int* info) @@ -1763,169 +1562,6 @@ } #endif - - - - #if defined(ARMA_USE_HDF5_ALT) - - hid_t arma_H5Tcopy(hid_t dtype_id) - { - return H5Tcopy(dtype_id); - } - - hid_t arma_H5Tcreate(H5T_class_t cl, size_t size) - { - return H5Tcreate(cl, size); - } - - herr_t arma_H5Tinsert(hid_t dtype_id, const char* name, size_t offset, hid_t field_id) - { - return H5Tinsert(dtype_id, name, offset, field_id); - } - - htri_t arma_H5Tequal(hid_t dtype_id1, hid_t dtype_id2) - { - return H5Tequal(dtype_id1, dtype_id2); - } - - herr_t arma_H5Tclose(hid_t dtype_id) - { - return H5Tclose(dtype_id); - } - - hid_t arma_H5Dopen(hid_t loc_id, const char* name, hid_t dapl_id) - { - return H5Dopen(loc_id, name, dapl_id); - } - - hid_t arma_H5Dget_type(hid_t dataset_id) - { - return H5Dget_type(dataset_id); - } - - hid_t arma_H5Dcreate(hid_t loc_id, const char* name, hid_t dtype_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id) - { - return H5Dcreate(loc_id, name, dtype_id, space_id, lcpl_id, dcpl_id, dapl_id); - } - - herr_t arma_H5Dwrite(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, const void* buf) - { - return H5Dwrite(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, buf); - } - - herr_t arma_H5Dclose(hid_t dataset_id) - { - return H5Dclose(dataset_id); - } - - hid_t arma_H5Dget_space(hid_t dataset_id) - { - return H5Dget_space(dataset_id); - } - - herr_t arma_H5Dread(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, void* buf) - { - return H5Dread(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, buf); - } - - int arma_H5Sget_simple_extent_ndims(hid_t space_id) - { - return H5Sget_simple_extent_ndims(space_id); - } - - int arma_H5Sget_simple_extent_dims(hid_t space_id, hsize_t* dims, hsize_t* maxdims) - { - return H5Sget_simple_extent_dims(space_id, dims, maxdims); - } - - herr_t arma_H5Sclose(hid_t space_id) - { - return H5Sclose(space_id); - } - - hid_t arma_H5Screate_simple(int rank, const hsize_t* current_dims, const hsize_t* maximum_dims) - { - return H5Screate_simple(rank, current_dims, maximum_dims); - } - - herr_t arma_H5Ovisit(hid_t object_id, H5_index_t index_type, H5_iter_order_t order, H5O_iterate_t op, void* op_data) - { - return H5Ovisit(object_id, index_type, order, op, op_data); - } - - herr_t arma_H5Eset_auto(hid_t estack_id, H5E_auto_t func, void* client_data) - { - return H5Eset_auto(estack_id, func, client_data); - } - - herr_t arma_H5Eget_auto(hid_t estack_id, H5E_auto_t* func, void** client_data) - { - return H5Eget_auto(estack_id, func, client_data); - } - - hid_t arma_H5Fopen(const char* name, unsigned flags, hid_t fapl_id) - { - return H5Fopen(name, flags, fapl_id); - } - - hid_t arma_H5Fcreate(const char* name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) - { - return H5Fcreate(name, flags, fcpl_id, fapl_id); - } - - herr_t arma_H5Fclose(hid_t file_id) - { - return H5Fclose(file_id); - } - - htri_t arma_H5Fis_hdf5(const char* name) - { - return H5Fis_hdf5(name); - } - - hid_t arma_H5Gcreate(hid_t loc_id, const char* name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id) - { - return H5Gcreate(loc_id, name, lcpl_id, gcpl_id, gapl_id); - } - - hid_t arma_H5Gopen(hid_t loc_id, const char* name, hid_t gapl_id) - { - return H5Gopen(loc_id, name, gapl_id); - } - - herr_t arma_H5Gclose(hid_t group_id) - { - return H5Gclose(group_id); - } - - htri_t arma_H5Lexists(hid_t loc_id, const char* name, hid_t lapl_id) - { - return H5Lexists(loc_id, name, lapl_id); - } - - herr_t arma_H5Ldelete(hid_t loc_id, const char* name, hid_t lapl_id) - { - return H5Ldelete(loc_id, name, lapl_id); - } - - - // H5T_NATIVE_* types. The rhs here expands to some macros. - hid_t arma_H5T_NATIVE_UCHAR = H5T_NATIVE_UCHAR; - hid_t arma_H5T_NATIVE_CHAR = H5T_NATIVE_CHAR; - hid_t arma_H5T_NATIVE_SHORT = H5T_NATIVE_SHORT; - hid_t arma_H5T_NATIVE_USHORT = H5T_NATIVE_USHORT; - hid_t arma_H5T_NATIVE_INT = H5T_NATIVE_INT; - hid_t arma_H5T_NATIVE_UINT = H5T_NATIVE_UINT; - hid_t arma_H5T_NATIVE_LONG = H5T_NATIVE_LONG; - hid_t arma_H5T_NATIVE_ULONG = H5T_NATIVE_ULONG; - hid_t arma_H5T_NATIVE_LLONG = H5T_NATIVE_LLONG; - hid_t arma_H5T_NATIVE_ULLONG = H5T_NATIVE_ULLONG; - hid_t arma_H5T_NATIVE_FLOAT = H5T_NATIVE_FLOAT; - hid_t arma_H5T_NATIVE_DOUBLE = H5T_NATIVE_DOUBLE; - - #endif - - } // end of extern "C" diff -Nru armadillo-10.8.2+dfsg/src/wrapper2.cpp armadillo-12.6.1+dfsg/src/wrapper2.cpp --- armadillo-10.8.2+dfsg/src/wrapper2.cpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/src/wrapper2.cpp 2016-06-16 16:27:01.000000000 +0000 @@ -20,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 @@ -1118,18 +1113,6 @@ } - - void arma_fortran_with_prefix(arma_slarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, float* x) - { - arma_fortran_sans_prefix(arma_slarnv)(idist, iseed, n, x); - } - - void arma_fortran_with_prefix(arma_dlarnv)(const blas_int* idist, blas_int* iseed, const blas_int* n, double* x) - { - arma_fortran_sans_prefix(arma_dlarnv)(idist, iseed, n, x); - } - - void arma_fortran_with_prefix(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) { diff -Nru armadillo-10.8.2+dfsg/tests2/catch.hpp armadillo-12.6.1+dfsg/tests2/catch.hpp --- armadillo-10.8.2+dfsg/tests2/catch.hpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/tests2/catch.hpp 2016-06-16 16:27:01.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Catch v2.13.8 - * Generated: 2022-01-03 21:20:09.589503 + * Catch v2.13.10 + * Generated: 2022-10-16 11:01:23.452308 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 8 +#define CATCH_VERSION_PATCH 10 #ifdef __clang__ # pragma clang system_header @@ -7395,8 +7395,6 @@ template struct ObjectStorage { - using TStorage = typename std::aligned_storage::value>::type; - ObjectStorage() : data() {} ObjectStorage(const ObjectStorage& other) @@ -7439,7 +7437,7 @@ return *static_cast(static_cast(&data)); } - TStorage data; + struct { alignas(T) unsigned char data[sizeof(T)]; } data; }; } @@ -7949,7 +7947,7 @@ #if defined(__i386__) || defined(__x86_64__) #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ #elif defined(__aarch64__) - #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #define CATCH_TRAP() __asm__(".inst 0xd43e0000") #endif #elif defined(CATCH_PLATFORM_IPHONE) @@ -13392,6 +13390,10 @@ filename.erase(0, lastSlash); filename[0] = '#'; } + else + { + filename.insert(0, "#"); + } auto lastDot = filename.find_last_of('.'); if (lastDot != std::string::npos) { @@ -13554,7 +13556,7 @@ // Handle list request if( Option listed = list( m_config ) ) - return static_cast( *listed ); + return (std::min) (MaxExitCode, static_cast(*listed)); TestGroup tests { m_config }; auto const totals = tests.execute(); @@ -15387,7 +15389,7 @@ } Version const& libraryVersion() { - static Version version( 2, 13, 8, "", 0 ); + static Version version( 2, 13, 10, "", 0 ); return version; } @@ -17522,12 +17524,20 @@ #ifndef __OBJC__ +#ifndef CATCH_INTERNAL_CDECL +#ifdef _MSC_VER +#define CATCH_INTERNAL_CDECL __cdecl +#else +#define CATCH_INTERNAL_CDECL +#endif +#endif + #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && 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 * []) { +extern "C" int CATCH_INTERNAL_CDECL wmain (int argc, wchar_t * argv[], wchar_t * []) { #else // Standard C/C++ main entry point -int main (int argc, char * argv[]) { +int CATCH_INTERNAL_CDECL main (int argc, char * argv[]) { #endif return Catch::Session().run( argc, argv ); @@ -17890,7 +17900,7 @@ #define INFO( msg ) (void)(0) #define UNSCOPED_INFO( msg ) (void)(0) #define WARN( msg ) (void)(0) -#define CAPTURE( msg ) (void)(0) +#define CAPTURE( ... ) (void)(0) #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) diff -Nru armadillo-10.8.2+dfsg/tests2/fn_solve.cpp armadillo-12.6.1+dfsg/tests2/fn_solve.cpp --- armadillo-10.8.2+dfsg/tests2/fn_solve.cpp 1970-01-01 00:00:00.000000000 +0000 +++ armadillo-12.6.1+dfsg/tests2/fn_solve.cpp 2016-06-16 16:27:01.000000000 +0000 @@ -0,0 +1,147 @@ +// 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("fn_solve_1") + { + // square-sized A + + 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 = + "\ + 0.906104;\ + 0.372084;\ + 0.826970;\ + 0.911125;\ + 0.764937;\ + "; + + mat X1; + mat X2; + + bool status1 = solve(X1, A, B); + bool status2 = solve(X2, A, B, solve_opts::fast + solve_opts::no_approx); + + REQUIRE( status1 == true ); + REQUIRE( status2 == true ); + + REQUIRE( norm(vectorise(X1-X2),1) == Approx(0.0) ); + + REQUIRE( X1(0) == Approx(-1.486404584527645e+00) ); + REQUIRE( X1(1) == Approx(-1.298396730449162e+01) ); + REQUIRE( X1(2) == Approx( 9.470697159029561e+00) ); + REQUIRE( X1(3) == Approx(-9.356796987754391e+00) ); + REQUIRE( X1(4) == Approx( 9.375696966670487e+00) ); + } + + + +TEST_CASE("fn_solve_2") + { + // square-sized A; rank-deficient + + 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.col(0) *= datum::eps; + + mat B = + "\ + 0.906104;\ + 0.372084;\ + 0.826970;\ + 0.911125;\ + 0.764937;\ + "; + + mat X1; + mat X2; + + bool status1 = solve(X1, A, B); + bool status2 = solve(X2, A, B, solve_opts::no_approx); + + REQUIRE( status1 == true ); + REQUIRE( status2 == false ); + + REQUIRE( X1(0) == Approx( 9.929054488765161e-15) ); + REQUIRE( X1(1) == Approx(-1.088301076771930e+01) ); + REQUIRE( X1(2) == Approx( 8.435894619970558e+00) ); + REQUIRE( X1(3) == Approx(-6.820665349768506e+00) ); + REQUIRE( X1(4) == Approx( 6.785813315231441e+00) ); + } + + + +TEST_CASE("fn_solve_3") + { + // non-square-sized A + + 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 = + "\ + 0.906104;\ + 0.372084;\ + 0.826970;\ + 0.911125;\ + 0.764937;\ + "; + + mat X1; + mat X2; + + bool status1 = solve(X1, A, B); + bool status2 = solve(X2, A, B, solve_opts::fast + solve_opts::no_approx); + + REQUIRE( status1 == true ); + REQUIRE( status2 == true ); + + REQUIRE( norm(vectorise(X1-X2),1) == Approx(0.0) ); + + REQUIRE( X1(0) == Approx( 4.115847103194906) ); + REQUIRE( X1(1) == Approx(-3.878220128389104) ); + REQUIRE( X1(2) == Approx( 4.328088888881608) ); + REQUIRE( X1(3) == Approx(-2.949916817226818) ); + REQUIRE( X1(4) == Approx(-1.602040603621000) ); + REQUIRE( X1(5) == Approx(-5.985543296434588) ); + } diff -Nru armadillo-10.8.2+dfsg/tests2/fn_spsolve.cpp armadillo-12.6.1+dfsg/tests2/fn_spsolve.cpp --- armadillo-10.8.2+dfsg/tests2/fn_spsolve.cpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/tests2/fn_spsolve.cpp 2016-06-16 16:27:01.000000000 +0000 @@ -881,4 +881,58 @@ } } + + +TEST_CASE("spsolve_factoriser_test") + { + sp_mat A; + A.sprandu(100, 100, 0.2); + A.diag().randu(); + A.diag() += 1; + + vec B(100, fill::randu); + + vec X1; + bool X1_status = spsolve(X1, A, B); + REQUIRE( X1_status ); + + + spsolve_factoriser SF; + bool SF_status = SF.factorise(A); + REQUIRE( SF_status ); + + double rcond_value = SF.rcond(); + REQUIRE( rcond_value > 0.0 ); + + vec X2; + bool X2_status = SF.solve(X2, B); + REQUIRE( X2_status ); + + vec X3; + bool X3_status = SF.solve(X3, B); + REQUIRE( X3_status ); + + REQUIRE( X1.n_rows == X2.n_rows ); + REQUIRE( X1.n_rows == X3.n_rows ); + + REQUIRE( approx_equal(X1, X2, "absdiff", 100.0*datum::eps) ); + REQUIRE( approx_equal(X1, X3, "absdiff", 100.0*datum::eps) ); + + vec C(100, fill::randu); + vec Y; + + bool Y_status = SF.solve(Y, C); + REQUIRE( Y_status ); + + REQUIRE( approx_equal(X1, Y, "absdiff", 100.0*datum::eps) == false ); + + vec D(101, fill::randu); + vec Z(100, fill::randu); + + bool Z_status = SF.solve(Z, D); + REQUIRE( Z_status == false ); + + REQUIRE( Z.n_elem == 0 ); + } + #endif diff -Nru armadillo-10.8.2+dfsg/tests2/Makefile armadillo-12.6.1+dfsg/tests2/Makefile --- armadillo-10.8.2+dfsg/tests2/Makefile 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/tests2/Makefile 2016-06-16 16:27:01.000000000 +0000 @@ -3,11 +3,11 @@ #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 +#CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -O0 +CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -Og +#CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -Og -fopenmp +#CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -Og -DARMA_DONT_USE_WRAPPER +#CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -Og -fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize=bounds -fsanitize=bounds-strict -g OBJECTS = $(patsubst %.cpp,%.o,$(wildcard *.cpp)) diff -Nru armadillo-10.8.2+dfsg/tests2/spmat.cpp armadillo-12.6.1+dfsg/tests2/spmat.cpp --- armadillo-10.8.2+dfsg/tests2/spmat.cpp 2016-06-16 16:24:22.000000000 +0000 +++ armadillo-12.6.1+dfsg/tests2/spmat.cpp 2016-06-16 16:27:01.000000000 +0000 @@ -718,6 +718,8 @@ REQUIRE( a(0, 0) == 0 ); REQUIRE( a(1, 0) == 0 ); REQUIRE( a(2, 0) == 1 ); + // Make sure that the row indices are sized appropriately. + REQUIRE( a.row_indices[a.n_nonzero] == 0 ); b.shed_cols(1, 2); REQUIRE( b.n_cols == 1 ); @@ -727,6 +729,7 @@ REQUIRE( b(0, 0) == 1 ); REQUIRE( b(1, 0) == 0 ); REQUIRE( b(2, 0) == 0 ); + REQUIRE( b.row_indices[b.n_nonzero] == 0 ); c.shed_cols(0, 0); c.shed_cols(1, 1); @@ -737,6 +740,7 @@ REQUIRE( c(0, 0) == 0 ); REQUIRE( c(1, 0) == 1 ); REQUIRE( c(2, 0) == 0 ); + REQUIRE( c.row_indices[c.n_nonzero] == 0 ); } TEST_CASE("shed_row_test")