diff --git a/.appveyor.yml b/.appveyor.yml
index 068f2e4c76..f0ffa39490 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -85,8 +85,8 @@ build_script:
- cd C:\projects\mlpack && mkdir build && cd build
- >
cmake -G "%VSVER%"
- -DBLAS_LIBRARY:FILEPATH=%BLAS_LIBRARY%
- -DLAPACK_LIBRARY:FILEPATH=%BLAS_LIBRARY%
+ -DBLAS_LIBRARIES:FILEPATH=%BLAS_LIBRARY%
+ -DLAPACK_LIBRARIES:FILEPATH=%BLAS_LIBRARY%
-DARMADILLO_INCLUDE_DIR="C:/projects/mlpack/armadillo-8.400.0/include"
-DARMADILLO_LIBRARY:FILEPATH=%ARMADILLO_LIBRARY%
-DBOOST_INCLUDEDIR:PATH=%BOOST_INCLUDE%
diff --git a/.ci/ci.yaml b/.ci/ci.yaml
index be1ca4b4c1..e0654b49e1 100644
--- a/.ci/ci.yaml
+++ b/.ci/ci.yaml
@@ -1,3 +1,12 @@
+trigger:
+ branches:
+ include:
+ - '*'
+pr:
+ branches:
+ include:
+ - '*'
+
jobs:
- job: Linux
timeoutInMinutes: 360
@@ -28,7 +37,7 @@ jobs:
- job: macOS
timeoutInMinutes: 360
pool:
- vmImage: macOS-10.13
+ vmImage: macOS-10.14
strategy:
matrix:
Plain:
@@ -48,23 +57,6 @@ jobs:
steps:
- template: macos-steps.yaml
-- job: WindowsVS14
- timeoutInMinutes: 360
- displayName: Windows VS14
- pool:
- vmImage: vs2015-win2012r2
- strategy:
- matrix:
- Plain:
- CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF'
- CMakeGenerator: '-G "Visual Studio 14 2015 Win64"'
- MSBuildVersion: '14.0'
- ArchiveNoLibs: 'mlpack-windows-vs14-no-libs.zip'
- ArchiveLibs: 'mlpack-windows-vs14.zip'
- ArchiveTests: 'mlpack_test-vs14.xml'
- steps:
- - template: windows-steps.yaml
-
- job: WindowsVS15
timeoutInMinutes: 360
displayName: Windows VS15
diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml
index bdc11fe3f7..968abd018f 100644
--- a/.ci/macos-steps.yaml
+++ b/.ci/macos-steps.yaml
@@ -14,8 +14,7 @@ steps:
set -e
sudo xcode-select --switch /Applications/Xcode_10.1.app/Contents/Developer
unset BOOST_ROOT
- pip install cython numpy pandas zipp
- brew update
+ pip install cython numpy pandas zipp configparser
brew install openblas armadillo boost
if [ "a$(julia.version)" != "a" ]; then
diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml
index 4d8b9e7923..26cd2c0ff4 100644
--- a/.ci/windows-steps.yaml
+++ b/.ci/windows-steps.yaml
@@ -28,7 +28,7 @@ steps:
# Configure armadillo
- bash: |
git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf
-
+
curl -O http://masterblaster.mlpack.org:5005/armadillo-8.400.0.tar.gz -o armadillo-8.400.0.tar.gz
tar -xzvf armadillo-8.400.0.tar.gz
@@ -60,12 +60,13 @@ steps:
cmake $(CMakeGenerator) `
$(CMakeArgs) `
- -DBLAS_LIBRARY:FILEPATH=$(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\lib\x64\libopenblas.dll.a `
- -DLAPACK_LIBRARY:FILEPATH=$(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\lib\x64\libopenblas.dll.a `
+ -DBLAS_LIBRARIES:FILEPATH=$(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\lib\x64\libopenblas.dll.a `
+ -DLAPACK_LIBRARIES:FILEPATH=$(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\lib\x64\libopenblas.dll.a `
-DARMADILLO_INCLUDE_DIR="..\armadillo-8.400.0\include" `
-DARMADILLO_LIBRARY="..\armadillo-8.400.0\Release\armadillo.lib" `
-DBOOST_INCLUDEDIR=$(Agent.ToolsDirectory)\boost.1.60.0.0\lib\native\include `
-DBOOST_LIBRARYDIR=$(Agent.ToolsDirectory)\boost_libs `
+ -DBUILD_JULIA_BINDINGS=OFF `
-DCMAKE_BUILD_TYPE=Release ..
displayName: 'Configure mlpack'
diff --git a/CMake/ARMA_FindACML.cmake b/CMake/ARMA_FindACML.cmake
deleted file mode 100644
index 42561cafda..0000000000
--- a/CMake/ARMA_FindACML.cmake
+++ /dev/null
@@ -1,37 +0,0 @@
-# - Find AMD's ACML library (no includes) which provides optimised BLAS and LAPACK functions
-# This module defines
-# ACML_LIBRARIES, the libraries needed to use ACML.
-# ACML_FOUND, If false, do not try to use ACML.
-# also defined, but not for general use are
-# ACML_LIBRARY, where to find the ACML library.
-
-set(ACML_NAMES ${ACML_NAMES} acml)
-find_library(ACML_LIBRARY
- NAMES ${ACML_NAMES}
- PATHS /usr/lib64 /usr/lib /usr/*/lib64 /usr/*/lib /usr/*/gfortran64/lib/ /usr/*/gfortran32/lib/ /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib /opt/*/lib64 /opt/*/lib /opt/*/gfortran64/lib/ /opt/*/gfortran32/lib/
- )
-
-if (ACML_LIBRARY)
- set(ACML_LIBRARIES ${ACML_LIBRARY})
- set(ACML_FOUND "YES")
-else ()
- set(ACML_FOUND "NO")
-endif ()
-
-
-if (ACML_FOUND)
- if (NOT ACML_FIND_QUIETLY)
- message(STATUS "Found the ACML library: ${ACML_LIBRARIES}")
- endif ()
-else ()
- if (ACML_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find the ACML library")
- endif ()
-endif ()
-
-# Deprecated declarations.
-get_filename_component (NATIVE_ACML_LIB_PATH ${ACML_LIBRARY} PATH)
-
-mark_as_advanced(
- ACML_LIBRARY
- )
diff --git a/CMake/ARMA_FindACMLMP.cmake b/CMake/ARMA_FindACMLMP.cmake
deleted file mode 100644
index 47a192ced6..0000000000
--- a/CMake/ARMA_FindACMLMP.cmake
+++ /dev/null
@@ -1,37 +0,0 @@
-# - Find AMD's ACMLMP library (no includes) which provides optimised and parallelised BLAS and LAPACK functions
-# This module defines
-# ACMLMP_LIBRARIES, the libraries needed to use ACMLMP.
-# ACMLMP_FOUND, If false, do not try to use ACMLMP.
-# also defined, but not for general use are
-# ACMLMP_LIBRARY, where to find the ACMLMP library.
-
-set(ACMLMP_NAMES ${ACMLMP_NAMES} acml_mp)
-find_library(ACMLMP_LIBRARY
- NAMES ${ACMLMP_NAMES}
- PATHS /usr/lib64 /usr/lib /usr/*/lib64 /usr/*/lib /usr/*/gfortran64_mp/lib/ /usr/*/gfortran32_mp/lib/ /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib /opt/*/lib64 /opt/*/lib /opt/*/gfortran64_mp/lib/ /opt/*/gfortran32_mp/lib/
- )
-
-if (ACMLMP_LIBRARY)
- set(ACMLMP_LIBRARIES ${ACMLMP_LIBRARY})
- set(ACMLMP_FOUND "YES")
-else ()
- set(ACMLMP_FOUND "NO")
-endif ()
-
-
-if (ACMLMP_FOUND)
- if (NOT ACMLMP_FIND_QUIETLY)
- message(STATUS "Found the ACMLMP library: ${ACMLMP_LIBRARIES}")
- endif ()
-else ()
- if (ACMLMP_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find the ACMLMP library")
- endif ()
-endif ()
-
-# Deprecated declarations.
-get_filename_component (NATIVE_ACMLMP_LIB_PATH ${ACMLMP_LIBRARY} PATH)
-
-mark_as_advanced(
- ACMLMP_LIBRARY
- )
diff --git a/CMake/ARMA_FindARPACK.cmake b/CMake/ARMA_FindARPACK.cmake
deleted file mode 100644
index ff1ee22797..0000000000
--- a/CMake/ARMA_FindARPACK.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-# - Try to find ARPACK
-# Once done this will define
-#
-# ARPACK_FOUND - system has ARPACK
-# ARPACK_LIBRARY - Link this to use ARPACK
-
-
-find_library(ARPACK_LIBRARY
- NAMES arpack
- PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
- )
-
-
-if (ARPACK_LIBRARY)
- set(ARPACK_FOUND YES)
-else ()
- # Search for PARPACK.
- find_library(ARPACK_LIBRARY
- NAMES parpack
- PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
- )
-
- if (ARPACK_LIBRARY)
- set(ARPACK_FOUND YES)
- else ()
- set(ARPACK_FOUND NO)
- endif ()
-endif ()
-
-
-if (ARPACK_FOUND)
- if (NOT ARPACK_FIND_QUIETLY)
- message(STATUS "Found an ARPACK library: ${ARPACK_LIBRARY}")
- endif ()
-else ()
- if (ARPACK_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find an ARPACK library")
- endif ()
-endif ()
diff --git a/CMake/ARMA_FindBLAS.cmake b/CMake/ARMA_FindBLAS.cmake
deleted file mode 100644
index ff37b4fc79..0000000000
--- a/CMake/ARMA_FindBLAS.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-# - Find a BLAS library (no includes)
-# This module defines
-# BLAS_LIBRARIES, the libraries needed to use BLAS.
-# BLAS_FOUND, If false, do not try to use BLAS.
-# also defined, but not for general use are
-# BLAS_LIBRARY, where to find the BLAS library.
-
-set(BLAS_NAMES ${BLAS_NAMES} blas)
-
-# Find the ATLAS version preferentially.
-find_library(BLAS_LIBRARY
- NAMES ${BLAS_NAMES}
- PATHS /usr/lib64/atlas /usr/lib/atlas /usr/local/lib64/atlas /usr/local/lib/atlas
- NO_DEFAULT_PATH)
-
-find_library(BLAS_LIBRARY
- NAMES ${BLAS_NAMES}
- PATHS /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
- )
-
-if (BLAS_LIBRARY)
- set(BLAS_LIBRARIES ${BLAS_LIBRARY})
- set(BLAS_FOUND "YES")
-else ()
- set(BLAS_FOUND "NO")
-endif ()
-
-
-if (BLAS_FOUND)
- if (NOT BLAS_FIND_QUIETLY)
- message(STATUS "Found BLAS: ${BLAS_LIBRARIES}")
- endif ()
-else ()
- if (BLAS_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find BLAS")
- endif ()
-endif ()
-
-# Deprecated declarations.
-get_filename_component (NATIVE_BLAS_LIB_PATH ${BLAS_LIBRARY} PATH)
-
-mark_as_advanced(
- BLAS_LIBRARY
- )
diff --git a/CMake/ARMA_FindCBLAS.cmake b/CMake/ARMA_FindCBLAS.cmake
deleted file mode 100644
index da84c246b8..0000000000
--- a/CMake/ARMA_FindCBLAS.cmake
+++ /dev/null
@@ -1,47 +0,0 @@
-# - Find CBLAS (includes and library)
-# This module defines
-# CBLAS_INCLUDE_DIR
-# CBLAS_LIBRARIES
-# CBLAS_FOUND
-# also defined, but not for general use are
-# CBLAS_LIBRARY, where to find the library.
-
-find_path(CBLAS_INCLUDE_DIR cblas.h
-/usr/include/atlas/
-/usr/local/include/atlas/
-/usr/include/
-/usr/local/include/
-)
-
-set(CBLAS_NAMES ${CBLAS_NAMES} cblas)
-find_library(CBLAS_LIBRARY
- NAMES ${CBLAS_NAMES}
- PATHS /usr/lib64/atlas-sse3 /usr/lib64/atlas /usr/lib64 /usr/local/lib64/atlas /usr/local/lib64 /usr/lib/atlas-sse3 /usr/lib/atlas-sse2 /usr/lib/atlas-sse /usr/lib/atlas-3dnow /usr/lib/atlas /usr/lib /usr/local/lib/atlas /usr/local/lib
- )
-
-if (CBLAS_LIBRARY AND CBLAS_INCLUDE_DIR)
- set(CBLAS_LIBRARIES ${CBLAS_LIBRARY})
- set(CBLAS_FOUND "YES")
-else ()
- set(CBLAS_FOUND "NO")
-endif ()
-
-
-if (CBLAS_FOUND)
- if (NOT CBLAS_FIND_QUIETLY)
- message(STATUS "Found a CBLAS library: ${CBLAS_LIBRARIES}")
- endif ()
-else ()
- if (CBLAS_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find a CBLAS library")
- endif ()
-endif ()
-
-# Deprecated declarations.
-set (NATIVE_CBLAS_INCLUDE_PATH ${CBLAS_INCLUDE_DIR} )
-get_filename_component (NATIVE_CBLAS_LIB_PATH ${CBLAS_LIBRARY} PATH)
-
-mark_as_advanced(
- CBLAS_LIBRARY
- CBLAS_INCLUDE_DIR
- )
diff --git a/CMake/ARMA_FindCLAPACK.cmake b/CMake/ARMA_FindCLAPACK.cmake
deleted file mode 100644
index 97a9792a31..0000000000
--- a/CMake/ARMA_FindCLAPACK.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# - Find a version of CLAPACK (includes and library)
-# This module defines
-# CLAPACK_INCLUDE_DIR
-# CLAPACK_LIBRARIES
-# CLAPACK_FOUND
-# also defined, but not for general use are
-# CLAPACK_LIBRARY, where to find the library.
-
-find_path(CLAPACK_INCLUDE_DIR clapack.h
-/usr/include/atlas/
-/usr/local/include/atlas/
-/usr/include/
-/usr/local/include/
-)
-
-set(CLAPACK_NAMES ${CLAPACK_NAMES} lapack_atlas)
-set(CLAPACK_NAMES ${CLAPACK_NAMES} clapack)
-find_library(CLAPACK_LIBRARY
- NAMES ${CLAPACK_NAMES}
- PATHS /usr/lib64/atlas-sse3 /usr/lib64/atlas /usr/lib64 /usr/local/lib64/atlas /usr/local/lib64 /usr/lib/atlas-sse3 /usr/lib/atlas-sse2 /usr/lib/atlas-sse /usr/lib/atlas-3dnow /usr/lib/atlas /usr/lib /usr/local/lib/atlas /usr/local/lib
- )
-
-if (CLAPACK_LIBRARY AND CLAPACK_INCLUDE_DIR)
- set(CLAPACK_LIBRARIES ${CLAPACK_LIBRARY})
- set(CLAPACK_FOUND "YES")
-else ()
- set(CLAPACK_FOUND "NO")
-endif ()
-
-
-if (CLAPACK_FOUND)
- if (NOT CLAPACK_FIND_QUIETLY)
- message(STATUS "Found a CLAPACK library: ${CLAPACK_LIBRARIES}")
- endif ()
-else ()
- if (CLAPACK_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find a CLAPACK library")
- endif ()
-endif ()
-
-# Deprecated declarations.
-set (NATIVE_CLAPACK_INCLUDE_PATH ${CLAPACK_INCLUDE_DIR} )
-get_filename_component (NATIVE_CLAPACK_LIB_PATH ${CLAPACK_LIBRARY} PATH)
-
-mark_as_advanced(
- CLAPACK_LIBRARY
- CLAPACK_INCLUDE_DIR
- )
diff --git a/CMake/ARMA_FindLAPACK.cmake b/CMake/ARMA_FindLAPACK.cmake
deleted file mode 100644
index b40d16d04c..0000000000
--- a/CMake/ARMA_FindLAPACK.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-# - Find a LAPACK library (no includes)
-# This module defines
-# LAPACK_LIBRARIES, the libraries needed to use LAPACK.
-# LAPACK_FOUND, If false, do not try to use LAPACK.
-# also defined, but not for general use are
-# LAPACK_LIBRARY, where to find the LAPACK library.
-
-set(LAPACK_NAMES ${LAPACK_NAMES} lapack)
-
-# Check ATLAS paths preferentially, using this necessary hack (I love CMake).
-find_library(LAPACK_LIBRARY
- NAMES ${LAPACK_NAMES}
- PATHS /usr/lib64/atlas /usr/lib/atlas /usr/local/lib64/atlas /usr/local/lib/atlas
- NO_DEFAULT_PATH)
-
-find_library(LAPACK_LIBRARY
- NAMES ${LAPACK_NAMES}
- PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
- )
-
-if (LAPACK_LIBRARY)
- set(LAPACK_LIBRARIES ${LAPACK_LIBRARY})
- set(LAPACK_FOUND "YES")
-else ()
- set(LAPACK_FOUND "NO")
-endif ()
-
-
-if (LAPACK_FOUND)
- if (NOT LAPACK_FIND_QUIETLY)
- message(STATUS "Found LAPACK: ${LAPACK_LIBRARIES}")
- endif ()
-else ()
- if (LAPACK_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find LAPACK")
- endif ()
-endif ()
-
-# Deprecated declarations.
-get_filename_component (NATIVE_LAPACK_LIB_PATH ${LAPACK_LIBRARY} PATH)
-
-mark_as_advanced(
- LAPACK_LIBRARY
- )
diff --git a/CMake/ARMA_FindMKL.cmake b/CMake/ARMA_FindMKL.cmake
deleted file mode 100644
index 452fa5a643..0000000000
--- a/CMake/ARMA_FindMKL.cmake
+++ /dev/null
@@ -1,49 +0,0 @@
-# - Find the MKL libraries (no includes)
-# This module defines
-# MKL_LIBRARIES, the libraries needed to use Intel's implementation of BLAS & LAPACK.
-# MKL_FOUND, If false, do not try to use MKL.
-
-set(MKL_NAMES ${MKL_NAMES} mkl_lapack)
-set(MKL_NAMES ${MKL_NAMES} mkl_intel_thread)
-set(MKL_NAMES ${MKL_NAMES} mkl_core)
-set(MKL_NAMES ${MKL_NAMES} guide)
-set(MKL_NAMES ${MKL_NAMES} mkl)
-set(MKL_NAMES ${MKL_NAMES} iomp5)
-#set(MKL_NAMES ${MKL_NAMES} pthread)
-
-if(CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(MKL_NAMES ${MKL_NAMES} mkl_intel_lp64)
-else()
- set(MKL_NAMES ${MKL_NAMES} mkl_intel)
-endif()
-
-foreach (MKL_NAME ${MKL_NAMES})
- find_library(${MKL_NAME}_LIBRARY
- NAMES ${MKL_NAME}
- PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/intel/lib/intel64 /opt/intel/lib/ia32 /opt/intel/mkl/lib/lib64 /opt/intel/mkl/lib/intel64 /opt/intel/mkl/lib/ia32 /opt/intel/mkl/lib /opt/intel/*/mkl/lib/intel64 /opt/intel/*/mkl/lib/ia32/ /opt/mkl/*/lib/em64t /opt/mkl/*/lib/32 /opt/intel/mkl/*/lib/em64t /opt/intel/mkl/*/lib/32
- )
-
- set(TMP_LIBRARY ${${MKL_NAME}_LIBRARY})
-
- if(TMP_LIBRARY)
- set(MKL_LIBRARIES ${MKL_LIBRARIES} ${TMP_LIBRARY})
- endif()
-endforeach()
-
-if (MKL_LIBRARIES)
- set(MKL_FOUND "YES")
-else ()
- set(MKL_FOUND "NO")
-endif ()
-
-if (MKL_FOUND)
- if (NOT MKL_FIND_QUIETLY)
- message(STATUS "Found MKL libraries: ${MKL_LIBRARIES}")
- endif ()
-else ()
- if (MKL_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find MKL libraries")
- endif ()
-endif ()
-
-# mark_as_advanced(MKL_LIBRARY)
diff --git a/CMake/ARMA_FindOpenBLAS.cmake b/CMake/ARMA_FindOpenBLAS.cmake
deleted file mode 100644
index edfa27db83..0000000000
--- a/CMake/ARMA_FindOpenBLAS.cmake
+++ /dev/null
@@ -1,37 +0,0 @@
-# - Find the OpenBLAS library (no includes)
-# This module defines
-# OpenBLAS_LIBRARIES, the libraries needed to use OpenBLAS.
-# OpenBLAS_FOUND, If false, do not try to use OpenBLAS.
-# also defined, but not for general use are
-# OpenBLAS_LIBRARY, where to find the OpenBLAS library.
-
-set(OpenBLAS_NAMES ${OpenBLAS_NAMES} openblas)
-find_library(OpenBLAS_LIBRARY
- NAMES ${OpenBLAS_NAMES}
- PATHS /lib64 /lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
- )
-
-if (OpenBLAS_LIBRARY)
- set(OpenBLAS_LIBRARIES ${OpenBLAS_LIBRARY})
- set(OpenBLAS_FOUND "YES")
-else ()
- set(OpenBLAS_FOUND "NO")
-endif ()
-
-
-if (OpenBLAS_FOUND)
- if (NOT OpenBLAS_FIND_QUIETLY)
- message(STATUS "Found the OpenBLAS library: ${OpenBLAS_LIBRARIES}")
- endif ()
-else ()
- if (OpenBLAS_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find the OpenBLAS library")
- endif ()
-endif ()
-
-# Deprecated declarations.
-get_filename_component (NATIVE_OpenBLAS_LIB_PATH ${OpenBLAS_LIBRARY} PATH)
-
-mark_as_advanced(
- OpenBLAS_LIBRARY
- )
diff --git a/CMake/FindARPACK.cmake b/CMake/FindARPACK.cmake
new file mode 100644
index 0000000000..08baa3b2b1
--- /dev/null
+++ b/CMake/FindARPACK.cmake
@@ -0,0 +1,55 @@
+# Searches for an installation of the ARPACK library. On success, it sets the following variables:
+#
+# ARPACK_FOUND Set to true to indicate the library was found
+# ARPACK_LIBRARIES All libraries needed to use ARPACK (with full path)
+#
+# To specify an additional directory to search, set ARPACK_ROOT.
+#
+# TODO: Do we need to explicitly search for BLAS and LAPACK as well? The source distribution statically links these to
+# libarpack. Are there any installations that don't do this or the equivalent?
+#
+# Author: Siddhartha Chaudhuri, 2009
+#
+
+SET(ARPACK_FOUND FALSE)
+
+# First look in user-provided root directory, then look in system locations
+FIND_LIBRARY(ARPACK_LIBRARIES NAMES arpack libarpack ARPACK libARPACK PATHS "${ARPACK_ROOT}" "${ARPACK_ROOT}/lib"
+ NO_DEFAULT_PATH)
+IF(NOT ARPACK_LIBRARIES)
+ FIND_LIBRARY(ARPACK_LIBRARIES NAMES arpack libarpack ARPACK libARPACK)
+ENDIF(NOT ARPACK_LIBRARIES)
+
+IF(ARPACK_LIBRARIES)
+ # On OS X we probably also need gfortran and BLAS and LAPACK libraries
+ IF(APPLE)
+ FIND_LIBRARY(ARPACK_LAPACK_LIBRARY NAMES lapack LAPACK PATHS "${ARPACK_ROOT}" "${ARPACK_ROOT}/lib")
+ FIND_LIBRARY(ARPACK_BLAS_LIBRARY NAMES blas BLAS PATHS "${ARPACK_ROOT}" "${ARPACK_ROOT}/lib")
+ FIND_LIBRARY(ARPACK_GFORTRAN_LIBRARY NAMES gfortran PATHS "${ARPACK_ROOT}" "${ARPACK_ROOT}/lib"
+ PATH_SUFFIXES "" "gfortran/lib" "../gfortran/lib")
+
+ IF(ARPACK_BLAS_LIBRARY)
+ SET(ARPACK_LIBRARIES ${ARPACK_LIBRARIES} ${ARPACK_BLAS_LIBRARY})
+ ENDIF(ARPACK_BLAS_LIBRARY)
+
+ IF(ARPACK_LAPACK_LIBRARY)
+ SET(ARPACK_LIBRARIES ${ARPACK_LIBRARIES} ${ARPACK_LAPACK_LIBRARY})
+ ENDIF(ARPACK_LAPACK_LIBRARY)
+
+ IF(ARPACK_GFORTRAN_LIBRARY)
+ SET(ARPACK_LIBRARIES ${ARPACK_LIBRARIES} ${ARPACK_GFORTRAN_LIBRARY})
+ ENDIF(ARPACK_GFORTRAN_LIBRARY)
+ ENDIF(APPLE)
+
+ SET(ARPACK_FOUND TRUE)
+ENDIF(ARPACK_LIBRARIES)
+
+IF(ARPACK_FOUND)
+ IF(NOT ARPACK_FIND_QUIETLY)
+ MESSAGE(STATUS "Found ARPACK: libraries at ${ARPACK_LIBRARIES}")
+ ENDIF(NOT ARPACK_FIND_QUIETLY)
+ELSE(ARPACK_FOUND)
+ IF(ARPACK_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "ARPACK not found")
+ ENDIF(ARPACK_FIND_REQUIRED)
+ENDIF(ARPACK_FOUND)
diff --git a/CMake/FindArmadillo.cmake b/CMake/FindArmadillo.cmake
index 1244f64936..36ec63b515 100644
--- a/CMake/FindArmadillo.cmake
+++ b/CMake/FindArmadillo.cmake
@@ -1,41 +1,41 @@
-# - Find Armadillo
-# Find the Armadillo C++ library
-#
-# Using Armadillo:
-# find_package(Armadillo REQUIRED)
-# include_directories(${ARMADILLO_INCLUDE_DIRS})
-# add_executable(foo foo.cc)
-# target_link_libraries(foo ${ARMADILLO_LIBRARIES})
-# This module sets the following variables:
-# ARMADILLO_FOUND - set to true if the library is found
-# ARMADILLO_INCLUDE_DIRS - list of required include directories
-# ARMADILLO_LIBRARIES - list of libraries to be linked
-# ARMADILLO_VERSION_MAJOR - major version number
-# ARMADILLO_VERSION_MINOR - minor version number
-# ARMADILLO_VERSION_PATCH - patch version number
-# ARMADILLO_VERSION_STRING - version number as a string (ex: "1.0.4")
-# ARMADILLO_VERSION_NAME - name of the version (ex: "Antipodean Antileech")
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
-#=============================================================================
-# Copyright 2011 Clement Creusot
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
+#[=======================================================================[.rst:
+FindArmadillo
+-------------
+Find the Armadillo C++ library.
+Armadillo is a library for linear algebra & scientific computing.
+
+Using Armadillo:
+
+::
+
+ find_package(Armadillo REQUIRED)
+ include_directories(${ARMADILLO_INCLUDE_DIRS})
+ add_executable(foo foo.cc)
+ target_link_libraries(foo ${ARMADILLO_LIBRARIES})
+
+This module sets the following variables:
+
+::
+
+ ARMADILLO_FOUND - set to true if the library is found
+ ARMADILLO_INCLUDE_DIRS - list of required include directories
+ ARMADILLO_LIBRARIES - list of libraries to be linked
+ ARMADILLO_VERSION_MAJOR - major version number
+ ARMADILLO_VERSION_MINOR - minor version number
+ ARMADILLO_VERSION_PATCH - patch version number
+ ARMADILLO_VERSION_STRING - version number as a string (ex: "1.0.4")
+ ARMADILLO_VERSION_NAME - name of the version (ex: "Antipodean Antileech")
+#]=======================================================================]
find_path(ARMADILLO_INCLUDE_DIR
NAMES armadillo
PATHS "$ENV{ProgramFiles}/Armadillo/include"
)
-
if(ARMADILLO_INCLUDE_DIR)
# ------------------------------------------------------------------------
# Extract version information from
@@ -52,318 +52,117 @@ if(ARMADILLO_INCLUDE_DIR)
if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp")
# Read and parse armdillo version header file for version number
- file(READ "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _armadillo_HEADER_CONTENTS)
- string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_armadillo_HEADER_CONTENTS}")
- string(REGEX REPLACE ".*#define ARMA_VERSION_MINOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MINOR "${_armadillo_HEADER_CONTENTS}")
- string(REGEX REPLACE ".*#define ARMA_VERSION_PATCH ([0-9]+).*" "\\1" ARMADILLO_VERSION_PATCH "${_armadillo_HEADER_CONTENTS}")
+ file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _ARMA_HEADER_CONTENTS REGEX "#define ARMA_VERSION_[A-Z]+ ")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_ARMA_HEADER_CONTENTS}")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_MINOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MINOR "${_ARMA_HEADER_CONTENTS}")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_PATCH ([0-9]+).*" "\\1" ARMADILLO_VERSION_PATCH "${_ARMA_HEADER_CONTENTS}")
# WARNING: The number of spaces before the version name is not one.
- string(REGEX REPLACE ".*#define ARMA_VERSION_NAME\ +\"([0-9a-zA-Z\ _-]+)\".*" "\\1" ARMADILLO_VERSION_NAME "${_armadillo_HEADER_CONTENTS}")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_NAME\ +\"([0-9a-zA-Z\ _-]+)\".*" "\\1" ARMADILLO_VERSION_NAME "${_ARMA_HEADER_CONTENTS}")
endif()
set(ARMADILLO_VERSION_STRING "${ARMADILLO_VERSION_MAJOR}.${ARMADILLO_VERSION_MINOR}.${ARMADILLO_VERSION_PATCH}")
endif ()
-
-#======================
-
-# Determine what support libraries are being used, and whether or not we need to
-# link against them. We need to look in config.hpp.
-set(SUPPORT_INCLUDE_DIRS "")
-set(SUPPORT_LIBRARIES "")
-set(ARMA_NEED_LIBRARY true) # Assume true.
if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp")
- file(READ "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp" _armadillo_CONFIG_CONTENTS)
- # ARMA_USE_WRAPPER
- string(REGEX MATCH "\r?\n[\t ]*#define[ \t]+ARMA_USE_WRAPPER[ \t]*\r?\n" ARMA_USE_WRAPPER "${_armadillo_CONFIG_CONTENTS}")
-
- # ARMA_USE_LAPACK
- string(REGEX MATCH "\r?\n[\t ]*#if[\t ]+!defined[(]ARMA_USE_LAPACK[)][\t ]*\r?\n[\t ]*#define[ \t]+ARMA_USE_LAPACK[ \t]*\r?\n" ARMA_USE_LAPACK "${_armadillo_CONFIG_CONTENTS}")
-
- # ARMA_USE_BLAS
- string(REGEX MATCH "\r?\n[\t ]*#if[\t ]+!defined[(]ARMA_USE_BLAS[)][\t ]*\r?\n[\t ]*#define[ \t]+ARMA_USE_BLAS[ \t]*\r?\n" ARMA_USE_BLAS "${_armadillo_CONFIG_CONTENTS}")
- # ARMA_USE_ARPACK
- # ARMA_USE_ARPACK
- string(REGEX MATCH "\r?\n[\t ]*#if[\t ]+!defined[(]ARMA_USE_ARPACK[)][\t ]*\r?\n[\t ]*#define[ \t]+ARMA_USE_ARPACK[ \t]*\r?\n" ARMA_USE_ARPACK "${_armadillo_CONFIG_CONTENTS}")
-
- # Look for #define ARMA_USE_HDF5.
- string(REGEX MATCH "\r?\n[\t ]*#if[\t ]+!defined[(]ARMA_USE_HDF5[)][\t ]*\r?\n[\t ]*#define[ \t]+ARMA_USE_HDF5[ \t]*\r?\n" ARMA_USE_HDF5 "${_armadillo_CONFIG_CONTENTS}")
-
- # If we aren't wrapping, things get a little more complex.
- if("${ARMA_USE_WRAPPER}" STREQUAL "")
- set(ARMA_NEED_LIBRARY false)
- message(STATUS "ARMA_USE_WRAPPER is not defined, so all dependencies of "
- "Armadillo must be manually linked.")
-
- set(HAVE_LAPACK false)
- set(HAVE_BLAS false)
-
- # Search for LAPACK/BLAS (or replacement).
- if ((NOT "${ARMA_USE_LAPACK}" STREQUAL "") AND
- (NOT "${ARMA_USE_BLAS}" STREQUAL ""))
- # In order of preference: MKL, ACML, OpenBLAS, ATLAS
- set(MKL_FIND_QUIETLY true)
- include(ARMA_FindMKL)
- set(ACMLMP_FIND_QUIETLY true)
- include(ARMA_FindACMLMP)
- set(ACML_FIND_QUIETLY true)
- include(ARMA_FindACML)
-
- if (MKL_FOUND)
- message(STATUS "Using MKL for LAPACK/BLAS: ${MKL_LIBRARIES}")
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${MKL_LIBRARIES}")
- set(HAVE_LAPACK true)
- set(HAVE_BLAS true)
- elseif (ACMLMP_FOUND)
- message(STATUS "Using multi-core ACML libraries for LAPACK/BLAS:
- ${ACMLMP_LIBRARIES}")
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${ACMLMP_LIBRARIES}")
- set(HAVE_LAPACK true)
- set(HAVE_BLAS true)
- elseif (ACML_FOUND)
- message(STATUS "Using ACML for LAPACK/BLAS: ${ACML_LIBRARIES}")
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${ACML_LIBRARIES}")
- set(HAVE_LAPACK true)
- set(HAVE_BLAS true)
- endif ()
- endif ()
-
- # If we haven't found BLAS, try.
- if (NOT "${ARMA_USE_BLAS}" STREQUAL "" AND NOT HAVE_BLAS)
- # Search for BLAS.
- set(OpenBLAS_FIND_QUIETLY true)
- include(ARMA_FindOpenBLAS)
- set(CBLAS_FIND_QUIETLY true)
- include(ARMA_FindCBLAS)
- set(BLAS_FIND_QUIETLY true)
- include(ARMA_FindBLAS)
-
- if (OpenBLAS_FOUND)
- # Warn if ATLAS is found also.
- if (CBLAS_FOUND)
- message(STATUS "Warning: both OpenBLAS and ATLAS have been found; "
- "ATLAS will not be used.")
- endif ()
- message(STATUS "Using OpenBLAS for BLAS: ${OpenBLAS_LIBRARIES}")
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${OpenBLAS_LIBRARIES}")
- set(HAVE_BLAS true)
- elseif (CBLAS_FOUND)
- message(STATUS "Using ATLAS for BLAS: ${CBLAS_LIBRARIES}")
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${CBLAS_LIBRARIES}")
- set(SUPPORT_INCLUDE_DIRS "${SUPPORT_INCLUDE_DIRS}"
- "${CBLAS_INCLUDE_DIR}")
- set(HAVE_BLAS true)
- elseif (BLAS_FOUND)
- message(STATUS "Using standard BLAS: ${BLAS_LIBRARIES}")
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${BLAS_LIBRARIES}")
- set(HAVE_BLAS true)
- endif ()
- endif ()
-
- # If we haven't found LAPACK, try.
- if (NOT "${ARMA_USE_LAPACK}" STREQUAL "" AND NOT HAVE_LAPACK)
- # Search for LAPACK.
- set(CLAPACK_FIND_QUIETLY true)
- include(ARMA_FindCLAPACK)
- set(LAPACK_FIND_QUIETLY true)
- include(ARMA_FindLAPACK)
-
- # Only use ATLAS if OpenBLAS isn't being used.
- if (CLAPACK_FOUND AND NOT OpenBLAS_FOUND)
- message(STATUS "Using ATLAS for LAPACK: ${CLAPACK_LIBRARIES}")
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${CLAPACK_LIBRARIES}")
- set(SUPPORT_INCLUDE_DIRS "${SUPPORT_INCLUDE_DIRS}"
- "${CLAPACK_INCLUDE_DIR}")
- set(HAVE_LAPACK true)
- elseif (LAPACK_FOUND)
- message(STATUS "Using standard LAPACK: ${LAPACK_LIBRARIES}")
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${LAPACK_LIBRARIES}")
- set(HAVE_LAPACK true)
- endif ()
- endif ()
-
- if (NOT "${ARMA_USE_LAPACK}" STREQUAL "" AND NOT HAVE_LAPACK)
- message(FATAL_ERROR "Cannot find LAPACK library, but ARMA_USE_LAPACK is "
- "set. Try specifying LAPACK libraries manually by setting the "
- "LAPACK_LIBRARY variable.")
- endif ()
-
- if (NOT "${ARMA_USE_BLAS}" STREQUAL "" AND NOT HAVE_BLAS)
- message(FATAL_ERROR "Cannot find BLAS library, but ARMA_USE_BLAS is set. "
- "Try specifying BLAS libraries manually by setting the BLAS_LIBRARY "
- "variable.")
- endif ()
-
- # Search for ARPACK (or replacement).
- if (NOT "${ARMA_USE_ARPACK}" STREQUAL "")
- # Use Armadillo ARPACK-finding procedure.
- set(ARPACK_FIND_QUIETLY true)
- include(ARMA_FindARPACK)
-
- if (NOT ARPACK_FOUND)
- message(FATAL_ERROR "ARMA_USE_ARPACK is defined in "
- "armadillo_bits/config.hpp, but ARPACK cannot be found. Try "
- "specifying ARPACK_LIBRARY.")
- endif ()
-
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${ARPACK_LIBRARY}")
- endif ()
-
- # Search for HDF5 (or replacement).
- if (NOT "${ARMA_USE_HDF5}" STREQUAL "")
- find_package(HDF5 QUIET)
-
- 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.
- find_package(PkgConfig)
- 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.
- if (HDF5_FOUND)
- # I'm not sure what I think of doing this here...
- link_directories("${HDF5_LIBRARY_DIRS}")
- endif()
- endif()
- endif()
-
- if(NOT HDF5_FOUND)
- # We tried but didn't find it.
- message(FATAL_ERROR "Armadillo HDF5 support is enabled, but HDF5 "
- "cannot be found on the system. Consider disabling HDF5 support.")
- endif()
-
- set(SUPPORT_INCLUDE_DIRS "${SUPPORT_INCLUDE_DIRS}" "${HDF5_INCLUDE_DIRS}")
- set(SUPPORT_LIBRARIES "${SUPPORT_LIBRARIES}" "${HDF5_LIBRARIES}")
- endif ()
-
- else()
- # Some older versions still require linking against HDF5 since they did not
- # wrap libhdf5. This was true for versions older than 4.300.
- if(NOT "${ARMA_USE_HDF5}" STREQUAL "" AND
- "${ARMADILLO_VERSION_STRING}" VERSION_LESS "4.300.0")
- message(STATUS "Armadillo HDF5 support is enabled and manual linking is "
- "required.")
- # We have HDF5 support and need to link against HDF5.
- find_package(HDF5)
-
- 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.
- find_package(PkgConfig)
- 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.
- if (HDF5_FOUND)
- # I'm not sure what I think of doing this here...
- link_directories("${HDF5_LIBRARY_DIRS}")
- endif()
- endif()
- endif()
-
- if(NOT HDF5_FOUND)
- # We tried but didn't find it.
- message(FATAL_ERROR "Armadillo HDF5 support is enabled, but HDF5 "
- "cannot be found on the system. Consider disabling HDF5 support.")
- endif()
-
- set(SUPPORT_INCLUDE_DIRS "${HDF5_INCLUDE_DIRS}")
- set(SUPPORT_LIBRARIES "${HDF5_LIBRARIES}")
- endif()
-
- # Versions between 4.300 and 4.500 did successfully wrap HDF5, but didn't have good support for setting the include directory correctly.
- if(NOT "${ARMA_USE_HDF5}" STREQUAL "" AND
- "${ARMADILLO_VERSION_STRING}" VERSION_GREATER "4.299.0" AND
- "${ARMADILLO_VERSION_STRING}" VERSION_LESS "4.450.0")
- message(STATUS "Armadillo HDF5 support is enabled and include "
- "directories must be found.")
- find_package(HDF5)
-
- 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.
- find_package(PkgConfig)
- if (PKG_CONFIG_FOUND)
- pkg_check_modules(HDF5 hdf5)
- endif()
- endif()
-
- if(NOT HDF5_FOUND)
- # We tried but didn't find it.
- message(FATAL_ERROR "Armadillo HDF5 support is enabled, but HDF5 "
- "cannot be found on the system. Consider disabling HDF5 support.")
- endif()
-
- set(SUPPORT_INCLUDE_DIRS "${HDF5_INCLUDE_DIRS}")
- endif()
-
- endif()
-else()
- message(FATAL_ERROR "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp not "
- "found! Cannot determine what to link against.")
+ file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp" _ARMA_CONFIG_CONTENTS REGEX "^#define ARMA_USE_[A-Z]+")
+ string(REGEX MATCH "ARMA_USE_WRAPPER" _ARMA_USE_WRAPPER "${_ARMA_CONFIG_CONTENTS}")
+ string(REGEX MATCH "ARMA_USE_LAPACK" _ARMA_USE_LAPACK "${_ARMA_CONFIG_CONTENTS}")
+ string(REGEX MATCH "ARMA_USE_BLAS" _ARMA_USE_BLAS "${_ARMA_CONFIG_CONTENTS}")
+ string(REGEX MATCH "ARMA_USE_ARPACK" _ARMA_USE_ARPACK "${_ARMA_CONFIG_CONTENTS}")
+ string(REGEX MATCH "ARMA_USE_HDF5" _ARMA_USE_HDF5 "${_ARMA_CONFIG_CONTENTS}")
endif()
-if (ARMA_NEED_LIBRARY)
+include(FindPackageHandleStandardArgs)
+
+# If _ARMA_USE_WRAPPER is set, then we just link to armadillo, but if it's not then we need support libraries instead
+set(_ARMA_SUPPORT_LIBRARIES)
+
+if(_ARMA_USE_WRAPPER)
# UNIX paths are standard, no need to write.
find_library(ARMADILLO_LIBRARY
NAMES armadillo
PATHS "$ENV{ProgramFiles}/Armadillo/lib" "$ENV{ProgramFiles}/Armadillo/lib64" "$ENV{ProgramFiles}/Armadillo"
)
+ set(_ARMA_REQUIRED_VARS ARMADILLO_LIBRARY ARMADILLO_INCLUDE_DIR VERSION_VAR ARMADILLO_VERSION_STRING)
+else()
+ # don't link to armadillo in this case
+ set(ARMADILLO_LIBRARY "")
+ if(_ARMA_USE_LAPACK)
+ if(ARMADILLO_FIND_QUIETLY OR NOT ARMADILLO_FIND_REQUIRED)
+ find_package(LAPACK QUIET)
+ else()
+ find_package(LAPCK REQUIRED)
+ endif()
+ if(LAPACK_FOUND)
+ set(_ARMA_SUPPORT_LIBRARIES "${_ARMA_SUPPORT_LIBRARIES}" "${LAPACK_LIBRARIES}")
+ endif()
+ endif()
+ if(_ARMA_USE_BLAS)
+ if(ARMADILLO_FIND_QUIETLY OR NOT ARMADILLO_FIND_REQUIRED)
+ find_package(BLAS QUIET)
+ else()
+ find_package(BLAS REQUIRED)
+ endif()
+ if(BLAS_FOUND)
+ set(_ARMA_SUPPORT_LIBRARIES "${_ARMA_SUPPORT_LIBRARIES}" "${BLAS_LIBRARIES}")
+ endif()
+ endif()
+ if(_ARMA_USE_ARPACK)
+ if(ARMADILLO_FIND_QUIETLY OR NOT ARMADILLO_FIND_REQUIRED)
+ find_package(ARPACK QUIET)
+ else()
+ find_package(ARPACK REQUIRED)
+ endif()
+ if(ARPACK_FOUND)
+ set(_ARMA_SUPPORT_LIBRARIES "${_ARMA_SUPPORT_LIBRARIES}" "${ARPACK_LIBRARIES}")
+ endif()
+ endif()
+ if(_ARMA_USE_HDF5)
+ find_package(HDF5 QUIET)
+ 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 FindHDF5.cmake will
+ # not find. Thus, we'll also quickly check pkgconfig to see if there is
+ # information on what to use there.
+ message(WARNING "HDF5 required but not found; using PkgConfig")
+ find_package(PkgConfig)
+ if (PKG_CONFIG_FOUND)
+ pkg_check_modules(HDF5 REQUIRED hdf5)
+ link_directories("${HDF5_LIBRARY_DIRS}")
+ else()
+ message(FATAL_ERROR "PkgConfig (Used to help find HDF5) was not found")
+ endif()
+ endif()
+ set(_ARMA_SUPPORT_INCLUDE_DIRS "${HDF5_INCLUDE_DIRS}")
+ set(_ARMA_SUPPORT_LIBRARIES "${_ARMA_SUPPORT_LIBRARIES}" "${HDF5_LIBRARIES}")
+ endif()
+ set(ARMADILLO_FOUND true)
+ set(_ARMA_REQUIRED_VARS ARMADILLO_INCLUDE_DIR VERSION_VAR ARMADILLO_VERSION_STRING)
+endif()
- # Checks 'REQUIRED', 'QUIET' and versions.
- include(FindPackageHandleStandardArgs)
- find_package_handle_standard_args(Armadillo
- REQUIRED_VARS ARMADILLO_LIBRARY ARMADILLO_INCLUDE_DIR
- VERSION_VAR ARMADILLO_VERSION_STRING)
- # version_var fails with cmake < 2.8.4.
-else ()
- # Checks 'REQUIRED', 'QUIET' and versions.
- include(FindPackageHandleStandardArgs)
- find_package_handle_standard_args(Armadillo
- REQUIRED_VARS ARMADILLO_INCLUDE_DIR
- VERSION_VAR ARMADILLO_VERSION_STRING)
-endif ()
+find_package_handle_standard_args(Armadillo REQUIRED_VARS ${_ARMA_REQUIRED_VARS})
if (ARMADILLO_FOUND)
- # Also include support include directories.
- set(ARMADILLO_INCLUDE_DIRS ${ARMADILLO_INCLUDE_DIR} ${SUPPORT_INCLUDE_DIRS})
- # Also include support libraries to link against.
- if (ARMA_NEED_LIBRARY)
- set(ARMADILLO_LIBRARIES ${ARMADILLO_LIBRARY} ${SUPPORT_LIBRARIES})
- else ()
- set(ARMADILLO_LIBRARIES ${SUPPORT_LIBRARIES})
- endif ()
- message(STATUS "Armadillo libraries: ${ARMADILLO_LIBRARIES}")
+ set(ARMADILLO_INCLUDE_DIRS ${ARMADILLO_INCLUDE_DIR})
+ set(ARMADILLO_LIBRARIES ${ARMADILLO_LIBRARY} ${_ARMA_SUPPORT_LIBRARIES})
endif ()
+# Clean up internal variables
+unset(_ARMA_REQUIRED_VARS)
+unset(_ARMA_SUPPORT_LIBRARIES)
+unset(_ARMA_USE_WRAPPER)
+unset(_ARMA_USE_LAPACK)
+unset(_ARMA_USE_BLAS)
+unset(_ARMA_USE_ARPACK)
+unset(_ARMA_USE_HDF5)
+unset(_ARMA_CONFIG_CONTENTS)
+unset(_ARMA_HEADER_CONTENTS)
+unset(__ARMA_SUPPORT_INCLUDE_DIRS)
# Hide internal variables
mark_as_advanced(
ARMADILLO_INCLUDE_DIR
ARMADILLO_LIBRARY)
-
-#======================
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 84e96b4510..4dc6d0beb8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -292,51 +292,6 @@ else()
endif ()
endif()
-# On Windows, Armadillo should be using LAPACK and BLAS but we still need to
-# link against it. We don't want to use the FindLAPACK or FindBLAS modules
-# because then we are required to have a FORTRAN compiler (argh!) so we will try
-# and find LAPACK and BLAS ourselves, using a slightly modified variant of the
-# script Armadillo uses to find these.
-if (WIN32)
- find_library(LAPACK_LIBRARY
- NAMES lapack liblapack lapack_win32_MT lapack_win32
- PATHS "C:/Program Files/Armadillo"
- PATH_SUFFIXES "examples/lib_win32/")
-
- if (NOT LAPACK_LIBRARY)
- message(FATAL_ERROR "Cannot find LAPACK library (.lib)!")
- endif ()
-
- find_library(BLAS_LIBRARY
- NAMES blas libblas blas_win32_MT blas_win32
- PATHS "C:/Program Files/Armadillo"
- PATH_SUFFIXES "examples/lib_win32/")
-
- if (NOT BLAS_LIBRARY)
- message(FATAL_ERROR "Cannot find BLAS library (.lib)!")
- endif ()
-
- # Piggyback LAPACK and BLAS linking into Armadillo link.
- set(ARMADILLO_LIBRARIES
- ${ARMADILLO_LIBRARIES} ${BLAS_LIBRARY} ${LAPACK_LIBRARY})
-
- # Ensure that the libraries are added to the MSVC IDE runtime path.
- get_filename_component(BLAS_DIR ${BLAS_LIBRARY} DIRECTORY)
- get_filename_component(LAPACK_DIR ${LAPACK_LIBRARY} DIRECTORY)
-
- # Sometimes, especially with an OpenBLAS install via nuget, the DLLs are
- # actually in ../../bin/x64/. Automatically add these.
- if (EXISTS "${BLAS_DIR}/../../bin/x64/")
- get_filename_component(BLAS_DLL_DIR "${BLAS_DIR}/../../bin/x64" ABSOLUTE)
- set(DLL_COPY_DIRS ${DLL_COPY_DIRS} "${BLAS_DLL_DIR}")
- endif ()
-
- if (EXISTS "${LAPACK_DIR}/../../bin/x64/")
- get_filename_component(LAPACK_DLL_DIR "${LAPACK_DIR}/../../bin/x64" ABSOLUTE)
- set(DLL_COPY_DIRS ${DLL_COPY_DIRS} "${BLAS_DLL_DIR}")
- endif ()
-endif ()
-
# Include directories for the previous dependencies.
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS})
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${ARMADILLO_LIBRARIES})
@@ -373,6 +328,7 @@ if (NOT STB_IMAGE_FOUND)
install(FILES "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image_write.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
add_definitions(-DHAS_STB)
+ set(STB_AVAILABLE "1")
else ()
message(WARNING
"stb/stb_image.h is not installed. Image utilities will not be available!")
@@ -393,6 +349,7 @@ else ()
# Already has STB installed.
add_definitions(-DHAS_STB)
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${STB_IMAGE_INCLUDE_DIR})
+ set(STB_AVAILABLE "1")
endif ()
@@ -415,7 +372,12 @@ if (NOT ENSMALLEN_FOUND)
# Get the name of the directory.
file (GLOB ENS_DIRECTORIES RELATIVE "${CMAKE_BINARY_DIR}/deps/"
"${CMAKE_BINARY_DIR}/deps/ensmallen-[0-9]*.[0-9]*.[0-9]*")
- list(FILTER ENS_DIRECTORIES EXCLUDE REGEX "ensmallen-.*\.tar\.gz")
+ # list(FILTER) is not available on 3.5 or older, but try to keep
+ # configuring without filtering the list anyway (it might work if only
+ # the file ensmallen-latest.tar.gz is present.
+ if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.6.0")
+ list(FILTER ENS_DIRECTORIES EXCLUDE REGEX "ensmallen-.*\.tar\.gz")
+ endif ()
list(LENGTH ENS_DIRECTORIES ENS_DIRECTORIES_LEN)
if (ENS_DIRECTORIES_LEN EQUAL 1)
list(GET ENS_DIRECTORIES 0 ENSMALLEN_INCLUDE_DIR)
@@ -453,6 +415,9 @@ endif ()
# Unfortunately this configuration variable is necessary and will need to be
# updated as time goes on and new versions are released.
set(Boost_ADDITIONAL_VERSIONS
+ "1.72.0" "1.72"
+ "1.71.0" "1.71"
+ "1.70.0" "1.70"
"1.69.0" "1.69"
"1.68.0" "1.68"
"1.67.0" "1.67"
@@ -464,23 +429,14 @@ set(Boost_ADDITIONAL_VERSIONS
"1.61.1" "1.61.0" "1.61"
"1.60.1" "1.60.0" "1.60"
"1.59.1" "1.59.0" "1.59"
- "1.58.1" "1.58.0" "1.58"
- "1.57.1" "1.57.0" "1.57"
- "1.56.1" "1.56.0" "1.56"
- "1.55.1" "1.55.0" "1.55"
- "1.54.1" "1.54.0" "1.54"
- "1.53.1" "1.53.0" "1.53"
- "1.52.1" "1.52.0" "1.52"
- "1.51.1" "1.51.0" "1.51"
- "1.50.1" "1.50.0" "1.50"
- "1.49.1" "1.49.0" "1.49")
+ "1.58.1" "1.58.0" "1.58")
# Disable forced config-mode CMake search for Boost, which only imports targets
# and does not set the variables that we need.
#
# TODO for the brave: transition all mlpack's CMake to 'target-based modern
# CMake'. Good luck! You'll need it.
set(Boost_NO_BOOST_CMAKE 1)
-find_package(Boost 1.49
+find_package(Boost 1.58
COMPONENTS
program_options
unit_test_framework
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b377a24e69..c9ac5e5aa7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -28,3 +28,49 @@ Members of the Contributors team are encouraged to review pull requests that
have already been reviewed, and pull request contributors are encouraged to seek
multiple reviews. Reviews from anyone not on the Contributors team are always
appreciated and encouraged!
+
+## Reviewing Pull Requests
+
+All mlpack contributors who choose to review and provide feedback on pull
+requests have a responsibility to both the project and the individual making
+the contribution.
+
+Reviews and feedback should be
+[helpful, insightful, and geared towards improving the contribution](
+ https://www.youtube.com/watch?v=NNXk_WJzyMI).
+If there are reasons why you feel the PR should not be merged, explain
+what those are. Be open to having your mind changed. Be open to
+working with the contributor to make the pull request better.
+
+Please don't leave dismissive or disrespectful reviews! It's not helpful for
+anyone.
+
+When reviewing a pull request, the primary goals are:
+
+- For the codebase/project to improve
+- For the person submitting the request to succeed
+
+Even if a pull request does not get merged, the submitters should come away
+from the experience feeling like their effort was not wasted or unappreciated.
+Every pull request from a new contributor is an opportunity to grow the community.
+
+When changes are necessary, request them, do not demand them, and do not assume
+that the contributor already knows how to do that. Be there to lend a helping
+hand in case of need.
+
+Since there can sometimes be a lot more pull requests being opened than
+reviewed, we highly encourage everyone to review each others pull request
+keeping in mind all the above mentioned points.
+
+Let's welcome new contributors with ❤️.
+
+## Pull Request Waiting Time
+
+mlpack is a community-driven project, so everyone only works on it in their
+free time; this means it may take some time for them to review pull requests.
+While gentle reminders are welcome, please be patient and avoid constantly
+messaging contributors or tagging them on pull requests.
+
+Typically small PRs will be reviewed within a handful of days; larger PRs might
+take a few weeks for an initial review, and it may be a little bit longer in
+times of high activity.
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 60fba03e0a..db423bb3b8 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -128,6 +128,9 @@ Copyright:
Copyright 2020, Sriram S K
Copyright 2020, Manoranjan Kumar Bharti ( Nakul Bharti )
Copyright 2020, Saraansh Tandon
+ Copyright 2020, Gaurav Singh
+ Copyright 2020, Lakshya Ojha
+ Copyright 2020, Bisakh Mondal
License: BSD-3-clause
All rights reserved.
diff --git a/HISTORY.md b/HISTORY.md
index 6e4798c57b..6d086bf76f 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,10 +1,14 @@
### mlpack ?.?.?
###### ????-??-??
+ * Templated return type of `Forward function` of loss functions (#2339).
+
+ * Added `R2 Score` regression metric (#2323).
+
* Added `mean squared logarithmic error` loss function for neural networks
(#2210).
-
+
* Added `mean bias loss function` for neural networks (#2210).
-
+
* The DecisionStump class has been marked deprecated; use the `DecisionTree`
class with `NoRecursion=true` or use `ID3DecisionStump` instead (#2099).
@@ -25,12 +29,18 @@
* Add functions to access parameters of `Convolution` and `AtrousConvolution`
layers (#1985).
+ * Add Compute Error function in lars regression and changing Train function to
+ return computed error (#2139).
+
* Add Julia bindings (#1949). Build settings can be controlled with the
`BUILD_JULIA_BINDINGS=(ON/OFF)` and `JULIA_EXECUTABLE=/path/to/julia` CMake
parameters.
* CMake fix for finding STB include directory (#2145).
+ * Add bindings for loading and saving images (#2019); `mlpack_image_converter`
+ from the command-line, `mlpack.image_converter()` from Python.
+
* Add normalization support for CF binding (#2136).
* Add Mish activation function (#2158).
@@ -42,12 +52,32 @@
* Better error handling of eigendecompositions and Cholesky decompositions
(#2088, #1840).
-
+
* Add LiSHT activation function (#2182).
* Add Valid and Same Padding for Transposed Convolution layer (#2163).
+
+ * Add CELU activation function (#2191)
- * Add Log-Hyperbolic-Cosine Loss function (#2207).
+ * Add Log-Hyperbolic-Cosine Loss function (#2207)
+
+ * Change neural network types to avoid unnecessary use of rvalue references
+ (#2259).
+
+ * Bump minimum Boost version to 1.58 (#2305).
+
+ * Refactor STB support so HAS_STB macro is not needed when compiling against
+ mlpack (#2312).
+
+ * Add Hard Shrink Activation Function (#2186).
+
+ * Add Soft Shrink Activation Function (#2174).
+
+ * Add Hinge Embedding Loss Function (#2229).
+
+ * Add Cosine Embedding Loss Function (#2209).
+
+ * Add Margin Ranking Loss Function (#2264).
### mlpack 3.2.2
###### 2019-11-26
diff --git a/README.md b/README.md
index da9d26a9c8..d204bb4b3a 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@ src="https://cdn.rawgit.com/mlpack/mlpack.org/e7d36ed8/mlpack-black.svg" style="
+
@@ -33,6 +34,8 @@ functions as a "swiss army knife" for machine learning researchers. In addition
to its powerful C++ interface, mlpack also provides command-line programs,
Python bindings, and Julia bindings.
+[//]: # (numfocus-fiscal-sponsor-attribution)
+
mlpack uses an [open governance model](./GOVERNANCE.md) and is fiscally
sponsored by [NumFOCUS](https://numfocus.org/). Consider making a
[tax-deductible donation](https://numfocus.org/donate-to-mlpack) to help the
@@ -40,7 +43,7 @@ project pay for developer time, professional services, travel, workshops, and a
variety of other needs.
-
+
@@ -97,11 +100,11 @@ Citations are beneficial for the growth and improvement of mlpack.
mlpack has the following dependencies:
- Armadillo >= 8.400.0
+ Armadillo >= 8.400.0
Boost (program_options, math_c99, unit_test_framework, serialization,
- spirit)
- CMake >= 3.3.2
- ensmallen >= 2.10.0
+ spirit) >= 1.58.0
+ CMake >= 3.3.2
+ ensmallen >= 2.10.0
All of those should be available in your distribution's package manager. If
not, you will have to compile each of them by hand. See the documentation for
diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp
index e0577c39ba..df5e2edb82 100644
--- a/doc/guide/build.hpp
+++ b/doc/guide/build.hpp
@@ -79,7 +79,7 @@ system and have headers present:
- Armadillo >= 8.400.0 (with LAPACK support)
- Boost (math_c99, program_options, serialization, unit_test_framework, heap,
- spirit) >= 1.49
+ spirit) >= 1.58
- ensmallen >= 2.10.0 (will be downloaded if not found)
In addition, mlpack has the following optional dependencies:
diff --git a/doc/guide/build_windows.hpp b/doc/guide/build_windows.hpp
index 469b866066..bb8ce9a1ea 100644
--- a/doc/guide/build_windows.hpp
+++ b/doc/guide/build_windows.hpp
@@ -118,7 +118,7 @@ compiler version, check if the Visual Studio compiler and Windows SDK are instal
- Run cmake:
@code
-cmake -G "Visual Studio 16 2019" -A x64 -DBLAS_LIBRARY:FILEPATH="C:/mlpack/mlpack/packages/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a" -DLAPACK_LIBRARY:FILEPATH="C:/mlpack/mlpack/packages/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a" -DARMADILLO_INCLUDE_DIR="C:/mlpack/armadillo/include" -DARMADILLO_LIBRARY:FILEPATH="C:/mlpack/armadillo/build/Debug/armadillo.lib" -DBOOST_INCLUDEDIR:PATH="C:/boost/" -DBOOST_LIBRARYDIR:PATH="C:/boost/lib64-msvc-14.2" -DDEBUG=OFF -DPROFILE=OFF ..
+cmake -G "Visual Studio 16 2019" -A x64 -DBLAS_LIBRARIES:FILEPATH="C:/mlpack/mlpack/packages/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a" -DLAPACK_LIBRARIES:FILEPATH="C:/mlpack/mlpack/packages/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a" -DARMADILLO_INCLUDE_DIR="C:/mlpack/armadillo/include" -DARMADILLO_LIBRARY:FILEPATH="C:/mlpack/armadillo/build/Debug/armadillo.lib" -DBOOST_INCLUDEDIR:PATH="C:/boost/" -DBOOST_LIBRARYDIR:PATH="C:/boost/lib64-msvc-14.2" -DDEBUG=OFF -DPROFILE=OFF ..
@endcode
@note cmake will attempt to automatically download the ensmallen dependency. If for some reason cmake can't download the dependency, you will need to manually download ensmallen from http://ensmallen.org/ and extract it to "C:\mlpack\mlpack\deps\". Then, specify the path to ensmallen using the flag: -DENSMALLEN_INCLUDE_DIR=C:/mlpack/mlpack/deps/ensmallen/include
diff --git a/doc/guide/formats.hpp b/doc/guide/formats.hpp
index acf8a00c20..e7f216aae3 100644
--- a/doc/guide/formats.hpp
+++ b/doc/guide/formats.hpp
@@ -330,39 +330,46 @@ mlpack's image saving/loading functionality is based on [stb/](https://github.co
Image utilities supports loading and saving of images.
-It supports filetypes "jpg", "png", "tga","bmp", "psd", "gif", "hdr", "pic", "pnm" for loading and "jpg", "png", "tga", "bmp", "hdr" for saving.
+It supports filetypes "jpg", "png", "tga", "bmp", "psd", "gif", "hdr", "pic",
+"pnm" for loading and "jpg", "png", "tga", "bmp", "hdr" for saving.
-The datatype associated is unsigned char to support RGB values in the range 1-255. To feed data into the network typecast of `arma::Mat` may be required. Images are stored in matrix as (width * height * channels, NumberOfImages). Therefore imageMatrix.col(0) would be the first image if images are loaded in imageMatrix.
+The datatype associated is unsigned char to support RGB values in the range
+1-255. To feed data into the network typecast of `arma::Mat` may be required.
+Images are stored in the matrix as (width * height * channels, NumberOfImages).
+Therefore @c imageMatrix.col(0) would be the first image if images are loaded in
+@c imageMatrix.
@section imageinfo_api_imagetut Accessing Metadata of Images: ImageInfo
ImageInfo class contains the metadata of the images.
@code
ImageInfo(const size_t width,
- const size_t height,
- const size_t channels);
+ const size_t height,
+ const size_t channels,
+ const size_t quality = 90);
@endcode
-Other public memebers include:
- - flipVertical Flip the image vertical upon loading.
- - quality Compression of the image if saved as jpg (0-100).
+
+The @c quality member denotes the compression of the image if it is saved as
+`jpg`; it takes values from 0 to 100.
@section load_api_imagetut Loading Images in C++
-
Standalone loading of images.
+
@code
- template
- bool Load(const std::string& filename,
- arma::Mat& matrix,
- ImageInfo& info,
- const bool fatal,
- const bool transpose);
+template
+bool Load(const std::string& filename,
+ arma::Mat& matrix,
+ ImageInfo& info,
+ const bool fatal);
@endcode
-Loading a test image. It also fills up the ImageInfo class object.
+The example below loads a test image. It also fills up the ImageInfo class
+object.
+
@code
data::ImageInfo info;
-data::Load("test_image.png", matrix, info, false, true);
+data::Load("test_image.png", matrix, info, false);
@endcode
ImageInfo requires height, width, number of channels of the image.
@@ -377,18 +384,17 @@ More than one image can be loaded into the same matrix.
Loading multiple images:
@code
- template
- bool Load(const std::vector& files,
- arma::Mat& matrix,
- ImageInfo& info,
- const bool fatal,
- const bool transpose);
+template
+bool Load(const std::vector& files,
+ arma::Mat& matrix,
+ ImageInfo& info,
+ const bool fatal);
@endcode
@code
- data::ImageInfo info;
- std::vector> files{"test_image1.bmp","test_image2.bmp"};
- data::load(files, matrix, info, false, true);
+data::ImageInfo info;
+std::vector> files{"test_image1.bmp","test_image2.bmp"};
+data::Load(files, matrix, info, false);
@endcode
@section save_api_imagetut Saving Images in C++
diff --git a/doc/tutorials/ann/ann.txt b/doc/tutorials/ann/ann.txt
index c1e7da31c1..db28bef868 100644
--- a/doc/tutorials/ann/ann.txt
+++ b/doc/tutorials/ann/ann.txt
@@ -204,17 +204,17 @@ using namespace mlpack::ann;
int main()
{
- // Load the training set.
- arma::mat dataset;
- data::Load("thyroid_train.csv", dataset, true);
+ // Load the training set and testing set.
+ arma::mat trainData;
+ data::Load("thyroid_train.csv", trainData, true);
+ arma::mat testData;
+ data::Load("thyroid_test.csv", testData, true);
- // Split the labels from the training set.
- arma::mat trainData = dataset.submat(0, 0, dataset.n_rows - 4,
- dataset.n_cols - 1);
-
- // Split the data from the training set.
- arma::mat trainLabels = dataset.submat(dataset.n_rows - 3, 0,
- dataset.n_rows - 1, dataset.n_cols - 1);
+ // Split the labels from the training set and testing set respectively.
+ arma::mat trainLabels = trainData.row(trainData.n_rows - 1);
+ arma::mat testLabels = testData.row(testData.n_rows - 1);
+ trainData.shed_row(trainData.n_rows - 1);
+ testData.shed_row(testData.n_rows - 1);
// Initialize the network.
FFN<> model;
@@ -226,14 +226,48 @@ int main()
// Train the model.
model.Train(trainData, trainLabels);
- // Use the Predict method to get the assignments.
- arma::mat assignments;
- model.Predict(trainData, assignments);
+ // Use the Predict method to get the predictions.
+ arma::mat predictionTemp;
+ model.Predict(testData, predictionTemp);
+
+ /*
+ Since the predictionsTemp is of dimensions (3 x number_of_data_points)
+ with continuous values, we first need to reduce it to a dimension of
+ (1 x number_of_data_points) with scalar values, to be able to compare with
+ testLabels.
+
+ The first step towards doing this is to create a matrix of zeros with the
+ desired dimensions (1 x number_of_data_points).
+
+ In predictionsTemp, the 3 dimensions for each data point correspond to the
+ probabilities of belonging to the three possible classes.
+ */
+ arma::mat prediction = arma::zeros(1, predictionTemp.n_cols);
+
+ // Find index of max prediction for each data point and store in "prediction"
+ for (size_t i = 0; i < predictionTemp.n_cols; ++i)
+ {
+ // we add 1 to the max index, so that it matches the actual test labels.
+ prediction(i) = arma::as_scalar(arma::find(
+ arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1)) + 1;
+ }
+
+ /*
+ Compute the error between predictions and testLabels,
+ now that we have the desired predictions.
+ */
+ size_t correct = arma::accu(prediction == testLabels);
+ double classificationError = 1 - double(correct) / testData.n_cols;
+
+ // Print out the classification error for the testing dataset.
+ std::cout << "Classification Error for the Test set: " << classificationError << std::endl;
+ return 0;
}
@endcode
-Now, the matrix assignments holds the classification of each point in the
-dataset.
+Now, the matrix prediction holds the classification of each point in the
+dataset. Subsequently, we find the classification error by comparing it
+with testLabels.
In the next example, we create simple noisy sine sequences, which are trained
later on, using the RNN class in the `RNNModel()` method.
@@ -328,7 +362,7 @@ implementation of a \c Forward() method. The interface looks like:
@code
template
-void Forward(const arma::Mat&& input, arma::Mat&& output);
+void Forward(const arma::Mat& input, arma::Mat& output);
@endcode
The method should calculate the output of the layer given the input matrix and
@@ -339,9 +373,9 @@ through f:
@code
template
-void Backward(const arma::Mat&& input,
- arma::Mat&& gy,
- arma::Mat&& g);
+void Backward(const arma::Mat& input,
+ const arma::Mat& gy,
+ arma::Mat& g);
@endcode
Finally, if the layer is differentiable, the layer must also implement
@@ -349,9 +383,9 @@ a Gradient() method:
@code
template
-void Gradient(const arma::Mat&& input,
- arma::Mat&& error,
- arma::Mat&& gradient);
+void Gradient(const arma::Mat& input,
+ const arma::Mat& error,
+ arma::Mat& gradient);
@endcode
The Gradient function should calculate the gradient with respect to the input
@@ -434,21 +468,21 @@ API, so we must implement some additional functions.
@code
template
-void Forward(const InputType&& input, OutputType&& output)
+void Forward(const InputType& input, OutputType& output)
{
output = arma::ones(input.n_rows, input.n_cols);
}
template
-void Backward(const InputType&& input, ErrorType&& gy, GradientType&& g)
+void Backward(const InputType& input, const ErrorType& gy, GradientType& g)
{
g = arma::zeros(gy.n_rows, gy.n_cols) + gy;
}
template
-void Gradient(const InputType&& input,
- ErrorType&& error,
- GradientType&& gradient)
+void Gradient(const InputType& input,
+ ErrorType& error,
+ GradientType& gradient)
{
gradient = arma::zeros(input.n_rows, input.n_cols) * error;
}
diff --git a/doc/tutorials/image/image.txt b/doc/tutorials/image/image.txt
new file mode 100644
index 0000000000..b64a86c24a
--- /dev/null
+++ b/doc/tutorials/image/image.txt
@@ -0,0 +1,188 @@
+/*!
+@file image.txt
+@author Mehul Kumar Nirala
+@brief Tutorial for how to load and save images in mlpack.
+
+@page imagetutorial Image Utilities tutorial
+
+@section intro_imagetut Introduction
+
+Image datasets are becoming increasingly popular in deep learning.
+
+mlpack's image saving/loading functionality is based on [stb/](https://github.com/nothings/stb).
+
+@section toc_imagetut Table of Contents
+
+This tutorial is split into the following sections:
+
+ - \ref intro_imagetut
+ - \ref toc_imagetut
+ - \ref model_api_imagetut
+ - \ref imageinfo_api_imagetut
+ - \ref load_api_imagetut
+ - \ref save_api_imagetut
+
+@section model_api_imagetut Model API
+
+Image utilities supports loading and saving of images.
+
+It supports filetypes "jpg", "png", "tga","bmp", "psd", "gif", "hdr", "pic", "pnm" for loading and "jpg", "png", "tga", "bmp", "hdr" for saving.
+
+The datatype associated is unsigned char to support RGB values in the range 1-255. To feed data into the network typecast of `arma::Mat` may be required. Images are stored in matrix as (width * height * channels, NumberOfImages). Therefore imageMatrix.col(0) would be the first image if images are loaded in imageMatrix.
+
+@section imageinfo_api_imagetut ImageInfo
+
+ImageInfo class contains the metadata of the images.
+@code
+ /**
+ * Instantiate the ImageInfo object with the image width, height, channels.
+ *
+ * @param width Image width.
+ * @param height Image height.
+ * @param channels number of channels in the image.
+ */
+ ImageInfo(const size_t width,
+ const size_t height,
+ const size_t channels);
+@endcode
+Other public memebers include:
+ - quality Compression of the image if saved as jpg (0-100).
+
+@section load_api_imagetut Load
+
+
+Standalone loading of images.
+@code
+ /**
+ * Load the image file into the given matrix.
+ *
+ * @param filename Name of the image file.
+ * @param matrix Matrix to load the image into.
+ * @param info An object of ImageInfo class.
+ * @param fatal If an error should be reported as fatal (default false).
+ * @param transpose If true, flips the image, same as transposing the
+ * matrix after loading.
+ * @return Boolean value indicating success or failure of load.
+ */
+ template
+ bool Load(const std::string& filename,
+ arma::Mat& matrix,
+ ImageInfo& info,
+ const bool fatal,
+ const bool transpose);
+@endcode
+
+Loading a test image. It also fills up the ImageInfo class object.
+@code
+data::ImageInfo info;
+data::Load("test_image.png", matrix, info, false, true);
+@endcode
+
+ImageInfo requires height, width, number of channels of the image.
+
+@code
+size_t height = 64, width = 64, channels = 1;
+data::ImageInfo info(width, height, channels);
+@endcode
+
+More than one image can be loaded into the same matrix.
+
+Loading multiple images:
+
+@code
+ /**
+ * Load the image file into the given matrix.
+ *
+ * @param files A vector consisting of filenames.
+ * @param matrix Matrix to save the image from.
+ * @param info An object of ImageInfo class.
+ * @param fatal If an error should be reported as fatal (default false).
+ * @param transpose If true, flips the image, same as transposing the
+ * matrix after loading.
+ * @return Boolean value indicating success or failure of load.
+ */
+ template
+ bool Load(const std::vector& files,
+ arma::Mat& matrix,
+ ImageInfo& info,
+ const bool fatal,
+ const bool transpose);
+@endcode
+
+@code
+ data::ImageInfo info;
+ std::vector> files{"test_image1.bmp","test_image2.bmp"};
+ data::load(files, matrix, info, false, true);
+@endcode
+
+@section save_api_imagetut Save
+
+Save images expects a matrix of type unsigned char in the form (width * height * channels, NumberOfImages).
+Just like load it can be used to save one image or multiple images. Besides image data it also expects the shape of the image as input (width, height, channels).
+
+Saving one image:
+
+@code
+ /**
+ * Save the image file from the given matrix.
+ *
+ * @param filename Name of the image file.
+ * @param matrix Matrix to save the image from.
+ * @param info An object of ImageInfo class.
+ * @param fatal If an error should be reported as fatal (default false).
+ * @param transpose If true, flips the image, same as transposing the
+ * matrix after loading.
+ * @return Boolean value indicating success or failure of load.
+ */
+ template
+ bool Save(const std::string& filename,
+ arma::Mat& matrix,
+ ImageInfo& info,
+ const bool fatal,
+ const bool transpose);
+@endcode
+
+@code
+ data::ImageInfo info;
+ info.width = info.height = 25;
+ info.channels = 3;
+ info.quality = 90;
+ data::Save("test_image.bmp", matrix, info, false, true);
+@endcode
+
+If the matrix contains more than one image, only the first one is saved.
+
+Saving multiple images:
+
+@code
+ /**
+ * Save the image file from the given matrix.
+ *
+ * @param files A vector consisting of filenames.
+ * @param matrix Matrix to save the image from.
+ * @param info An object of ImageInfo class.
+ * @param fatal If an error should be reported as fatal (default false).
+ * @param transpose If true, Flips the image, same as transposing the
+ * matrix after loading.
+ * @return Boolean value indicating success or failure of load.
+ */
+ template
+ bool Save(const std::vector& files,
+ arma::Mat& matrix,
+ ImageInfo& info,
+ const bool fatal,
+ const bool transpose);
+@endcode
+
+@code
+ data::ImageInfo info;
+ info.width = info.height = 25;
+ info.channels = 3;
+ info.quality = 90;
+ std::vector> files{"test_image1.bmp", "test_image2.bmp"};
+ data::Save(files, matrix, info, false, true);
+@endcode
+
+Multiple images are saved according to the vector of filenames specified.
+
+*/
diff --git a/doc/tutorials/reinforcement_learning/reinforcement_learning.txt b/doc/tutorials/reinforcement_learning/reinforcement_learning.txt
new file mode 100644
index 0000000000..a91dc27671
--- /dev/null
+++ b/doc/tutorials/reinforcement_learning/reinforcement_learning.txt
@@ -0,0 +1,399 @@
+/*!
+@file rl.txt
+@author Sriram S K
+@author Joel Joseph
+@brief Tutorial for how to use the Reinforcement Learning module in mlpack.
+
+@page rltutorial Reinforcement Learning Tutorial
+
+@section intro_rltut Introduction
+
+Reinforcement Learning is one of the hottest topics right now, with
+interest surging after DeepMind published their article on training
+deep neural networks to play Atari games to great success. mlpack
+implements a complete end-to-end framework for Reinforcement Learning,
+featuring multiple environments, policies and methods. Of course,
+custom environments and policies can be used and plugged into the
+existing framework with no runtime overhead.
+
+mlpack implements typical benchmark environments (Acrobot, Mountain car etc.),
+commonly used policies, replay methods and supports asynchronous
+learning as well. In addition, it can [communicate](https://github.com/zoq/gym_tcp_api)
+with the OpenAI Gym toolkit for more environments.
+
+@section toc_rltut Table of Contents
+
+This tutorial is split into the following sections:
+
+ - \ref intro_rltut
+ - \ref toc_rltut
+ - \ref environment_rltut
+ - \ref agent_components_rltut
+ - \ref q_learning_rltut
+ - \ref async_learning_rltut
+ - \ref further_rltut
+
+@section environment_rltut Reinforcement Learning Environments
+
+mlpack implements a number of the most popular environments used for testing
+RL agents and algorithms. These include the Cart Pole, Acrobot, Mountain Car
+and their variations. Of course, as mentioned above, you can communicate with
+OpenAI Gym for other environments, like the Atari video games.
+
+A key component of mlpack is its extensibility. It is a simple process to create
+your own custom environments, specific to your needs, and use it with mlpack's
+RL framework. All the environments implement a few specific methods and classes
+which are used by the agents while learning.
+
+- \c State: The State class is a representation of the environment. For the CartPole,
+ this would involve storing the position, velocity, angle and angular velocity.
+
+- \c Action: It is an enum naming all the possible actions the agent can take in the
+ environment. Continuing with the CartPole example, the Action enum would simply
+ contain the two possible actions, backward and forward.
+
+- \c Sample: This method is perhaps the heart of the environment, providing rewards to
+ the agent depending on the state and the action taken, and updates the state based on
+ the action taken as well.
+
+Of course, your custom environment will most likely make use of a number of helper methods, depending
+on your application, such as the \c Dsdt method in the \c Acrobot environment, used in the \c RK4
+iterative method (also another helper method) to estimate the next state.
+
+@section agent_components_rltut Components of an RL Agent
+
+A Reinforcement Learning agent, in general, takes actions in an environment in order
+to maximize a cumulative reward. To that end, it requires a way to choose actions (\b policy)
+and a way to sample previous experiences (\b replay).
+
+An example of a simple policy would be an epsilon-greedy policy. Using such a policy, the agent
+will choose actions greedily with some probability epsilon. This probability is slowly decreased
+over time, balancing the line between exploration and exploitation.
+
+Similarly, an example of a simple replay would be a random replay. At each time step, the
+interactions between the agent and the environment are saved to a memory buffer and previous
+experiences are sampled from the buffer to train the agent.
+
+Instantiating the components of an agent can be easily done by passing the Environment as
+a templated argument and the parameters of the policy/replay to the constructor.
+
+To create a Greedy Policy and Prioritized Replay for the CartPole environment, we would do the
+following:
+
+@code
+GreedyPolicy policy(1.0, 1000, 0.1);
+PrioritizedReplay replayMethod(10, 10000, 0.6);
+@endcode
+
+The arguments to `policy` are the initial epsilon values, the interval of decrease in its value
+and the value at which epsilon bottoms out and won't be reduced further. The arguments to
+`replayMethod` are size of the batch returned, the number of examples stored in memory, and the
+degree of prioritization.
+
+In addition to the above components, an RL agent requires many hyperparameters to be tuned during
+ it's training period. These parameters include everything from the discount rate of the future
+reward to whether Double Q-learning should be used or not. The `TrainingConfig` class can be
+instantiated and configured as follows:
+
+@code
+ TrainingConfig config;
+ config.StepSize() = 0.01;
+ config.Discount() = 0.9;
+ config.TargetNetworkSyncInterval() = 100;
+ config.ExplorationSteps() = 100;
+ config.DoubleQLearning() = false;
+ config.StepLimit() = 200;
+@endcode
+
+The object `config` describes an RL agent, using a step size of 0.01 for the optimization process,
+a discount factor of 0.9, sync interval of 200 episodes. This agent only starts learning after storing
+100 exploration steps, has a step limit of 200, and does not utilize double q-learning.
+
+In this way, we can easily configure an RL agent with the desired hyperparameters.
+
+@section q_learning_rltut Q-Learning in mlpack
+
+Here, we demonstrate Q-Learning in mlpack through the use of a simple example, the training of a Q-Learning
+agent on the CartPole environment. The code has been broken into chunks for easy understanding.
+
+@code
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace mlpack;
+using namespace mlpack::ann;
+using namespace ens;
+using namespace mlpack::rl;
+@endcode
+
+We include all the necessary components of our toy example and declare namespaces for convenience.
+
+@code
+int main()
+{
+ // Set up the network.
+ FFN, GaussianInitialization> model(MeanSquaredError<>(),
+ GaussianInitialization(0, 0.001));
+ model.Add>(4, 128);
+ model.Add>();
+ model.Add>(128, 128);
+ model.Add>();
+ model.Add>(128, 2);
+
+@endcode
+
+The first step in setting our Q-learning agent is to setup the network for it to use. Here,
+we use mlpack's ann module to setup a simple FFN network, consisting of a single hidden layer.
+
+@note
+The network constructed here has an input shape of 4 and output shape of 2. This corresponds to
+the structure of the CartPole environment, where each state is represented as a column vector with
+4 data members (position, velocity, angle, angular velocity). Similarly, the output shape is represented
+by the number of possible actions, which in this case, is only 2 (foward and backward).
+
+The next step would be to setup the other components of the Q-learning agent, namely its policy, replay
+method and hyperparameters.
+
+@code
+ // Set up the policy and replay method.
+ GreedyPolicy policy(1.0, 1000, 0.1, 0.99);
+ RandomReplay replayMethod(10, 10000);
+
+ TrainingConfig config;
+ config.StepSize() = 0.01;
+ config.Discount() = 0.9;
+ config.TargetNetworkSyncInterval() = 100;
+ config.ExplorationSteps() = 100;
+ config.DoubleQLearning() = false;
+ config.StepLimit() = 200;
+@endcode
+
+And now, we get to the heart of the program, declaring a Q-Learning agent.
+
+@code
+ QLearning
+ agent(std::move(config), std::move(model), std::move(policy),
+ std::move(replayMethod));
+@endcode
+
+Here, we call the `QLearning` constructor, passing in the type of environment,
+network, updater, policy and replay. We use `decltype(var)` as a shorthand for
+the variable, saving us the trouble of copying the lengthy templated type.
+
+Similarly, `std::move` is called for convenience, moving the components instead of
+duplicating them and copying them over.
+
+We have our Q-Learning agent `agent` ready to be trained on the Cart Pole environment.
+
+@code
+ arma::running_stat averageReturn;
+ size_t episodes = 0;
+ bool converged = true;
+ while (true)
+ {
+ double episodeReturn = agent.Episode();
+ averageReturn(episodeReturn);
+ episodes += 1;
+
+ if (episodes > 1000)
+ {
+ std::cout << "Cart Pole with DQN failed." << std::endl;
+ converged = false;
+ break;
+ }
+
+ /**
+ * Reaching running average return 35 is enough to show it works.
+ */
+ std::cout << "Average return: " << averageReturn.mean()
+ << " Episode return: " << episodeReturn << std::endl;
+ if (averageReturn.mean() > 35)
+ break;
+ }
+ if (converged)
+ std::cout << "Hooray! Q-Learning agent successfully trained" << std::endl;
+
+ return 0;
+}
+@endcode
+
+We set up a loop to train the agent. The exit condition is determined by the average
+reward which can be computed with `arma::running_stat`. It is used for storing running
+statistics of scalars, which in this case is the reward signal. The agent can be said
+to have converged when the average return reaches a predetermined value (i.e. > 35).
+
+Conversely, if the average return does not go beyond that amount even after a thousand
+episodes, we can conclude that the agent will not converge and exit the training loop.
+
+@section async_learning_rltut
+
+In 2016, Researchers at Deepmind and University of Montreal published their paper
+"Asynchronous Methods for Deep Reinforcement Learning". In it they described asynchronous
+variants of four standard reinforcement learning algorithms:
+ - One-Step SARSA
+ - One-Step Q-Learning
+ - N-Step Q-Learning
+ - Advantage Actor-Critic(A3C)
+
+Online RL algorithms and Deep Neural Networks make an unstable combination because of the
+non-stationary and correlated nature of online updates. Although this is solved by Experience Replay,
+it has several drawbacks: it uses more memory and computation per real interaction; and it requires
+off-policy learning algorithms.
+
+Asynchronous methods, instead of experience replay, asynchronously executes multiple agents
+in parallel, on multiple instances of the environment, which solves all the above problems.
+
+Here, we demonstrate Asynchronous Learning methods in mlpack through the training of an async
+agent. Asynchronous learning involves training several agents simultaneously. Here, each of the
+agents are referred to as "workers". Currently mlpack has One-Step Q-Learning worker, N-Step
+Q-Learning worker and One-Step SARSA worker.
+
+Let's examine the sample code in chunks.
+
+Apart from the includes used for the q-learning example, two more have to be included:
+
+@code
+#include
+#include
+@endcode
+
+Here we don't use experience replay, and instead of a single policy, we use three different
+policies, each corresponding to its worker. Number of workers created, depends on the number of
+policies given in the Aggregated Policy. The column vector contains the probability distribution
+for each child policy. We should make sure its size is same as the number of policies and the sum
+of its elements is equal to 1.
+
+@code
+AggregatedPolicy> policy({GreedyPolicy(0.7, 5000, 0.1),
+ GreedyPolicy(0.7, 5000, 0.01),
+ GreedyPolicy(0.7, 5000, 0.5)},
+ arma::colvec("0.4 0.3 0.3"));
+@endcode
+
+Now, we will create the "OneStepQLearning" agent. We could have used "NStepQLearning" or "OneStepSarsa"
+here according to our requirement.
+
+@code
+OneStepQLearning
+ agent(std::move(config), std::move(model), std::move(policy));
+@endcode
+
+Here, unlike the Q-Learning example, instead of the entire while loop, we use the Train method of the Asynchronous
+Learning class inside a for loop. 100 training episodes will take around 50 seconds.
+
+@code
+for (int i = 0; i < 100; i++)
+{
+ agent.Train(measure);
+}
+@endcode
+
+What is "measure" here? It is a lambda function which returns a boolean value (indicating the end of training)
+and accepts the episode return (total reward of a deterministic test episode) as parameter.
+So, let's create that.
+
+@code
+arma::vec returns(20, arma::fill::zeros);
+size_t position = 0;
+size_t episode = 0;
+
+auto measure = [&returns, &position, &episode](double episodeReturn)
+{
+ if(episode > 10000) return true;
+
+ returns[position++] = episodeReturn;
+ position = position % returns.n_elem;
+ episode++;
+
+ std::cout << "Episode No.: " << episode
+ << "; Episode Return: " << episodeReturn
+ << "; Average Return: " << arma::mean(returns) << endl;
+};
+@endcode
+
+This will train three different agents on three CPU threads asynchronously and use this data to update the
+action value estimate.
+Voila, thats all there is to it.
+
+Here is the full code to try this right away:
+
+@code
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace mlpack;
+using namespace mlpack::ann;
+using namespace mlpack::rl;
+int main()
+{
+ // Set up the network.
+ FFN, GaussianInitialization> model(MeanSquaredError<>(), GaussianInitialization(0, 0.001));
+ model.Add>(4, 128);
+ model.Add>();
+ model.Add>(128, 128);
+ model.Add>();
+ model.Add>(128, 2);
+
+ AggregatedPolicy> policy({GreedyPolicy(0.7, 5000, 0.1),
+ GreedyPolicy(0.7, 5000, 0.01),
+ GreedyPolicy(0.7, 5000, 0.5)},
+ arma::colvec("0.4 0.3 0.3"));
+
+ TrainingConfig config;
+ config.StepSize() = 0.01;
+ config.Discount() = 0.9;
+ config.TargetNetworkSyncInterval() = 100;
+ config.ExplorationSteps() = 100;
+ config.DoubleQLearning() = false;
+ config.StepLimit() = 200;
+
+ OneStepQLearning
+ agent(std::move(config), std::move(model), std::move(policy));
+
+ arma::vec returns(20, arma::fill::zeros);
+ size_t position = 0;
+ size_t episode = 0;
+
+ auto measure = [&returns, &position, &episode](double episodeReturn)
+ {
+ if(episode > 10000) return true;
+
+ returns[position++] = episodeReturn;
+ position = position % returns.n_elem;
+ episode++;
+
+ std::cout << "Episode No.: " << episode
+ << "; Episode Return: " << episodeReturn
+ << "; Average Return: " << arma::mean(returns) << endl;
+ };
+
+ for (int i = 0; i < 100; i++)
+ {
+ agent.Train(measure);
+ }
+}
+@endcode
+
+@section further_rltut Further documentation
+
+For further documentation on the rl classes, consult the \ref mlpack::rl
+"complete API documentation".
+
+*/
diff --git a/src/mlpack/bindings/julia/CMakeLists.txt b/src/mlpack/bindings/julia/CMakeLists.txt
index d3249e96ef..461d7b7a22 100644
--- a/src/mlpack/bindings/julia/CMakeLists.txt
+++ b/src/mlpack/bindings/julia/CMakeLists.txt
@@ -18,10 +18,6 @@ if (BUILD_JULIA_BINDINGS)
add_custom_command(TARGET julia PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/)
- add_custom_command(TARGET julia PRE_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy
- ${CMAKE_CURRENT_SOURCE_DIR}/mlpack/REQUIRE
- ${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/REQUIRE)
add_library(mlpack_julia_util
julia_util.h
@@ -52,12 +48,16 @@ if (BUILD_JULIA_BINDINGS)
configure_file(${CMAKE_SOURCE_DIR}/src/mlpack/bindings/julia/mlpack/cli.jl.in
${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/cli.jl)
- # Create the empty mlpack.jl file that we will fill with includes.
- file(WRITE
- "${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/mlpack.jl"
- "module mlpack\n\n"
- "module util\n\n"
- "include(\"cli.jl\")\n")
+ # Create the empty mlpack.jl file that we will fill with includes using the
+ # exsiting template. Unfortunately COPY doesn't let us change the extension
+ # so we need a follow-up RENAME command.
+ file(COPY
+ "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/mlpack.jl.in"
+ DESTINATION
+ "${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/")
+ file(RENAME
+ "${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/mlpack.jl.in"
+ "${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/mlpack.jl")
file(WRITE
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/functions.jl"
@@ -150,10 +150,10 @@ if (BUILD_JULIA_BINDINGS)
# Append the code to define the function in the module.
file(APPEND
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/functions.jl"
- "${name} = util.${name}\n")
+ "${name} = _Internal.${name}\n")
endif ()
endmacro ()
-if (BUILD_TESTS)
+if (BUILD_TESTS AND BUILD_JULIA_BINDINGS)
add_subdirectory(tests)
endif ()
diff --git a/src/mlpack/bindings/julia/default_param_impl.hpp b/src/mlpack/bindings/julia/default_param_impl.hpp
index 6a25fb494f..47f1bd7ab1 100644
--- a/src/mlpack/bindings/julia/default_param_impl.hpp
+++ b/src/mlpack/bindings/julia/default_param_impl.hpp
@@ -116,11 +116,11 @@ std::string DefaultParamImpl(
else if (std::is_same>::value ||
std::is_same>::value)
{
- return "Int64[]";
+ return "Int[]";
}
else if (std::is_same>::value)
{
- return "zeros(Int64, 0, 0)";
+ return "zeros(Int, 0, 0)";
}
else
{
diff --git a/src/mlpack/bindings/julia/get_julia_type.hpp b/src/mlpack/bindings/julia/get_julia_type.hpp
index 9ff62e4cb9..096c420ab9 100644
--- a/src/mlpack/bindings/julia/get_julia_type.hpp
+++ b/src/mlpack/bindings/julia/get_julia_type.hpp
@@ -101,9 +101,9 @@ inline std::string GetJuliaType(
const typename std::enable_if::value>::type* = 0)
{
// size_t matrices are special: we want to represent them in Julia as
- // Array{Int64, X} not UInt64 because Julia displays UInt64s strangely.
+ // Array{Int, X} not UInt because Julia displays UInts strangely.
if (std::is_same::value)
- return std::string("Array{Int64, ") + (T::is_col || T::is_row ? "1" : "2")
+ return std::string("Array{Int, ") + (T::is_col || T::is_row ? "1" : "2")
+ "}";
else
return "Array{" + GetJuliaType() + ", "
diff --git a/src/mlpack/bindings/julia/get_printable_type_impl.hpp b/src/mlpack/bindings/julia/get_printable_type_impl.hpp
index c46e75b365..524fe62a0b 100644
--- a/src/mlpack/bindings/julia/get_printable_type_impl.hpp
+++ b/src/mlpack/bindings/julia/get_printable_type_impl.hpp
@@ -47,7 +47,7 @@ std::string GetPrintableType(
const typename std::enable_if::value>::type*)
{
if (std::is_same>::value)
- return "Array{Int64, 1}";
+ return "Array{Int, 1}";
else if (std::is_same>::value)
return "Array{String, 1}";
else
@@ -65,15 +65,15 @@ std::string GetPrintableType(
if (std::is_same::value)
return "Float64 matrix-like";
else if (std::is_same>::value)
- return "Int64 matrix-like";
+ return "Int matrix-like";
else if (std::is_same::value)
return "Float64 vector-like";
else if (std::is_same>::value)
- return "Int64 vector-like";
+ return "Int vector-like";
else if (std::is_same::value)
return "Float64 vector-like";
else if (std::is_same>::value)
- return "Int64 vector-like";
+ return "Int vector-like";
else
throw std::invalid_argument("unknown Armadillo type " + data.cppType);
}
diff --git a/src/mlpack/bindings/julia/julia_util.cpp b/src/mlpack/bindings/julia/julia_util.cpp
index 8db14179a3..faa639956f 100644
--- a/src/mlpack/bindings/julia/julia_util.cpp
+++ b/src/mlpack/bindings/julia/julia_util.cpp
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
using namespace mlpack;
@@ -82,13 +83,14 @@ void CLI_SetParamVectorStrStr(const char* paramName,
* Call CLI::SetParam>().
*/
void CLI_SetParamVectorInt(const char* paramName,
- uint64_t* ints,
+ int* ints,
const size_t length)
{
// Create a std::vector object; unfortunately this requires copying the
// vector elements.
- std::vector vec(length);
- for (size_t i = 0; i < (size_t) length; ++i)
+ std::vector vec;
+ vec.resize(length);
+ for (size_t i = 0; i < length; ++i)
vec[i] = ints[i];
CLI::GetParam>(paramName) = std::move(vec);
@@ -105,7 +107,7 @@ void CLI_SetParamMat(const char* paramName,
const bool pointsAsRows)
{
// Create the matrix as an alias.
- arma::mat m(memptr, rows, cols, false, true);
+ arma::mat m(memptr, arma::uword(rows), arma::uword(cols), false, true);
CLI::GetParam(paramName) = pointsAsRows ? m.t() : std::move(m);
CLI::SetPassed(paramName);
}
@@ -120,7 +122,8 @@ void CLI_SetParamUMat(const char* paramName,
const bool pointsAsRows)
{
// Create the matrix as an alias.
- arma::Mat m(memptr, rows, cols, false, true);
+ arma::Mat m(memptr, arma::uword(rows), arma::uword(cols), false,
+ true);
CLI::GetParam>(paramName) = pointsAsRows ? m.t() :
std::move(m);
CLI::SetPassed(paramName);
@@ -133,7 +136,7 @@ void CLI_SetParamRow(const char* paramName,
double* memptr,
const size_t cols)
{
- arma::rowvec m(memptr, cols, false, true);
+ arma::rowvec m(memptr, arma::uword(cols), false, true);
CLI::GetParam(paramName) = std::move(m);
CLI::SetPassed(paramName);
}
@@ -145,7 +148,7 @@ void CLI_SetParamURow(const char* paramName,
size_t* memptr,
const size_t cols)
{
- arma::Row m(memptr, cols, false, true);
+ arma::Row m(memptr, arma::uword(cols), false, true);
CLI::GetParam>(paramName) = std::move(m);
CLI::SetPassed(paramName);
}
@@ -157,7 +160,7 @@ void CLI_SetParamCol(const char* paramName,
double* memptr,
const size_t rows)
{
- arma::vec m(memptr, rows, false, true);
+ arma::vec m(memptr, arma::uword(rows), false, true);
CLI::GetParam(paramName) = std::move(m);
CLI::SetPassed(paramName);
}
@@ -166,10 +169,10 @@ void CLI_SetParamCol(const char* paramName,
* Call CLI::SetParam>().
*/
void CLI_SetParamUCol(const char* paramName,
- size_t* memptr,
- const size_t rows)
+ size_t* memptr,
+ const size_t rows)
{
- arma::Col m(memptr, rows, false, true);
+ arma::Col m(memptr, arma::uword(rows), false, true);
CLI::GetParam>(paramName) = std::move(m);
CLI::SetPassed(paramName);
}
@@ -191,7 +194,7 @@ void CLI_SetParamMatWithInfo(const char* paramName,
data::Datatype::numeric;
}
- arma::mat m(memptr, rows, cols, false, true);
+ arma::mat m(memptr, arma::uword(rows), arma::uword(cols), false, true);
std::get<0>(CLI::GetParam>(
paramName)) = std::move(d);
std::get<1>(CLI::GetParam>(
@@ -243,7 +246,7 @@ size_t CLI_GetParamVectorStrLen(const char* paramName)
/**
* Call CLI::GetParam>() and get the i'th string.
*/
-const char* CLI_GetParamVectorStrStr(const char* paramName, const int i)
+const char* CLI_GetParamVectorStrStr(const char* paramName, const size_t i)
{
return CLI::GetParam>(paramName)[i].c_str();
}
@@ -261,10 +264,10 @@ size_t CLI_GetParamVectorIntLen(const char* paramName)
* The vector will be created in-place and it is expected that the calling
* function will take ownership.
*/
-uint64_t* CLI_GetParamVectorIntPtr(const char* paramName)
+int* CLI_GetParamVectorIntPtr(const char* paramName)
{
const size_t size = CLI::GetParam>(paramName).size();
- uint64_t* ints = new uint64_t[size];
+ int* ints = new int[size];
for (size_t i = 0; i < size; ++i)
ints[i] = CLI::GetParam>(paramName)[i];
@@ -335,15 +338,17 @@ size_t CLI_GetParamUMatCols(const char* paramName)
*/
size_t* CLI_GetParamUMat(const char* paramName)
{
+ arma::Mat& mat = CLI::GetParam>(paramName);
+
// Are we using preallocated memory? If so we have to handle this more
// carefully.
- arma::Mat& mat = CLI::GetParam>(paramName);
if (mat.n_elem <= arma::arma_config::mat_prealloc)
{
// Copy the memory to something that we can give back to Julia.
size_t* newMem = new size_t[mat.n_elem];
arma::arrayops::copy(newMem, mat.mem, mat.n_elem);
- return newMem; // We believe Julia will free it. Hopefully we are right.
+ // We believe Julia will free it. Hopefully we are right.
+ return newMem;
}
else
{
@@ -399,15 +404,17 @@ size_t CLI_GetParamUColRows(const char* paramName)
*/
size_t* CLI_GetParamUCol(const char* paramName)
{
+ arma::Col& vec = CLI::GetParam>(paramName);
+
// Are we using preallocated memory? If so we have to handle this more
// carefully.
- arma::Col& vec = CLI::GetParam>(paramName);
if (vec.n_elem <= arma::arma_config::mat_prealloc)
{
// Copy the memory to something we can give back to Julia.
size_t* newMem = new size_t[vec.n_elem];
arma::arrayops::copy(newMem, vec.mem, vec.n_elem);
- return newMem; // We believe Julia will free it. Hopefully we are right.
+ // We believe Julia will free it. Hopefully we are right.
+ return newMem;
}
else
{
@@ -463,9 +470,10 @@ size_t CLI_GetParamURowCols(const char* paramName)
*/
size_t* CLI_GetParamURow(const char* paramName)
{
+ arma::Row& vec = CLI::GetParam>(paramName);
+
// Are we using preallocated memory? If so we have to handle this more
// carefully.
- arma::Row& vec = CLI::GetParam>(paramName);
if (vec.n_elem <= arma::arma_config::mat_prealloc)
{
// Copy the memory to something we can give back to Julia.
diff --git a/src/mlpack/bindings/julia/julia_util.h b/src/mlpack/bindings/julia/julia_util.h
index 706d363919..06ec97ad0a 100644
--- a/src/mlpack/bindings/julia/julia_util.h
+++ b/src/mlpack/bindings/julia/julia_util.h
@@ -61,7 +61,7 @@ void CLI_SetParamVectorStrStr(const char* paramName,
* Call CLI::SetParam>().
*/
void CLI_SetParamVectorInt(const char* paramName,
- uint64_t* ints,
+ int* ints,
const size_t length);
/**
@@ -149,7 +149,7 @@ size_t CLI_GetParamVectorStrLen(const char* paramName);
/**
* Call CLI::GetParam>() and get the i'th string.
*/
-const char* CLI_GetParamVectorStrStr(const char* paramName, const int i);
+const char* CLI_GetParamVectorStrStr(const char* paramName, const size_t i);
/**
* Call CLI::GetParam>() and get the length of the vector.
@@ -161,7 +161,7 @@ size_t CLI_GetParamVectorIntLen(const char* paramName);
* The vector will be created in-place and it is expected that the calling
* function will take ownership.
*/
-uint64_t* CLI_GetParamVectorIntPtr(const char* paramName);
+int* CLI_GetParamVectorIntPtr(const char* paramName);
/**
* Get the number of rows in a matrix parameter.
diff --git a/src/mlpack/bindings/julia/mlpack/REQUIRE b/src/mlpack/bindings/julia/mlpack/REQUIRE
deleted file mode 100644
index aef1ca2bd9..0000000000
--- a/src/mlpack/bindings/julia/mlpack/REQUIRE
+++ /dev/null
@@ -1 +0,0 @@
-julia 0.7.0
diff --git a/src/mlpack/bindings/julia/mlpack/cli.jl.in b/src/mlpack/bindings/julia/mlpack/cli.jl.in
index 687f532a2e..b5f7c2c0a6 100644
--- a/src/mlpack/bindings/julia/mlpack/cli.jl.in
+++ b/src/mlpack/bindings/julia/mlpack/cli.jl.in
@@ -66,8 +66,8 @@ function CLIRestoreSettings(programName::String)
end
function CLISetParam(paramName::String, paramValue::Int)
- ccall((:CLI_SetParamInt, library), Nothing, (Cstring, Int), paramName,
- paramValue);
+ ccall((:CLI_SetParamInt, library), Nothing, (Cstring, Cint), paramName,
+ Cint(paramValue));
end
function CLISetParam(paramName::String, paramValue::Float64)
@@ -89,15 +89,15 @@ function CLISetParamMat(paramName::String,
paramValue,
pointsAsRows::Bool)
paramMat = to_matrix(paramValue, Float64)
- ccall((:CLI_SetParamMat, library), Nothing, (Cstring, Ptr{Float64}, UInt64,
- UInt64, Bool), paramName, Base.pointer(paramMat), size(paramMat, 1),
+ ccall((:CLI_SetParamMat, library), Nothing, (Cstring, Ptr{Float64}, Csize_t,
+ Csize_t, Bool), paramName, Base.pointer(paramMat), size(paramMat, 1),
size(paramMat, 2), pointsAsRows);
end
function CLISetParamUMat(paramName::String,
paramValue,
pointsAsRows::Bool)
- paramMat = to_matrix(paramValue, Int64)
+ paramMat = to_matrix(paramValue, Int)
# Sanity check.
if minimum(paramMat) <= 0
@@ -105,9 +105,9 @@ function CLISetParamUMat(paramName::String,
"Must be 1 or greater."))
end
- m = convert(Array{UInt64, 2}, paramMat .- 1)
- ccall((:CLI_SetParamUMat, library), Nothing, (Cstring, Ptr{UInt64}, UInt64,
- UInt64, Bool), paramName, Base.pointer(m), size(paramValue, 1),
+ m = convert(Array{Csize_t, 2}, paramMat .- 1)
+ ccall((:CLI_SetParamUMat, library), Nothing, (Cstring, Ptr{Csize_t}, Csize_t,
+ Csize_t, Bool), paramName, Base.pointer(m), size(paramValue, 1),
size(paramValue, 2), pointsAsRows);
end
@@ -117,25 +117,26 @@ function CLISetParam(paramName::String,
# sequentially. I am not sure if this is fully necessary but I have some
# reservations about Julia's support for passing arrays of strings correctly
# as a const char**.
- ccall((:CLI_SetParamVectorStrLen, library), Nothing, (Cstring, UInt64),
+ ccall((:CLI_SetParamVectorStrLen, library), Nothing, (Cstring, Csize_t),
paramName, size(vector, 1));
for i in 1:size(vector, 1)
ccall((:CLI_SetParamVectorStrStr, library), Nothing, (Cstring, Cstring,
- UInt64), paramName, vector[i], i .- 1);
+ Csize_t), paramName, vector[i], i .- 1);
end
end
function CLISetParam(paramName::String,
- vector::Vector{Int64})
- ccall((:CLI_SetParamVectorInt, library), Nothing, (Cstring, Ptr{Int64},
- Int64), paramName, Base.pointer(vector), size(vector, 1));
+ vector::Vector{Int})
+ cint_vec = convert(Vector{Cint}, vector)
+ ccall((:CLI_SetParamVectorInt, library), Nothing, (Cstring, Ptr{Cint},
+ Csize_t), paramName, Base.pointer(cint_vec), size(cint_vec, 1));
end
function CLISetParam(paramName::String,
matWithInfo::Tuple{Array{Bool, 1}, Array{Float64, 2}},
pointsAsRows::Bool)
ccall((:CLI_SetParamMatWithInfo, library), Nothing, (Cstring, Ptr{Bool},
- Ptr{Float64}, Int64, Int64, Bool), paramName,
+ Ptr{Float64}, Int, Int, Bool), paramName,
Base.pointer(matWithInfo[1]), Base.pointer(matWithInfo[2]),
size(matWithInfo[2], 1), size(matWithInfo[2], 2), pointsAsRows);
end
@@ -143,44 +144,44 @@ end
function CLISetParamRow(paramName::String,
paramValue)
paramVec = to_vector(paramValue, Float64)
- ccall((:CLI_SetParamRow, library), Nothing, (Cstring, Ptr{Float64}, UInt64),
+ ccall((:CLI_SetParamRow, library), Nothing, (Cstring, Ptr{Float64}, Csize_t),
paramName, Base.pointer(paramVec), size(paramVec, 1));
end
function CLISetParamCol(paramName::String,
paramValue)
paramVec = to_vector(paramValue, Float64)
- ccall((:CLI_SetParamCol, library), Nothing, (Cstring, Ptr{Float64}, UInt64),
+ ccall((:CLI_SetParamCol, library), Nothing, (Cstring, Ptr{Float64}, Csize_t),
paramName, Base.pointer(paramVec), size(paramVec, 1));
end
function CLISetParamURow(paramName::String,
paramValue)
- paramVec = to_vector(paramValue, Int64)
+ paramVec = to_vector(paramValue, Int)
# Sanity check.
if minimum(paramVec) <= 0
throw(DomainError("Input $(paramName) cannot have 0 or negative values! " *
"Must be 1 or greater."))
end
- m = convert(Array{UInt64, 1}, paramVec .- 1)
+ m = convert(Array{Csize_t, 1}, paramVec .- 1)
- ccall((:CLI_SetParamURow, library), Nothing, (Cstring, Ptr{UInt64}, UInt64),
+ ccall((:CLI_SetParamURow, library), Nothing, (Cstring, Ptr{Csize_t}, Csize_t),
paramName, Base.pointer(m), size(paramValue, 1));
end
function CLISetParamUCol(paramName::String,
paramValue)
- paramVec = to_vector(paramValue, Int64)
+ paramVec = to_vector(paramValue, Int)
# Sanity check.
if minimum(paramVec) <= 0
throw(DomainError("Input $(paramName) cannot have 0 or negative values! " *
"Must be 1 or greater."))
end
- m = convert(Array{UInt64, 1}, paramValue .- 1)
+ m = convert(Array{Csize_t, 1}, paramValue .- 1)
- ccall((:CLI_SetParamUCol, library), Nothing, (Cstring, Ptr{UInt64}, UInt64),
+ ccall((:CLI_SetParamUCol, library), Nothing, (Cstring, Ptr{Csize_t}, Csize_t),
paramName, Base.pointer(m), size(paramValue, 1));
end
@@ -189,7 +190,7 @@ function CLIGetParamBool(paramName::String)
end
function CLIGetParamInt(paramName::String)
- return ccall((:CLI_GetParamInt, library), Int64, (Cstring,), paramName)
+ return Int(ccall((:CLI_GetParamInt, library), Cint, (Cstring,), paramName))
end
function CLIGetParamDouble(paramName::String)
@@ -201,15 +202,15 @@ function CLIGetParamString(paramName::String)
end
function CLIGetParamVectorStr(paramName::String)
- local size::UInt64
+ local size::Csize_t
local ptr::Ptr{String}
# Get the size of the vector, then each element.
- size = ccall((:CLI_GetParamVectorStrLen, library), UInt64, (Cstring,),
+ size = ccall((:CLI_GetParamVectorStrLen, library), Csize_t, (Cstring,),
paramName);
out = Array{String, 1}()
for i = 1:size
- s = ccall((:CLI_GetParamVectorStrStr, library), Cstring, (Cstring, UInt64),
+ s = ccall((:CLI_GetParamVectorStrStr, library), Cstring, (Cstring, Csize_t),
paramName, i .- 1)
push!(out, Base.unsafe_string(s))
end
@@ -218,28 +219,29 @@ function CLIGetParamVectorStr(paramName::String)
end
function CLIGetParamVectorInt(paramName::String)
- local size::UInt64
- local ptr::Ptr{Int64}
+ local size::Csize_t
+ local ptr::Ptr{Cint}
# Get the size of the vector, then the pointer to it. We will own the
# pointer.
- size = ccall((:CLI_GetParamVectorIntLen, library), UInt64, (Cstring,),
+ size = ccall((:CLI_GetParamVectorIntLen, library), Csize_t, (Cstring,),
paramName);
- ptr = ccall((:CLI_GetParamVectorIntPtr, library), Ptr{Int64}, (Cstring,),
+ ptr = ccall((:CLI_GetParamVectorIntPtr, library), Ptr{Cint}, (Cstring,),
paramName);
- return Base.unsafe_wrap(Array{Int64, 1}, ptr, (size), own=true)
+ return convert(Array{Int, 1}, Base.unsafe_wrap(Array{Cint, 1}, ptr, (size),
+ own=true))
end
function CLIGetParamMat(paramName::String, pointsAsRows::Bool)
# Can we return different return types? For now let's restrict to a matrix to
# make it easy...
local ptr::Ptr{Float64}
- local rows::UInt64, cols::UInt64;
+ local rows::Csize_t, cols::Csize_t;
# I suppose it would be possible to do this all in one call, but this seems
# easy enough.
- rows = ccall((:CLI_GetParamMatRows, library), UInt64, (Cstring,), paramName);
- cols = ccall((:CLI_GetParamMatCols, library), UInt64, (Cstring,), paramName);
+ rows = ccall((:CLI_GetParamMatRows, library), Csize_t, (Cstring,), paramName);
+ cols = ccall((:CLI_GetParamMatCols, library), Csize_t, (Cstring,), paramName);
ptr = ccall((:CLI_GetParamMat, library), Ptr{Float64}, (Cstring,), paramName);
if pointsAsRows
@@ -255,30 +257,30 @@ end
function CLIGetParamUMat(paramName::String, pointsAsRows::Bool)
# Can we return different return types? For now let's restrict to a matrix to
# make it easy...
- local ptr::Ptr{UInt64}
- local rows::UInt64, cols::UInt64;
+ local ptr::Ptr{Csize_t}
+ local rows::Csize_t, cols::Csize_t;
# I suppose it would be possible to do this all in one call, but this seems
# easy enough.
- rows = ccall((:CLI_GetParamUMatRows, library), UInt64, (Cstring,), paramName);
- cols = ccall((:CLI_GetParamUMatCols, library), UInt64, (Cstring,), paramName);
- ptr = ccall((:CLI_GetParamUMat, library), Ptr{UInt64}, (Cstring,), paramName);
+ rows = ccall((:CLI_GetParamUMatRows, library), Csize_t, (Cstring,), paramName);
+ cols = ccall((:CLI_GetParamUMatCols, library), Csize_t, (Cstring,), paramName);
+ ptr = ccall((:CLI_GetParamUMat, library), Ptr{Csize_t}, (Cstring,), paramName);
if pointsAsRows
# In this case we have to transpose, unfortunately.
- m = Base.unsafe_wrap(Array{UInt64, 2}, ptr, (rows, cols), own=true);
- return convert(Array{Int64, 2}, m' .+ 1) # Add 1 because these are indexes.
+ m = Base.unsafe_wrap(Array{Csize_t, 2}, ptr, (rows, cols), own=true);
+ return convert(Array{Int, 2}, m' .+ 1) # Add 1 because these are indexes.
else
# Here no transpose is necessary.
- m = Base.unsafe_wrap(Array{UInt64, 2}, ptr, (rows, cols), own=true);
- return convert(Array{Int64, 2}, m .+ 1)
+ m = Base.unsafe_wrap(Array{Csize_t, 2}, ptr, (rows, cols), own=true);
+ return convert(Array{Int, 2}, m .+ 1)
end
end
function CLIGetParamCol(paramName::String)
local ptr::Ptr{Float64};
- local rows::UInt64;
+ local rows::Csize_t;
- rows = ccall((:CLI_GetParamColRows, library), UInt64, (Cstring,), paramName);
+ rows = ccall((:CLI_GetParamColRows, library), Csize_t, (Cstring,), paramName);
ptr = ccall((:CLI_GetParamCol, library), Ptr{Float64}, (Cstring,), paramName);
return Base.unsafe_wrap(Array{Float64, 1}, ptr, rows, own=true);
@@ -286,45 +288,45 @@ end
function CLIGetParamRow(paramName::String)
local ptr::Ptr{Float64};
- local cols::UInt64;
+ local cols::Csize_t;
- cols = ccall((:CLI_GetParamRowCols, library), UInt64, (Cstring,), paramName);
+ cols = ccall((:CLI_GetParamRowCols, library), Csize_t, (Cstring,), paramName);
ptr = ccall((:CLI_GetParamRow, library), Ptr{Float64}, (Cstring,), paramName);
return Base.unsafe_wrap(Array{Float64, 1}, ptr, cols, own=true);
end
function CLIGetParamUCol(paramName::String)
- local ptr::Ptr{UInt64};
- local rows::UInt64;
+ local ptr::Ptr{Csize_t};
+ local rows::Csize_t;
- rows = ccall((:CLI_GetParamUColRows, library), UInt64, (Cstring,), paramName);
- ptr = ccall((:CLI_GetParamUCol, library), Ptr{UInt64}, (Cstring,), paramName);
+ rows = ccall((:CLI_GetParamUColRows, library), Csize_t, (Cstring,), paramName);
+ ptr = ccall((:CLI_GetParamUCol, library), Ptr{Csize_t}, (Cstring,), paramName);
- m = Base.unsafe_wrap(Array{UInt64, 1}, ptr, rows, own=true);
- return convert(Array{Int64, 1}, m .+ 1)
+ m = Base.unsafe_wrap(Array{Csize_t, 1}, ptr, rows, own=true);
+ return convert(Array{Int, 1}, m .+ 1)
end
function CLIGetParamURow(paramName::String)
- local ptr::Ptr{UInt64};
- local cols::UInt64;
+ local ptr::Ptr{Csize_t};
+ local cols::Csize_t;
- cols = ccall((:CLI_GetParamURowCols, library), UInt64, (Cstring,), paramName);
- ptr = ccall((:CLI_GetParamURow, library), Ptr{UInt64}, (Cstring,), paramName);
+ cols = ccall((:CLI_GetParamURowCols, library), Csize_t, (Cstring,), paramName);
+ ptr = ccall((:CLI_GetParamURow, library), Ptr{Csize_t}, (Cstring,), paramName);
- m = Base.unsafe_wrap(Array{UInt64, 1}, ptr, cols, own=true);
- return convert(Array{Int64, 1}, m .+ 1)
+ m = Base.unsafe_wrap(Array{Csize_t, 1}, ptr, cols, own=true);
+ return convert(Array{Int, 1}, m .+ 1)
end
function CLIGetParamMatWithInfo(paramName::String, pointsAsRows::Bool)
local ptrBool::Ptr{Bool};
local ptrData::Ptr{Float64};
- local rows::UInt64;
- local cols::UInt64;
+ local rows::Csize_t;
+ local cols::Csize_t;
- rows = ccall((:CLI_GetParamMatWithInfoRows, library), UInt64, (Cstring,),
+ rows = ccall((:CLI_GetParamMatWithInfoRows, library), Csize_t, (Cstring,),
paramName);
- cols = ccall((:CLI_GetParamMatWithInfoCols, library), UInt64, (Cstring,),
+ cols = ccall((:CLI_GetParamMatWithInfoCols, library), Csize_t, (Cstring,),
paramName);
ptrBool = ccall((:CLI_GetParamMatWithInfoBoolPtr, library), Ptr{Bool},
(Cstring,), paramName);
diff --git a/src/mlpack/bindings/julia/mlpack/mlpack.jl.in b/src/mlpack/bindings/julia/mlpack/mlpack.jl.in
new file mode 100644
index 0000000000..b2368ecb75
--- /dev/null
+++ b/src/mlpack/bindings/julia/mlpack/mlpack.jl.in
@@ -0,0 +1,30 @@
+"""
+ mlpack
+
+mlpack is a fast, flexible machine learning library, written in C++, that aims
+to provide fast, extensible implementations of cutting-edge machine learning
+algorithms. This module provides those implementations as Julia functions.
+
+Each function inside the module performs a specific machine learning task.
+
+For complete documentation of these functions, including example usage, see the
+mlpack website's documentation for the Julia bindings:
+
+https://www.mlpack.org/doc/stable/julia_documentation.html
+
+Each function also contains an equivalent docstring; the Julia REPL's help
+functionality can be used to access the documentation that way.
+"""
+module mlpack
+
+"""
+ mlpack._Internal
+
+This module contains internal implementations details of mlpack. There
+shouldn't be any need to go digging around in here if you're just using mlpack.
+(But don't let this comment discourage you if you're just curious and poking
+around!)
+"""
+module _Internal
+
+include("cli.jl")
diff --git a/src/mlpack/bindings/julia/print_doc_functions_impl.hpp b/src/mlpack/bindings/julia/print_doc_functions_impl.hpp
index c428b5986a..8fb2534f72 100644
--- a/src/mlpack/bindings/julia/print_doc_functions_impl.hpp
+++ b/src/mlpack/bindings/julia/print_doc_functions_impl.hpp
@@ -124,7 +124,7 @@ inline std::string CreateInputArguments(const std::string& paramName,
d.cppType == "arma::Col")
{
oss << "julia> " << value << " = CSV.read(\"" << value
- << ".csv\"; type=Int64)" << std::endl;
+ << ".csv\"; type=Int)" << std::endl;
}
}
@@ -375,6 +375,9 @@ inline std::string ProgramCall(const std::string& programName, Args... args)
{
std::ostringstream oss;
+ // The code should appear in a Markdown code block.
+ oss << "```julia" << std::endl;
+
// Print any input argument definitions. The only input argument definitions
// will be the definitions of matrices, which use the CSV.jl package, so we
// should also include a `using CSV` in there too.
@@ -401,6 +404,9 @@ inline std::string ProgramCall(const std::string& programName, Args... args)
// Since `julia> ` is 8 characters, let's indent 12 otherwise it looks weird.
oss << util::HyphenateString(ossCall.str(), 12);
+ // Close the Markdown code block.
+ oss << std::endl << "```";
+
return oss.str();
}
diff --git a/src/mlpack/bindings/julia/print_jl.cpp b/src/mlpack/bindings/julia/print_jl.cpp
index 939b606386..7f4fb86a02 100644
--- a/src/mlpack/bindings/julia/print_jl.cpp
+++ b/src/mlpack/bindings/julia/print_jl.cpp
@@ -62,7 +62,7 @@ void PrintJL(const util::ProgramDoc& programInfo,
cout << endl;
// We need to include utility functions.
- cout << "using mlpack.util.cli" << endl;
+ cout << "using mlpack._Internal.cli" << endl;
cout << endl;
// Make sure the libraries we need are accessible.
diff --git a/src/mlpack/bindings/julia/print_type_doc_impl.hpp b/src/mlpack/bindings/julia/print_type_doc_impl.hpp
index 9e81099bfd..e6522d36d2 100644
--- a/src/mlpack/bindings/julia/print_type_doc_impl.hpp
+++ b/src/mlpack/bindings/julia/print_type_doc_impl.hpp
@@ -109,15 +109,15 @@ std::string PrintTypeDoc(
if (T::is_col || T::is_row)
{
return "A 1-d vector-like containing `Int` data (elements should be "
- "greater than or equal to 0). Could be an `Array{Int64, 1}`, an "
- "`Array{Int64, 2}` with one dimension of size 1, or anything "
- "convertible to `Array{Int64, 1}`.";
+ "greater than or equal to 0). Could be an `Array{Int, 1}`, an "
+ "`Array{Int, 2}` with one dimension of size 1, or anything "
+ "convertible to `Array{Int, 1}`.";
}
else
{
return "A 2-d matrix-like containing `Int` data (elements should be "
- "greater than or equal to 0). Could be an `Array{Int64, 2}` or a "
- "`DataFrame` or anything convertible to an `Array{Int64, 2}`. It is "
+ "greater than or equal to 0). Could be an `Array{Int, 2}` or a "
+ "`DataFrame` or anything convertible to an `Array{Int, 2}`. It is "
"expected that each row of the matrix corresponds to a data point, "
"unless `points_are_rows` is set to `false` when calling mlpack "
"bindings.";
diff --git a/src/mlpack/bindings/julia/tests/runtests.jl b/src/mlpack/bindings/julia/tests/runtests.jl
index 616a0c2804..7a859063a0 100644
--- a/src/mlpack/bindings/julia/tests/runtests.jl
+++ b/src/mlpack/bindings/julia/tests/runtests.jl
@@ -129,7 +129,7 @@ end
# Same as TestMatrix but with an unsigned matrix.
@testset "TestUMatrix" begin
# Generate a random matrix of integers.
- x = convert(Array{Int64, 2}, rand(1:500, (100, 5)))
+ x = convert(Array{Int, 2}, rand(1:500, (100, 5)))
_, _, _, _, _, _, _, _, _, _, _, umatOut, _, _ =
test_julia_binding(4.0, 12, "hello",
@@ -138,7 +138,7 @@ end
@test size(umatOut, 1) == 100
@test size(umatOut, 2) == 4
- @test typeof(umatOut[1, 1]) == Int64
+ @test typeof(umatOut[1, 1]) == Int
for i in [0, 1, 3]
for j in 1:100
@test umatOut[j, i + 1] == x[j, i + 1]
@@ -155,7 +155,7 @@ end
# Same as TestMatrix but with an unsigned column major matrix.
@testset "TestUMatrixColMajor" begin
# Generate a random matrix of integers.
- x = convert(Array{Int64, 2}, rand(1:500, (5, 100)))
+ x = convert(Array{Int, 2}, rand(1:500, (5, 100)))
_, _, _, _, _, _, _, _, _, _, _, umatOut, _, _ =
test_julia_binding(4.0, 12, "hello",
@@ -164,7 +164,7 @@ end
@test size(umatOut, 1) == 4
@test size(umatOut, 2) == 100
- @test typeof(umatOut[1, 1]) == Int64
+ @test typeof(umatOut[1, 1]) == Int
for i in 1:100
for j in [0, 1, 3]
@test umatOut[j + 1, i] == x[j + 1, i]
@@ -196,14 +196,14 @@ end
# Test an unsigned column vector input parameter.
@testset "TestUCol" begin
- x = convert(Array{Int64, 1}, rand(1:500, 100))
+ x = convert(Array{Int, 1}, rand(1:500, 100))
_, _, _, _, _, _, _, _, _, _, ucolOut, _, _, _ =
test_julia_binding(4.0, 12, "hello",
ucol_in=x)
@test size(ucolOut, 1) == 100
- @test typeof(ucolOut) == Array{Int64, 1}
+ @test typeof(ucolOut) == Array{Int, 1}
for i in 1:100
# Since we subtract one when we convert to C++, and then add one when we
# convert back, we get a slightly different result here.
@@ -228,14 +228,14 @@ end
# Test an unsigned row vector input parameter.
@testset "TestURow" begin
- x = convert(Array{Int64, 1}, rand(1:500, 100))
+ x = convert(Array{Int, 1}, rand(1:500, 100))
_, _, _, _, _, _, _, _, _, _, _, _, urowOut, _ =
test_julia_binding(4.0, 12, "hello",
urow_in=x)
@test size(urowOut, 1) == 100
- @test typeof(urowOut) == Array{Int64, 1}
+ @test typeof(urowOut) == Array{Int, 1}
for i in 1:100
# Since we subtract one when we convert to C++, and then add one when we
# convert back, we get a slightly different result here.
diff --git a/src/mlpack/bindings/markdown/print_doc_functions_impl.hpp b/src/mlpack/bindings/markdown/print_doc_functions_impl.hpp
index 28e0fbea6d..0e9da65798 100644
--- a/src/mlpack/bindings/markdown/print_doc_functions_impl.hpp
+++ b/src/mlpack/bindings/markdown/print_doc_functions_impl.hpp
@@ -451,20 +451,21 @@ inline std::string PrintModel(const std::string& model)
template
std::string ProgramCall(const std::string& programName, Args... args)
{
- std::string s = "```";
+ std::string s;
if (BindingInfo::Language() == "cli")
{
- s += "bash\n";
+ s += "```bash\n";
s += cli::ProgramCall(programName, args...);
}
else if (BindingInfo::Language() == "python")
{
- s += "python\n";
+ s += "```python\n";
s += python::ProgramCall(programName, args...);
}
else if (BindingInfo::Language() == "julia")
{
- s += "julia\n";
+ // Julia's ProgramCall() with a set of arguments will automatically enclose
+ // the text in Markdown code, so we don't need to.
s += julia::ProgramCall(programName, args...);
}
else
@@ -472,7 +473,10 @@ std::string ProgramCall(const std::string& programName, Args... args)
throw std::invalid_argument("ProgramCall(): unknown "
"BindingInfo::Language(): " + BindingInfo::Language() + "!");
}
- s += "\n```";
+
+ // Close the Markdown code block, but only if we opened one.
+ if (BindingInfo::Language() != "julia")
+ s += "\n```";
return s;
}
diff --git a/src/mlpack/bindings/markdown/print_docs.cpp b/src/mlpack/bindings/markdown/print_docs.cpp
index 8b464baa1e..2ebb67b8bd 100644
--- a/src/mlpack/bindings/markdown/print_docs.cpp
+++ b/src/mlpack/bindings/markdown/print_docs.cpp
@@ -126,7 +126,8 @@ void PrintDocs(const std::string& bindingName,
cout << "| ";
cout << ParamString(it->second.name) << " | ";
cout << ParamType(it->second) << " | ";
- cout << it->second.desc; // just a string
+ string desc = boost::replace_all_copy(it->second.desc, "|", "\\|");
+ cout << desc; // just a string
// Print whether or not it's a "special" language-only parameter.
if (it->second.name == "copy_all_inputs" || it->second.name == "help" ||
it->second.name == "info" || it->second.name == "version")
@@ -180,7 +181,9 @@ void PrintDocs(const std::string& bindingName,
cout << "{: #" << languages[i] << "_" << bindingName
<< "_detailed-documentation }" << endl;
cout << endl;
- cout << programDoc.documentation() << endl;
+ string doc = boost::replace_all_copy(programDoc.documentation(),
+ "|", "\\|");
+ cout << doc << endl;
cout << endl;
cout << "### See also" << endl;
diff --git a/src/mlpack/core/arma_extend/Cube_extra_meat.hpp b/src/mlpack/core/arma_extend/Cube_extra_meat.hpp
index a2ebd94cb4..3f33bb59d8 100644
--- a/src/mlpack/core/arma_extend/Cube_extra_meat.hpp
+++ b/src/mlpack/core/arma_extend/Cube_extra_meat.hpp
@@ -19,6 +19,9 @@ void Cube::serialize(Archive& ar, const unsigned int /* version */)
// mem_state will always be 0 on load, so we don't need to save it.
if (Archive::is_loading::value)
{
+ // Clean any mat pointers.
+ delete_mat();
+
// Don't free if local memory is being used.
if (mem_state == 0 && mem != NULL && old_n_elem > arma_config::mat_prealloc)
{
diff --git a/src/mlpack/core/arma_extend/arma_extend.hpp b/src/mlpack/core/arma_extend/arma_extend.hpp
index e323b993ea..ba47c1f190 100644
--- a/src/mlpack/core/arma_extend/arma_extend.hpp
+++ b/src/mlpack/core/arma_extend/arma_extend.hpp
@@ -36,6 +36,12 @@
#endif
#endif
+// Force definition of old HDF5 API. Thanks to Mike Roberts for helping find
+// this workaround.
+#if !defined(H5_USE_110_API)
+ #define H5_USE_110_API
+#endif
+
// Include everything we'll need for serialize().
#include
#include
diff --git a/src/mlpack/core/boost_backport/CMakeLists.txt b/src/mlpack/core/boost_backport/CMakeLists.txt
index c2b15d5120..5edfe13cab 100644
--- a/src/mlpack/core/boost_backport/CMakeLists.txt
+++ b/src/mlpack/core/boost_backport/CMakeLists.txt
@@ -2,18 +2,14 @@
# Anything not in this list will not be compiled into mlpack.
set(SOURCES
bernoulli.hpp
- boost_backport_math.hpp
boost_backport_serialization.hpp
detail/bernoulli_details.hpp
detail/polygamma.hpp
detail/unchecked_bernoulli.hpp
math_fwd.hpp
policy.hpp
- polygamma.hpp
- trigamma.hpp
unordered_collections_load_imp.hpp
unordered_collections_save_imp.hpp
- unordered_map.hpp
vector.hpp
string_view.hpp
string_view_fwd.hpp
diff --git a/src/mlpack/core/boost_backport/boost_backport_math.hpp b/src/mlpack/core/boost_backport/boost_backport_math.hpp
deleted file mode 100644
index f3d7f3cc32..0000000000
--- a/src/mlpack/core/boost_backport/boost_backport_math.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @file boost_backport.hpp
- * @author Yannis Mentekidis
- *
- * Centralized control of what boost files to include. We have backported the
- * following boost functionality here:
- *
- * * trigamma and polygamma function evaluation (added in boost 1.58.0)
- *
- * For versions 1.56, 1.57 we include the backported polygamma and trigamma
- * functions. Anything newer, we include from Boost.
- */
-#ifndef MLPACK_CORE_BOOST_BACKPORT_MATH_HPP
-#define MLPACK_CORE_BOOST_BACKPORT_MATH_HPP
-
-#include
-
-#if BOOST_VERSION < 105800
- // Backported trigamma and polygamma.
- #include "mlpack/core/boost_backport/trigamma.hpp"
- #include "mlpack/core/boost_backport/polygamma.hpp"
-#else
- // Boost's version.
- #include
- #include
-#endif
-
-#endif // MLPACK_CORE_BOOST_BACKPORT_HPP
-
diff --git a/src/mlpack/core/boost_backport/boost_backport_serialization.hpp b/src/mlpack/core/boost_backport/boost_backport_serialization.hpp
index 173761f5f7..2b6c2cdd03 100644
--- a/src/mlpack/core/boost_backport/boost_backport_serialization.hpp
+++ b/src/mlpack/core/boost_backport/boost_backport_serialization.hpp
@@ -16,14 +16,7 @@
#define MLPACK_CORE_BOOST_BACKPORT_SERIALIZATION_HPP
#include
-
-#if BOOST_VERSION < 105600
- // Backported unordered_map.
- #include "mlpack/core/boost_backport/unordered_map.hpp"
-#else
- // Boost's version.
- #include
-#endif
+#include
#if BOOST_VERSION == 105800
/**
diff --git a/src/mlpack/core/boost_backport/polygamma.hpp b/src/mlpack/core/boost_backport/polygamma.hpp
deleted file mode 100644
index 3ff77836b3..0000000000
--- a/src/mlpack/core/boost_backport/polygamma.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-
-///////////////////////////////////////////////////////////////////////////////
-// Copyright 2013 Nikhar Agrawal
-// Copyright 2013 Christopher Kormanyos
-// Copyright 2014 John Maddock
-// Copyright 2013 Paul Bristow
-// Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef _BOOST_POLYGAMMA_2013_07_30_HPP_
- #define _BOOST_POLYGAMMA_2013_07_30_HPP_
-
-#include "detail/polygamma.hpp"
-#include "trigamma.hpp"
-#include
-
-// Forward declarations
-namespace boost { namespace math {
- template
- inline typename tools::promote_args::type
- trigamma(T x, const Policy&);
-
- template
- inline typename tools::promote_args::type
- trigamma(T x);
-}}
-
-namespace boost { namespace math {
-
-
- template
- inline typename tools::promote_args::type polygamma(const int n, T x, const Policy& pol)
- {
- //
- // Filter off special cases right at the start:
- //
- if(n == 0)
- return boost::math::digamma(x, pol);
- if(n == 1)
- return boost::math::trigamma(x, pol);
- //
- // We've found some standard library functions to misbehave if any FPU exception flags
- // are set prior to their call, this code will clear those flags, then reset them
- // on exit:
- //
- BOOST_FPU_EXCEPTION_GUARD
- //
- // The type of the result - the common type of T and U after
- // any integer types have been promoted to double:
- //
- typedef typename tools::promote_args::type result_type;
- //
- // The type used for the calculation. This may be a wider type than
- // the result in order to ensure full precision:
- //
- typedef typename policies::evaluation::type value_type;
- //
- // The type of the policy to forward to the actual implementation.
- // We disable promotion of float and double as that's [possibly]
- // happened already in the line above. Also reset to the default
- // any policies we don't use (reduces code bloat if we're called
- // multiple times with differing policies we don't actually use).
- // Also normalise the type, again to reduce code bloat in case we're
- // called multiple times with functionally identical policies that happen
- // to be different types.
- //
- typedef typename policies::normalise<
- Policy,
- policies::promote_float,
- policies::promote_double,
- policies::discrete_quantile<>,
- policies::assert_undefined<> >::type forwarding_policy;
- //
- // Whew. Now we can make the actual call to the implementation.
- // Arguments are explicitly cast to the evaluation type, and the result
- // passed through checked_narrowing_cast which handles things like overflow
- // according to the policy passed:
- //
- return policies::checked_narrowing_cast(
- detail::polygamma_imp(n, static_cast(x), forwarding_policy()),
- "boost::math::polygamma<%1%>(int, %1%)");
- }
-
- template
- inline typename tools::promote_args::type polygamma(const int n, T x)
- {
- return boost::math::polygamma(n, x, policies::policy<>());
- }
-
-} } // namespace boost::math
-
-#endif // _BOOST_BERNOULLI_2013_05_30_HPP_
-
diff --git a/src/mlpack/core/boost_backport/trigamma.hpp b/src/mlpack/core/boost_backport/trigamma.hpp
deleted file mode 100644
index ebf435289e..0000000000
--- a/src/mlpack/core/boost_backport/trigamma.hpp
+++ /dev/null
@@ -1,469 +0,0 @@
-// (C) Copyright John Maddock 2006.
-// Use, modification and distribution are subject to the
-// Boost Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_MATH_SF_TRIGAMMA_HPP
-#define BOOST_MATH_SF_TRIGAMMA_HPP
-
-#ifdef _MSC_VER
-#pragma once
-#endif
-
-#include "math_fwd.hpp"
-#include "polygamma.hpp"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace boost{
-namespace math{
-namespace detail{
-
-template
-T polygamma_imp(const int n, T x, const Policy &pol);
-
-template
-T trigamma_prec(T x, const mpl::int_<53>*, const Policy&)
-{
- // Max error in interpolated form: 3.736e-017
- static const T offset = BOOST_MATH_BIG_CONSTANT(T, 53, 2.1093254089355469);
- static const T P_1_2[] = {
- BOOST_MATH_BIG_CONSTANT(T, 53, -1.1093280605946045),
- BOOST_MATH_BIG_CONSTANT(T, 53, -3.8310674472619321),
- BOOST_MATH_BIG_CONSTANT(T, 53, -3.3703848401898283),
- BOOST_MATH_BIG_CONSTANT(T, 53, 0.28080574467981213),
- BOOST_MATH_BIG_CONSTANT(T, 53, 1.6638069578676164),
- BOOST_MATH_BIG_CONSTANT(T, 53, 0.64468386819102836),
- };
- static const T Q_1_2[] = {
- BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 53, 3.4535389668541151),
- BOOST_MATH_BIG_CONSTANT(T, 53, 4.5208926987851437),
- BOOST_MATH_BIG_CONSTANT(T, 53, 2.7012734178351534),
- BOOST_MATH_BIG_CONSTANT(T, 53, 0.64468798399785611),
- BOOST_MATH_BIG_CONSTANT(T, 53, -0.20314516859987728e-6),
- };
- // Max error in interpolated form: 1.159e-017
- static const T P_2_4[] = {
- BOOST_MATH_BIG_CONSTANT(T, 53, -0.13803835004508849e-7),
- BOOST_MATH_BIG_CONSTANT(T, 53, 0.50000049158540261),
- BOOST_MATH_BIG_CONSTANT(T, 53, 1.6077979838469348),
- BOOST_MATH_BIG_CONSTANT(T, 53, 2.5645435828098254),
- BOOST_MATH_BIG_CONSTANT(T, 53, 2.0534873203680393),
- BOOST_MATH_BIG_CONSTANT(T, 53, 0.74566981111565923),
- };
- static const T Q_2_4[] = {
- BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 53, 2.8822787662376169),
- BOOST_MATH_BIG_CONSTANT(T, 53, 4.1681660554090917),
- BOOST_MATH_BIG_CONSTANT(T, 53, 2.7853527819234466),
- BOOST_MATH_BIG_CONSTANT(T, 53, 0.74967671848044792),
- BOOST_MATH_BIG_CONSTANT(T, 53, -0.00057069112416246805),
- };
- // Maximum Deviation Found: 6.896e-018
- // Expected Error Term : -6.895e-018
- // Maximum Relative Change in Control Points : 8.497e-004
- static const T P_4_inf[] = {
- static_cast(0.68947581948701249e-17L),
- static_cast(0.49999999999998975L),
- static_cast(1.0177274392923795L),
- static_cast(2.498208511343429L),
- static_cast(2.1921221359427595L),
- static_cast(1.5897035272532764L),
- static_cast(0.40154388356961734L),
- };
- static const T Q_4_inf[] = {
- static_cast(1.0L),
- static_cast(1.7021215452463932L),
- static_cast(4.4290431747556469L),
- static_cast(2.9745631894384922L),
- static_cast(2.3013614809773616L),
- static_cast(0.28360399799075752L),
- static_cast(0.022892987908906897L),
- };
-
- if(x <= 2)
- {
- return (offset + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x);
- }
- else if(x <= 4)
- {
- T y = 1 / x;
- return (1 + tools::evaluate_polynomial(P_2_4, y) / tools::evaluate_polynomial(Q_2_4, y)) / x;
- }
- T y = 1 / x;
- return (1 + tools::evaluate_polynomial(P_4_inf, y) / tools::evaluate_polynomial(Q_4_inf, y)) / x;
-}
-
-template
-T trigamma_prec(T x, const mpl::int_<64>*, const Policy&)
-{
- // Max error in interpolated form: 1.178e-020
- static const T offset_1_2 = BOOST_MATH_BIG_CONSTANT(T, 64, 2.109325408935546875);
- static const T P_1_2[] = {
- BOOST_MATH_BIG_CONSTANT(T, 64, -1.10932535608960258341),
- BOOST_MATH_BIG_CONSTANT(T, 64, -4.18793841543017129052),
- BOOST_MATH_BIG_CONSTANT(T, 64, -4.63865531898487734531),
- BOOST_MATH_BIG_CONSTANT(T, 64, -0.919832884430500908047),
- BOOST_MATH_BIG_CONSTANT(T, 64, 1.68074038333180423012),
- BOOST_MATH_BIG_CONSTANT(T, 64, 1.21172611429185622377),
- BOOST_MATH_BIG_CONSTANT(T, 64, 0.259635673503366427284),
- };
- static const T Q_1_2[] = {
- BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 64, 3.77521119359546982995),
- BOOST_MATH_BIG_CONSTANT(T, 64, 5.664338024578956321),
- BOOST_MATH_BIG_CONSTANT(T, 64, 4.25995134879278028361),
- BOOST_MATH_BIG_CONSTANT(T, 64, 1.62956638448940402182),
- BOOST_MATH_BIG_CONSTANT(T, 64, 0.259635512844691089868),
- BOOST_MATH_BIG_CONSTANT(T, 64, 0.629642219810618032207e-8),
- };
- // Max error in interpolated form: 3.912e-020
- static const T P_2_8[] = {
- BOOST_MATH_BIG_CONSTANT(T, 64, -0.387540035162952880976e-11),
- BOOST_MATH_BIG_CONSTANT(T, 64, 0.500000000276430504),
- BOOST_MATH_BIG_CONSTANT(T, 64, 3.21926880986360957306),
- BOOST_MATH_BIG_CONSTANT(T, 64, 10.2550347708483445775),
- BOOST_MATH_BIG_CONSTANT(T, 64, 18.9002075150709144043),
- BOOST_MATH_BIG_CONSTANT(T, 64, 21.0357215832399705625),
- BOOST_MATH_BIG_CONSTANT(T, 64, 13.4346512182925923978),
- BOOST_MATH_BIG_CONSTANT(T, 64, 3.98656291026448279118),
- };
- static const T Q_2_8[] = {
- BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 64, 6.10520430478613667724),
- BOOST_MATH_BIG_CONSTANT(T, 64, 18.475001060603645512),
- BOOST_MATH_BIG_CONSTANT(T, 64, 31.7087534567758405638),
- BOOST_MATH_BIG_CONSTANT(T, 64, 31.908814523890465398),
- BOOST_MATH_BIG_CONSTANT(T, 64, 17.4175479039227084798),
- BOOST_MATH_BIG_CONSTANT(T, 64, 3.98749106958394941276),
- BOOST_MATH_BIG_CONSTANT(T, 64, -0.000115917322224411128566),
- };
- // Maximum Deviation Found: 2.635e-020
- // Expected Error Term : 2.635e-020
- // Maximum Relative Change in Control Points : 1.791e-003
- static const T P_8_inf[] = {
- BOOST_MATH_BIG_CONSTANT(T, 64, -0.263527875092466899848e-19),
- BOOST_MATH_BIG_CONSTANT(T, 64, 0.500000000000000058145),
- BOOST_MATH_BIG_CONSTANT(T, 64, 0.0730121433777364138677),
- BOOST_MATH_BIG_CONSTANT(T, 64, 1.94505878379957149534),
- BOOST_MATH_BIG_CONSTANT(T, 64, 0.0517092358874932620529),
- BOOST_MATH_BIG_CONSTANT(T, 64, 1.07995383547483921121),
- };
- static const T Q_8_inf[] = {
- BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 64, -0.187309046577818095504),
- BOOST_MATH_BIG_CONSTANT(T, 64, 3.95255391645238842975),
- BOOST_MATH_BIG_CONSTANT(T, 64, -1.14743283327078949087),
- BOOST_MATH_BIG_CONSTANT(T, 64, 2.52989799376344914499),
- BOOST_MATH_BIG_CONSTANT(T, 64, -0.627414303172402506396),
- BOOST_MATH_BIG_CONSTANT(T, 64, 0.141554248216425512536),
- };
-
- if(x <= 2)
- {
- return (offset_1_2 + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x);
- }
- else if(x <= 8)
- {
- T y = 1 / x;
- return (1 + tools::evaluate_polynomial(P_2_8, y) / tools::evaluate_polynomial(Q_2_8, y)) / x;
- }
- T y = 1 / x;
- return (1 + tools::evaluate_polynomial(P_8_inf, y) / tools::evaluate_polynomial(Q_8_inf, y)) / x;
-}
-
-template
-T trigamma_prec(T x, const mpl::int_<113>*, const Policy&)
-{
- // Max error in interpolated form: 1.916e-035
-
- static const T P_1_2[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, -0.999999999999999082554457936871832533),
- BOOST_MATH_BIG_CONSTANT(T, 113, -4.71237311120865266379041700054847734),
- BOOST_MATH_BIG_CONSTANT(T, 113, -7.94125711970499027763789342500817316),
- BOOST_MATH_BIG_CONSTANT(T, 113, -5.74657746697664735258222071695644535),
- BOOST_MATH_BIG_CONSTANT(T, 113, -0.404213349456398905981223965160595687),
- BOOST_MATH_BIG_CONSTANT(T, 113, 2.47877781178642876561595890095758896),
- BOOST_MATH_BIG_CONSTANT(T, 113, 2.07714151702455125992166949812126433),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.858877899162360138844032265418028567),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.20499222604410032375789018837922397),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.0272103140348194747360175268778415049),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.0015764849020876949848954081173520686),
- };
- static const T Q_1_2[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 113, 4.71237311120863419878375031457715223),
- BOOST_MATH_BIG_CONSTANT(T, 113, 9.58619118655339853449127952145877467),
- BOOST_MATH_BIG_CONSTANT(T, 113, 11.0940067269829372437561421279054968),
- BOOST_MATH_BIG_CONSTANT(T, 113, 8.09075424749327792073276309969037885),
- BOOST_MATH_BIG_CONSTANT(T, 113, 3.87705890159891405185343806884451286),
- BOOST_MATH_BIG_CONSTANT(T, 113, 1.22758678701914477836330837816976782),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.249092040606385004109672077814668716),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.0295750413900655597027079600025569048),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.00157648490200498142247694709728858139),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.161264050344059471721062360645432809e-14),
- };
-
- // Max error in interpolated form: 8.958e-035
- static const T P_2_4[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, -2.55843734739907925764326773972215085),
- BOOST_MATH_BIG_CONSTANT(T, 113, -12.2830208240542011967952466273455887),
- BOOST_MATH_BIG_CONSTANT(T, 113, -23.9195022162767993526575786066414403),
- BOOST_MATH_BIG_CONSTANT(T, 113, -24.9256431504823483094158828285470862),
- BOOST_MATH_BIG_CONSTANT(T, 113, -14.7979122765478779075108064826412285),
- BOOST_MATH_BIG_CONSTANT(T, 113, -4.46654453928610666393276765059122272),
- BOOST_MATH_BIG_CONSTANT(T, 113, -0.0191439033405649675717082465687845002),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.515412052554351265708917209749037352),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.195378348786064304378247325360320038),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.0334761282624174313035014426794245393),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.002373665205942206348500250056602687),
- };
- static const T Q_2_4[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 113, 4.80098558454419907830670928248659245),
- BOOST_MATH_BIG_CONSTANT(T, 113, 9.99220727843170133895059300223445265),
- BOOST_MATH_BIG_CONSTANT(T, 113, 11.8896146167631330735386697123464976),
- BOOST_MATH_BIG_CONSTANT(T, 113, 8.96613256683809091593793565879092581),
- BOOST_MATH_BIG_CONSTANT(T, 113, 4.47254136149624110878909334574485751),
- BOOST_MATH_BIG_CONSTANT(T, 113, 1.48600982028196527372434773913633152),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.319570735766764237068541501137990078),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.0407358345787680953107374215319322066),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.00237366520593271641375755486420859837),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.239554887903526152679337256236302116e-15),
- BOOST_MATH_BIG_CONSTANT(T, 113, -0.294749244740618656265237072002026314e-17),
- };
-
- static const T y_offset_2_4 = BOOST_MATH_BIG_CONSTANT(T, 113, 3.558437347412109375);
-
- // Max error in interpolated form: 4.319e-035
- static const T P_4_8[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.166626112697021464248967707021688845e-16),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.499999999999997739552090249208808197),
- BOOST_MATH_BIG_CONSTANT(T, 113, 6.40270945019053817915772473771553187),
- BOOST_MATH_BIG_CONSTANT(T, 113, 41.3833374155000608013677627389343329),
- BOOST_MATH_BIG_CONSTANT(T, 113, 166.803341854562809335667241074035245),
- BOOST_MATH_BIG_CONSTANT(T, 113, 453.39964786925369319960722793414521),
- BOOST_MATH_BIG_CONSTANT(T, 113, 851.153712317697055375935433362983944),
- BOOST_MATH_BIG_CONSTANT(T, 113, 1097.70657567285059133109286478004458),
- BOOST_MATH_BIG_CONSTANT(T, 113, 938.431232478455316020076349367632922),
- BOOST_MATH_BIG_CONSTANT(T, 113, 487.268001604651932322080970189930074),
- BOOST_MATH_BIG_CONSTANT(T, 113, 119.953445242335730062471193124820659),
- };
- static const T Q_4_8[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 113, 12.4720855670474488978638945855932398),
- BOOST_MATH_BIG_CONSTANT(T, 113, 78.6093129753298570701376952709727391),
- BOOST_MATH_BIG_CONSTANT(T, 113, 307.470246050318322489781182863190127),
- BOOST_MATH_BIG_CONSTANT(T, 113, 805.140686101151538537565264188630079),
- BOOST_MATH_BIG_CONSTANT(T, 113, 1439.12019760292146454787601409644413),
- BOOST_MATH_BIG_CONSTANT(T, 113, 1735.6105285756048831268586001383127),
- BOOST_MATH_BIG_CONSTANT(T, 113, 1348.32500712856328019355198611280536),
- BOOST_MATH_BIG_CONSTANT(T, 113, 607.225985860570846699704222144650563),
- BOOST_MATH_BIG_CONSTANT(T, 113, 119.952317857277045332558673164517227),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.000140165918355036060868680809129436084),
- };
-
- // Maximum Deviation Found: 2.867e-035
- // Expected Error Term : 2.866e-035
- // Maximum Relative Change in Control Points : 2.662e-004
- static const T P_8_16[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, -0.184828315274146610610872315609837439e-19),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.500000000000000004122475157735807738),
- BOOST_MATH_BIG_CONSTANT(T, 113, 3.02533865247313349284875558880415875),
- BOOST_MATH_BIG_CONSTANT(T, 113, 13.5995927517457371243039532492642734),
- BOOST_MATH_BIG_CONSTANT(T, 113, 35.3132224283087906757037999452941588),
- BOOST_MATH_BIG_CONSTANT(T, 113, 67.1639424550714159157603179911505619),
- BOOST_MATH_BIG_CONSTANT(T, 113, 83.5767733658513967581959839367419891),
- BOOST_MATH_BIG_CONSTANT(T, 113, 71.073491212235705900866411319363501),
- BOOST_MATH_BIG_CONSTANT(T, 113, 35.8621515614725564575893663483998663),
- BOOST_MATH_BIG_CONSTANT(T, 113, 8.72152231639983491987779743154333318),
- };
- static const T Q_8_16[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 113, 5.71734397161293452310624822415866372),
- BOOST_MATH_BIG_CONSTANT(T, 113, 25.293404179620438179337103263274815),
- BOOST_MATH_BIG_CONSTANT(T, 113, 62.2619767967468199111077640625328469),
- BOOST_MATH_BIG_CONSTANT(T, 113, 113.955048909238993473389714972250235),
- BOOST_MATH_BIG_CONSTANT(T, 113, 130.807138328938966981862203944329408),
- BOOST_MATH_BIG_CONSTANT(T, 113, 102.423146902337654110717764213057753),
- BOOST_MATH_BIG_CONSTANT(T, 113, 44.0424772805245202514468199602123565),
- BOOST_MATH_BIG_CONSTANT(T, 113, 8.89898032477904072082994913461386099),
- BOOST_MATH_BIG_CONSTANT(T, 113, -0.0296627336872039988632793863671456398),
- };
- // Maximum Deviation Found: 1.079e-035
- // Expected Error Term : -1.079e-035
- // Maximum Relative Change in Control Points : 7.884e-003
- static const T P_16_inf[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.0),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.500000000000000000000000000000087317),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.345625669885456215194494735902663968),
- BOOST_MATH_BIG_CONSTANT(T, 113, 9.62895499360842232127552650044647769),
- BOOST_MATH_BIG_CONSTANT(T, 113, 3.5936085382439026269301003761320812),
- BOOST_MATH_BIG_CONSTANT(T, 113, 49.459599118438883265036646019410669),
- BOOST_MATH_BIG_CONSTANT(T, 113, 7.77519237321893917784735690560496607),
- BOOST_MATH_BIG_CONSTANT(T, 113, 74.4536074488178075948642351179304121),
- BOOST_MATH_BIG_CONSTANT(T, 113, 2.75209340397069050436806159297952699),
- BOOST_MATH_BIG_CONSTANT(T, 113, 23.9292359711471667884504840186561598),
- };
- static const T Q_16_inf[] = {
- BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.357918006437579097055656138920742037),
- BOOST_MATH_BIG_CONSTANT(T, 113, 19.1386039850709849435325005484512944),
- BOOST_MATH_BIG_CONSTANT(T, 113, 0.874349081464143606016221431763364517),
- BOOST_MATH_BIG_CONSTANT(T, 113, 98.6516097434855572678195488061432509),
- BOOST_MATH_BIG_CONSTANT(T, 113, -16.1051972833382893468655223662534306),
- BOOST_MATH_BIG_CONSTANT(T, 113, 154.316860216253720989145047141653727),
- BOOST_MATH_BIG_CONSTANT(T, 113, -40.2026880424378986053105969312264534),
- BOOST_MATH_BIG_CONSTANT(T, 113, 60.1679136674264778074736441126810223),
- BOOST_MATH_BIG_CONSTANT(T, 113, -13.3414844622256422644504472438320114),
- BOOST_MATH_BIG_CONSTANT(T, 113, 2.53795636200649908779512969030363442),
- };
-
- if(x <= 2)
- {
- return (2 + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x);
- }
- else if(x <= 4)
- {
- return (y_offset_2_4 + boost::math::tools::evaluate_polynomial(P_2_4, x) / tools::evaluate_polynomial(Q_2_4, x)) / (x * x);
- }
- else if(x <= 8)
- {
- T y = 1 / x;
- return (1 + tools::evaluate_polynomial(P_4_8, y) / tools::evaluate_polynomial(Q_4_8, y)) / x;
- }
- else if(x <= 16)
- {
- T y = 1 / x;
- return (1 + tools::evaluate_polynomial(P_8_16, y) / tools::evaluate_polynomial(Q_8_16, y)) / x;
- }
- T y = 1 / x;
- return (1 + tools::evaluate_polynomial(P_16_inf, y) / tools::evaluate_polynomial(Q_16_inf, y)) / x;
-}
-
-template
-T trigamma_imp(T x, const Tag* t, const Policy& pol)
-{
- //
- // This handles reflection of negative arguments, and all our
- // error handling, then forwards to the T-specific approximation.
- //
- BOOST_MATH_STD_USING // ADL of std functions.
-
- T result = 0;
- //
- // Check for negative arguments and use reflection:
- //
- if(x <= 0)
- {
- // Reflect:
- T z = 1 - x;
- // Argument reduction for tan:
- if(floor(x) == x)
- {
- return policies::raise_pole_error("boost::math::trigamma<%1%>(%1%)", 0, (1-x), pol);
- }
- T s = fabs(x) < fabs(z) ? boost::math::sin_pi(x, pol) : boost::math::sin_pi(z, pol);
- return -trigamma_imp(z, t, pol) + boost::math::pow<2>(constants::pi()) / (s * s);
- }
- if(x < 1)
- {
- result = 1 / (x * x);
- x += 1;
- }
- return result + trigamma_prec(x, t, pol);
-}
-
-template
-T trigamma_imp(T x, const mpl::int_<0>*, const Policy& pol)
-{
- return polygamma_imp(1, x, pol);
-}
-//
-// Initializer: ensure all our constants are initialized prior to the first call of main:
-//
-template
-struct trigamma_initializer
-{
- struct init
- {
- init()
- {
- typedef typename policies::precision::type precision_type;
- do_init(mpl::bool_());
- }
- void do_init(const mpl::true_&)
- {
- boost::math::trigamma(T(2.5), Policy());
- }
- void do_init(const mpl::false_&){}
- void force_instantiate()const{}
- };
- static const init initializer;
- static void force_instantiate()
- {
- initializer.force_instantiate();
- }
-};
-
-template
-const typename trigamma_initializer::init trigamma_initializer::initializer;
-
-} // namespace detail
-
-template
-inline typename tools::promote_args::type
- trigamma(T x, const Policy&)
-{
- typedef typename tools::promote_args::type result_type;
- typedef typename policies::evaluation::type value_type;
- typedef typename policies::precision::type precision_type;
- typedef typename mpl::if_<
- mpl::or_<
- mpl::less_equal >,
- mpl::greater >
- >,
- mpl::int_<0>,
- typename mpl::if_<
- mpl::less >,
- mpl::int_<53>,
- typename mpl::if_<
- mpl::less >,
- mpl::int_<64>,
- mpl::int_<113>
- >::type
- >::type
- >::type tag_type;
-
- typedef typename policies::normalise<
- Policy,
- policies::promote_float,
- policies::promote_double,
- policies::discrete_quantile<>,
- policies::assert_undefined<> >::type forwarding_policy;
-
- // Force initialization of constants:
- detail::trigamma_initializer::force_instantiate();
-
- return policies::checked_narrowing_cast(detail::trigamma_imp(
- static_cast(x),
- static_cast(0), forwarding_policy()), "boost::math::trigamma<%1%>(%1%)");
-}
-
-template
-inline typename tools::promote_args::type
- trigamma(T x)
-{
- return trigamma(x, policies::policy<>());
-}
-
-} // namespace math
-} // namespace boost
-#endif
-
diff --git a/src/mlpack/core/boost_backport/unordered_map.hpp b/src/mlpack/core/boost_backport/unordered_map.hpp
deleted file mode 100644
index 4ae37d22c9..0000000000
--- a/src/mlpack/core/boost_backport/unordered_map.hpp
+++ /dev/null
@@ -1,234 +0,0 @@
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP
-#define BOOST_SERIALIZATION_UNORDERED_MAP_HPP
-
-// MS compatible compilers support #pragma once
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
-// serialization/unordered_map.hpp:
-// serialization for stl unordered_map templates
-
-// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
-// (C) Copyright 2014 Jim Bell
-// Use, modification and distribution is subject to the Boost Software
-// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-// See http://www.boost.org for updates, documentation, and revision history.
-
-#include
-
-#include
-
-#include
-#include "unordered_collections_save_imp.hpp"
-#include "unordered_collections_load_imp.hpp"
-#include
-
-namespace boost {
-namespace serialization {
-
-namespace stl {
-
-// map input
-template
-struct archive_input_unordered_map
-{
- inline void operator()(
- Archive &ar,
- Container &s,
- const unsigned int v
- ){
- typedef typename Container::value_type type;
- detail::stack_construct t(ar, v);
- // borland fails silently w/o full namespace
- ar >> boost::serialization::make_nvp("item", t.reference());
- std::pair result =
- s.insert(t.reference());
- // note: the following presumes that the map::value_type was NOT tracked
- // in the archive. This is the usual case, but here there is no way
- // to determine that.
- if(result.second){
- ar.reset_object_address(
- & (result.first->second),
- & t.reference().second
- );
- }
- }
-};
-
-// multimap input
-template
-struct archive_input_unordered_multimap
-{
- inline void operator()(
- Archive &ar,
- Container &s,
- const unsigned int v
- ){
- typedef typename Container::value_type type;
- detail::stack_construct t(ar, v);
- // borland fails silently w/o full namespace
- ar >> boost::serialization::make_nvp("item", t.reference());
- typename Container::const_iterator result
- = s.insert(t.reference());
- // note: the following presumes that the map::value_type was NOT tracked
- // in the archive. This is the usual case, but here there is no way
- // to determine that.
- ar.reset_object_address(
- & result->second,
- & t.reference()
- );
- }
-};
-
-} // stl
-
-template<
- class Archive,
- class Key,
- class HashFcn,
- class EqualKey,
- class Allocator
->
-inline void save(
- Archive & ar,
- const std::unordered_map<
- Key, HashFcn, EqualKey, Allocator
- > &t,
- const unsigned int /*file_version*/
-){
- boost::serialization::stl::save_unordered_collection<
- Archive,
- std::unordered_map<
- Key, HashFcn, EqualKey, Allocator
- >
- >(ar, t);
-}
-
-template<
- class Archive,
- class Key,
- class HashFcn,
- class EqualKey,
- class Allocator
->
-inline void load(
- Archive & ar,
- std::unordered_map<
- Key, HashFcn, EqualKey, Allocator
- > &t,
- const unsigned int /*file_version*/
-){
- boost::serialization::stl::load_unordered_collection<
- Archive,
- std::unordered_map<
- Key, HashFcn, EqualKey, Allocator
- >,
- boost::serialization::stl::archive_input_unordered_map<
- Archive,
- std::unordered_map<
- Key, HashFcn, EqualKey, Allocator
- >
- >
- >(ar, t);
-}
-
-// split non-intrusive serialization function member into separate
-// non intrusive save/load member functions
-template<
- class Archive,
- class Key,
- class HashFcn,
- class EqualKey,
- class Allocator
->
-inline void serialize(
- Archive & ar,
- std::unordered_map<
- Key, HashFcn, EqualKey, Allocator
- > &t,
- const unsigned int file_version
-){
- boost::serialization::split_free(ar, t, file_version);
-}
-
-// unordered_multimap
-template<
- class Archive,
- class Key,
- class HashFcn,
- class EqualKey,
- class Allocator
->
-inline void save(
- Archive & ar,
- const std::unordered_multimap<
- Key, HashFcn, EqualKey, Allocator
- > &t,
- const unsigned int /*file_version*/
-){
- boost::serialization::stl::save_unordered_collection<
- Archive,
- std::unordered_multimap<
- Key, HashFcn, EqualKey, Allocator
- >
- >(ar, t);
-}
-
-template<
- class Archive,
- class Key,
- class HashFcn,
- class EqualKey,
- class Allocator
->
-inline void load(
- Archive & ar,
- std::unordered_multimap<
- Key, HashFcn, EqualKey, Allocator
- > &t,
- const unsigned int /*file_version*/
-){
- boost::serialization::stl::load_unordered_collection<
- Archive,
- std::unordered_multimap<
- Key, HashFcn, EqualKey, Allocator
- >,
- boost::serialization::stl::archive_input_unordered_multimap<
- Archive,
- std::unordered_multimap<
- Key, HashFcn, EqualKey, Allocator
- >
- >
- >(ar, t);
-}
-
-// split non-intrusive serialization function member into separate
-// non intrusive save/load member functions
-template<
- class Archive,
- class Key,
- class HashFcn,
- class EqualKey,
- class Allocator
->
-inline void serialize(
- Archive & ar,
- std::unordered_multimap<
- Key, HashFcn, EqualKey, Allocator
- > &t,
- const unsigned int file_version
-){
- boost::serialization::split_free(ar, t, file_version);
-}
-
-} // namespace serialization
-} // namespace boost
-
-#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP
diff --git a/src/mlpack/core/cv/metrics/CMakeLists.txt b/src/mlpack/core/cv/metrics/CMakeLists.txt
index 4cf1027874..b9edacaf9a 100644
--- a/src/mlpack/core/cv/metrics/CMakeLists.txt
+++ b/src/mlpack/core/cv/metrics/CMakeLists.txt
@@ -13,6 +13,8 @@ set(SOURCES
precision_impl.hpp
recall.hpp
recall_impl.hpp
+ r2_score.hpp
+ r2_score_impl.hpp
)
# Add directory name to sources.
diff --git a/src/mlpack/core/cv/metrics/r2_score.hpp b/src/mlpack/core/cv/metrics/r2_score.hpp
new file mode 100644
index 0000000000..6fcac955aa
--- /dev/null
+++ b/src/mlpack/core/cv/metrics/r2_score.hpp
@@ -0,0 +1,76 @@
+/**
+ * @file r2_score.hpp
+ * @author Bisakh Mondal
+ *
+ * The R^2 (Coefficient of determination) regression metric.
+ *
+ * mlpack is free software; you may redistribute it and/or modify it under the
+ * terms of the 3-clause BSD license. You should have received a copy of the
+ * 3-clause BSD license along with mlpack. If not, see
+ * http://www.opensource.org/licenses/BSD-3-Clause for more information.
+ */
+#ifndef MLPACK_CORE_CV_METRICS_R2SCORE_HPP
+#define MLPACK_CORE_CV_METRICS_R2SCORE_HPP
+
+#include
+
+namespace mlpack {
+namespace cv {
+
+/**
+ * The R2 Score is a metric of performance for regression algorithms
+ * that represents the proportion of variance (here y) that has been
+ * explained by the independent variables in the model. It provides
+ * an indication of goodness of fit and therefore a measure of how
+ * well unseen samples are likely to be predicted by the model,
+ * through the proportion of explained variance.
+ * As R2 Score is dataset dependent it can have wide range of values. The
+ * best possible score is @f$R^2 =1.0@f$. Values of R2 outside the range
+ * 0 to 1 can occur when the model fits the data worse than a horizontal
+ * hyperplane. This would occur when the wrong model was chosen, or
+ * nonsensical constraints were applied by mistake. A model which
+ * predicts exactly the expected value of y, disregarding the input
+ * features, gets a R2 Score equals to 0.0.
+ * If a model predicts @f$ \hat{y}_i $@f of the @f$ i $@f-th sample for a true
+ * @f$ y_i $@f for total n samples, the R2 Score is calculated by
+ * @f{eqnarray*}{
+ * R^{2} \left( y, \hat{y} \right) &=& 1-\frac{\sum_{i=1}^{n}
+ * \left( y_i - \hat{y_i} \right)^2 }
+ * {\sum_{i=1}^{n} \left( y_i - \bar{y}\right)^2}\\
+ * @f}
+ *
+ * where @f$ \bar{y} = frac{1}{y}\sum_{i=1}^{n} y_i $@f.
+ * For example, a model having R2Score = 0.85, explains 85 \% variability of
+ * the response data around its mean.
+ */
+class R2Score
+{
+ public:
+ /**
+ * Run prediction and calculate the R squared error.
+ *
+ * @param model A regression model.
+ * @param data Column-major data containing test items.
+ * @param responses Ground truth (correct) target values for the test items,
+ * should be either a row vector or a column-major matrix.
+ * @return calculated R2 Score.
+ */
+ template
+ static double Evaluate(MLAlgorithm& model,
+ const DataType& data,
+ const ResponsesType& responses);
+
+ /**
+ * Information for hyper-parameter tuning code. It indicates that we want
+ * to maximize the measurement.
+ */
+ static const bool NeedsMinimization = false;
+};
+
+} // namespace cv
+} // namespace mlpack
+
+// Include implementation.
+#include "r2_score_impl.hpp"
+
+#endif
diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp
new file mode 100644
index 0000000000..86c57e11fb
--- /dev/null
+++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp
@@ -0,0 +1,55 @@
+/**
+ * @file r2_score_impl.hpp
+ * @author Bisakh Mondal
+ *
+ * The implementation of the class R2Score.
+ *
+ * mlpack is free software; you may redistribute it and/or modify it under the
+ * terms of the 3-clause BSD license. You should have received a copy of the
+ * 3-clause BSD license along with mlpack. If not, see
+ * http://www.opensource.org/licenses/BSD-3-Clause for more information.
+ */
+#ifndef MLPACK_CORE_CV_METRICS_R2SCORE_IMPL_HPP
+#define MLPACK_CORE_CV_METRICS_R2SCORE_IMPL_HPP
+
+namespace mlpack {
+namespace cv {
+
+template
+double R2Score::Evaluate(MLAlgorithm& model,
+ const DataType& data,
+ const ResponsesType& responses)
+{
+ if (data.n_cols != responses.n_cols)
+ {
+ std::ostringstream oss;
+ oss << "R2Score::Evaluate(): number of points (" << data.n_cols << ") "
+ << "does not match number of responses (" << responses.n_cols << ")!"
+ << std::endl;
+ throw std::invalid_argument(oss.str());
+ }
+
+ ResponsesType predictedResponses;
+ // Taking Predicted Output from the model.
+ model.Predict(data, predictedResponses);
+ // Mean value of response.
+ double meanResponses = arma::mean(responses);
+
+ // Calculate the numerator i.e. residual sum of squares.
+ double residualSumSquared = arma::accu(arma::square(responses -
+ predictedResponses));
+
+ // Calculate the denominator i.e.total sum of squares.
+ double totalSumSquared = arma::accu(arma::square(responses - meanResponses));
+
+ // Handling undefined R2 Score when both denominator and numerator is 0.0.
+ if (residualSumSquared == 0.0)
+ return totalSumSquared ? 1.0 : DBL_MIN;
+
+ return 1 - residualSumSquared / totalSumSquared;
+}
+
+} // namespace cv
+} // namespace mlpack
+
+#endif
diff --git a/src/mlpack/core/data/CMakeLists.txt b/src/mlpack/core/data/CMakeLists.txt
index d21c27da75..0ef68d4a94 100644
--- a/src/mlpack/core/data/CMakeLists.txt
+++ b/src/mlpack/core/data/CMakeLists.txt
@@ -11,6 +11,7 @@ set(SOURCES
load_csv.cpp
load.hpp
load_image_impl.hpp
+ load_image.cpp
load_model_impl.hpp
load_vec_impl.hpp
load_impl.hpp
@@ -21,6 +22,7 @@ set(SOURCES
normalize_labels_impl.hpp
save.hpp
save_impl.hpp
+ save_image.cpp
serialization_template_version.hpp
split_data.hpp
imputer.hpp
diff --git a/src/mlpack/core/data/image_info.hpp b/src/mlpack/core/data/image_info.hpp
index e7f444447c..3fa91ef303 100644
--- a/src/mlpack/core/data/image_info.hpp
+++ b/src/mlpack/core/data/image_info.hpp
@@ -13,28 +13,12 @@
#ifndef MLPACK_CORE_DATA_IMAGE_INFO_HPP
#define MLPACK_CORE_DATA_IMAGE_INFO_HPP
-
#include
-
#include "extension.hpp"
-#ifdef HAS_STB // Compile this only if stb is present.
-
-#define STB_IMAGE_STATIC
-#define STB_IMAGE_IMPLEMENTATION
-#include
-
-#define STB_IMAGE_WRITE_STATIC
-#define STB_IMAGE_WRITE_IMPLEMENTATION
-#include
-
-#endif
-
namespace mlpack {
namespace data {
-#ifdef HAS_STB // Compile this only if stb is present.
-
/**
* Checks if the given image filename is supported.
*
@@ -44,8 +28,6 @@ namespace data {
inline bool ImageFormatSupported(const std::string& fileName,
const bool save = false);
-#endif
-
/**
* Implements meta-data of images required by data::Load and
* data::Save for loading and saving images into arma::Mat.
@@ -87,6 +69,15 @@ class ImageInfo
//! Modify the image quality.
size_t& Quality() { return quality; }
+ template
+ void serialize(Archive& ar, const unsigned int /* version */)
+ {
+ ar & BOOST_SERIALIZATION_NVP(width);
+ ar & BOOST_SERIALIZATION_NVP(channels);
+ ar & BOOST_SERIALIZATION_NVP(height);
+ ar & BOOST_SERIALIZATION_NVP(quality);
+ }
+
private:
// To store the image width.
size_t width;
diff --git a/src/mlpack/core/data/load.hpp b/src/mlpack/core/data/load.hpp
index 7974227409..256163f72b 100644
--- a/src/mlpack/core/data/load.hpp
+++ b/src/mlpack/core/data/load.hpp
@@ -291,7 +291,6 @@ bool Load(const std::string& filename,
/**
* Image load/save interfaces.
*/
-#ifdef HAS_STB
/**
* Load the image file into the given matrix.
@@ -300,15 +299,13 @@ bool Load(const std::string& filename,
* @param matrix Matrix to load the image into.
* @param info An object of ImageInfo class.
* @param fatal If an error should be reported as fatal (default false).
- * @param transpose If true, transpose the matrix after loading.
* @return Boolean value indicating success or failure of load.
*/
template
bool Load(const std::string& filename,
arma::Mat