summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/matrix
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/matrix')
-rw-r--r--ml/dlib/dlib/matrix/cblas_constants.h22
-rw-r--r--ml/dlib/dlib/matrix/lapack/fortran_id.h62
-rw-r--r--ml/dlib/dlib/matrix/lapack/gees.h264
-rw-r--r--ml/dlib/dlib/matrix/lapack/geev.h234
-rw-r--r--ml/dlib/dlib/matrix/lapack/geqrf.h168
-rw-r--r--ml/dlib/dlib/matrix/lapack/gesdd.h364
-rw-r--r--ml/dlib/dlib/matrix/lapack/gesvd.h323
-rw-r--r--ml/dlib/dlib/matrix/lapack/getrf.h132
-rw-r--r--ml/dlib/dlib/matrix/lapack/ormqr.h224
-rw-r--r--ml/dlib/dlib/matrix/lapack/pbtrf.h178
-rw-r--r--ml/dlib/dlib/matrix/lapack/potrf.h174
-rw-r--r--ml/dlib/dlib/matrix/lapack/syev.h218
-rw-r--r--ml/dlib/dlib/matrix/lapack/syevr.h445
-rw-r--r--ml/dlib/dlib/matrix/matrix.h2162
-rw-r--r--ml/dlib/dlib/matrix/matrix_abstract.h857
-rw-r--r--ml/dlib/dlib/matrix/matrix_assign.h978
-rw-r--r--ml/dlib/dlib/matrix/matrix_assign_fwd.h413
-rw-r--r--ml/dlib/dlib/matrix/matrix_blas_bindings.h1637
-rw-r--r--ml/dlib/dlib/matrix/matrix_cholesky.h231
-rw-r--r--ml/dlib/dlib/matrix/matrix_conj_trans.h71
-rw-r--r--ml/dlib/dlib/matrix/matrix_conv.h358
-rw-r--r--ml/dlib/dlib/matrix/matrix_conv_abstract.h158
-rw-r--r--ml/dlib/dlib/matrix/matrix_data_layout.h1271
-rw-r--r--ml/dlib/dlib/matrix/matrix_data_layout_abstract.h40
-rw-r--r--ml/dlib/dlib/matrix/matrix_default_mul.h134
-rw-r--r--ml/dlib/dlib/matrix/matrix_eigenvalue.h1379
-rw-r--r--ml/dlib/dlib/matrix/matrix_exp.h271
-rw-r--r--ml/dlib/dlib/matrix/matrix_exp_abstract.h210
-rw-r--r--ml/dlib/dlib/matrix/matrix_expressions.h280
-rw-r--r--ml/dlib/dlib/matrix/matrix_fft.h846
-rw-r--r--ml/dlib/dlib/matrix/matrix_fft_abstract.h118
-rw-r--r--ml/dlib/dlib/matrix/matrix_fwd.h31
-rw-r--r--ml/dlib/dlib/matrix/matrix_generic_image.h110
-rw-r--r--ml/dlib/dlib/matrix/matrix_la.h1807
-rw-r--r--ml/dlib/dlib/matrix/matrix_la_abstract.h1005
-rw-r--r--ml/dlib/dlib/matrix/matrix_lu.h361
-rw-r--r--ml/dlib/dlib/matrix/matrix_mat.h733
-rw-r--r--ml/dlib/dlib/matrix/matrix_mat_abstract.h243
-rw-r--r--ml/dlib/dlib/matrix/matrix_math_functions.h448
-rw-r--r--ml/dlib/dlib/matrix/matrix_math_functions_abstract.h595
-rw-r--r--ml/dlib/dlib/matrix/matrix_op.h479
-rw-r--r--ml/dlib/dlib/matrix/matrix_qr.h466
-rw-r--r--ml/dlib/dlib/matrix/matrix_read_from_istream.h108
-rw-r--r--ml/dlib/dlib/matrix/matrix_subexp.h1566
-rw-r--r--ml/dlib/dlib/matrix/matrix_subexp_abstract.h570
-rw-r--r--ml/dlib/dlib/matrix/matrix_trsm.h654
-rw-r--r--ml/dlib/dlib/matrix/matrix_utilities.h4544
-rw-r--r--ml/dlib/dlib/matrix/matrix_utilities_abstract.h1874
-rw-r--r--ml/dlib/dlib/matrix/symmetric_matrix_cache.h464
-rw-r--r--ml/dlib/dlib/matrix/symmetric_matrix_cache_abstract.h63
50 files changed, 0 insertions, 30343 deletions
diff --git a/ml/dlib/dlib/matrix/cblas_constants.h b/ml/dlib/dlib/matrix/cblas_constants.h
deleted file mode 100644
index 6ff89f141..000000000
--- a/ml/dlib/dlib/matrix/cblas_constants.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_CBLAS_CONSTAnTS_Hh_
-#define DLIB_CBLAS_CONSTAnTS_Hh_
-
-#ifndef CBLAS_H
-namespace dlib
-{
- namespace blas_bindings
- {
- enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102};
- enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113};
- enum CBLAS_UPLO {CblasUpper=121, CblasLower=122};
- enum CBLAS_DIAG {CblasNonUnit=131, CblasUnit=132};
- enum CBLAS_SIDE {CblasLeft=141, CblasRight=142};
-
- }
-}
-#endif // if not CBLAS_H
-
-#endif // DLIB_CBLAS_CONSTAnTS_Hh_
-
diff --git a/ml/dlib/dlib/matrix/lapack/fortran_id.h b/ml/dlib/dlib/matrix/lapack/fortran_id.h
deleted file mode 100644
index 8027ea34f..000000000
--- a/ml/dlib/dlib/matrix/lapack/fortran_id.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_BOOST_NUMERIC_BINDINGS_TRAITS_FORTRAN_H
-#define DLIB_BOOST_NUMERIC_BINDINGS_TRAITS_FORTRAN_H
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// FORTRAN BINDING STUFF FROM BOOST
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-// Permission to copy, use, modify, sell and
-// distribute this software is granted provided this copyright notice appears
-// in all copies. This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-// Copyright (C) 2002, 2003 Si-Lab b.v.b.a., Toon Knapen and Kresimir Fresl
-
-
-// First we need to know what the conventions for linking
-// C with Fortran is on this platform/toolset
-#if defined(LAPACK_FORCE_UNDERSCORE)
-#define DLIB_BIND_FORTRAN_LOWERCASE_UNDERSCORE
-#elif defined(LAPACK_FORCE_NOUNDERSCORE)
-#define DLIB_BIND_FORTRAN_LOWERCASE
-#elif defined(__GNUC__) || defined(__ICC) || defined(__sgi) || defined(__COMO__) || defined(__KCC)
-#define DLIB_BIND_FORTRAN_LOWERCASE_UNDERSCORE
-#elif defined(__IBMCPP__) || defined(_MSC_VER) || defined(__BORLANDC__)
-#define DLIB_BIND_FORTRAN_LOWERCASE
-#else
-#error do not know how to link with fortran for the given platform
-#endif
-
-// Next we define macros to convert our symbols to
-// the current convention
-#if defined(DLIB_BIND_FORTRAN_LOWERCASE_UNDERSCORE)
-#define DLIB_FORTRAN_ID( id ) id##_
-#elif defined(DLIB_BIND_FORTRAN_LOWERCASE)
-#define DLIB_FORTRAN_ID( id ) id
-#else
-#error do not know how to bind to fortran calling convention
-#endif
-
-
-
-namespace dlib
-{
- namespace lapack
- {
- // stuff from f2c used to define what exactly is an integer in fortran
-#if (defined(__alpha__) || defined(__sparc64__) || defined(__x86_64__) || defined(__ia64__)) && !defined(MATLAB_MEX_FILE)
- typedef int integer;
- typedef unsigned int uinteger;
-#else
- typedef long int integer;
- typedef unsigned long int uinteger;
-#endif
-
- }
-}
-
-#endif // DLIB_BOOST_NUMERIC_BINDINGS_TRAITS_FORTRAN_H
-
diff --git a/ml/dlib/dlib/matrix/lapack/gees.h b/ml/dlib/dlib/matrix/lapack/gees.h
deleted file mode 100644
index a8ee63ff1..000000000
--- a/ml/dlib/dlib/matrix/lapack/gees.h
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_ES_Hh_
-#define DLIB_LAPACk_ES_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
-#if defined(__alpha__) || defined(__sparc64__) || defined(__x86_64__) || defined(__ia64__)
- typedef int logical;
-#else
- typedef long int logical;
-#endif
- typedef logical (*L_fp)(...);
-
- extern "C"
- {
- void DLIB_FORTRAN_ID(dgees) (char *jobvs, char *sort, L_fp select, integer *n,
- double *a, integer *lda, integer *sdim, double *wr,
- double *wi, double *vs, integer *ldvs, double *work,
- integer *lwork, logical *bwork, integer *info);
-
- void DLIB_FORTRAN_ID(sgees) (char *jobvs, char *sort, L_fp select, integer *n,
- float *a, integer *lda, integer *sdim, float *wr,
- float *wi, float *vs, integer *ldvs, float *work,
- integer *lwork, logical *bwork, integer *info);
-
- }
-
- inline int gees (char jobvs, integer n,
- double *a, integer lda, double *wr,
- double *wi, double *vs, integer ldvs, double *work,
- integer lwork)
- {
- // No sorting allowed
- integer info = 0;
- char sort = 'N';
- L_fp fnil = 0;
- logical bwork = 0;
- integer sdim = 0;
- DLIB_FORTRAN_ID(dgees)(&jobvs, &sort, fnil, &n,
- a, &lda, &sdim, wr,
- wi, vs, &ldvs, work,
- &lwork, &bwork, &info);
- return info;
- }
-
-
- inline int gees (char jobvs, integer n,
- float *a, integer lda, float *wr,
- float *wi, float *vs, integer ldvs, float *work,
- integer lwork)
- {
- // No sorting allowed
- integer info = 0;
- char sort = 'N';
- L_fp fnil = 0;
- logical bwork = 0;
- integer sdim = 0;
- DLIB_FORTRAN_ID(sgees)(&jobvs, &sort, fnil, &n,
- a, &lda, &sdim, wr,
- wi, vs, &ldvs, work,
- &lwork, &bwork, &info);
- return info;
- }
-
-
- }
-
- // ------------------------------------------------------------------------------------
-
-/* -- LAPACK driver routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-/* .. Function Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DGEES computes for an N-by-N real nonsymmetric matrix A, the */
-/* eigenvalues, the real Schur form T, and, optionally, the matrix of */
-/* Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T). */
-
-/* Optionally, it also orders the eigenvalues on the diagonal of the */
-/* real Schur form so that selected eigenvalues are at the top left. */
-/* The leading columns of Z then form an orthonormal basis for the */
-/* invariant subspace corresponding to the selected eigenvalues. */
-
-/* A matrix is in real Schur form if it is upper quasi-triangular with */
-/* 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in the */
-/* form */
-/* [ a b ] */
-/* [ c a ] */
-
-/* where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc). */
-
-/* Arguments */
-/* ========= */
-
-/* JOBVS (input) CHARACTER*1 */
-/* = 'N': Schur vectors are not computed; */
-/* = 'V': Schur vectors are computed. */
-
-/* SORT (input) CHARACTER*1 */
-/* Specifies whether or not to order the eigenvalues on the */
-/* diagonal of the Schur form. */
-/* = 'N': Eigenvalues are not ordered; */
-/* = 'S': Eigenvalues are ordered (see SELECT). */
-
-/* SELECT (external procedure) LOGICAL FUNCTION of two DOUBLE PRECISION arguments */
-/* SELECT must be declared EXTERNAL in the calling subroutine. */
-/* If SORT = 'S', SELECT is used to select eigenvalues to sort */
-/* to the top left of the Schur form. */
-/* If SORT = 'N', SELECT is not referenced. */
-/* An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if */
-/* SELECT(WR(j),WI(j)) is true; i.e., if either one of a complex */
-/* conjugate pair of eigenvalues is selected, then both complex */
-/* eigenvalues are selected. */
-/* Note that a selected complex eigenvalue may no longer */
-/* satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since */
-/* ordering may change the value of complex eigenvalues */
-/* (especially if the eigenvalue is ill-conditioned); in this */
-/* case INFO is set to N+2 (see INFO below). */
-
-/* N (input) INTEGER */
-/* The order of the matrix A. N >= 0. */
-
-/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
-/* On entry, the N-by-N matrix A. */
-/* On exit, A has been overwritten by its real Schur form T. */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. LDA >= max(1,N). */
-
-/* SDIM (output) INTEGER */
-/* If SORT = 'N', SDIM = 0. */
-/* If SORT = 'S', SDIM = number of eigenvalues (after sorting) */
-/* for which SELECT is true. (Complex conjugate */
-/* pairs for which SELECT is true for either */
-/* eigenvalue count as 2.) */
-
-/* WR (output) DOUBLE PRECISION array, dimension (N) */
-/* WI (output) DOUBLE PRECISION array, dimension (N) */
-/* WR and WI contain the real and imaginary parts, */
-/* respectively, of the computed eigenvalues in the same order */
-/* that they appear on the diagonal of the output Schur form T. */
-/* Complex conjugate pairs of eigenvalues will appear */
-/* consecutively with the eigenvalue having the positive */
-/* imaginary part first. */
-
-/* VS (output) DOUBLE PRECISION array, dimension (LDVS,N) */
-/* If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur */
-/* vectors. */
-/* If JOBVS = 'N', VS is not referenced. */
-
-/* LDVS (input) INTEGER */
-/* The leading dimension of the array VS. LDVS >= 1; if */
-/* JOBVS = 'V', LDVS >= N. */
-
-/* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
-/* On exit, if INFO = 0, WORK(1) contains the optimal LWORK. */
-
-/* LWORK (input) INTEGER */
-/* The dimension of the array WORK. LWORK >= max(1,3*N). */
-/* For good performance, LWORK must generally be larger. */
-
-/* If LWORK = -1, then a workspace query is assumed; the routine */
-/* only calculates the optimal size of the WORK array, returns */
-/* this value as the first entry of the WORK array, and no error */
-/* message related to LWORK is issued by XERBLA. */
-
-/* BWORK (workspace) LOGICAL array, dimension (N) */
-/* Not referenced if SORT = 'N'. */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit */
-/* < 0: if INFO = -i, the i-th argument had an illegal value. */
-/* > 0: if INFO = i, and i is */
-/* <= N: the QR algorithm failed to compute all the */
-/* eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI */
-/* contain those eigenvalues which have converged; if */
-/* JOBVS = 'V', VS contains the matrix which reduces A */
-/* to its partially converged Schur form. */
-/* = N+1: the eigenvalues could not be reordered because some */
-/* eigenvalues were too close to separate (the problem */
-/* is very ill-conditioned); */
-/* = N+2: after reordering, roundoff changed values of some */
-/* complex eigenvalues so that leading eigenvalues in */
-/* the Schur form no longer satisfy SELECT=.TRUE. This */
-/* could also be caused by underflow due to scaling. */
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3, long NR4,
- long NC1, long NC2, long NC3, long NC4,
- typename MM,
- typename layout
- >
- int gees (
- const char jobz,
- matrix<T,NR1,NC1,MM,column_major_layout>& a,
- matrix<T,NR2,NC2,MM,layout>& wr,
- matrix<T,NR3,NC3,MM,layout>& wi,
- matrix<T,NR4,NC4,MM,column_major_layout>& vs
- )
- {
- matrix<T,0,1,MM,column_major_layout> work;
-
- const long n = a.nr();
-
- wr.set_size(n,1);
- wi.set_size(n,1);
-
- if (jobz == 'V')
- vs.set_size(n,n);
- else
- vs.set_size(NR4?NR4:1, NC4?NC4:1);
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::gees(jobz, n,
- &a(0,0), a.nr(), &wr(0,0),
- &wi(0,0), &vs(0,0), vs.nr(), &work_size,
- -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual decomposition
- info = binding::gees(jobz, n,
- &a(0,0), a.nr(), &wr(0,0),
- &wi(0,0), &vs(0,0), vs.nr(), &work(0,0),
- work.size());
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_ES_Hh_
-
diff --git a/ml/dlib/dlib/matrix/lapack/geev.h b/ml/dlib/dlib/matrix/lapack/geev.h
deleted file mode 100644
index d8fdc4af5..000000000
--- a/ml/dlib/dlib/matrix/lapack/geev.h
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_GEEV_Hh_
-#define DLIB_LAPACk_GEEV_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dgeev) (char *jobvl, char *jobvr, integer *n, double * a,
- integer *lda, double *wr, double *wi, double *vl,
- integer *ldvl, double *vr, integer *ldvr, double *work,
- integer *lwork, integer *info);
-
- void DLIB_FORTRAN_ID(sgeev) (char *jobvl, char *jobvr, integer *n, float * a,
- integer *lda, float *wr, float *wi, float *vl,
- integer *ldvl, float *vr, integer *ldvr, float *work,
- integer *lwork, integer *info);
-
- }
-
- inline int geev (char jobvl, char jobvr, integer n, double *a,
- integer lda, double *wr, double *wi, double *vl,
- integer ldvl, double *vr, integer ldvr, double *work,
- integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dgeev)(&jobvl, &jobvr, &n, a,
- &lda, wr, wi, vl,
- &ldvl, vr, &ldvr, work,
- &lwork, &info);
- return info;
- }
-
- inline int geev (char jobvl, char jobvr, integer n, float *a,
- integer lda, float *wr, float *wi, float *vl,
- integer ldvl, float *vr, integer ldvr, float *work,
- integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(sgeev)(&jobvl, &jobvr, &n, a,
- &lda, wr, wi, vl,
- &ldvl, vr, &ldvr, work,
- &lwork, &info);
- return info;
- }
-
-
- }
-
- // ------------------------------------------------------------------------------------
-
-/* -- LAPACK driver routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DGEEV computes for an N-by-N real nonsymmetric matrix A, the */
-/* eigenvalues and, optionally, the left and/or right eigenvectors. */
-
-/* The right eigenvector v(j) of A satisfies */
-/* A * v(j) = lambda(j) * v(j) */
-/* where lambda(j) is its eigenvalue. */
-/* The left eigenvector u(j) of A satisfies */
-/* u(j)**H * A = lambda(j) * u(j)**H */
-/* where u(j)**H denotes the conjugate transpose of u(j). */
-
-/* The computed eigenvectors are normalized to have Euclidean norm */
-/* equal to 1 and largest component real. */
-
-/* Arguments */
-/* ========= */
-
-/* JOBVL (input) CHARACTER*1 */
-/* = 'N': left eigenvectors of A are not computed; */
-/* = 'V': left eigenvectors of A are computed. */
-
-/* JOBVR (input) CHARACTER*1 */
-/* = 'N': right eigenvectors of A are not computed; */
-/* = 'V': right eigenvectors of A are computed. */
-
-/* N (input) INTEGER */
-/* The order of the matrix A. N >= 0. */
-
-/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
-/* On entry, the N-by-N matrix A. */
-/* On exit, A has been overwritten. */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. LDA >= max(1,N). */
-
-/* WR (output) DOUBLE PRECISION array, dimension (N) */
-/* WI (output) DOUBLE PRECISION array, dimension (N) */
-/* WR and WI contain the real and imaginary parts, */
-/* respectively, of the computed eigenvalues. Complex */
-/* conjugate pairs of eigenvalues appear consecutively */
-/* with the eigenvalue having the positive imaginary part */
-/* first. */
-
-/* VL (output) DOUBLE PRECISION array, dimension (LDVL,N) */
-/* If JOBVL = 'V', the left eigenvectors u(j) are stored one */
-/* after another in the columns of VL, in the same order */
-/* as their eigenvalues. */
-/* If JOBVL = 'N', VL is not referenced. */
-/* If the j-th eigenvalue is real, then u(j) = VL(:,j), */
-/* the j-th column of VL. */
-/* If the j-th and (j+1)-st eigenvalues form a complex */
-/* conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and */
-/* u(j+1) = VL(:,j) - i*VL(:,j+1). */
-
-/* LDVL (input) INTEGER */
-/* The leading dimension of the array VL. LDVL >= 1; if */
-/* JOBVL = 'V', LDVL >= N. */
-
-/* VR (output) DOUBLE PRECISION array, dimension (LDVR,N) */
-/* If JOBVR = 'V', the right eigenvectors v(j) are stored one */
-/* after another in the columns of VR, in the same order */
-/* as their eigenvalues. */
-/* If JOBVR = 'N', VR is not referenced. */
-/* If the j-th eigenvalue is real, then v(j) = VR(:,j), */
-/* the j-th column of VR. */
-/* If the j-th and (j+1)-st eigenvalues form a complex */
-/* conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and */
-/* v(j+1) = VR(:,j) - i*VR(:,j+1). */
-
-/* LDVR (input) INTEGER */
-/* The leading dimension of the array VR. LDVR >= 1; if */
-/* JOBVR = 'V', LDVR >= N. */
-
-/* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
-/* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
-
-/* LWORK (input) INTEGER */
-/* The dimension of the array WORK. LWORK >= max(1,3*N), and */
-/* if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N. For good */
-/* performance, LWORK must generally be larger. */
-
-/* If LWORK = -1, then a workspace query is assumed; the routine */
-/* only calculates the optimal size of the WORK array, returns */
-/* this value as the first entry of the WORK array, and no error */
-/* message related to LWORK is issued by XERBLA. */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit */
-/* < 0: if INFO = -i, the i-th argument had an illegal value. */
-/* > 0: if INFO = i, the QR algorithm failed to compute all the */
-/* eigenvalues, and no eigenvectors have been computed; */
-/* elements i+1:N of WR and WI contain eigenvalues which */
-/* have converged. */
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3, long NR4, long NR5,
- long NC1, long NC2, long NC3, long NC4, long NC5,
- typename MM,
- typename layout
- >
- int geev (
- const char jobvl,
- const char jobvr,
- matrix<T,NR1,NC1,MM,column_major_layout>& a,
- matrix<T,NR2,NC2,MM,layout>& wr,
- matrix<T,NR3,NC3,MM,layout>& wi,
- matrix<T,NR4,NC4,MM,column_major_layout>& vl,
- matrix<T,NR5,NC5,MM,column_major_layout>& vr
- )
- {
- matrix<T,0,1,MM,column_major_layout> work;
-
- const long n = a.nr();
-
- wr.set_size(n,1);
- wi.set_size(n,1);
-
- if (jobvl == 'V')
- vl.set_size(n,n);
- else
- vl.set_size(NR4?NR4:1, NC4?NC4:1);
-
- if (jobvr == 'V')
- vr.set_size(n,n);
- else
- vr.set_size(NR5?NR5:1, NC5?NC5:1);
-
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::geev(jobvl, jobvr, n, &a(0,0),
- a.nr(), &wr(0,0), &wi(0,0), &vl(0,0),
- vl.nr(), &vr(0,0), vr.nr(), &work_size,
- -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual decomposition
- info = binding::geev(jobvl, jobvr, n, &a(0,0),
- a.nr(), &wr(0,0), &wi(0,0), &vl(0,0),
- vl.nr(), &vr(0,0), vr.nr(), &work(0,0),
- work.size());
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_GEEV_Hh_
-
-
diff --git a/ml/dlib/dlib/matrix/lapack/geqrf.h b/ml/dlib/dlib/matrix/lapack/geqrf.h
deleted file mode 100644
index c1f8fc050..000000000
--- a/ml/dlib/dlib/matrix/lapack/geqrf.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_GEQRF_Hh_
-#define DLIB_LAPACk_GEQRF_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dgeqrf) (integer *m, integer *n, double *a, integer *
- lda, double *tau, double *work, integer *lwork,
- integer *info);
-
- void DLIB_FORTRAN_ID(sgeqrf) (integer *m, integer *n, float *a, integer *
- lda, float *tau, float *work, integer *lwork,
- integer *info);
- }
-
- inline int geqrf (integer m, integer n, double *a, integer lda,
- double *tau, double *work, integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dgeqrf)(&m, &n, a, &lda,
- tau, work, &lwork, &info);
- return info;
- }
-
- inline int geqrf (integer m, integer n, float *a, integer lda,
- float *tau, float *work, integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(sgeqrf)(&m, &n, a, &lda,
- tau, work, &lwork, &info);
- return info;
- }
-
-
- }
-
- // ------------------------------------------------------------------------------------
-
-/* -- LAPACK routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DGEQRF computes a QR factorization of a real M-by-N matrix A: */
-/* A = Q * R. */
-
-/* Arguments */
-/* ========= */
-
-/* M (input) INTEGER */
-/* The number of rows of the matrix A. M >= 0. */
-
-/* N (input) INTEGER */
-/* The number of columns of the matrix A. N >= 0. */
-
-/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
-/* On entry, the M-by-N matrix A. */
-/* On exit, the elements on and above the diagonal of the array */
-/* contain the min(M,N)-by-N upper trapezoidal matrix R (R is */
-/* upper triangular if m >= n); the elements below the diagonal, */
-/* with the array TAU, represent the orthogonal matrix Q as a */
-/* product of min(m,n) elementary reflectors (see Further */
-/* Details). */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. LDA >= max(1,M). */
-
-/* TAU (output) DOUBLE PRECISION array, dimension (min(M,N)) */
-/* The scalar factors of the elementary reflectors (see Further */
-/* Details). */
-
-/* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
-/* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
-
-/* LWORK (input) INTEGER */
-/* The dimension of the array WORK. LWORK >= max(1,N). */
-/* For optimum performance LWORK >= N*NB, where NB is */
-/* the optimal blocksize. */
-
-/* If LWORK = -1, then a workspace query is assumed; the routine */
-/* only calculates the optimal size of the WORK array, returns */
-/* this value as the first entry of the WORK array, and no error */
-/* message related to LWORK is issued by XERBLA. */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit */
-/* < 0: if INFO = -i, the i-th argument had an illegal value */
-
-/* Further Details */
-/* =============== */
-
-/* The matrix Q is represented as a product of elementary reflectors */
-
-/* Q = H(1) H(2) . . . H(k), where k = min(m,n). */
-
-/* Each H(i) has the form */
-
-/* H(i) = I - tau * v * v' */
-
-/* where tau is a real scalar, and v is a real vector with */
-/* v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i), */
-/* and tau in TAU(i). */
-
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2,
- long NC1, long NC2,
- typename MM
- >
- int geqrf (
- matrix<T,NR1,NC1,MM,column_major_layout>& a,
- matrix<T,NR2,NC2,MM,column_major_layout>& tau
- )
- {
- matrix<T,0,1,MM,column_major_layout> work;
-
- tau.set_size(std::min(a.nr(), a.nc()), 1);
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::geqrf(a.nr(), a.nc(), &a(0,0), a.nr(),
- &tau(0,0), &work_size, -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual decomposition
- info = binding::geqrf(a.nr(), a.nc(), &a(0,0), a.nr(),
- &tau(0,0), &work(0,0), work.size());
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_GEQRF_Hh_
-
-
-
diff --git a/ml/dlib/dlib/matrix/lapack/gesdd.h b/ml/dlib/dlib/matrix/lapack/gesdd.h
deleted file mode 100644
index e6b4d26e1..000000000
--- a/ml/dlib/dlib/matrix/lapack/gesdd.h
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_SDD_Hh_
-#define DLIB_LAPACk_SDD_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dgesdd) (char const* jobz,
- const integer* m, const integer* n, double* a, const integer* lda,
- double* s, double* u, const integer* ldu,
- double* vt, const integer* ldvt,
- double* work, const integer* lwork, integer* iwork, integer* info);
-
- void DLIB_FORTRAN_ID(sgesdd) (char const* jobz,
- const integer* m, const integer* n, float* a, const integer* lda,
- float* s, float* u, const integer* ldu,
- float* vt, const integer* ldvt,
- float* work, const integer* lwork, integer* iwork, integer* info);
-
- }
-
- inline integer gesdd (const char jobz,
- const integer m, const integer n, double* a, const integer lda,
- double* s, double* u, const integer ldu,
- double* vt, const integer ldvt,
- double* work, const integer lwork, integer* iwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dgesdd)(&jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, iwork, &info);
- return info;
- }
-
- inline integer gesdd (const char jobz,
- const integer m, const integer n, float* a, const integer lda,
- float* s, float* u, const integer ldu,
- float* vt, const integer ldvt,
- float* work, const integer lwork, integer* iwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(sgesdd)(&jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, iwork, &info);
- return info;
- }
- }
-
- // ------------------------------------------------------------------------------------
-
-/* -- LAPACK driver routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DGESDD computes the singular value decomposition (SVD) of a real */
-/* M-by-N matrix A, optionally computing the left and right singular */
-/* vectors. If singular vectors are desired, it uses a */
-/* divide-and-conquer algorithm. */
-
-/* The SVD is written */
-
-/* A = U * SIGMA * transpose(V) */
-
-/* where SIGMA is an M-by-N matrix which is zero except for its */
-/* min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and */
-/* V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA */
-/* are the singular values of A; they are real and non-negative, and */
-/* are returned in descending order. The first min(m,n) columns of */
-/* U and V are the left and right singular vectors of A. */
-
-/* Note that the routine returns VT = V**T, not V. */
-
-/* The divide and conquer algorithm makes very mild assumptions about */
-/* floating point arithmetic. It will work on machines with a guard */
-/* digit in add/subtract, or on those binary machines without guard */
-/* digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or */
-/* Cray-2. It could conceivably fail on hexadecimal or decimal machines */
-/* without guard digits, but we know of none. */
-
-/* Arguments */
-/* ========= */
-
-/* JOBZ (input) CHARACTER*1 */
-/* Specifies options for computing all or part of the matrix U: */
-/* = 'A': all M columns of U and all N rows of V**T are */
-/* returned in the arrays U and VT; */
-/* = 'S': the first min(M,N) columns of U and the first */
-/* min(M,N) rows of V**T are returned in the arrays U */
-/* and VT; */
-/* = 'O': If M >= N, the first N columns of U are overwritten */
-/* on the array A and all rows of V**T are returned in */
-/* the array VT; */
-/* otherwise, all columns of U are returned in the */
-/* array U and the first M rows of V**T are overwritten */
-/* in the array A; */
-/* = 'N': no columns of U or rows of V**T are computed. */
-
-/* M (input) INTEGER */
-/* The number of rows of the input matrix A. M >= 0. */
-
-/* N (input) INTEGER */
-/* The number of columns of the input matrix A. N >= 0. */
-
-/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
-/* On entry, the M-by-N matrix A. */
-/* On exit, */
-/* if JOBZ = 'O', A is overwritten with the first N columns */
-/* of U (the left singular vectors, stored */
-/* columnwise) if M >= N; */
-/* A is overwritten with the first M rows */
-/* of V**T (the right singular vectors, stored */
-/* rowwise) otherwise. */
-/* if JOBZ .ne. 'O', the contents of A are destroyed. */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. LDA >= max(1,M). */
-
-/* S (output) DOUBLE PRECISION array, dimension (min(M,N)) */
-/* The singular values of A, sorted so that S(i) >= S(i+1). */
-
-/* U (output) DOUBLE PRECISION array, dimension (LDU,UCOL) */
-/* UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N; */
-/* UCOL = min(M,N) if JOBZ = 'S'. */
-/* If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M */
-/* orthogonal matrix U; */
-/* if JOBZ = 'S', U contains the first min(M,N) columns of U */
-/* (the left singular vectors, stored columnwise); */
-/* if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced. */
-
-/* LDU (input) INTEGER */
-/* The leading dimension of the array U. LDU >= 1; if */
-/* JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M. */
-
-/* VT (output) DOUBLE PRECISION array, dimension (LDVT,N) */
-/* If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the */
-/* N-by-N orthogonal matrix V**T; */
-/* if JOBZ = 'S', VT contains the first min(M,N) rows of */
-/* V**T (the right singular vectors, stored rowwise); */
-/* if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced. */
-
-/* LDVT (input) INTEGER */
-/* The leading dimension of the array VT. LDVT >= 1; if */
-/* JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N; */
-/* if JOBZ = 'S', LDVT >= min(M,N). */
-
-/* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
-/* On exit, if INFO = 0, WORK(1) returns the optimal LWORK; */
-
-/* LWORK (input) INTEGER */
-/* The dimension of the array WORK. LWORK >= 1. */
-/* If JOBZ = 'N', */
-/* LWORK >= 3*min(M,N) + max(max(M,N),7*min(M,N)). */
-/* If JOBZ = 'O', */
-/* LWORK >= 3*min(M,N)*min(M,N) + */
-/* max(max(M,N),5*min(M,N)*min(M,N)+4*min(M,N)). */
-/* If JOBZ = 'S' or 'A' */
-/* LWORK >= 3*min(M,N)*min(M,N) + */
-/* max(max(M,N),4*min(M,N)*min(M,N)+4*min(M,N)). */
-/* For good performance, LWORK should generally be larger. */
-/* If LWORK = -1 but other input arguments are legal, WORK(1) */
-/* returns the optimal LWORK. */
-
-/* IWORK (workspace) INTEGER array, dimension (8*min(M,N)) */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit. */
-/* < 0: if INFO = -i, the i-th argument had an illegal value. */
-/* > 0: DBDSDC did not converge, updating process failed. */
-
-/* Further Details */
-/* =============== */
-
-/* Based on contributions by */
-/* Ming Gu and Huan Ren, Computer Science Division, University of */
-/* California at Berkeley, USA */
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3, long NR4,
- long NC1, long NC2, long NC3, long NC4,
- typename MM
- >
- int gesdd (
- const char jobz,
- matrix<T,NR1,NC1,MM,column_major_layout>& a,
- matrix<T,NR2,NC2,MM,column_major_layout>& s,
- matrix<T,NR3,NC3,MM,column_major_layout>& u,
- matrix<T,NR4,NC4,MM,column_major_layout>& vt
- )
- {
- matrix<T,0,1,MM,column_major_layout> work;
- matrix<integer,0,1,MM,column_major_layout> iwork;
-
- const long m = a.nr();
- const long n = a.nc();
- s.set_size(std::min(m,n), 1);
-
- // make sure the iwork memory block is big enough
- if (iwork.size() < 8*std::min(m,n))
- iwork.set_size(8*std::min(m,n), 1);
-
- if (jobz == 'A')
- {
- u.set_size(m,m);
- vt.set_size(n,n);
- }
- else if (jobz == 'S')
- {
- u.set_size(m, std::min(m,n));
- vt.set_size(std::min(m,n), n);
- }
- else if (jobz == 'O')
- {
- DLIB_CASSERT(false, "jobz == 'O' not supported");
- }
- else
- {
- u.set_size(NR3?NR3:1, NC3?NC3:1);
- vt.set_size(NR4?NR4:1, NC4?NC4:1);
- }
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::gesdd(jobz, a.nr(), a.nc(), &a(0,0), a.nr(),
- &s(0,0), &u(0,0), u.nr(), &vt(0,0), vt.nr(),
- &work_size, -1, &iwork(0,0));
-
- if (info != 0)
- return info;
-
- // There is a bug in an older version of LAPACK in Debian etch
- // that causes the gesdd to return the wrong value for work_size
- // when jobz == 'N'. So verify the value of work_size.
- if (jobz == 'N')
- {
- using std::min;
- using std::max;
- const T min_work_size = 3*min(m,n) + max(max(m,n),7*min(m,n));
- if (work_size < min_work_size)
- work_size = min_work_size;
- }
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual SVD
- info = binding::gesdd(jobz, a.nr(), a.nc(), &a(0,0), a.nr(),
- &s(0,0), &u(0,0), u.nr(), &vt(0,0), vt.nr(),
- &work(0,0), work.size(), &iwork(0,0));
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3, long NR4,
- long NC1, long NC2, long NC3, long NC4,
- typename MM
- >
- int gesdd (
- const char jobz,
- matrix<T,NR1,NC1,MM,row_major_layout>& a,
- matrix<T,NR2,NC2,MM,row_major_layout>& s,
- matrix<T,NR3,NC3,MM,row_major_layout>& u_,
- matrix<T,NR4,NC4,MM,row_major_layout>& vt_
- )
- {
- matrix<T,0,1,MM,row_major_layout> work;
- matrix<integer,0,1,MM,row_major_layout> iwork;
-
- // Row major order matrices are transposed from LAPACK's point of view.
- matrix<T,NR4,NC4,MM,row_major_layout>& u = vt_;
- matrix<T,NR3,NC3,MM,row_major_layout>& vt = u_;
-
-
- const long m = a.nc();
- const long n = a.nr();
- s.set_size(std::min(m,n), 1);
-
- // make sure the iwork memory block is big enough
- if (iwork.size() < 8*std::min(m,n))
- iwork.set_size(8*std::min(m,n), 1);
-
- if (jobz == 'A')
- {
- u.set_size(m,m);
- vt.set_size(n,n);
- }
- else if (jobz == 'S')
- {
- u.set_size(std::min(m,n), m);
- vt.set_size(n, std::min(m,n));
- }
- else if (jobz == 'O')
- {
- DLIB_CASSERT(false, "jobz == 'O' not supported");
- }
- else
- {
- u.set_size(NR4?NR4:1, NC4?NC4:1);
- vt.set_size(NR3?NR3:1, NC3?NC3:1);
- }
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::gesdd(jobz, m, n, &a(0,0), a.nc(),
- &s(0,0), &u(0,0), u.nc(), &vt(0,0), vt.nc(),
- &work_size, -1, &iwork(0,0));
-
- if (info != 0)
- return info;
-
- // There is a bug in an older version of LAPACK in Debian etch
- // that causes the gesdd to return the wrong value for work_size
- // when jobz == 'N'. So verify the value of work_size.
- if (jobz == 'N')
- {
- using std::min;
- using std::max;
- const T min_work_size = 3*min(m,n) + max(max(m,n),7*min(m,n));
- if (work_size < min_work_size)
- work_size = min_work_size;
- }
-
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual SVD
- info = binding::gesdd(jobz, m, n, &a(0,0), a.nc(),
- &s(0,0), &u(0,0), u.nc(), &vt(0,0), vt.nc(),
- &work(0,0), work.size(), &iwork(0,0));
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_SDD_Hh_
-
-
diff --git a/ml/dlib/dlib/matrix/lapack/gesvd.h b/ml/dlib/dlib/matrix/lapack/gesvd.h
deleted file mode 100644
index e00654db6..000000000
--- a/ml/dlib/dlib/matrix/lapack/gesvd.h
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_SVD_Hh_
-#define DLIB_LAPACk_SVD_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dgesvd) (const char* jobu, const char* jobvt,
- const integer* m, const integer* n, double* a, const integer* lda,
- double* s, double* u, const integer* ldu,
- double* vt, const integer* ldvt,
- double* work, const integer* lwork, integer* info);
-
- void DLIB_FORTRAN_ID(sgesvd) (const char* jobu, const char* jobvt,
- const integer* m, const integer* n, float* a, const integer* lda,
- float* s, float* u, const integer* ldu,
- float* vt, const integer* ldvt,
- float* work, const integer* lwork, integer* info);
-
- }
-
- inline integer gesvd (const char jobu, const char jobvt,
- const integer m, const integer n, double* a, const integer lda,
- double* s, double* u, const integer ldu,
- double* vt, const integer ldvt,
- double* work, const integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dgesvd)(&jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, &info);
- return info;
- }
-
- inline integer gesvd (const char jobu, const char jobvt,
- const integer m, const integer n, float* a, const integer lda,
- float* s, float* u, const integer ldu,
- float* vt, const integer ldvt,
- float* work, const integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(sgesvd)(&jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, &info);
- return info;
- }
-
- }
-
- // ------------------------------------------------------------------------------------
-
-/* -- LAPACK driver routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DGESVD computes the singular value decomposition (SVD) of a real */
-/* M-by-N matrix A, optionally computing the left and/or right singular */
-/* vectors. The SVD is written */
-
-/* A = U * SIGMA * transpose(V) */
-
-/* where SIGMA is an M-by-N matrix which is zero except for its */
-/* min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and */
-/* V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA */
-/* are the singular values of A; they are real and non-negative, and */
-/* are returned in descending order. The first min(m,n) columns of */
-/* U and V are the left and right singular vectors of A. */
-
-/* Note that the routine returns V**T, not V. */
-
-/* Arguments */
-/* ========= */
-
-/* JOBU (input) CHARACTER*1 */
-/* Specifies options for computing all or part of the matrix U: */
-/* = 'A': all M columns of U are returned in array U: */
-/* = 'S': the first min(m,n) columns of U (the left singular */
-/* vectors) are returned in the array U; */
-/* = 'O': the first min(m,n) columns of U (the left singular */
-/* vectors) are overwritten on the array A; */
-/* = 'N': no columns of U (no left singular vectors) are */
-/* computed. */
-
-/* JOBVT (input) CHARACTER*1 */
-/* Specifies options for computing all or part of the matrix */
-/* V**T: */
-/* = 'A': all N rows of V**T are returned in the array VT; */
-/* = 'S': the first min(m,n) rows of V**T (the right singular */
-/* vectors) are returned in the array VT; */
-/* = 'O': the first min(m,n) rows of V**T (the right singular */
-/* vectors) are overwritten on the array A; */
-/* = 'N': no rows of V**T (no right singular vectors) are */
-/* computed. */
-
-/* JOBVT and JOBU cannot both be 'O'. */
-
-/* M (input) INTEGER */
-/* The number of rows of the input matrix A. M >= 0. */
-
-/* N (input) INTEGER */
-/* The number of columns of the input matrix A. N >= 0. */
-
-/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
-/* On entry, the M-by-N matrix A. */
-/* On exit, */
-/* if JOBU = 'O', A is overwritten with the first min(m,n) */
-/* columns of U (the left singular vectors, */
-/* stored columnwise); */
-/* if JOBVT = 'O', A is overwritten with the first min(m,n) */
-/* rows of V**T (the right singular vectors, */
-/* stored rowwise); */
-/* if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A */
-/* are destroyed. */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. LDA >= max(1,M). */
-
-/* S (output) DOUBLE PRECISION array, dimension (min(M,N)) */
-/* The singular values of A, sorted so that S(i) >= S(i+1). */
-
-/* U (output) DOUBLE PRECISION array, dimension (LDU,UCOL) */
-/* (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'. */
-/* If JOBU = 'A', U contains the M-by-M orthogonal matrix U; */
-/* if JOBU = 'S', U contains the first min(m,n) columns of U */
-/* (the left singular vectors, stored columnwise); */
-/* if JOBU = 'N' or 'O', U is not referenced. */
-
-/* LDU (input) INTEGER */
-/* The leading dimension of the array U. LDU >= 1; if */
-/* JOBU = 'S' or 'A', LDU >= M. */
-
-/* VT (output) DOUBLE PRECISION array, dimension (LDVT,N) */
-/* If JOBVT = 'A', VT contains the N-by-N orthogonal matrix */
-/* V**T; */
-/* if JOBVT = 'S', VT contains the first min(m,n) rows of */
-/* V**T (the right singular vectors, stored rowwise); */
-/* if JOBVT = 'N' or 'O', VT is not referenced. */
-
-/* LDVT (input) INTEGER */
-/* The leading dimension of the array VT. LDVT >= 1; if */
-/* JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N). */
-
-/* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
-/* On exit, if INFO = 0, WORK(1) returns the optimal LWORK; */
-/* if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged */
-/* superdiagonal elements of an upper bidiagonal matrix B */
-/* whose diagonal is in S (not necessarily sorted). B */
-/* satisfies A = U * B * VT, so it has the same singular values */
-/* as A, and singular vectors related by U and VT. */
-
-/* LWORK (input) INTEGER */
-/* The dimension of the array WORK. */
-/* LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)). */
-/* For good performance, LWORK should generally be larger. */
-
-/* If LWORK = -1, then a workspace query is assumed; the routine */
-/* only calculates the optimal size of the WORK array, returns */
-/* this value as the first entry of the WORK array, and no error */
-/* message related to LWORK is issued by XERBLA. */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit. */
-/* < 0: if INFO = -i, the i-th argument had an illegal value. */
-/* > 0: if DBDSQR did not converge, INFO specifies how many */
-/* superdiagonals of an intermediate bidiagonal form B */
-/* did not converge to zero. See the description of WORK */
-/* above for details. */
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3, long NR4,
- long NC1, long NC2, long NC3, long NC4,
- typename MM
- >
- int gesvd (
- const char jobu,
- const char jobvt,
- matrix<T,NR1,NC1,MM,column_major_layout>& a,
- matrix<T,NR2,NC2,MM,column_major_layout>& s,
- matrix<T,NR3,NC3,MM,column_major_layout>& u,
- matrix<T,NR4,NC4,MM,column_major_layout>& vt
- )
- {
- matrix<T,0,1,MM,column_major_layout> work;
-
- const long m = a.nr();
- const long n = a.nc();
- s.set_size(std::min(m,n), 1);
-
- if (jobu == 'A')
- u.set_size(m,m);
- else if (jobu == 'S')
- u.set_size(m, std::min(m,n));
- else
- u.set_size(NR3?NR3:1, NC3?NC3:1);
-
- if (jobvt == 'A')
- vt.set_size(n,n);
- else if (jobvt == 'S')
- vt.set_size(std::min(m,n), n);
- else
- vt.set_size(NR4?NR4:1, NC4?NC4:1);
-
-
- if (jobu == 'O' || jobvt == 'O')
- {
- DLIB_CASSERT(false, "job == 'O' not supported");
- }
-
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::gesvd(jobu, jobvt, a.nr(), a.nc(), &a(0,0), a.nr(),
- &s(0,0), &u(0,0), u.nr(), &vt(0,0), vt.nr(),
- &work_size, -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual SVD
- info = binding::gesvd(jobu, jobvt, a.nr(), a.nc(), &a(0,0), a.nr(),
- &s(0,0), &u(0,0), u.nr(), &vt(0,0), vt.nr(),
- &work(0,0), work.size());
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3, long NR4,
- long NC1, long NC2, long NC3, long NC4,
- typename MM
- >
- int gesvd (
- char jobu,
- char jobvt,
- matrix<T,NR1,NC1,MM,row_major_layout>& a,
- matrix<T,NR2,NC2,MM,row_major_layout>& s,
- matrix<T,NR3,NC3,MM,row_major_layout>& u_,
- matrix<T,NR4,NC4,MM,row_major_layout>& vt_
- )
- {
- matrix<T,0,1,MM,row_major_layout> work;
-
- // Row major order matrices are transposed from LAPACK's point of view.
- matrix<T,NR4,NC4,MM,row_major_layout>& u = vt_;
- matrix<T,NR3,NC3,MM,row_major_layout>& vt = u_;
- std::swap(jobu, jobvt);
-
- const long m = a.nc();
- const long n = a.nr();
- s.set_size(std::min(m,n), 1);
-
- if (jobu == 'A')
- u.set_size(m,m);
- else if (jobu == 'S')
- u.set_size(std::min(m,n), m);
- else
- u.set_size(NR4?NR4:1, NC4?NC4:1);
-
- if (jobvt == 'A')
- vt.set_size(n,n);
- else if (jobvt == 'S')
- vt.set_size(n, std::min(m,n));
- else
- vt.set_size(NR3?NR3:1, NC3?NC3:1);
-
- if (jobu == 'O' || jobvt == 'O')
- {
- DLIB_CASSERT(false, "job == 'O' not supported");
- }
-
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::gesvd(jobu, jobvt, m, n, &a(0,0), a.nc(),
- &s(0,0), &u(0,0), u.nc(), &vt(0,0), vt.nc(),
- &work_size, -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual SVD
- info = binding::gesvd(jobu, jobvt, m, n, &a(0,0), a.nc(),
- &s(0,0), &u(0,0), u.nc(), &vt(0,0), vt.nc(),
- &work(0,0), work.size());
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_SVD_Hh_
-
diff --git a/ml/dlib/dlib/matrix/lapack/getrf.h b/ml/dlib/dlib/matrix/lapack/getrf.h
deleted file mode 100644
index a1f0b139d..000000000
--- a/ml/dlib/dlib/matrix/lapack/getrf.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_GETRF_Hh_
-#define DLIB_LAPACk_GETRF_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dgetrf) (integer* m, integer *n, double *a,
- integer* lda, integer *ipiv, integer *info);
-
- void DLIB_FORTRAN_ID(sgetrf) (integer* m, integer *n, float *a,
- integer* lda, integer *ipiv, integer *info);
-
- }
-
- inline int getrf (integer m, integer n, double *a,
- integer lda, integer *ipiv)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dgetrf)(&m, &n, a, &lda, ipiv, &info);
- return info;
- }
-
- inline int getrf (integer m, integer n, float *a,
- integer lda, integer *ipiv)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(sgetrf)(&m, &n, a, &lda, ipiv, &info);
- return info;
- }
-
-
- }
-
- // ------------------------------------------------------------------------------------
-
-
-/* -- LAPACK routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DGETRF computes an LU factorization of a general M-by-N matrix A */
-/* using partial pivoting with row interchanges. */
-
-/* The factorization has the form */
-/* A = P * L * U */
-/* where P is a permutation matrix, L is lower triangular with unit */
-/* diagonal elements (lower trapezoidal if m > n), and U is upper */
-/* triangular (upper trapezoidal if m < n). */
-
-/* This is the right-looking Level 3 BLAS version of the algorithm. */
-
-/* Arguments */
-/* ========= */
-
-/* M (input) INTEGER */
-/* The number of rows of the matrix A. M >= 0. */
-
-/* N (input) INTEGER */
-/* The number of columns of the matrix A. N >= 0. */
-
-/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
-/* On entry, the M-by-N matrix to be factored. */
-/* On exit, the factors L and U from the factorization */
-/* A = P*L*U; the unit diagonal elements of L are not stored. */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. LDA >= max(1,M). */
-
-/* IPIV (output) INTEGER array, dimension (min(M,N)) */
-/* The pivot indices; for 1 <= i <= min(M,N), row i of the */
-/* matrix was interchanged with row IPIV(i). */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit */
-/* < 0: if INFO = -i, the i-th argument had an illegal value */
-/* > 0: if INFO = i, U(i,i) is exactly zero. The factorization */
-/* has been completed, but the factor U is exactly */
-/* singular, and division by zero will occur if it is used */
-/* to solve a system of equations. */
-
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2,
- long NC1, long NC2,
- typename MM,
- typename layout
- >
- int getrf (
- matrix<T,NR1,NC1,MM,column_major_layout>& a,
- matrix<integer,NR2,NC2,MM,layout>& ipiv
- )
- {
- const long m = a.nr();
- const long n = a.nc();
-
- ipiv.set_size(std::min(m,n), 1);
-
- // compute the actual decomposition
- return binding::getrf(m, n, &a(0,0), a.nr(), &ipiv(0,0));
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_GETRF_Hh_
-
diff --git a/ml/dlib/dlib/matrix/lapack/ormqr.h b/ml/dlib/dlib/matrix/lapack/ormqr.h
deleted file mode 100644
index ab66ff4d2..000000000
--- a/ml/dlib/dlib/matrix/lapack/ormqr.h
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_ORMQR_Hh_
-#define DLIB_LAPACk_ORMQR_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dormqr) (char *side, char *trans, integer *m, integer *n,
- integer *k, const double *a, integer *lda, const double *tau,
- double * c_, integer *ldc, double *work, integer *lwork,
- integer *info);
-
- void DLIB_FORTRAN_ID(sormqr) (char *side, char *trans, integer *m, integer *n,
- integer *k, const float *a, integer *lda, const float *tau,
- float * c_, integer *ldc, float *work, integer *lwork,
- integer *info);
-
- }
-
- inline int ormqr (char side, char trans, integer m, integer n,
- integer k, const double *a, integer lda, const double *tau,
- double *c_, integer ldc, double *work, integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dormqr)(&side, &trans, &m, &n,
- &k, a, &lda, tau,
- c_, &ldc, work, &lwork, &info);
- return info;
- }
-
- inline int ormqr (char side, char trans, integer m, integer n,
- integer k, const float *a, integer lda, const float *tau,
- float *c_, integer ldc, float *work, integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(sormqr)(&side, &trans, &m, &n,
- &k, a, &lda, tau,
- c_, &ldc, work, &lwork, &info);
- return info;
- }
-
-
-
- }
-
- // ------------------------------------------------------------------------------------
-
-/* -- LAPACK routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DORMQR overwrites the general real M-by-N matrix C with */
-
-/* SIDE = 'L' SIDE = 'R' */
-/* TRANS = 'N': Q * C C * Q */
-/* TRANS = 'T': Q**T * C C * Q**T */
-
-/* where Q is a real orthogonal matrix defined as the product of k */
-/* elementary reflectors */
-
-/* Q = H(1) H(2) . . . H(k) */
-
-/* as returned by DGEQRF. Q is of order M if SIDE = 'L' and of order N */
-/* if SIDE = 'R'. */
-
-/* Arguments */
-/* ========= */
-
-/* SIDE (input) CHARACTER*1 */
-/* = 'L': apply Q or Q**T from the Left; */
-/* = 'R': apply Q or Q**T from the Right. */
-
-/* TRANS (input) CHARACTER*1 */
-/* = 'N': No transpose, apply Q; */
-/* = 'T': Transpose, apply Q**T. */
-
-/* M (input) INTEGER */
-/* The number of rows of the matrix C. M >= 0. */
-
-/* N (input) INTEGER */
-/* The number of columns of the matrix C. N >= 0. */
-
-/* K (input) INTEGER */
-/* The number of elementary reflectors whose product defines */
-/* the matrix Q. */
-/* If SIDE = 'L', M >= K >= 0; */
-/* if SIDE = 'R', N >= K >= 0. */
-
-/* A (input) DOUBLE PRECISION array, dimension (LDA,K) */
-/* The i-th column must contain the vector which defines the */
-/* elementary reflector H(i), for i = 1,2,...,k, as returned by */
-/* DGEQRF in the first k columns of its array argument A. */
-/* A is modified by the routine but restored on exit. */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. */
-/* If SIDE = 'L', LDA >= max(1,M); */
-/* if SIDE = 'R', LDA >= max(1,N). */
-
-/* TAU (input) DOUBLE PRECISION array, dimension (K) */
-/* TAU(i) must contain the scalar factor of the elementary */
-/* reflector H(i), as returned by DGEQRF. */
-
-/* C (input/output) DOUBLE PRECISION array, dimension (LDC,N) */
-/* On entry, the M-by-N matrix C. */
-/* On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. */
-
-/* LDC (input) INTEGER */
-/* The leading dimension of the array C. LDC >= max(1,M). */
-
-/* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
-/* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
-
-/* LWORK (input) INTEGER */
-/* The dimension of the array WORK. */
-/* If SIDE = 'L', LWORK >= max(1,N); */
-/* if SIDE = 'R', LWORK >= max(1,M). */
-/* For optimum performance LWORK >= N*NB if SIDE = 'L', and */
-/* LWORK >= M*NB if SIDE = 'R', where NB is the optimal */
-/* blocksize. */
-
-/* If LWORK = -1, then a workspace query is assumed; the routine */
-/* only calculates the optimal size of the WORK array, returns */
-/* this value as the first entry of the WORK array, and no error */
-/* message related to LWORK is issued by XERBLA. */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit */
-/* < 0: if INFO = -i, the i-th argument had an illegal value */
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3,
- long NC1, long NC2, long NC3,
- typename MM,
- typename C_LAYOUT
- >
- int ormqr (
- char side,
- char trans,
- const matrix<T,NR1,NC1,MM,column_major_layout>& a,
- const matrix<T,NR2,NC2,MM,column_major_layout>& tau,
- matrix<T,NR3,NC3,MM,C_LAYOUT>& c
- )
- {
- long m = c.nr();
- long n = c.nc();
- const long k = a.nc();
- long ldc;
- if (is_same_type<C_LAYOUT,column_major_layout>::value)
- {
- ldc = c.nr();
- }
- else
- {
- // Since lapack expects c to be in column major layout we have to
- // do something to make this work. Since a row major layout matrix
- // will look just like a transposed C we can just swap a few things around.
-
- ldc = c.nc();
- swap(m,n);
-
- if (side == 'L')
- side = 'R';
- else
- side = 'L';
-
- if (trans == 'T')
- trans = 'N';
- else
- trans = 'T';
- }
-
- matrix<T,0,1,MM,column_major_layout> work;
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::ormqr(side, trans, m, n,
- k, &a(0,0), a.nr(), &tau(0,0),
- &c(0,0), ldc, &work_size, -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual result
- info = binding::ormqr(side, trans, m, n,
- k, &a(0,0), a.nr(), &tau(0,0),
- &c(0,0), ldc, &work(0,0), work.size());
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_ORMQR_Hh_
-
diff --git a/ml/dlib/dlib/matrix/lapack/pbtrf.h b/ml/dlib/dlib/matrix/lapack/pbtrf.h
deleted file mode 100644
index 23bcc127b..000000000
--- a/ml/dlib/dlib/matrix/lapack/pbtrf.h
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_BDC_Hh_
-#define DLIB_LAPACk_BDC_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dpbtrf) (const char* uplo, const integer* n, const integer* kd,
- double* ab, const integer* ldab, integer* info);
-
- void DLIB_FORTRAN_ID(spbtrf) (const char* uplo, const integer* n, const integer* kd,
- float* ab, const integer* ldab, integer* info);
-
- }
-
- inline integer pbtrf (const char uplo, const integer n, const integer kd,
- double* ab, const integer ldab)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dpbtrf)(&uplo, &n, &kd, ab, &ldab, &info);
- return info;
- }
-
- inline integer pbtrf (const char uplo, const integer n, const integer kd,
- float* ab, const integer ldab)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(spbtrf)(&uplo, &n, &kd, ab, &ldab, &info);
- return info;
- }
- }
-
- // ------------------------------------------------------------------------------------
-/* DPBTRF(l) LAPACK routine (version 1.1) DPBTRF(l)
-
-NAME
- DPBTRF - compute the Cholesky factorization of a real symmetric positive
- definite band matrix A
-
-SYNOPSIS
-
- SUBROUTINE DPBTRF( UPLO, N, KD, AB, LDAB, INFO )
-
- CHARACTER UPLO
-
- INTEGER INFO, KD, LDAB, N
-
- DOUBLE PRECISION AB( LDAB, * )
-
-PURPOSE
- DPBTRF computes the Cholesky factorization of a real symmetric positive
- definite band matrix A.
-
- The factorization has the form
- A = U**T * U, if UPLO = 'U', or
- A = L * L**T, if UPLO = 'L',
- where U is an upper triangular matrix and L is lower triangular.
-
-ARGUMENTS
-
- UPLO (input) CHARACTER*1
- = 'U': Upper triangle of A is stored;
- = 'L': Lower triangle of A is stored.
-
- N (input) INTEGER
- The order of the matrix A. N >= 0.
-
- KD (input) INTEGER
- The number of superdiagonals of the matrix A if UPLO = 'U', or the
- number of subdiagonals if UPLO = 'L'. KD >= 0.
-
- AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
- On entry, the upper or lower triangle of the symmetric band matrix
- A, stored in the first KD+1 rows of the array. The j-th column of
- A is stored in the j-th column of the array AB as follows: if UPLO
- = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j; if UPLO =
- 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).
-
- On exit, if INFO = 0, the triangular factor U or L from the Chole-
- sky factorization A = U**T*U or A = L*L**T of the band matrix A, in
- the same storage format as A.
-
- LDAB (input) INTEGER
- The leading dimension of the array AB. LDAB >= KD+1.
-
- INFO (output) INTEGER
- = 0: successful exit
- < 0: if INFO = -i, the i-th argument had an illegal value
- > 0: if INFO = i, the leading minor of order i is not positive
- definite, and the factorization could not be completed.
-
-FURTHER DETAILS
- The band storage scheme is illustrated by the following example, when N =
- 6, KD = 2, and UPLO = 'U':
-
- On entry: On exit:
-
- * * a13 a24 a35 a46 * * u13 u24 u35 u46
- * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56
- a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66
-
- Similarly, if UPLO = 'L' the format of A is as follows:
-
- On entry: On exit:
-
- a11 a22 a33 a44 a55 a66 l11 l22 l33 l44 l55 l66
- a21 a32 a43 a54 a65 * l21 l32 l43 l54 l65 *
- a31 a42 a53 a64 * * l31 l42 l53 l64 * *
-
- Array elements marked * are not used by the routine.
-
- Contributed by
- Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989 */
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NC1,
- typename MM
- >
- int pbtrf (
- char uplo, matrix<T,NR1,NC1,MM,column_major_layout>& ab
- )
- {
- const long ldab = ab.nr();
- const long n = ab.nc();
- const long kd = ldab - 1; // assume fully packed
-
- int info = binding::pbtrf(uplo, n, kd, &ab(0,0), ldab);
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
-
- template <
- typename T,
- long NR1, long NC1,
- typename MM
- >
- int pbtrf (
- char uplo, matrix<T,NR1,NC1,MM,row_major_layout>& ab
- )
- {
- const long ldab = ab.nr();
- const long n = ab.nc();
- const long kd = ldab - 1; // assume fully packed
-
- matrix<T,NC1,NR1,MM,row_major_layout> abt = trans(ab);
-
- int info = binding::pbtrf(uplo, n, kd, &abt(0,0), ldab);
-
- ab = trans(abt);
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_BDC_Hh_
-
-
diff --git a/ml/dlib/dlib/matrix/lapack/potrf.h b/ml/dlib/dlib/matrix/lapack/potrf.h
deleted file mode 100644
index b9d6a7cc8..000000000
--- a/ml/dlib/dlib/matrix/lapack/potrf.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_POTRF_Hh_
-#define DLIB_LAPACk_POTRF_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dpotrf) (char *uplo, integer *n, double *a,
- integer* lda, integer *info);
-
- void DLIB_FORTRAN_ID(spotrf) (char *uplo, integer *n, float *a,
- integer* lda, integer *info);
-
- }
-
- inline int potrf (char uplo, integer n, double *a, integer lda)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dpotrf)(&uplo, &n, a, &lda, &info);
- return info;
- }
-
- inline int potrf (char uplo, integer n, float *a, integer lda)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(spotrf)(&uplo, &n, a, &lda, &info);
- return info;
- }
-
- }
-
- // ------------------------------------------------------------------------------------
-
-/* -- LAPACK routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DPOTRF computes the Cholesky factorization of a real symmetric */
-/* positive definite matrix A. */
-
-/* The factorization has the form */
-/* A = U**T * U, if UPLO = 'U', or */
-/* A = L * L**T, if UPLO = 'L', */
-/* where U is an upper triangular matrix and L is lower triangular. */
-
-/* This is the block version of the algorithm, calling Level 3 BLAS. */
-
-/* Arguments */
-/* ========= */
-
-/* UPLO (input) CHARACTER*1 */
-/* = 'U': Upper triangle of A is stored; */
-/* = 'L': Lower triangle of A is stored. */
-
-/* N (input) INTEGER */
-/* The order of the matrix A. N >= 0. */
-
-/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
-/* On entry, the symmetric matrix A. If UPLO = 'U', the leading */
-/* N-by-N upper triangular part of A contains the upper */
-/* triangular part of the matrix A, and the strictly lower */
-/* triangular part of A is not referenced. If UPLO = 'L', the */
-/* leading N-by-N lower triangular part of A contains the lower */
-/* triangular part of the matrix A, and the strictly upper */
-/* triangular part of A is not referenced. */
-
-/* On exit, if INFO = 0, the factor U or L from the Cholesky */
-/* factorization A = U**T*U or A = L*L**T. */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. LDA >= max(1,N). */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit */
-/* < 0: if INFO = -i, the i-th argument had an illegal value */
-/* > 0: if INFO = i, the leading minor of order i is not */
-/* positive definite, and the factorization could not be */
-/* completed. */
-
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1,
- long NC1,
- typename MM
- >
- int potrf (
- char uplo,
- matrix<T,NR1,NC1,MM,column_major_layout>& a
- )
- {
- // compute the actual decomposition
- int info = binding::potrf(uplo, a.nr(), &a(0,0), a.nr());
-
- // If it fails part way though the factorization then make sure
- // the end of the matrix gets properly initialized with zeros.
- if (info > 0)
- {
- if (uplo == 'L')
- set_colm(a, range(info-1, a.nc()-1)) = 0;
- else
- set_rowm(a, range(info-1, a.nr()-1)) = 0;
- }
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1,
- long NC1,
- typename MM
- >
- int potrf (
- char uplo,
- matrix<T,NR1,NC1,MM,row_major_layout>& a
- )
- {
- // since we are working on a row major order matrix we need to ask
- // LAPACK for the transpose of whatever the user asked for.
-
- if (uplo == 'L')
- uplo = 'U';
- else
- uplo = 'L';
-
- // compute the actual decomposition
- int info = binding::potrf(uplo, a.nr(), &a(0,0), a.nr());
-
- // If it fails part way though the factorization then make sure
- // the end of the matrix gets properly initialized with zeros.
- if (info > 0)
- {
- if (uplo == 'U')
- set_colm(a, range(info-1, a.nc()-1)) = 0;
- else
- set_rowm(a, range(info-1, a.nr()-1)) = 0;
- }
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_POTRF_Hh_
-
-
diff --git a/ml/dlib/dlib/matrix/lapack/syev.h b/ml/dlib/dlib/matrix/lapack/syev.h
deleted file mode 100644
index 0c9fd251a..000000000
--- a/ml/dlib/dlib/matrix/lapack/syev.h
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_EV_Hh_
-#define DLIB_LAPACk_EV_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dsyev) (char *jobz, char *uplo, integer *n, double *a,
- integer *lda, double *w, double *work, integer *lwork,
- integer *info);
-
- void DLIB_FORTRAN_ID(ssyev) (char *jobz, char *uplo, integer *n, float *a,
- integer *lda, float *w, float *work, integer *lwork,
- integer *info);
-
- }
-
- inline int syev (char jobz, char uplo, integer n, double *a,
- integer lda, double *w, double *work, integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dsyev)(&jobz, &uplo, &n, a,
- &lda, w, work, &lwork, &info);
- return info;
- }
-
- inline int syev (char jobz, char uplo, integer n, float *a,
- integer lda, float *w, float *work, integer lwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(ssyev)(&jobz, &uplo, &n, a,
- &lda, w, work, &lwork, &info);
- return info;
- }
-
-
- }
-
- // ------------------------------------------------------------------------------------
-
-/* -- LAPACK driver routine (version 3.1) -- */
-/* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
-/* November 2006 */
-
-/* .. Scalar Arguments .. */
-/* .. */
-/* .. Array Arguments .. */
-/* .. */
-
-/* Purpose */
-/* ======= */
-
-/* DSYEV computes all eigenvalues and, optionally, eigenvectors of a */
-/* real symmetric matrix A. */
-
-/* Arguments */
-/* ========= */
-
-/* JOBZ (input) CHARACTER*1 */
-/* = 'N': Compute eigenvalues only; */
-/* = 'V': Compute eigenvalues and eigenvectors. */
-
-/* UPLO (input) CHARACTER*1 */
-/* = 'U': Upper triangle of A is stored; */
-/* = 'L': Lower triangle of A is stored. */
-
-/* N (input) INTEGER */
-/* The order of the matrix A. N >= 0. */
-
-/* A (input/output) DOUBLE PRECISION array, dimension (LDA, N) */
-/* On entry, the symmetric matrix A. If UPLO = 'U', the */
-/* leading N-by-N upper triangular part of A contains the */
-/* upper triangular part of the matrix A. If UPLO = 'L', */
-/* the leading N-by-N lower triangular part of A contains */
-/* the lower triangular part of the matrix A. */
-/* On exit, if JOBZ = 'V', then if INFO = 0, A contains the */
-/* orthonormal eigenvectors of the matrix A. */
-/* If JOBZ = 'N', then on exit the lower triangle (if UPLO='L') */
-/* or the upper triangle (if UPLO='U') of A, including the */
-/* diagonal, is destroyed. */
-
-/* LDA (input) INTEGER */
-/* The leading dimension of the array A. LDA >= max(1,N). */
-
-/* W (output) DOUBLE PRECISION array, dimension (N) */
-/* If INFO = 0, the eigenvalues in ascending order. */
-
-/* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
-/* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
-
-/* LWORK (input) INTEGER */
-/* The length of the array WORK. LWORK >= max(1,3*N-1). */
-/* For optimal efficiency, LWORK >= (NB+2)*N, */
-/* where NB is the blocksize for DSYTRD returned by ILAENV. */
-
-/* If LWORK = -1, then a workspace query is assumed; the routine */
-/* only calculates the optimal size of the WORK array, returns */
-/* this value as the first entry of the WORK array, and no error */
-/* message related to LWORK is issued by XERBLA. */
-
-/* INFO (output) INTEGER */
-/* = 0: successful exit */
-/* < 0: if INFO = -i, the i-th argument had an illegal value */
-/* > 0: if INFO = i, the algorithm failed to converge; i */
-/* off-diagonal elements of an intermediate tridiagonal */
-/* form did not converge to zero. */
-
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2,
- long NC1, long NC2,
- typename MM
- >
- int syev (
- const char jobz,
- const char uplo,
- matrix<T,NR1,NC1,MM,column_major_layout>& a,
- matrix<T,NR2,NC2,MM,column_major_layout>& w
- )
- {
- matrix<T,0,1,MM,column_major_layout> work;
-
- const long n = a.nr();
-
- w.set_size(n,1);
-
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::syev(jobz, uplo, n, &a(0,0),
- a.nr(), &w(0,0), &work_size, -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual decomposition
- info = binding::syev(jobz, uplo, n, &a(0,0),
- a.nr(), &w(0,0), &work(0,0), work.size());
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2,
- long NC1, long NC2,
- typename MM
- >
- int syev (
- char jobz,
- char uplo,
- matrix<T,NR1,NC1,MM,row_major_layout>& a,
- matrix<T,NR2,NC2,MM,row_major_layout>& w
- )
- {
- matrix<T,0,1,MM,row_major_layout> work;
-
- if (uplo == 'L')
- uplo = 'U';
- else
- uplo = 'L';
-
- const long n = a.nr();
-
- w.set_size(n,1);
-
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- int info = binding::syev(jobz, uplo, n, &a(0,0),
- a.nc(), &w(0,0), &work_size, -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
-
- // compute the actual decomposition
- info = binding::syev(jobz, uplo, n, &a(0,0),
- a.nc(), &w(0,0), &work(0,0), work.size());
-
-
- a = trans(a);
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_EV_Hh_
-
-
-
-
diff --git a/ml/dlib/dlib/matrix/lapack/syevr.h b/ml/dlib/dlib/matrix/lapack/syevr.h
deleted file mode 100644
index 65190b3d8..000000000
--- a/ml/dlib/dlib/matrix/lapack/syevr.h
+++ /dev/null
@@ -1,445 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_LAPACk_EVR_Hh_
-#define DLIB_LAPACk_EVR_Hh_
-
-#include "fortran_id.h"
-#include "../matrix.h"
-
-namespace dlib
-{
- namespace lapack
- {
- namespace binding
- {
- extern "C"
- {
- void DLIB_FORTRAN_ID(dsyevr) (char *jobz, char *range, char *uplo, integer *n,
- double *a, integer *lda, double *vl, double *vu, integer * il,
- integer *iu, double *abstol, integer *m, double *w,
- double *z_, integer *ldz, integer *isuppz, double *work,
- integer *lwork, integer *iwork, integer *liwork, integer *info);
-
- void DLIB_FORTRAN_ID(ssyevr) (char *jobz, char *range, char *uplo, integer *n,
- float *a, integer *lda, float *vl, float *vu, integer * il,
- integer *iu, float *abstol, integer *m, float *w,
- float *z_, integer *ldz, integer *isuppz, float *work,
- integer *lwork, integer *iwork, integer *liwork, integer *info);
- }
-
- inline int syevr (char jobz, char range, char uplo, integer n,
- double* a, integer lda, double vl, double vu, integer il,
- integer iu, double abstol, integer *m, double *w,
- double *z, integer ldz, integer *isuppz, double *work,
- integer lwork, integer *iwork, integer liwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(dsyevr)(&jobz, &range, &uplo, &n,
- a, &lda, &vl, &vu, &il,
- &iu, &abstol, m, w,
- z, &ldz, isuppz, work,
- &lwork, iwork, &liwork, &info);
- return info;
- }
-
- inline int syevr (char jobz, char range, char uplo, integer n,
- float* a, integer lda, float vl, float vu, integer il,
- integer iu, float abstol, integer *m, float *w,
- float *z, integer ldz, integer *isuppz, float *work,
- integer lwork, integer *iwork, integer liwork)
- {
- integer info = 0;
- DLIB_FORTRAN_ID(ssyevr)(&jobz, &range, &uplo, &n,
- a, &lda, &vl, &vu, &il,
- &iu, &abstol, m, w,
- z, &ldz, isuppz, work,
- &lwork, iwork, &liwork, &info);
- return info;
- }
-
- }
-
- // ------------------------------------------------------------------------------------
-
- /*
-
-* -- LAPACK driver routine (version 3.1) --
-* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
-* November 2006
-*
-* .. Scalar Arguments ..
- CHARACTER JOBZ, RANGE, UPLO
- INTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LWORK, M, N
- DOUBLE PRECISION ABSTOL, VL, VU
-* ..
-* .. Array Arguments ..
- INTEGER ISUPPZ( * ), IWORK( * )
- DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * )
-* ..
-*
-* Purpose
-* =======
-*
-* DSYEVR computes selected eigenvalues and, optionally, eigenvectors
-* of a real symmetric matrix A. Eigenvalues and eigenvectors can be
-* selected by specifying either a range of values or a range of
-* indices for the desired eigenvalues.
-*
-* DSYEVR first reduces the matrix A to tridiagonal form T with a call
-* to DSYTRD. Then, whenever possible, DSYEVR calls DSTEMR to compute
-* the eigenspectrum using Relatively Robust Representations. DSTEMR
-* computes eigenvalues by the dqds algorithm, while orthogonal
-* eigenvectors are computed from various "good" L D L^T representations
-* (also known as Relatively Robust Representations). Gram-Schmidt
-* orthogonalization is avoided as far as possible. More specifically,
-* the various steps of the algorithm are as follows.
-*
-* For each unreduced block (submatrix) of T,
-* (a) Compute T - sigma I = L D L^T, so that L and D
-* define all the wanted eigenvalues to high relative accuracy.
-* This means that small relative changes in the entries of D and L
-* cause only small relative changes in the eigenvalues and
-* eigenvectors. The standard (unfactored) representation of the
-* tridiagonal matrix T does not have this property in general.
-* (b) Compute the eigenvalues to suitable accuracy.
-* If the eigenvectors are desired, the algorithm attains full
-* accuracy of the computed eigenvalues only right before
-* the corresponding vectors have to be computed, see steps c) and d).
-* (c) For each cluster of close eigenvalues, select a new
-* shift close to the cluster, find a new factorization, and refine
-* the shifted eigenvalues to suitable accuracy.
-* (d) For each eigenvalue with a large enough relative separation compute
-* the corresponding eigenvector by forming a rank revealing twisted
-* factorization. Go back to (c) for any clusters that remain.
-*
-* The desired accuracy of the output can be specified by the input
-* parameter ABSTOL.
-*
-* For more details, see DSTEMR's documentation and:
-* - Inderjit S. Dhillon and Beresford N. Parlett: "Multiple representations
-* to compute orthogonal eigenvectors of symmetric tridiagonal matrices,"
-* Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.
-* - Inderjit Dhillon and Beresford Parlett: "Orthogonal Eigenvectors and
-* Relative Gaps," SIAM Journal on Matrix Analysis and Applications, Vol. 25,
-* 2004. Also LAPACK Working Note 154.
-* - Inderjit Dhillon: "A new O(n^2) algorithm for the symmetric
-* tridiagonal eigenvalue/eigenvector problem",
-* Computer Science Division Technical Report No. UCB/CSD-97-971,
-* UC Berkeley, May 1997.
-*
-*
-* Note 1 : DSYEVR calls DSTEMR when the full spectrum is requested
-* on machines which conform to the ieee-754 floating point standard.
-* DSYEVR calls DSTEBZ and SSTEIN on non-ieee machines and
-* when partial spectrum requests are made.
-*
-* Normal execution of DSTEMR may create NaNs and infinities and
-* hence may abort due to a floating point exception in environments
-* which do not handle NaNs and infinities in the ieee standard default
-* manner.
-*
-* Arguments
-* =========
-*
-* JOBZ (input) CHARACTER*1
-* = 'N': Compute eigenvalues only;
-* = 'V': Compute eigenvalues and eigenvectors.
-*
-* RANGE (input) CHARACTER*1
-* = 'A': all eigenvalues will be found.
-* = 'V': all eigenvalues in the half-open interval (VL,VU]
-* will be found.
-* = 'I': the IL-th through IU-th eigenvalues will be found.
-********** For RANGE = 'V' or 'I' and IU - IL < N - 1, DSTEBZ and
-********** DSTEIN are called
-*
-* UPLO (input) CHARACTER*1
-* = 'U': Upper triangle of A is stored;
-* = 'L': Lower triangle of A is stored.
-*
-* N (input) INTEGER
-* The order of the matrix A. N >= 0.
-*
-* A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
-* On entry, the symmetric matrix A. If UPLO = 'U', the
-* leading N-by-N upper triangular part of A contains the
-* upper triangular part of the matrix A. If UPLO = 'L',
-* the leading N-by-N lower triangular part of A contains
-* the lower triangular part of the matrix A.
-* On exit, the lower triangle (if UPLO='L') or the upper
-* triangle (if UPLO='U') of A, including the diagonal, is
-* destroyed.
-*
-* LDA (input) INTEGER
-* The leading dimension of the array A. LDA >= max(1,N).
-*
-* VL (input) DOUBLE PRECISION
-* VU (input) DOUBLE PRECISION
-* If RANGE='V', the lower and upper bounds of the interval to
-* be searched for eigenvalues. VL < VU.
-* Not referenced if RANGE = 'A' or 'I'.
-*
-* IL (input) INTEGER
-* IU (input) INTEGER
-* If RANGE='I', the indices (in ascending order) of the
-* smallest and largest eigenvalues to be returned.
-* 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
-* Not referenced if RANGE = 'A' or 'V'.
-*
-* ABSTOL (input) DOUBLE PRECISION
-* The absolute error tolerance for the eigenvalues.
-* An approximate eigenvalue is accepted as converged
-* when it is determined to lie in an interval [a,b]
-* of width less than or equal to
-*
-* ABSTOL + EPS * max( |a|,|b| ) ,
-*
-* where EPS is the machine precision. If ABSTOL is less than
-* or equal to zero, then EPS*|T| will be used in its place,
-* where |T| is the 1-norm of the tridiagonal matrix obtained
-* by reducing A to tridiagonal form.
-*
-* See "Computing Small Singular Values of Bidiagonal Matrices
-* with Guaranteed High Relative Accuracy," by Demmel and
-* Kahan, LAPACK Working Note #3.
-*
-* If high relative accuracy is important, set ABSTOL to
-* DLAMCH( 'Safe minimum' ). Doing so will guarantee that
-* eigenvalues are computed to high relative accuracy when
-* possible in future releases. The current code does not
-* make any guarantees about high relative accuracy, but
-* future releases will. See J. Barlow and J. Demmel,
-* "Computing Accurate Eigensystems of Scaled Diagonally
-* Dominant Matrices", LAPACK Working Note #7, for a discussion
-* of which matrices define their eigenvalues to high relative
-* accuracy.
-*
-* M (output) INTEGER
-* The total number of eigenvalues found. 0 <= M <= N.
-* If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
-*
-* W (output) DOUBLE PRECISION array, dimension (N)
-* The first M elements contain the selected eigenvalues in
-* ascending order.
-*
-* Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M))
-* If JOBZ = 'V', then if INFO = 0, the first M columns of Z
-* contain the orthonormal eigenvectors of the matrix A
-* corresponding to the selected eigenvalues, with the i-th
-* column of Z holding the eigenvector associated with W(i).
-* If JOBZ = 'N', then Z is not referenced.
-* Note: the user must ensure that at least max(1,M) columns are
-* supplied in the array Z; if RANGE = 'V', the exact value of M
-* is not known in advance and an upper bound must be used.
-* Supplying N columns is always safe.
-*
-* LDZ (input) INTEGER
-* The leading dimension of the array Z. LDZ >= 1, and if
-* JOBZ = 'V', LDZ >= max(1,N).
-*
-* ISUPPZ (output) INTEGER array, dimension ( 2*max(1,M) )
-* The support of the eigenvectors in Z, i.e., the indices
-* indicating the nonzero elements in Z. The i-th eigenvector
-* is nonzero only in elements ISUPPZ( 2*i-1 ) through
-* ISUPPZ( 2*i ).
-********** Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1
-*
-* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
-* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
-*
-* LWORK (input) INTEGER
-* The dimension of the array WORK. LWORK >= max(1,26*N).
-* For optimal efficiency, LWORK >= (NB+6)*N,
-* where NB is the max of the blocksize for DSYTRD and DORMTR
-* returned by ILAENV.
-*
-* If LWORK = -1, then a workspace query is assumed; the routine
-* only calculates the optimal size of the WORK array, returns
-* this value as the first entry of the WORK array, and no error
-* message related to LWORK is issued by XERBLA.
-*
-* IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
-* On exit, if INFO = 0, IWORK(1) returns the optimal LWORK.
-*
-* LIWORK (input) INTEGER
-* The dimension of the array IWORK. LIWORK >= max(1,10*N).
-*
-* If LIWORK = -1, then a workspace query is assumed; the
-* routine only calculates the optimal size of the IWORK array,
-* returns this value as the first entry of the IWORK array, and
-* no error message related to LIWORK is issued by XERBLA.
-*
-* INFO (output) INTEGER
-* = 0: successful exit
-* < 0: if INFO = -i, the i-th argument had an illegal value
-* > 0: Internal error
-*
-* Further Details
-* ===============
-*
-* Based on contributions by
-* Inderjit Dhillon, IBM Almaden, USA
-* Osni Marques, LBNL/NERSC, USA
-* Ken Stanley, Computer Science Division, University of
-* California at Berkeley, USA
-* Jason Riedy, Computer Science Division, University of
-* California at Berkeley, USA
-*
-* =====================================================================
-
- */
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3, long NR4,
- long NC1, long NC2, long NC3, long NC4,
- typename MM
- >
- int syevr (
- const char jobz,
- const char range,
- const char uplo,
- matrix<T,NR1,NC1,MM,column_major_layout>& a,
- const double vl,
- const double vu,
- const integer il,
- const integer iu,
- const double abstol,
- integer& num_eigenvalues_found,
- matrix<T,NR2,NC2,MM,column_major_layout>& w,
- matrix<T,NR3,NC3,MM,column_major_layout>& z,
- matrix<integer,NR4,NC4,MM,column_major_layout>& isuppz
- )
- {
- matrix<T,0,1,MM,column_major_layout> work;
- matrix<integer,0,1,MM,column_major_layout> iwork;
-
- const long n = a.nr();
-
- w.set_size(n,1);
-
- isuppz.set_size(2*n, 1);
-
- if (jobz == 'V')
- {
- z.set_size(n,n);
- }
- else
- {
- z.set_size(NR3?NR3:1, NC3?NC3:1);
- }
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- integer iwork_size = 1;
- int info = binding::syevr(jobz, range, uplo, n, &a(0,0),
- a.nr(), vl, vu, il, iu, abstol, &num_eigenvalues_found,
- &w(0,0), &z(0,0), z.nr(), &isuppz(0,0), &work_size, -1,
- &iwork_size, -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
- if (iwork.size() < iwork_size)
- iwork.set_size(iwork_size, 1);
-
- // compute the actual decomposition
- info = binding::syevr(jobz, range, uplo, n, &a(0,0),
- a.nr(), vl, vu, il, iu, abstol, &num_eigenvalues_found,
- &w(0,0), &z(0,0), z.nr(), &isuppz(0,0), &work(0,0), work.size(),
- &iwork(0,0), iwork.size());
-
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2, long NR3, long NR4,
- long NC1, long NC2, long NC3, long NC4,
- typename MM
- >
- int syevr (
- const char jobz,
- const char range,
- char uplo,
- matrix<T,NR1,NC1,MM,row_major_layout>& a,
- const double vl,
- const double vu,
- const integer il,
- const integer iu,
- const double abstol,
- integer& num_eigenvalues_found,
- matrix<T,NR2,NC2,MM,row_major_layout>& w,
- matrix<T,NR3,NC3,MM,row_major_layout>& z,
- matrix<integer,NR4,NC4,MM,row_major_layout>& isuppz
- )
- {
- matrix<T,0,1,MM,row_major_layout> work;
- matrix<integer,0,1,MM,row_major_layout> iwork;
-
- if (uplo == 'L')
- uplo = 'U';
- else
- uplo = 'L';
-
- const long n = a.nr();
-
- w.set_size(n,1);
-
- isuppz.set_size(2*n, 1);
-
- if (jobz == 'V')
- {
- z.set_size(n,n);
- }
- else
- {
- z.set_size(NR3?NR3:1, NC3?NC3:1);
- }
-
- // figure out how big the workspace needs to be.
- T work_size = 1;
- integer iwork_size = 1;
- int info = binding::syevr(jobz, range, uplo, n, &a(0,0),
- a.nc(), vl, vu, il, iu, abstol, &num_eigenvalues_found,
- &w(0,0), &z(0,0), z.nc(), &isuppz(0,0), &work_size, -1,
- &iwork_size, -1);
-
- if (info != 0)
- return info;
-
- if (work.size() < work_size)
- work.set_size(static_cast<long>(work_size), 1);
- if (iwork.size() < iwork_size)
- iwork.set_size(iwork_size, 1);
-
- // compute the actual decomposition
- info = binding::syevr(jobz, range, uplo, n, &a(0,0),
- a.nc(), vl, vu, il, iu, abstol, &num_eigenvalues_found,
- &w(0,0), &z(0,0), z.nc(), &isuppz(0,0), &work(0,0), work.size(),
- &iwork(0,0), iwork.size());
-
- z = trans(z);
-
- return info;
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_LAPACk_EVR_Hh_
-
-
-
diff --git a/ml/dlib/dlib/matrix/matrix.h b/ml/dlib/dlib/matrix/matrix.h
deleted file mode 100644
index b16635879..000000000
--- a/ml/dlib/dlib/matrix/matrix.h
+++ /dev/null
@@ -1,2162 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_
-#define DLIB_MATRIx_
-
-#include "matrix_exp.h"
-#include "matrix_abstract.h"
-#include "../algs.h"
-#include "../serialize.h"
-#include "../enable_if.h"
-#include <sstream>
-#include <algorithm>
-#include "../memory_manager.h"
-#include "../is_kind.h"
-#include "matrix_data_layout.h"
-#include "matrix_assign_fwd.h"
-#include "matrix_op.h"
-#include <utility>
-#ifdef DLIB_HAS_INITIALIZER_LISTS
-#include <initializer_list>
-#endif
-
-#ifdef MATLAB_MEX_FILE
-#include <mex.h>
-#endif
-
-#ifdef _MSC_VER
-// Disable the following warnings for Visual Studio
-
-// This warning is:
-// "warning C4355: 'this' : used in base member initializer list"
-// Which we get from this code but it is not an error so I'm turning this
-// warning off and then turning it back on at the end of the file.
-#pragma warning(disable : 4355)
-
-// "warning C4723: potential divide by 0" - This warning is triggered in
-// matrix(const std::initializer_list<T>& l) where the compiler can see that
-// matrix<> was templated in a way making NR ending up 0, but division by 0 at runtime
-// is not possible because the division operation is inside "if (NR!=0)" block.
-#pragma warning(disable : 4723)
-
-#endif
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- // This template will perform the needed loop for element multiplication using whichever
- // dimension is provided as a compile time constant (if one is at all).
- template <
- typename LHS,
- typename RHS,
- long lhs_nc = LHS::NC,
- long rhs_nr = RHS::NR
- >
- struct matrix_multiply_helper
- {
- typedef typename LHS::type type;
- template <typename RHS_, typename LHS_>
- inline const static type eval (
- const RHS_& rhs,
- const LHS_& lhs,
- const long r,
- const long c
- )
- {
- type temp = lhs(r,0)*rhs(0,c);
- for (long i = 1; i < rhs.nr(); ++i)
- {
- temp += lhs(r,i)*rhs(i,c);
- }
- return temp;
- }
- };
-
- template <
- typename LHS,
- typename RHS,
- long lhs_nc
- >
- struct matrix_multiply_helper <LHS,RHS,lhs_nc,0>
- {
- typedef typename LHS::type type;
- template <typename RHS_, typename LHS_>
- inline const static type eval (
- const RHS_& rhs,
- const LHS_& lhs,
- const long r,
- const long c
- )
- {
- type temp = lhs(r,0)*rhs(0,c);
- for (long i = 1; i < lhs.nc(); ++i)
- {
- temp += lhs(r,i)*rhs(i,c);
- }
- return temp;
- }
- };
-
- template <typename LHS, typename RHS>
- class matrix_multiply_exp;
-
- template <typename LHS, typename RHS>
- struct matrix_traits<matrix_multiply_exp<LHS,RHS> >
- {
- typedef typename LHS::type type;
- typedef typename LHS::type const_ret_type;
- typedef typename LHS::mem_manager_type mem_manager_type;
- typedef typename LHS::layout_type layout_type;
- const static long NR = LHS::NR;
- const static long NC = RHS::NC;
-
-#ifdef DLIB_USE_BLAS
- // if there are BLAS functions to be called then we want to make sure we
- // always evaluate any complex expressions so that the BLAS bindings can happen.
- const static bool lhs_is_costly = (LHS::cost > 2)&&(RHS::NC != 1 || LHS::cost >= 10000);
- const static bool rhs_is_costly = (RHS::cost > 2)&&(LHS::NR != 1 || RHS::cost >= 10000);
-#else
- const static bool lhs_is_costly = (LHS::cost > 4)&&(RHS::NC != 1);
- const static bool rhs_is_costly = (RHS::cost > 4)&&(LHS::NR != 1);
-#endif
-
- // Note that if we decide that one of the matrices is too costly we will evaluate it
- // into a temporary. Doing this resets its cost back to 1.
- const static long lhs_cost = ((lhs_is_costly==true)? 1 : (LHS::cost));
- const static long rhs_cost = ((rhs_is_costly==true)? 1 : (RHS::cost));
-
- // The cost of evaluating an element of a matrix multiply is the cost of evaluating elements from
- // RHS and LHS times the number of rows/columns in the RHS/LHS matrix. If we don't know the matrix
- // dimensions then just assume it is really large.
- const static long cost = ((tmax<LHS::NC,RHS::NR>::value!=0)? ((lhs_cost+rhs_cost)*tmax<LHS::NC,RHS::NR>::value):(10000));
- };
-
- template <typename T, bool is_ref> struct conditional_matrix_temp { typedef typename T::matrix_type type; };
- template <typename T> struct conditional_matrix_temp<T,true> { typedef T& type; };
-
- template <
- typename LHS,
- typename RHS
- >
- class matrix_multiply_exp : public matrix_exp<matrix_multiply_exp<LHS,RHS> >
- {
- /*!
- REQUIREMENTS ON LHS AND RHS
- - must be matrix_exp objects.
- !*/
- public:
-
- typedef typename matrix_traits<matrix_multiply_exp>::type type;
- typedef typename matrix_traits<matrix_multiply_exp>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_multiply_exp>::mem_manager_type mem_manager_type;
- const static long NR = matrix_traits<matrix_multiply_exp>::NR;
- const static long NC = matrix_traits<matrix_multiply_exp>::NC;
- const static long cost = matrix_traits<matrix_multiply_exp>::cost;
- typedef typename matrix_traits<matrix_multiply_exp>::layout_type layout_type;
-
-
- const static bool lhs_is_costly = matrix_traits<matrix_multiply_exp>::lhs_is_costly;
- const static bool rhs_is_costly = matrix_traits<matrix_multiply_exp>::rhs_is_costly;
- const static bool either_is_costly = lhs_is_costly || rhs_is_costly;
- const static bool both_are_costly = lhs_is_costly && rhs_is_costly;
-
- typedef typename conditional_matrix_temp<const LHS,lhs_is_costly == false>::type LHS_ref_type;
- typedef typename conditional_matrix_temp<const RHS,rhs_is_costly == false>::type RHS_ref_type;
-
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of objects.
- template <typename T1, typename T2>
- matrix_multiply_exp (T1,T2);
-
- inline matrix_multiply_exp (
- const LHS& lhs_,
- const RHS& rhs_
- ) :
- lhs(lhs_),
- rhs(rhs_)
- {
- // You are trying to multiply two incompatible matrices together. The number of columns
- // in the matrix on the left must match the number of rows in the matrix on the right.
- COMPILE_TIME_ASSERT(LHS::NC == RHS::NR || LHS::NC*RHS::NR == 0);
- DLIB_ASSERT(lhs.nc() == rhs.nr() && lhs.size() > 0 && rhs.size() > 0,
- "\tconst matrix_exp operator*(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to multiply two incompatible matrices together"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
- // You can't multiply matrices together if they don't both contain the same type of elements.
- COMPILE_TIME_ASSERT((is_same_type<typename LHS::type, typename RHS::type>::value == true));
- }
-
- inline const type operator() (
- const long r,
- const long c
- ) const
- {
- return matrix_multiply_helper<LHS,RHS>::eval(rhs,lhs,r,c);
- }
-
- inline const type operator() ( long i ) const
- { return matrix_exp<matrix_multiply_exp>::operator()(i); }
-
- long nr (
- ) const { return lhs.nr(); }
-
- long nc (
- ) const { return rhs.nc(); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return lhs.aliases(item) || rhs.aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return aliases(item); }
-
- LHS_ref_type lhs;
- RHS_ref_type rhs;
- };
-
- template < typename EXP1, typename EXP2 >
- inline const matrix_multiply_exp<EXP1, EXP2> operator* (
- const matrix_exp<EXP1>& m1,
- const matrix_exp<EXP2>& m2
- )
- {
- return matrix_multiply_exp<EXP1, EXP2>(m1.ref(), m2.ref());
- }
-
- template <typename M, bool use_reference = true>
- class matrix_mul_scal_exp;
-
- // -------------------------
-
- // Now we declare some overloads that cause any scalar multiplications to percolate
- // up and outside of any matrix multiplies. Note that we are using the non-reference containing
- // mode of the matrix_mul_scal_exp object since we are passing in locally constructed matrix_multiply_exp
- // objects. So the matrix_mul_scal_exp object will contain copies of matrix_multiply_exp objects
- // rather than references to them. This could result in extra matrix copies if the matrix_multiply_exp
- // decided it should evaluate any of its arguments. So we also try to not apply this percolating operation
- // if the matrix_multiply_exp would contain a fully evaluated copy of the original matrix_mul_scal_exp
- // expression.
- //
- // Also, the reason we want to apply this transformation in the first place is because it (1) makes
- // the expressions going into matrix multiply expressions simpler and (2) it makes it a lot more
- // straightforward to bind BLAS calls to matrix expressions involving scalar multiplies.
- template < typename EXP1, typename EXP2 >
- inline const typename disable_if_c< matrix_multiply_exp<matrix_mul_scal_exp<EXP1>, matrix_mul_scal_exp<EXP2> >::both_are_costly ,
- matrix_mul_scal_exp<matrix_multiply_exp<EXP1, EXP2>,false> >::type operator* (
- const matrix_mul_scal_exp<EXP1>& m1,
- const matrix_mul_scal_exp<EXP2>& m2
- )
- {
- typedef matrix_multiply_exp<EXP1, EXP2> exp1;
- typedef matrix_mul_scal_exp<exp1,false> exp2;
- return exp2(exp1(m1.m, m2.m), m1.s*m2.s);
- }
-
- template < typename EXP1, typename EXP2 >
- inline const typename disable_if_c< matrix_multiply_exp<matrix_mul_scal_exp<EXP1>, EXP2 >::lhs_is_costly ,
- matrix_mul_scal_exp<matrix_multiply_exp<EXP1, EXP2>,false> >::type operator* (
- const matrix_mul_scal_exp<EXP1>& m1,
- const matrix_exp<EXP2>& m2
- )
- {
- typedef matrix_multiply_exp<EXP1, EXP2> exp1;
- typedef matrix_mul_scal_exp<exp1,false> exp2;
- return exp2(exp1(m1.m, m2.ref()), m1.s);
- }
-
- template < typename EXP1, typename EXP2 >
- inline const typename disable_if_c< matrix_multiply_exp<EXP1, matrix_mul_scal_exp<EXP2> >::rhs_is_costly ,
- matrix_mul_scal_exp<matrix_multiply_exp<EXP1, EXP2>,false> >::type operator* (
- const matrix_exp<EXP1>& m1,
- const matrix_mul_scal_exp<EXP2>& m2
- )
- {
- typedef matrix_multiply_exp<EXP1, EXP2> exp1;
- typedef matrix_mul_scal_exp<exp1,false> exp2;
- return exp2(exp1(m1.ref(), m2.m), m2.s);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename LHS, typename RHS>
- class matrix_add_exp;
-
- template <typename LHS, typename RHS>
- struct matrix_traits<matrix_add_exp<LHS,RHS> >
- {
- typedef typename LHS::type type;
- typedef typename LHS::type const_ret_type;
- typedef typename LHS::mem_manager_type mem_manager_type;
- typedef typename LHS::layout_type layout_type;
- const static long NR = (RHS::NR > LHS::NR) ? RHS::NR : LHS::NR;
- const static long NC = (RHS::NC > LHS::NC) ? RHS::NC : LHS::NC;
- const static long cost = LHS::cost+RHS::cost+1;
- };
-
- template <
- typename LHS,
- typename RHS
- >
- class matrix_add_exp : public matrix_exp<matrix_add_exp<LHS,RHS> >
- {
- /*!
- REQUIREMENTS ON LHS AND RHS
- - must be matrix_exp objects.
- !*/
- public:
- typedef typename matrix_traits<matrix_add_exp>::type type;
- typedef typename matrix_traits<matrix_add_exp>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_add_exp>::mem_manager_type mem_manager_type;
- const static long NR = matrix_traits<matrix_add_exp>::NR;
- const static long NC = matrix_traits<matrix_add_exp>::NC;
- const static long cost = matrix_traits<matrix_add_exp>::cost;
- typedef typename matrix_traits<matrix_add_exp>::layout_type layout_type;
-
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of objects.
- template <typename T1, typename T2>
- matrix_add_exp (T1,T2);
-
- matrix_add_exp (
- const LHS& lhs_,
- const RHS& rhs_
- ) :
- lhs(lhs_),
- rhs(rhs_)
- {
- // You can only add matrices together if they both have the same number of rows and columns.
- COMPILE_TIME_ASSERT(LHS::NR == RHS::NR || LHS::NR == 0 || RHS::NR == 0);
- COMPILE_TIME_ASSERT(LHS::NC == RHS::NC || LHS::NC == 0 || RHS::NC == 0);
- DLIB_ASSERT(lhs.nc() == rhs.nc() &&
- lhs.nr() == rhs.nr(),
- "\tconst matrix_exp operator+(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to add two incompatible matrices together"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
- // You can only add matrices together if they both contain the same types of elements.
- COMPILE_TIME_ASSERT((is_same_type<typename LHS::type, typename RHS::type>::value == true));
- }
-
- const type operator() (
- long r,
- long c
- ) const { return lhs(r,c) + rhs(r,c); }
-
- inline const type operator() ( long i ) const
- { return matrix_exp<matrix_add_exp>::operator()(i); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return lhs.aliases(item) || rhs.aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return lhs.destructively_aliases(item) || rhs.destructively_aliases(item); }
-
- long nr (
- ) const { return lhs.nr(); }
-
- long nc (
- ) const { return lhs.nc(); }
-
- const LHS& lhs;
- const RHS& rhs;
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_add_exp<EXP1, EXP2> operator+ (
- const matrix_exp<EXP1>& m1,
- const matrix_exp<EXP2>& m2
- )
- {
- return matrix_add_exp<EXP1, EXP2>(m1.ref(),m2.ref());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename LHS, typename RHS>
- class matrix_subtract_exp;
-
- template <typename LHS, typename RHS>
- struct matrix_traits<matrix_subtract_exp<LHS,RHS> >
- {
- typedef typename LHS::type type;
- typedef typename LHS::type const_ret_type;
- typedef typename LHS::mem_manager_type mem_manager_type;
- typedef typename LHS::layout_type layout_type;
- const static long NR = (RHS::NR > LHS::NR) ? RHS::NR : LHS::NR;
- const static long NC = (RHS::NC > LHS::NC) ? RHS::NC : LHS::NC;
- const static long cost = LHS::cost+RHS::cost+1;
- };
-
- template <
- typename LHS,
- typename RHS
- >
- class matrix_subtract_exp : public matrix_exp<matrix_subtract_exp<LHS,RHS> >
- {
- /*!
- REQUIREMENTS ON LHS AND RHS
- - must be matrix_exp objects.
- !*/
- public:
- typedef typename matrix_traits<matrix_subtract_exp>::type type;
- typedef typename matrix_traits<matrix_subtract_exp>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_subtract_exp>::mem_manager_type mem_manager_type;
- const static long NR = matrix_traits<matrix_subtract_exp>::NR;
- const static long NC = matrix_traits<matrix_subtract_exp>::NC;
- const static long cost = matrix_traits<matrix_subtract_exp>::cost;
- typedef typename matrix_traits<matrix_subtract_exp>::layout_type layout_type;
-
-
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of objects.
- template <typename T1, typename T2>
- matrix_subtract_exp (T1,T2);
-
- matrix_subtract_exp (
- const LHS& lhs_,
- const RHS& rhs_
- ) :
- lhs(lhs_),
- rhs(rhs_)
- {
- // You can only subtract one matrix from another if they both have the same number of rows and columns.
- COMPILE_TIME_ASSERT(LHS::NR == RHS::NR || LHS::NR == 0 || RHS::NR == 0);
- COMPILE_TIME_ASSERT(LHS::NC == RHS::NC || LHS::NC == 0 || RHS::NC == 0);
- DLIB_ASSERT(lhs.nc() == rhs.nc() &&
- lhs.nr() == rhs.nr(),
- "\tconst matrix_exp operator-(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to subtract two incompatible matrices"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
- // You can only subtract one matrix from another if they both contain elements of the same type.
- COMPILE_TIME_ASSERT((is_same_type<typename LHS::type, typename RHS::type>::value == true));
- }
-
- const type operator() (
- long r,
- long c
- ) const { return lhs(r,c) - rhs(r,c); }
-
- inline const type operator() ( long i ) const
- { return matrix_exp<matrix_subtract_exp>::operator()(i); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return lhs.aliases(item) || rhs.aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return lhs.destructively_aliases(item) || rhs.destructively_aliases(item); }
-
- long nr (
- ) const { return lhs.nr(); }
-
- long nc (
- ) const { return lhs.nc(); }
-
- const LHS& lhs;
- const RHS& rhs;
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_subtract_exp<EXP1, EXP2> operator- (
- const matrix_exp<EXP1>& m1,
- const matrix_exp<EXP2>& m2
- )
- {
- return matrix_subtract_exp<EXP1, EXP2>(m1.ref(),m2.ref());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- class matrix_div_scal_exp;
-
- template <typename M>
- struct matrix_traits<matrix_div_scal_exp<M> >
- {
- typedef typename M::type type;
- typedef typename M::type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const static long NR = M::NR;
- const static long NC = M::NC;
- const static long cost = M::cost+1;
- };
-
- template <
- typename M
- >
- class matrix_div_scal_exp : public matrix_exp<matrix_div_scal_exp<M> >
- {
- /*!
- REQUIREMENTS ON M
- - must be a matrix_exp object.
- !*/
- public:
- typedef typename matrix_traits<matrix_div_scal_exp>::type type;
- typedef typename matrix_traits<matrix_div_scal_exp>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_div_scal_exp>::mem_manager_type mem_manager_type;
- const static long NR = matrix_traits<matrix_div_scal_exp>::NR;
- const static long NC = matrix_traits<matrix_div_scal_exp>::NC;
- const static long cost = matrix_traits<matrix_div_scal_exp>::cost;
- typedef typename matrix_traits<matrix_div_scal_exp>::layout_type layout_type;
-
-
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of objects.
- template <typename T1>
- matrix_div_scal_exp (T1, const type&);
-
- matrix_div_scal_exp (
- const M& m_,
- const type& s_
- ) :
- m(m_),
- s(s_)
- {}
-
- const type operator() (
- long r,
- long c
- ) const { return m(r,c)/s; }
-
- inline const type operator() ( long i ) const
- { return matrix_exp<matrix_div_scal_exp>::operator()(i); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return m.aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return m.destructively_aliases(item); }
-
- long nr (
- ) const { return m.nr(); }
-
- long nc (
- ) const { return m.nc(); }
-
- const M& m;
- const type s;
- };
-
- template <
- typename EXP,
- typename S
- >
- inline const typename enable_if_c<std::numeric_limits<typename EXP::type>::is_integer, matrix_div_scal_exp<EXP> >::type operator/ (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- return matrix_div_scal_exp<EXP>(m.ref(),static_cast<typename EXP::type>(s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, bool use_reference >
- struct matrix_traits<matrix_mul_scal_exp<M,use_reference> >
- {
- typedef typename M::type type;
- typedef typename M::type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const static long NR = M::NR;
- const static long NC = M::NC;
- const static long cost = M::cost+1;
- };
-
- template <typename T, bool is_ref> struct conditional_reference { typedef T type; };
- template <typename T> struct conditional_reference<T,true> { typedef T& type; };
-
-
- template <
- typename M,
- bool use_reference
- >
- class matrix_mul_scal_exp : public matrix_exp<matrix_mul_scal_exp<M,use_reference> >
- {
- /*!
- REQUIREMENTS ON M
- - must be a matrix_exp object.
-
- !*/
- public:
- typedef typename matrix_traits<matrix_mul_scal_exp>::type type;
- typedef typename matrix_traits<matrix_mul_scal_exp>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_mul_scal_exp>::mem_manager_type mem_manager_type;
- const static long NR = matrix_traits<matrix_mul_scal_exp>::NR;
- const static long NC = matrix_traits<matrix_mul_scal_exp>::NC;
- const static long cost = matrix_traits<matrix_mul_scal_exp>::cost;
- typedef typename matrix_traits<matrix_mul_scal_exp>::layout_type layout_type;
-
- // You aren't allowed to multiply a matrix of matrices by a scalar.
- COMPILE_TIME_ASSERT(is_matrix<type>::value == false);
-
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of objects.
- template <typename T1>
- matrix_mul_scal_exp (T1, const type&);
-
- matrix_mul_scal_exp (
- const M& m_,
- const type& s_
- ) :
- m(m_),
- s(s_)
- {}
-
- const type operator() (
- long r,
- long c
- ) const { return m(r,c)*s; }
-
- inline const type operator() ( long i ) const
- { return matrix_exp<matrix_mul_scal_exp>::operator()(i); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return m.aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return m.destructively_aliases(item); }
-
- long nr (
- ) const { return m.nr(); }
-
- long nc (
- ) const { return m.nc(); }
-
- typedef typename conditional_reference<const M,use_reference>::type M_ref_type;
-
- M_ref_type m;
- const type s;
- };
-
- template <
- typename EXP,
- typename S
- >
- inline typename disable_if<is_matrix<S>, const matrix_mul_scal_exp<EXP> >::type operator* (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- typedef typename EXP::type type;
- return matrix_mul_scal_exp<EXP>(m.ref(),static_cast<type>(s));
- }
-
- template <
- typename EXP,
- typename S,
- bool B
- >
- inline typename disable_if<is_matrix<S>, const matrix_mul_scal_exp<EXP> >::type operator* (
- const matrix_mul_scal_exp<EXP,B>& m,
- const S& s
- )
- {
- typedef typename EXP::type type;
- return matrix_mul_scal_exp<EXP>(m.m,static_cast<type>(s)*m.s);
- }
-
- template <
- typename EXP,
- typename S
- >
- inline typename disable_if<is_matrix<S>, const matrix_mul_scal_exp<EXP> >::type operator* (
- const S& s,
- const matrix_exp<EXP>& m
- )
- {
- typedef typename EXP::type type;
- return matrix_mul_scal_exp<EXP>(m.ref(),static_cast<type>(s));
- }
-
- template <
- typename EXP,
- typename S,
- bool B
- >
- inline typename disable_if<is_matrix<S>, const matrix_mul_scal_exp<EXP> >::type operator* (
- const S& s,
- const matrix_mul_scal_exp<EXP,B>& m
- )
- {
- typedef typename EXP::type type;
- return matrix_mul_scal_exp<EXP>(m.m,static_cast<type>(s)*m.s);
- }
-
- template <
- typename EXP ,
- typename S
- >
- inline const typename disable_if_c<std::numeric_limits<typename EXP::type>::is_integer, matrix_mul_scal_exp<EXP> >::type operator/ (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- typedef typename EXP::type type;
- const type one = 1;
- return matrix_mul_scal_exp<EXP>(m.ref(),one/static_cast<type>(s));
- }
-
- template <
- typename EXP,
- bool B,
- typename S
- >
- inline const typename disable_if_c<std::numeric_limits<typename EXP::type>::is_integer, matrix_mul_scal_exp<EXP> >::type operator/ (
- const matrix_mul_scal_exp<EXP,B>& m,
- const S& s
- )
- {
- typedef typename EXP::type type;
- return matrix_mul_scal_exp<EXP>(m.m,m.s/static_cast<type>(s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_s_div_m : basic_op_m<M>
- {
- typedef typename M::type type;
-
- op_s_div_m( const M& m_, const type& s_) : basic_op_m<M>(m_), s(s_){}
-
- const type s;
-
- const static long cost = M::cost+1;
- typedef const typename M::type const_ret_type;
- const_ret_type apply (long r, long c) const
- {
- return s/this->m(r,c);
- }
- };
-
- template <
- typename EXP,
- typename S
- >
- const typename disable_if<is_matrix<S>, matrix_op<op_s_div_m<EXP> > >::type operator/ (
- const S& val,
- const matrix_exp<EXP>& m
- )
- {
- typedef typename EXP::type type;
-
- typedef op_s_div_m<EXP> op;
- return matrix_op<op>(op(m.ref(), static_cast<type>(val)));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- inline const matrix_mul_scal_exp<EXP> operator- (
- const matrix_exp<EXP>& m
- )
- {
- return matrix_mul_scal_exp<EXP>(m.ref(),-1);
- }
-
- template <
- typename EXP,
- bool B
- >
- inline const matrix_mul_scal_exp<EXP> operator- (
- const matrix_mul_scal_exp<EXP,B>& m
- )
- {
- return matrix_mul_scal_exp<EXP>(m.m,-1*m.s);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_add_scalar : basic_op_m<M>
- {
- typedef typename M::type type;
-
- op_add_scalar( const M& m_, const type& s_) : basic_op_m<M>(m_), s(s_){}
-
- const type s;
-
- const static long cost = M::cost+1;
- typedef const typename M::type const_ret_type;
- const_ret_type apply (long r, long c) const
- {
- return this->m(r,c) + s;
- }
- };
-
- template <
- typename EXP,
- typename T
- >
- const typename disable_if<is_matrix<T>, matrix_op<op_add_scalar<EXP> > >::type operator+ (
- const matrix_exp<EXP>& m,
- const T& val
- )
- {
- typedef typename EXP::type type;
-
- typedef op_add_scalar<EXP> op;
- return matrix_op<op>(op(m.ref(), static_cast<type>(val)));
- }
-
- template <
- typename EXP,
- typename T
- >
- const typename disable_if<is_matrix<T>, matrix_op<op_add_scalar<EXP> > >::type operator+ (
- const T& val,
- const matrix_exp<EXP>& m
- )
- {
- typedef typename EXP::type type;
-
- typedef op_add_scalar<EXP> op;
- return matrix_op<op>(op(m.ref(), static_cast<type>(val)));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_subl_scalar : basic_op_m<M>
- {
- typedef typename M::type type;
-
- op_subl_scalar( const M& m_, const type& s_) : basic_op_m<M>(m_), s(s_){}
-
- const type s;
-
- const static long cost = M::cost+1;
- typedef const typename M::type const_ret_type;
- const_ret_type apply (long r, long c) const
- {
- return s - this->m(r,c) ;
- }
- };
-
- template <
- typename EXP,
- typename T
- >
- const typename disable_if<is_matrix<T>, matrix_op<op_subl_scalar<EXP> > >::type operator- (
- const T& val,
- const matrix_exp<EXP>& m
- )
- {
- typedef typename EXP::type type;
-
- typedef op_subl_scalar<EXP> op;
- return matrix_op<op>(op(m.ref(), static_cast<type>(val)));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_subr_scalar : basic_op_m<M>
- {
- typedef typename M::type type;
-
- op_subr_scalar( const M& m_, const type& s_) : basic_op_m<M>(m_), s(s_){}
-
- const type s;
-
- const static long cost = M::cost+1;
- typedef const typename M::type const_ret_type;
- const_ret_type apply (long r, long c) const
- {
- return this->m(r,c) - s;
- }
- };
-
- template <
- typename EXP,
- typename T
- >
- const typename disable_if<is_matrix<T>, matrix_op<op_subr_scalar<EXP> > >::type operator- (
- const matrix_exp<EXP>& m,
- const T& val
- )
- {
- typedef typename EXP::type type;
-
- typedef op_subr_scalar<EXP> op;
- return matrix_op<op>(op(m.ref(), static_cast<type>(val)));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP1,
- typename EXP2
- >
- bool operator== (
- const matrix_exp<EXP1>& m1,
- const matrix_exp<EXP2>& m2
- )
- {
- if (m1.nr() == m2.nr() && m1.nc() == m2.nc())
- {
- for (long r = 0; r < m1.nr(); ++r)
- {
- for (long c = 0; c < m1.nc(); ++c)
- {
- if (m1(r,c) != m2(r,c))
- return false;
- }
- }
- return true;
- }
- return false;
- }
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline bool operator!= (
- const matrix_exp<EXP1>& m1,
- const matrix_exp<EXP2>& m2
- ) { return !(m1 == m2); }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- struct op_pointer_to_mat;
- template <typename T>
- struct op_pointer_to_col_vect;
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager,
- typename layout
- >
- struct matrix_traits<matrix<T,num_rows, num_cols, mem_manager, layout> >
- {
- typedef T type;
- typedef const T& const_ret_type;
- typedef mem_manager mem_manager_type;
- typedef layout layout_type;
- const static long NR = num_rows;
- const static long NC = num_cols;
- const static long cost = 1;
-
- };
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager,
- typename layout
- >
- class matrix : public matrix_exp<matrix<T,num_rows,num_cols, mem_manager,layout> >
- {
-
- COMPILE_TIME_ASSERT(num_rows >= 0 && num_cols >= 0);
-
- public:
- typedef typename matrix_traits<matrix>::type type;
- typedef typename matrix_traits<matrix>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix>::mem_manager_type mem_manager_type;
- typedef typename matrix_traits<matrix>::layout_type layout_type;
- const static long NR = matrix_traits<matrix>::NR;
- const static long NC = matrix_traits<matrix>::NC;
- const static long cost = matrix_traits<matrix>::cost;
- typedef T* iterator;
- typedef const T* const_iterator;
-
- matrix ()
- {
- }
-
- explicit matrix (
- long length
- )
- {
- // This object you are trying to call matrix(length) on is not a column or
- // row vector.
- COMPILE_TIME_ASSERT(NR == 1 || NC == 1);
- DLIB_ASSERT( length >= 0,
- "\tmatrix::matrix(length)"
- << "\n\tlength must be at least 0"
- << "\n\tlength: " << length
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- << "\n\tthis: " << this
- );
-
- if (NR == 1)
- {
- DLIB_ASSERT(NC == 0 || NC == length,
- "\tmatrix::matrix(length)"
- << "\n\tSince this is a statically sized matrix length must equal NC"
- << "\n\tlength: " << length
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- << "\n\tthis: " << this
- );
-
- data.set_size(1,length);
- }
- else
- {
- DLIB_ASSERT(NR == 0 || NR == length,
- "\tvoid matrix::set_size(length)"
- << "\n\tSince this is a statically sized matrix length must equal NR"
- << "\n\tlength: " << length
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- << "\n\tthis: " << this
- );
-
- data.set_size(length,1);
- }
- }
-
- matrix (
- long rows,
- long cols
- )
- {
- DLIB_ASSERT( (NR == 0 || NR == rows) && ( NC == 0 || NC == cols) &&
- rows >= 0 && cols >= 0,
- "\tvoid matrix::matrix(rows, cols)"
- << "\n\tYou have supplied conflicting matrix dimensions"
- << "\n\trows: " << rows
- << "\n\tcols: " << cols
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- );
- data.set_size(rows,cols);
- }
-
- template <typename EXP>
- matrix (
- const matrix_exp<EXP>& m
- )
- {
- // You get an error on this line if the matrix m contains a type that isn't
- // the same as the type contained in the target matrix.
- COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true) ||
- (is_matrix<typename EXP::type>::value == true));
-
- // The matrix you are trying to assign m to is a statically sized matrix and
- // m's dimensions don't match that of *this.
- COMPILE_TIME_ASSERT(EXP::NR == NR || NR == 0 || EXP::NR == 0);
- COMPILE_TIME_ASSERT(EXP::NC == NC || NC == 0 || EXP::NC == 0);
- DLIB_ASSERT((NR == 0 || NR == m.nr()) && (NC == 0 || NC == m.nc()),
- "\tmatrix& matrix::matrix(const matrix_exp& m)"
- << "\n\tYou are trying to assign a dynamically sized matrix to a statically sized matrix with the wrong size"
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tthis: " << this
- );
-
- data.set_size(m.nr(),m.nc());
-
- matrix_assign(*this, m);
- }
-
- matrix (
- const matrix& m
- ) : matrix_exp<matrix>(*this)
- {
- data.set_size(m.nr(),m.nc());
- matrix_assign(*this, m);
- }
-
-#ifdef DLIB_HAS_INITIALIZER_LISTS
- matrix(const std::initializer_list<T>& l)
- {
- if (NR*NC != 0)
- {
- DLIB_ASSERT(l.size() == NR*NC,
- "\t matrix::matrix(const std::initializer_list& l)"
- << "\n\t You are trying to initialize a statically sized matrix with a list that doesn't have a matching size."
- << "\n\t l.size(): "<< l.size()
- << "\n\t NR*NC: "<< NR*NC);
-
- data.set_size(NR, NC);
- }
- else if (NR!=0)
- {
- DLIB_ASSERT(l.size()%NR == 0,
- "\t matrix::matrix(const std::initializer_list& l)"
- << "\n\t You are trying to initialize a statically sized matrix with a list that doesn't have a compatible size."
- << "\n\t l.size(): "<< l.size()
- << "\n\t NR: "<< NR);
-
- if (l.size() != 0)
- data.set_size(NR, l.size()/NR);
- }
- else if (NC!=0)
- {
- DLIB_ASSERT(l.size()%NC == 0,
- "\t matrix::matrix(const std::initializer_list& l)"
- << "\n\t You are trying to initialize a statically sized matrix with a list that doesn't have a compatible size."
- << "\n\t l.size(): "<< l.size()
- << "\n\t NC: "<< NC);
-
- if (l.size() != 0)
- data.set_size(l.size()/NC, NC);
- }
- else if (l.size() != 0)
- {
- data.set_size(l.size(),1);
- }
-
- if (l.size() != 0)
- {
- T* d = &data(0,0);
- for (auto&& v : l)
- *d++ = v;
- }
-
- }
-
- matrix& operator=(const std::initializer_list<T>& l)
- {
- matrix temp(l);
- temp.swap(*this);
- return *this;
- }
-#endif // DLIB_HAS_INITIALIZER_LISTS
-
-#ifdef DLIB_HAS_RVALUE_REFERENCES
- matrix(matrix&& item)
- {
- #ifdef MATLAB_MEX_FILE
- // You can't move memory around when compiled in a matlab mex file and the
- // different locations have different ownership settings.
- if (data._private_is_owned_by_matlab() == item.data._private_is_owned_by_matlab())
- {
- swap(item);
- }
- else
- {
- data.set_size(item.nr(),item.nc());
- matrix_assign(*this, item);
- }
- #else
- swap(item);
- #endif
- }
-
- matrix& operator= (
- matrix&& rhs
- )
- {
- #ifdef MATLAB_MEX_FILE
- // You can't move memory around when compiled in a matlab mex file and the
- // different locations have different ownership settings.
- if (data._private_is_owned_by_matlab() == rhs.data._private_is_owned_by_matlab())
- {
- swap(rhs);
- }
- else
- {
- data.set_size(rhs.nr(),rhs.nc());
- matrix_assign(*this, rhs);
- }
- #else
- swap(rhs);
- #endif
- return *this;
- }
-#endif // DLIB_HAS_RVALUE_REFERENCES
-
- template <typename U, size_t len>
- explicit matrix (
- U (&array)[len]
- )
- {
- COMPILE_TIME_ASSERT(NR*NC == len && len > 0);
- size_t idx = 0;
- for (long r = 0; r < NR; ++r)
- {
- for (long c = 0; c < NC; ++c)
- {
- data(r,c) = static_cast<T>(array[idx]);
- ++idx;
- }
- }
- }
-
- T& operator() (
- long r,
- long c
- )
- {
- DLIB_ASSERT(r < nr() && c < nc() &&
- r >= 0 && c >= 0,
- "\tT& matrix::operator(r,c)"
- << "\n\tYou must give a valid row and column"
- << "\n\tr: " << r
- << "\n\tc: " << c
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
- return data(r,c);
- }
-
- const T& operator() (
- long r,
- long c
- ) const
- {
- DLIB_ASSERT(r < nr() && c < nc() &&
- r >= 0 && c >= 0,
- "\tconst T& matrix::operator(r,c)"
- << "\n\tYou must give a valid row and column"
- << "\n\tr: " << r
- << "\n\tc: " << c
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
- return data(r,c);
- }
-
- T& operator() (
- long i
- )
- {
- // You can only use this operator on column vectors.
- COMPILE_TIME_ASSERT(NC == 1 || NC == 0 || NR == 1 || NR == 0);
- DLIB_ASSERT(nc() == 1 || nr() == 1,
- "\tconst type matrix::operator(i)"
- << "\n\tYou can only use this operator on column or row vectors"
- << "\n\ti: " << i
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
- DLIB_ASSERT( 0 <= i && i < size(),
- "\tconst type matrix::operator(i)"
- << "\n\tYou must give a valid row/column number"
- << "\n\ti: " << i
- << "\n\tsize(): " << size()
- << "\n\tthis: " << this
- );
- return data(i);
- }
-
- const T& operator() (
- long i
- ) const
- {
- // You can only use this operator on column vectors.
- COMPILE_TIME_ASSERT(NC == 1 || NC == 0 || NR == 1 || NR == 0);
- DLIB_ASSERT(nc() == 1 || nr() == 1,
- "\tconst type matrix::operator(i)"
- << "\n\tYou can only use this operator on column or row vectors"
- << "\n\ti: " << i
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
- DLIB_ASSERT( 0 <= i && i < size(),
- "\tconst type matrix::operator(i)"
- << "\n\tYou must give a valid row/column number"
- << "\n\ti: " << i
- << "\n\tsize(): " << size()
- << "\n\tthis: " << this
- );
- return data(i);
- }
-
- inline operator const type (
- ) const
- {
- COMPILE_TIME_ASSERT(NC == 1 || NC == 0);
- COMPILE_TIME_ASSERT(NR == 1 || NR == 0);
- DLIB_ASSERT( nr() == 1 && nc() == 1 ,
- "\tmatrix::operator const type"
- << "\n\tYou can only attempt to implicit convert a matrix to a scalar if"
- << "\n\tthe matrix is a 1x1 matrix"
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
- return data(0);
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray(
- mxArray* mem
- )
- {
- data._private_set_mxArray(mem);
- }
-
- mxArray* _private_release_mxArray(
- )
- {
- return data._private_release_mxArray();
- }
-
- void _private_mark_owned_by_matlab()
- {
- data._private_mark_owned_by_matlab();
- }
-
- bool _private_is_owned_by_matlab()
- {
- return data._private_is_owned_by_matlab();
- }
-#endif
-
- void set_size (
- long rows,
- long cols
- )
- {
- DLIB_ASSERT( (NR == 0 || NR == rows) && ( NC == 0 || NC == cols) &&
- rows >= 0 && cols >= 0,
- "\tvoid matrix::set_size(rows, cols)"
- << "\n\tYou have supplied conflicting matrix dimensions"
- << "\n\trows: " << rows
- << "\n\tcols: " << cols
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- << "\n\tthis: " << this
- );
- if (nr() != rows || nc() != cols)
- data.set_size(rows,cols);
- }
-
- void set_size (
- long length
- )
- {
- // This object you are trying to call set_size(length) on is not a column or
- // row vector.
- COMPILE_TIME_ASSERT(NR == 1 || NC == 1);
- DLIB_ASSERT( length >= 0,
- "\tvoid matrix::set_size(length)"
- << "\n\tlength must be at least 0"
- << "\n\tlength: " << length
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- << "\n\tthis: " << this
- );
-
- if (NR == 1)
- {
- DLIB_ASSERT(NC == 0 || NC == length,
- "\tvoid matrix::set_size(length)"
- << "\n\tSince this is a statically sized matrix length must equal NC"
- << "\n\tlength: " << length
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- << "\n\tthis: " << this
- );
-
- if (nc() != length)
- data.set_size(1,length);
- }
- else
- {
- DLIB_ASSERT(NR == 0 || NR == length,
- "\tvoid matrix::set_size(length)"
- << "\n\tSince this is a statically sized matrix length must equal NR"
- << "\n\tlength: " << length
- << "\n\tNR: " << NR
- << "\n\tNC: " << NC
- << "\n\tthis: " << this
- );
-
- if (nr() != length)
- data.set_size(length,1);
- }
- }
-
- long nr (
- ) const { return data.nr(); }
-
- long nc (
- ) const { return data.nc(); }
-
- long size (
- ) const { return data.nr()*data.nc(); }
-
- template <typename U, size_t len>
- matrix& operator= (
- U (&array)[len]
- )
- {
- COMPILE_TIME_ASSERT(NR*NC == len && len > 0);
- size_t idx = 0;
- for (long r = 0; r < NR; ++r)
- {
- for (long c = 0; c < NC; ++c)
- {
- data(r,c) = static_cast<T>(array[idx]);
- ++idx;
- }
- }
- return *this;
- }
-
- template <typename EXP>
- matrix& operator= (
- const matrix_exp<EXP>& m
- )
- {
- // You get an error on this line if the matrix you are trying to
- // assign m to is a statically sized matrix and m's dimensions don't
- // match that of *this.
- COMPILE_TIME_ASSERT(EXP::NR == NR || NR == 0 || EXP::NR == 0);
- COMPILE_TIME_ASSERT(EXP::NC == NC || NC == 0 || EXP::NC == 0);
- DLIB_ASSERT((NR == 0 || nr() == m.nr()) &&
- (NC == 0 || nc() == m.nc()),
- "\tmatrix& matrix::operator=(const matrix_exp& m)"
- << "\n\tYou are trying to assign a dynamically sized matrix to a statically sized matrix with the wrong size"
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tthis: " << this
- );
-
- // You get an error on this line if the matrix m contains a type that isn't
- // the same as the type contained in the target matrix.
- COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true) ||
- (is_matrix<typename EXP::type>::value == true));
- if (m.destructively_aliases(*this) == false)
- {
- // This if statement is seemingly unnecessary since set_size() contains this
- // exact same if statement. However, structuring the code this way causes
- // gcc to handle the way it inlines this function in a much more favorable way.
- if (data.nr() == m.nr() && data.nc() == m.nc())
- {
- matrix_assign(*this, m);
- }
- else
- {
- set_size(m.nr(),m.nc());
- matrix_assign(*this, m);
- }
- }
- else
- {
- // we have to use a temporary matrix object here because
- // *this is aliased inside the matrix_exp m somewhere.
- matrix temp;
- temp.set_size(m.nr(),m.nc());
- matrix_assign(temp, m);
- temp.swap(*this);
- }
- return *this;
- }
-
- template <typename EXP>
- matrix& operator += (
- const matrix_exp<EXP>& m
- )
- {
- // The matrix you are trying to assign m to is a statically sized matrix and
- // m's dimensions don't match that of *this.
- COMPILE_TIME_ASSERT(EXP::NR == NR || NR == 0 || EXP::NR == 0);
- COMPILE_TIME_ASSERT(EXP::NC == NC || NC == 0 || EXP::NC == 0);
- COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true));
- if (nr() == m.nr() && nc() == m.nc())
- {
- if (m.destructively_aliases(*this) == false)
- {
- matrix_assign(*this, *this + m);
- }
- else
- {
- // we have to use a temporary matrix object here because
- // this->data is aliased inside the matrix_exp m somewhere.
- matrix temp;
- temp.set_size(m.nr(),m.nc());
- matrix_assign(temp, *this + m);
- temp.swap(*this);
- }
- }
- else
- {
- DLIB_ASSERT(size() == 0,
- "\t const matrix::operator+=(m)"
- << "\n\t You are trying to add two matrices that have incompatible dimensions.");
- *this = m;
- }
- return *this;
- }
-
-
- template <typename EXP>
- matrix& operator -= (
- const matrix_exp<EXP>& m
- )
- {
- // The matrix you are trying to assign m to is a statically sized matrix and
- // m's dimensions don't match that of *this.
- COMPILE_TIME_ASSERT(EXP::NR == NR || NR == 0 || EXP::NR == 0);
- COMPILE_TIME_ASSERT(EXP::NC == NC || NC == 0 || EXP::NC == 0);
- COMPILE_TIME_ASSERT((is_same_type<typename EXP::type,type>::value == true));
- if (nr() == m.nr() && nc() == m.nc())
- {
- if (m.destructively_aliases(*this) == false)
- {
- matrix_assign(*this, *this - m);
- }
- else
- {
- // we have to use a temporary matrix object here because
- // this->data is aliased inside the matrix_exp m somewhere.
- matrix temp;
- temp.set_size(m.nr(),m.nc());
- matrix_assign(temp, *this - m);
- temp.swap(*this);
- }
- }
- else
- {
- DLIB_ASSERT(size() == 0,
- "\t const matrix::operator-=(m)"
- << "\n\t You are trying to subtract two matrices that have incompatible dimensions.");
- *this = -m;
- }
- return *this;
- }
-
- template <typename EXP>
- matrix& operator *= (
- const matrix_exp<EXP>& m
- )
- {
- *this = *this * m;
- return *this;
- }
-
- matrix& operator += (
- const matrix& m
- )
- {
- const long size = m.nr()*m.nc();
- if (nr() == m.nr() && nc() == m.nc())
- {
- for (long i = 0; i < size; ++i)
- data(i) += m.data(i);
- }
- else
- {
- DLIB_ASSERT(this->size() == 0,
- "\t const matrix::operator+=(m)"
- << "\n\t You are trying to add two matrices that have incompatible dimensions.");
-
- set_size(m.nr(), m.nc());
- for (long i = 0; i < size; ++i)
- data(i) = m.data(i);
- }
- return *this;
- }
-
- matrix& operator -= (
- const matrix& m
- )
- {
- const long size = m.nr()*m.nc();
- if (nr() == m.nr() && nc() == m.nc())
- {
- for (long i = 0; i < size; ++i)
- data(i) -= m.data(i);
- }
- else
- {
- DLIB_ASSERT(this->size() == 0,
- "\t const matrix::operator-=(m)"
- << "\n\t You are trying to subtract two matrices that have incompatible dimensions.");
- set_size(m.nr(), m.nc());
- for (long i = 0; i < size; ++i)
- data(i) = -m.data(i);
- }
- return *this;
- }
-
- matrix& operator += (
- const T val
- )
- {
- const long size = nr()*nc();
- for (long i = 0; i < size; ++i)
- data(i) += val;
-
- return *this;
- }
-
- matrix& operator -= (
- const T val
- )
- {
- const long size = nr()*nc();
- for (long i = 0; i < size; ++i)
- data(i) -= val;
-
- return *this;
- }
-
- matrix& operator *= (
- const T a
- )
- {
- *this = *this * a;
- return *this;
- }
-
- matrix& operator /= (
- const T a
- )
- {
- *this = *this / a;
- return *this;
- }
-
- matrix& operator= (
- const matrix& m
- )
- {
- if (this != &m)
- {
- set_size(m.nr(),m.nc());
- const long size = m.nr()*m.nc();
- for (long i = 0; i < size; ++i)
- data(i) = m.data(i);
- }
- return *this;
- }
-
- void swap (
- matrix& item
- )
- {
- data.swap(item.data);
- }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>&
- ) const { return false; }
-
- bool aliases (
- const matrix_exp<matrix<T,num_rows,num_cols, mem_manager,layout> >& item
- ) const { return (this == &item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>&
- ) const { return false; }
-
- // These two aliases() routines are defined in matrix_mat.h
- bool aliases (
- const matrix_exp<matrix_op<op_pointer_to_mat<T> > >& item
- ) const;
- bool aliases (
- const matrix_exp<matrix_op<op_pointer_to_col_vect<T> > >& item
- ) const;
-
- iterator begin()
- {
- if (size() != 0)
- return &data(0,0);
- else
- return 0;
- }
-
- iterator end()
- {
- if (size() != 0)
- return &data(0,0)+size();
- else
- return 0;
- }
-
- const_iterator begin() const
- {
- if (size() != 0)
- return &data(0,0);
- else
- return 0;
- }
-
- const_iterator end() const
- {
- if (size() != 0)
- return &data(0,0)+size();
- else
- return 0;
- }
-
- private:
- struct literal_assign_helper
- {
- /*
- This struct is a helper struct returned by the operator<<() function below. It is
- used primarily to enable us to put DLIB_CASSERT statements on the usage of the
- operator<< form of matrix assignment.
- */
-
- literal_assign_helper(const literal_assign_helper& item) : m(item.m), r(item.r), c(item.c), has_been_used(false) {}
- explicit literal_assign_helper(matrix* m_): m(m_), r(0), c(0),has_been_used(false) {next();}
- ~literal_assign_helper() noexcept(false)
- {
- DLIB_CASSERT(!has_been_used || r == m->nr(),
- "You have used the matrix comma based assignment incorrectly by failing to\n"
- "supply a full set of values for every element of a matrix object.\n");
- }
-
- const literal_assign_helper& operator, (
- const T& val
- ) const
- {
- DLIB_CASSERT(r < m->nr() && c < m->nc(),
- "You have used the matrix comma based assignment incorrectly by attempting to\n" <<
- "supply more values than there are elements in the matrix object being assigned to.\n\n" <<
- "Did you forget to call set_size()?"
- << "\n\t r: " << r
- << "\n\t c: " << c
- << "\n\t m->nr(): " << m->nr()
- << "\n\t m->nc(): " << m->nc());
- (*m)(r,c) = val;
- next();
- has_been_used = true;
- return *this;
- }
-
- private:
-
- friend class matrix<T,num_rows,num_cols,mem_manager,layout>;
-
- void next (
- ) const
- {
- ++c;
- if (c == m->nc())
- {
- c = 0;
- ++r;
- }
- }
-
- matrix* m;
- mutable long r;
- mutable long c;
- mutable bool has_been_used;
- };
-
- public:
-
- matrix& operator = (
- const literal_assign_helper& val
- )
- {
- *this = *val.m;
- return *this;
- }
-
- const literal_assign_helper operator = (
- const T& val
- )
- {
- // assign the given value to every spot in this matrix
- const long size = nr()*nc();
- for (long i = 0; i < size; ++i)
- data(i) = val;
-
- // Now return the literal_assign_helper so that the user
- // can use the overloaded comma notation to initialize
- // the matrix if they want to.
- return literal_assign_helper(this);
- }
-
- private:
-
-
- typename layout::template layout<T,NR,NC,mem_manager> data;
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename mm,
- typename l
- >
- void swap(
- matrix<T,NR,NC,mm,l>& a,
- matrix<T,NR,NC,mm,l>& b
- ) { a.swap(b); }
-
- template <
- typename T,
- long NR,
- long NC,
- typename mm,
- typename l
- >
- void serialize (
- const matrix<T,NR,NC,mm,l>& item,
- std::ostream& out
- )
- {
- try
- {
- // The reason the serialization is a little funny is because we are trying to
- // maintain backwards compatibility with an older serialization format used by
- // dlib while also encoding things in a way that lets the array2d and matrix
- // objects have compatible serialization formats.
- serialize(-item.nr(),out);
- serialize(-item.nc(),out);
- for (long r = 0; r < item.nr(); ++r)
- {
- for (long c = 0; c < item.nc(); ++c)
- {
- serialize(item(r,c),out);
- }
- }
- }
- catch (serialization_error& e)
- {
- throw serialization_error(e.info + "\n while serializing dlib::matrix");
- }
- }
-
- template <
- typename T,
- long NR,
- long NC,
- typename mm,
- typename l
- >
- void deserialize (
- matrix<T,NR,NC,mm,l>& item,
- std::istream& in
- )
- {
- try
- {
- long nr, nc;
- deserialize(nr,in);
- deserialize(nc,in);
-
- // this is the newer serialization format
- if (nr < 0 || nc < 0)
- {
- nr *= -1;
- nc *= -1;
- }
-
- if (NR != 0 && nr != NR)
- throw serialization_error("Error while deserializing a dlib::matrix. Invalid rows");
- if (NC != 0 && nc != NC)
- throw serialization_error("Error while deserializing a dlib::matrix. Invalid columns");
-
- item.set_size(nr,nc);
- for (long r = 0; r < nr; ++r)
- {
- for (long c = 0; c < nc; ++c)
- {
- deserialize(item(r,c),in);
- }
- }
- }
- catch (serialization_error& e)
- {
- throw serialization_error(e.info + "\n while deserializing a dlib::matrix");
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename mm,
- typename l
- >
- void serialize (
- const ramdump_t<matrix<T,NR,NC,mm,l>>& item_,
- std::ostream& out
- )
- {
- auto& item = item_.item;
- serialize(item.nr(), out);
- serialize(item.nc(), out);
- if (item.size() != 0)
- out.write((char*)&item(0,0), sizeof(item(0,0))*item.size());
- }
-
- template <
- typename T,
- long NR,
- long NC,
- typename mm,
- typename l
- >
- void deserialize (
- ramdump_t<matrix<T,NR,NC,mm,l>>&& item_,
- std::istream& in
- )
- {
- auto& item = item_.item;
- long nr, nc;
- deserialize(nr, in);
- deserialize(nc, in);
- item.set_size(nr,nc);
- if (item.size() != 0)
- in.read((char*)&item(0,0), sizeof(item(0,0))*item.size());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- std::ostream& operator<< (
- std::ostream& out,
- const matrix_exp<EXP>& m
- )
- {
- using namespace std;
- const streamsize old = out.width();
-
- // first figure out how wide we should make each field
- string::size_type w = 0;
- ostringstream sout;
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- sout << m(r,c);
- w = std::max(sout.str().size(),w);
- sout.str("");
- }
- }
-
- // now actually print it
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- out.width(static_cast<streamsize>(w));
- out << m(r,c) << " ";
- }
- out << "\n";
- }
- out.width(old);
- return out;
- }
-
- /*
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename L
- >
- std::istream& operator>> (
- std::istream& in,
- matrix<T,NR,NC,MM,L>& m
- );
-
- This function is defined inside the matrix_read_from_istream.h file.
- */
-
-// ----------------------------------------------------------------------------------------
-
- class print_matrix_as_csv_helper
- {
- /*!
- This object is used to define an io manipulator for matrix expressions.
- In particular, this code allows you to write statements like:
- cout << csv << yourmatrix;
- and have it print the matrix with commas separating each element.
- !*/
- public:
- print_matrix_as_csv_helper (std::ostream& out_) : out(out_) {}
-
- template <typename EXP>
- std::ostream& operator<< (
- const matrix_exp<EXP>& m
- )
- {
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- if (c+1 == m.nc())
- out << m(r,c) << "\n";
- else
- out << m(r,c) << ", ";
- }
- }
- return out;
- }
-
- private:
- std::ostream& out;
- };
-
- class print_matrix_as_csv {};
- const print_matrix_as_csv csv = print_matrix_as_csv();
- inline print_matrix_as_csv_helper operator<< (
- std::ostream& out,
- const print_matrix_as_csv&
- )
- {
- return print_matrix_as_csv_helper(out);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- class const_temp_matrix;
-
- template <
- typename EXP
- >
- struct matrix_traits<const_temp_matrix<EXP> >
- {
- typedef typename EXP::type type;
- typedef typename EXP::const_ret_type const_ret_type;
- typedef typename EXP::mem_manager_type mem_manager_type;
- typedef typename EXP::layout_type layout_type;
- const static long NR = EXP::NR;
- const static long NC = EXP::NC;
- const static long cost = 1;
- };
-
- template <typename EXP>
- class const_temp_matrix : public matrix_exp<const_temp_matrix<EXP> >, noncopyable
- {
- public:
- typedef typename matrix_traits<const_temp_matrix>::type type;
- typedef typename matrix_traits<const_temp_matrix>::const_ret_type const_ret_type;
- typedef typename matrix_traits<const_temp_matrix>::mem_manager_type mem_manager_type;
- typedef typename matrix_traits<const_temp_matrix>::layout_type layout_type;
- const static long NR = matrix_traits<const_temp_matrix>::NR;
- const static long NC = matrix_traits<const_temp_matrix>::NC;
- const static long cost = matrix_traits<const_temp_matrix>::cost;
-
- const_temp_matrix (
- const matrix_exp<EXP>& item
- ) :
- ref_(item.ref())
- {}
- const_temp_matrix (
- const EXP& item
- ) :
- ref_(item)
- {}
-
- const_ret_type operator() (
- long r,
- long c
- ) const { return ref_(r,c); }
-
- const_ret_type operator() ( long i ) const
- { return ref_(i); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return ref_.aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return ref_.destructively_aliases(item); }
-
- long nr (
- ) const { return ref_.nr(); }
-
- long nc (
- ) const { return ref_.nc(); }
-
- private:
-
- typename conditional_matrix_temp<const EXP, (EXP::cost <= 1)>::type ref_;
- };
-
-// ----------------------------------------------------------------------------------------
-
- typedef matrix<double,0,0,default_memory_manager,column_major_layout> matrix_colmajor;
- typedef matrix<float,0,0,default_memory_manager,column_major_layout> fmatrix_colmajor;
-
-}
-
-#ifdef _MSC_VER
-// put warnings back to their default settings
-#pragma warning(default : 4355)
-#pragma warning(default : 4723)
-#endif
-
-#endif // DLIB_MATRIx_
-
diff --git a/ml/dlib/dlib/matrix/matrix_abstract.h b/ml/dlib/dlib/matrix/matrix_abstract.h
deleted file mode 100644
index 0d05ce981..000000000
--- a/ml/dlib/dlib/matrix/matrix_abstract.h
+++ /dev/null
@@ -1,857 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_ABSTRACT_
-#ifdef DLIB_MATRIx_ABSTRACT_
-
-#include "matrix_exp_abstract.h"
-#include "../serialize.h"
-#include "../algs.h"
-#include "matrix_data_layout_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- /*
- Note that these operator prototypes are not correct C++ (the real versions, which
- you can see in the implementation are really complex and so probably would
- distract/confuse people if shown here). Think of this as just a list of the
- operators available to you and what they do.
- */
-
- const matrix_exp operator* (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1.nc() == m2.nr()
- - m1.size() > 0 && m2.size() > 0
- (you can't multiply any sort of empty matrices together)
- - m1 and m2 both contain elements of the same type
- ensures
- - returns the result of doing the matrix multiplication m1*m2. The resulting
- matrix will have m1.nr() rows and m2.nc() columns.
- !*/
-
- const matrix_exp operator+ (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1.nr() == m2.nr()
- - m1.nc() == m2.nc()
- - m1 and m2 both contain elements of the same type
- ensures
- - returns a matrix R such that for all valid r and c:
- R(r,c) == m1(r,c) + m2(r,c)
- (i.e. returns the result of doing a pairwise addition of the matrices m1 and m2.)
- The resulting matrix will have the same dimensions as the originals.
- !*/
-
- const matrix_exp operator- (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1.nr() == m2.nr()
- - m1.nc() == m2.nc()
- - m1 and m2 both contain elements of the same type
- ensures
- - returns a matrix R such that for all valid r and c:
- R(r,c) == m1(r,c) - m2(r,c)
- (i.e. returns the result of doing a pairwise subtraction of the matrices m1 and m2.)
- The resulting matrix will have the same dimensions as the originals.
- !*/
-
- template <typename T>
- const matrix_exp operator* (
- const matrix_exp& m,
- const T& value
- );
- /*!
- ensures
- - returns the result of multiplying all the elements of matrix m by the given
- scalar value. The resulting matrix will have the same dimensions as m.
- !*/
-
- template <typename T>
- const matrix_exp operator* (
- const T& value,
- const matrix_exp& m
- );
- /*!
- ensures
- - returns the result of multiplying all the elements of matrix m by the given
- scalar value. The resulting matrix will have the same dimensions as m.
- !*/
-
- const matrix_exp operator- (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns -1*m
- !*/
-
- template <typename T>
- const matrix_exp operator/ (
- const matrix_exp& m,
- const T& value
- );
- /*!
- ensures
- - returns the result of dividing all the elements of matrix m by the given
- scalar value. The resulting matrix will have the same dimensions as m.
- !*/
-
- template <typename T>
- const matrix_exp operator/ (
- const T& value,
- const matrix_exp& m
- );
- /*!
- ensures
- - returns the result of dividing the given scalar value by all the elements
- of matrix m. The resulting matrix will have the same dimensions as m.
- !*/
-
- template <typename T>
- const matrix_exp operator+ (
- const matrix_exp& m,
- const T& value
- );
- /*!
- ensures
- - returns the result of adding value to all the elements of matrix m.
- The resulting matrix will have the same dimensions as m.
- !*/
-
- template <typename T>
- const matrix_exp operator+ (
- const T& value,
- const matrix_exp& m
- );
- /*!
- ensures
- - returns the result of adding value to all the elements of matrix m.
- The resulting matrix will have the same dimensions as m.
- !*/
-
- template <typename T>
- const matrix_exp operator- (
- const matrix_exp& m,
- const T& value
- );
- /*!
- ensures
- - returns the result of subtracting value from all the elements of matrix m.
- The resulting matrix will have the same dimensions as m.
- !*/
-
- template <typename T>
- const matrix_exp operator- (
- const T& value,
- const matrix_exp& m
- );
- /*!
- ensures
- - Returns a matrix M such that:
- - M has the same dimensions as m
- - M contains the same type of element as m
- - for all valid r and c:
- - M(r,c) == value - m(r,c)
- !*/
-
- bool operator== (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- ensures
- - if (m1.nr() == m2.nr() && m1.nc() == m2.nc() &&
- for all valid r and c: m1(r,c) == m2(r,c) ) then
- - returns true
- - else
- - returns false
- !*/
-
- bool operator!= (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- ensures
- - returns !(m1 == m2)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows = 0,
- long num_cols = 0,
- typename mem_manager = default_memory_manager,
- typename layout = row_major_layout
- >
- class matrix : public matrix_exp<matrix<T,num_rows,num_cols,mem_manager,layout> >
- {
- /*!
- REQUIREMENTS ON num_rows and num_cols
- both must be bigger than or equal to 0
-
- REQUIREMENTS ON mem_manager
- must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
- must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
- must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
- mem_manager::type can be set to anything.
-
- REQUIREMENTS ON layout
- Must be either row_major_layout or column_major_layout
-
- INITIAL VALUE
- - if (num_rows > 0) then
- - nr() == num_rows
- - else
- - nr() == 0
-
- - if (num_cols > 0) then
- - nc() == num_cols
- - else
- - nc() == 0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a matrix of nr() rows and nc() columns. This object
- is also a matrix_exp. Thus it can be used in all of the above
- global operators.
-
- The number of rows and columns of this object are determined by the template
- arguments num_rows and num_cols. If num_rows or num_cols are 0 then
- the matrix starts out empty (i.e. nr() == 0 and nc() == 0) and you may change
- its size via the set_size() member function.
-
- Setting num_rows or num_cols to something other than 0 causes that dimension
- to have a fixed size. Setting a fixed size at compile time is useful because
- any errors related to operating on matrices with incompatible dimensions will
- be detected at compile time. It also allows the compiler to perform loop
- unrolling which can result in substantially faster code.
-
- Also note that the elements of this matrix are laid out in memory by the layout
- object supplied as a template argument to this class. The row_major_layout
- sets elements down contiguously in memory and in row major order. Additionally,
- all memory allocations are performed using the memory manager object supplied as
- a template argument to this class.
- !*/
-
- public:
- typedef T type;
- typedef mem_manager mem_manager_type;
- typedef layout layout_type;
- const static long NR = num_rows;
- const static long NC = num_cols;
- const static long cost = 1;
- typedef T* iterator;
- typedef const T* const_iterator;
-
- matrix (
- );
- /*!
- ensures
- - #*this is properly initialized
- - #aliases(*this) == true
- - #ref().aliases(*this) == true
- !*/
-
- explicit matrix (
- long length
- );
- /*!
- requires
- - NR == 1 || NC == 1 (i.e. this must be a column or row vector)
- - length >= 0
- - if (NR == 1 && NC > 0) then
- - length == NC
- - if (NC == 1 && NR > 0) then
- - length == NR
- ensures
- - #*this is properly initialized
- - #aliases(*this) == true
- - #ref().aliases(*this) == true
- - if (NR == 1) then
- - #nr() == 1
- - #nc() == length
- - else
- - #nr() == length
- - #nc() == 1
- !*/
-
- matrix (
- long rows,
- long cols
- );
- /*!
- requires
- - rows == NR || NR == 0
- - cols == NC || NC == 0
- - rows >= 0 && cols >= 0
- ensures
- - #*this is properly initialized
- - #aliases(*this) == true
- - #ref().aliases(*this) == true
- - #nr() == rows
- - #nc() == cols
- !*/
-
- template <typename EXP>
- matrix (
- const matrix_exp<EXP>& m
- );
- /*!
- requires
- - matrix_exp<EXP>::type == T
- (i.e. m contains the same type as *this does)
- - if (NR != 0) then NR == m.nr()
- - if (NC != 0) then NC == m.nc()
- ensures
- - #*this == m
- - #aliases(*this) == true
- - #ref().aliases(*this) == true
- !*/
-
- template <typename U, size_t len>
- explicit matrix (
- U (&array)[len]
- );
- /*!
- requires
- - NR != 0 && NC != 0 (i.e. you can only use this constructor on statically sized matrices)
- - len == nr()*nc() (i.e. the array you give here must be the right size)
- ensures
- - for all valid r and c:
- #(*this)(r,c) == array[r*nc() + c]
- (i.e. initializes this matrix with the contents of the given array)
- - #aliases(*this) == true
- - #ref().aliases(*this) == true
- !*/
-
- matrix(
- const std::initializer_list<T>& l
- );
- /*!
- requires
- - This matrix is capable of having a size() == l.size(). Therefore, if
- NR*NC != 0 then l.size() must equal NR*NC. Alternatively, if NR or NC is
- != 0 then l.size() must be a multiple of the non-zero NR or NC.
- ensures
- - #size() == l.size()
- - The contents of l are enumerated and read into the matrix in row major order.
- - if (NR != 0) then
- - #nr() == NR
- - #nc() == l.size()/NR
- - if (NC != 0) then
- - #nr() == l.size()/NC
- - #nc() == NC
- - if (NR*NC==0) then
- - #nr() == l.size()
- - #nc() == 1
- - #aliases(*this) == true
- - #ref().aliases(*this) == true
- !*/
-
- T& operator() (
- long r,
- long c
- );
- /*!
- requires
- - 0 <= r < nr()
- - 0 <= c < nc()
- ensures
- - returns a reference to the value at the given row and column in
- this matrix.
- !*/
-
- const T& operator() (
- long r,
- long c
- ) const;
- /*!
- requires
- - 0 <= r < nr()
- - 0 <= c < nc()
- ensures
- - returns a const reference to the value at the given row and column in
- this matrix.
- !*/
-
- T& operator() (
- long i
- );
- /*!
- requires
- - nc() == 1 || nr() == 1 (i.e. this must be a column or row vector)
- - 0 <= i < size()
- ensures
- - if (nc() == 1) then
- - returns a reference to (*this)(i,0)
- - else
- - returns a reference to (*this)(0,i)
- !*/
-
- const T& operator() (
- long i
- ) const;
- /*!
- requires
- - nc() == 1 || nr() == 1 (i.e. this must be a column or row vector)
- - 0 <= i < size()
- ensures
- - if (nc() == 1) then
- - returns a reference to (*this)(i,0)
- - else
- - returns a reference to (*this)(0,i)
- !*/
-
- operator const type (
- ) const;
- /*!
- requires
- - nr() == 1
- - nc() == 1
- ensures
- - returns (*this)(0,0)
- !*/
-
- long nr(
- ) const;
- /*!
- ensures
- - returns the number of rows in this matrix
- !*/
-
- long nc(
- ) const;
- /*!
- ensures
- - returns the number of columns in this matrix
- !*/
-
- long size (
- ) const;
- /*!
- ensures
- - returns nr()*nc()
- !*/
-
- void set_size (
- long rows,
- long cols
- );
- /*!
- requires
- - rows == NR || NR == 0
- - cols == NC || NC == 0
- - rows >= 0 && cols >= 0
- ensures
- - #nr() == rows
- - #nc() == cols
- !*/
-
- void set_size (
- long length
- );
- /*!
- requires
- - NR == 1 || NC == 1 (i.e. this must be a column or row vector)
- - length >= 0
- - if (NR == 1 && NC > 0) then
- - length == NC
- - if (NC == 1 && NR > 0) then
- - length == NR
- ensures
- - if (NR == 1) then
- - #nr() == 1
- - #nc() == length
- - else
- - #nr() == length
- - #nc() == 1
- !*/
-
- template <typename U, size_t len>
- matrix& operator= (
- U (&array)[len]
- );
- /*!
- requires
- - len == nr()*nc() (i.e. the array you give here must be the right size)
- ensures
- - for all valid r and c:
- #(*this)(r,c) == array[r*nc() + c]
- (i.e. loads this matrix with the contents of the given array)
- - returns *this
- !*/
-
- matrix& operator=(
- const std::initializer_list<T>& l
- );
- /*!
- requires
- - This matrix is capable of having a size() == l.size(). Therefore, if
- NR*NC != 0 then l.size() must equal NR*NC. Alternatively, if NR or NC is
- != 0 then l.size() must be a multiple of the non-zero NR or NC.
- ensures
- - Assigns the contents of l to *this by performing: matrix(l).swap(*this)
- - returns *this
- !*/
-
- template <typename EXP>
- matrix& operator= (
- const matrix_exp<EXP>& m
- );
- /*!
- requires
- - matrix_exp<EXP>::type == T
- (i.e. m contains the same type as *this does)
- - if (NR != 0) then NR == m.nr()
- - if (NC != 0) then NC == m.nc()
- ensures
- - copies the given matrix expression m to *this
- - returns *this
- !*/
-
- template <typename EXP>
- matrix& operator += (
- const matrix_exp<EXP>& m
- );
- /*!
- requires
- - matrix_exp<EXP>::type == T
- - One of the following is true:
- - nr() == m.nr() && nc() == m.nc()
- - size() == 0
- (i.e. this matrix must have matching dimensions or it must be empty)
- ensures
- - if (nr() == m.nr() && nc() == m.nc()) then
- - #(*this) == *this + m
- - else
- - #(*this) == m
- (i.e. if the dimensions don't match then this function performs a
- normal assignment)
- - returns *this
- !*/
-
- template <typename EXP>
- matrix& operator -= (
- const matrix_exp<EXP>& m
- );
- /*!
- requires
- - matrix_exp<EXP>::type == T
- - One of the following is true:
- - nr() == m.nr() && nc() == m.nc()
- - size() == 0
- (i.e. this matrix must have matching dimensions or it must be empty)
- ensures
- - if (nr() == m.nr() && nc() == m.nc()) then
- - #(*this) == *this - m
- - else
- - #(*this) == -m
- - returns *this
- !*/
-
- template <typename EXP>
- matrix& operator *= (
- const matrix_exp<EXP>& m
- );
- /*!
- requires
- - matrix_exp<EXP>::type == T
- (i.e. m must contain the same type of element as *this)
- - nc() == m.nr()
- - size() > 0 && m.size() > 0
- (you can't multiply any sort of empty matrices together)
- ensures
- - #(*this) == *this * m
- - returns *this
- !*/
-
- matrix& operator *= (
- const T& a
- );
- /*!
- ensures
- - #(*this) == *this * a
- - returns *this
- !*/
-
- matrix& operator /= (
- const T& a
- );
- /*!
- ensures
- - #(*this) == *this / a
- - returns *this
- !*/
-
- matrix& operator += (
- const T& a
- );
- /*!
- ensures
- - #(*this) == *this + a
- - returns *this
- !*/
-
- matrix& operator -= (
- const T& a
- );
- /*!
- ensures
- - #(*this) == *this - a
- - returns *this
- !*/
-
- const literal_assign_helper operator = (
- const T& val
- );
- /*!
- This function is somewhat different than all the others defined in this file.
- The purpose of this function is to enable you to easily initialize a matrix object.
- For example:
- matrix<double> m(2,3);
- m = 1,2,3,
- 4,5,6;
-
- The above code creates a matrix m with 2 rows and 3 columns and sets it so that
- it contains the matrix | 1 2 3 |
- | 4 5 6 |
-
- You can also use this function to assign to all elements of a matrix. So
- saying m = 3; would assign all elements of m equal to 3.
-
- Note that to use this method of assignment it is required that you supply
- exactly m.size() or 1 values so that the matrix is fully initialized. Supplying
- fewer or more than that is an error that will cause a dlib::fatal_error to be
- thrown.
-
- Note also that using an expression of the form m = scalar; when m.size() == 0
- is legal but has no effect on m.
- !*/
-
- void swap (
- matrix& item
- );
- /*!
- ensures
- - swaps *this and item
- !*/
-
- iterator begin(
- );
- /*!
- ensures
- - returns a random access iterator pointing to the first element in this
- matrix.
- - The iterator will iterate over the elements of the matrix in row major
- order if layout is row_major_layout or in column major order if layout is
- column_major_layout.
- !*/
-
- iterator end(
- );
- /*!
- ensures
- - returns a random access iterator pointing to one past the end of the last
- element in this matrix.
- !*/
-
- const_iterator begin(
- ) const;
- /*!
- ensures
- - returns a random access iterator pointing to the first element in this
- matrix.
- - The iterator will iterate over the elements of the matrix in row major
- order if layout is row_major_layout or in column major order if layout is
- column_major_layout.
- !*/
-
- const_iterator end(
- ) const;
- /*!
- ensures
- - returns a random access iterator pointing to one past the end of the last
- element in this matrix.
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- /*!A matrix_colmajor
- This is just a typedef of the matrix object that uses column major layout.
- !*/
- typedef matrix<double,0,0,default_memory_manager,column_major_layout> matrix_colmajor;
-
- /*!A fmatrix_colmajor
- This is just a typedef of the matrix object that uses column major layout.
- !*/
- typedef matrix<float,0,0,default_memory_manager,column_major_layout> fmatrix_colmajor;
-
-// ----------------------------------------------------------------------------------------
-template <
- typename T,
- long NR,
- long NC,
- typename mm,
- typename l
- >
- void swap(
- matrix<T,NR,NC,mm,l>& a,
- matrix<T,NR,NC,mm,l>& b
- ) { a.swap(b); }
- /*!
- Provides a global swap function
- !*/
-
- template <
- typename T,
- long NR,
- long NC,
- typename mm,
- typename l
- >
- void serialize (
- const matrix<T,NR,NC,mm,l>& item,
- std::ostream& out
- );
- /*!
- Provides serialization support. Note that the serialization formats used by the
- dlib::matrix and dlib::array2d objects are compatible. That means you can load the
- serialized data from one into another and it will work properly.
- !*/
-
- template <
- typename T,
- long NR,
- long NC,
- typename mm,
- typename l
- >
- void deserialize (
- matrix<T,NR,NC,mm,l>& item,
- std::istream& in
- );
- /*!
- Provides deserialization support
- !*/
-
- template <
- typename EXP
- >
- std::ostream& operator<< (
- std::ostream& out,
- const matrix_exp<EXP>& m
- );
- /*!
- ensures
- - writes m to the given out stream in a form suitable for human consumption.
- - returns out
- !*/
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename L
- >
- std::istream& operator>> (
- std::istream& in,
- matrix<T,NR,NC,MM,L>& m
- );
- /*!
- ensures
- - Tries to read a matrix from the given input stream and store it into #m.
- - The format expected is the text format output by the above operator<<().
- That is, the format should be a grid of text such as:
- 2 3 4
- 5 2 6
- - The separation between numbers can be any number of whitespace characters or
- commas.
- - The matrix data is assumed to end upon the first blank line or end-of-file,
- whichever comes first. This means you can create an input stream with
- multiple matrices in it by separating them with empty lines.
- - returns in.
- - If there was a formatting error or something which prevents the input data
- from being parsed into a matrix then #in.fail() == true.
- !*/
-
- /*!A csv
- This object is used to define an io manipulator for matrix expressions. In
- particular, you can write statements like:
- cout << csv << yourmatrix;
- and have it print the matrix with commas separating each element.
- !*/
- some_undefined_iomnaip_type csv;
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- class const_temp_matrix : public matrix_exp<const_temp_matrix<EXP> >, noncopyable
- {
- /*!
- REQUIREMENTS ON EXP
- - must be an object that inherits publicly from matrix_exp.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a copy of a matrix expression. The twist
- is that it only actually makes a copy of its input matrix expression
- if that matrix expression is costly to evaluate. If it has
- low cost then this object just stores a reference.
-
- This class is useful in cases where you write a function that
- takes a matrix_exp object as input and you want to do some
- intensive computation that looks at each element of that matrix_exp
- many times. If the input matrix_exp has a high cost then you want
- to store it into a temporary matrix. But if it has low cost then
- it is faster if you just use a reference to it. The const_temp_matrix
- makes doing this easy.
- !*/
- public:
-
- const_temp_matrix (
- const matrix_exp<EXP>& item
- );
- /*!
- ensures
- - #*this == item
- - if (EXP::cost <= 1) then
- - this const_temp_matrix stores a reference to the item matrix
- - else
- - this const_temp_matrix creates a temporary matrix and copies
- item into it
- !*/
-
- const_temp_matrix (
- const EXP& item
- );
- /*!
- ensures
- - #*this == item
- - if (EXP::cost <= 1) then
- - this const_temp_matrix stores a reference to the item matrix
- - else
- - this const_temp_matrix creates a temporary matrix and copies
- item into it
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_ABSTRACT_
-
diff --git a/ml/dlib/dlib/matrix/matrix_assign.h b/ml/dlib/dlib/matrix/matrix_assign.h
deleted file mode 100644
index da53050b1..000000000
--- a/ml/dlib/dlib/matrix/matrix_assign.h
+++ /dev/null
@@ -1,978 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_ASSIGn_
-#define DLIB_MATRIx_ASSIGn_
-
-#include "matrix.h"
-#include "matrix_utilities.h"
-#include "matrix_subexp.h"
-#include "../enable_if.h"
-#include "matrix_assign_fwd.h"
-#include "matrix_default_mul.h"
-#include "matrix_conj_trans.h"
-#include "matrix_mat.h"
-
-namespace dlib
-{
- /*
- This file contains some templates that are used inside the matrix_blas_bindings.h
- file to bind various matrix expressions to optimized code for carrying them out.
- */
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace blas_bindings
- {
-
- // ------------------------------------------------------------------------------------
-
- template <typename T>
- void zero_matrix (
- T& m
- )
- {
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- m(r,c) = 0;
- }
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- // This template struct is used to tell us if a matrix expression contains a matrix multiply.
- template <typename T>
- struct has_matrix_multiply
- {
- const static bool value = false;
- };
-
- template <typename T, typename U>
- struct has_matrix_multiply<matrix_multiply_exp<T,U> >
- { const static bool value = true; };
-
- template <typename T, typename U>
- struct has_matrix_multiply<matrix_add_exp<T,U> >
- { const static bool value = has_matrix_multiply<T>::value || has_matrix_multiply<U>::value; };
-
- template <typename T, typename U>
- struct has_matrix_multiply<matrix_subtract_exp<T,U> >
- { const static bool value = has_matrix_multiply<T>::value || has_matrix_multiply<U>::value; };
-
- template <typename T, bool Tb>
- struct has_matrix_multiply<matrix_mul_scal_exp<T,Tb> >
- { const static bool value = true; };
-
- template <typename T>
- struct has_matrix_multiply<matrix_div_scal_exp<T> >
- { const static bool value = has_matrix_multiply<T>::value; };
-
- template <typename T>
- struct has_matrix_multiply<matrix_op<T> >
- { const static bool value = has_matrix_multiply<T>::value; };
-
- template <typename T>
- struct has_matrix_multiply<op_trans<T> >
- { const static bool value = has_matrix_multiply<T>::value; };
-
- template <typename T>
- struct has_matrix_multiply<op_conj_trans<T> >
- { const static bool value = has_matrix_multiply<T>::value; };
-
- template <typename T>
- struct has_matrix_multiply<op_conj<T> >
- { const static bool value = has_matrix_multiply<T>::value; };
-
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
-
- const int unknown_matrix = 0;
- const int general_matrix = 1;
- const int row_matrix = 2;
- const int column_matrix = 3;
-
- // ------------------------------------------------------------------------------------
-
- template <typename T>
- struct matrix_type_id
- {
- const static int value = unknown_matrix;
- };
-
- template <typename T, long NR, long NC, typename MM, typename L>
- struct matrix_type_id<matrix<T,NR,NC,MM,L> >
- {
- const static int value = general_matrix;
- };
-
- template <typename T, long NR, typename MM, typename L>
- struct matrix_type_id<matrix<T,NR,1,MM,L> >
- {
- const static int value = column_matrix;
- };
-
- template <typename T, typename MM, typename L>
- struct matrix_type_id<matrix<T,1,1,MM,L> >
- {
- const static int value = column_matrix;
- };
-
- template <typename T, long NC, typename MM, typename L>
- struct matrix_type_id<matrix<T,1,NC,MM,L> >
- {
- const static int value = row_matrix;
- };
-
- // ------------------------------------------------------------------------------------
-
- template <typename T, long NR, long NC, typename MM, typename L>
- struct matrix_type_id<matrix_op<op_colm<matrix<T,NR,NC,MM,L> > > >
- {
- const static int value = column_matrix;
- };
-
- template <typename T, long NR, long NC, typename MM, typename L>
- struct matrix_type_id<matrix_op<op_rowm<matrix<T,NR,NC,MM,L> > > >
- {
- const static int value = row_matrix;
- };
-
- template <typename T, long NR, long NC, typename MM, typename L>
- struct matrix_type_id<matrix_op<op_colm2<matrix<T,NR,NC,MM,L> > > >
- {
- const static int value = column_matrix;
- };
-
- template <typename T, long NR, long NC, typename MM, typename L>
- struct matrix_type_id<matrix_op<op_rowm2<matrix<T,NR,NC,MM,L> > > >
- {
- const static int value = row_matrix;
- };
-
- template <typename T, long NR, long NC, typename MM, typename L>
- struct matrix_type_id<matrix_op<op_subm<matrix<T,NR,NC,MM,L> > > >
- {
- const static int value = general_matrix;
- };
-
- template < typename T, typename MM >
- struct matrix_type_id<matrix_op<op_array2d_to_mat<array2d<T,MM> > > >
- { const static int value = general_matrix; };
-
- template < typename T, typename MM >
- struct matrix_type_id<matrix_op<op_array_to_mat<array<T,MM> > > >
- { const static int value = column_matrix; };
-
- template < typename value_type, typename alloc >
- struct matrix_type_id<matrix_op<op_std_vect_to_mat<std::vector<value_type,alloc> > > >
- { const static int value = column_matrix; };
-
- template < typename value_type, typename alloc >
- struct matrix_type_id<matrix_op<op_std_vect_to_mat<std_vector_c<value_type,alloc> > > >
- { const static int value = column_matrix; };
-
- template < typename T >
- struct matrix_type_id<matrix_op<op_pointer_to_col_vect<T> > >
- { const static int value = column_matrix; };
- template < typename T >
- struct matrix_type_id<matrix_op<op_pointer_to_mat<T> > >
- { const static int value = general_matrix; };
-
- // ------------------------------------------------------------------------------------
-
- template <typename T, typename U>
- struct same_matrix
- {
- const static int T_id = matrix_type_id<T>::value;
- const static int U_id = matrix_type_id<U>::value;
- // The check for unknown_matrix is here so that we can be sure that matrix types
- // other than the ones specifically enumerated above never get pushed into
- // any of the BLAS bindings. So saying they are never the same as anything
- // else prevents them from matching any of the BLAS bindings.
- const static bool value = (T_id == U_id) && (T_id != unknown_matrix);
- };
-
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
-
- // This template struct is used to tell us if two matrix expressions both contain the same
- // sequence of operators, expressions. It also only has a value of true if the T expression
- // contains only matrices with the given layout.
- template <typename T, typename U, typename layout>
- struct same_exp
- {
- const static bool value = (is_same_type<typename T::exp_type, typename U::exp_type>::value ||
- same_matrix<typename T::exp_type, typename U::exp_type>::value) &&
- is_same_type<typename T::layout_type,layout>::value;
-
- };
-
- // Used only below. They help strip off the const and & qualifiers that can show up
- // in the LHS_ref_type and RHS_ref_type typedefs.
- template <typename T> struct noref{ typedef T type;};
- template <typename T> struct noref<T&>{ typedef T type;};
- template <typename T> struct noref<const T&>{ typedef T type;};
- template <typename T> struct noref<const T>{ typedef T type;};
-
- template <typename Tlhs, typename Ulhs, typename Trhs, typename Urhs, typename layout>
- struct same_exp<matrix_multiply_exp<Tlhs,Trhs>, matrix_multiply_exp<Ulhs,Urhs>,layout >
- {
- // The reason this case is more complex than the others is because the matrix_multiply_exp
- // will use a temporary matrix instead of Tlhs or Trhs in the event that one of these
- // types corresponds to an expensive expression. So we have to use the type that really
- // gets used. The following typedefs are here to pick out that true type.
- typedef typename matrix_multiply_exp<Tlhs,Trhs>::LHS_ref_type T_LHS_ref_type;
- typedef typename matrix_multiply_exp<Tlhs,Trhs>::RHS_ref_type T_RHS_ref_type;
- typedef typename noref<T_LHS_ref_type>::type T_lhs_type;
- typedef typename noref<T_RHS_ref_type>::type T_rhs_type;
-
- typedef typename matrix_multiply_exp<Ulhs,Urhs>::LHS_ref_type U_LHS_ref_type;
- typedef typename matrix_multiply_exp<Ulhs,Urhs>::RHS_ref_type U_RHS_ref_type;
- typedef typename noref<U_LHS_ref_type>::type U_lhs_type;
- typedef typename noref<U_RHS_ref_type>::type U_rhs_type;
-
- const static bool value = same_exp<T_lhs_type,U_lhs_type,layout>::value &&
- same_exp<T_rhs_type,U_rhs_type,layout>::value;
- };
-
- template <typename Tlhs, typename Ulhs, typename Trhs, typename Urhs, typename layout>
- struct same_exp<matrix_add_exp<Tlhs,Trhs>, matrix_add_exp<Ulhs,Urhs>, layout >
- { const static bool value = same_exp<Tlhs,Ulhs,layout>::value && same_exp<Trhs,Urhs,layout>::value; };
-
- template <typename Tlhs, typename Ulhs, typename Trhs, typename Urhs, typename layout>
- struct same_exp<matrix_subtract_exp<Tlhs,Trhs>, matrix_subtract_exp<Ulhs,Urhs>, layout >
- { const static bool value = same_exp<Tlhs,Ulhs,layout>::value && same_exp<Trhs,Urhs,layout>::value; };
-
- template <typename T, typename U, bool Tb, bool Ub, typename layout>
- struct same_exp<matrix_mul_scal_exp<T,Tb>, matrix_mul_scal_exp<U,Ub>, layout >
- { const static bool value = same_exp<T,U,layout>::value; };
-
- template <typename T, typename U, typename layout>
- struct same_exp<matrix_div_scal_exp<T>, matrix_div_scal_exp<U>, layout >
- { const static bool value = same_exp<T,U,layout>::value; };
-
- template <typename T, typename U, typename layout>
- struct same_exp<matrix_op<op_trans<T> >, matrix_op<op_trans<U> >, layout >
- { const static bool value = same_exp<T,U,layout>::value; };
-
- template <typename T, typename U, typename layout>
- struct same_exp<matrix_op<op_conj<T> >, matrix_op<op_conj<U> >, layout >
- { const static bool value = same_exp<T,U,layout>::value; };
-
- template <typename T, typename U, typename layout>
- struct same_exp<matrix_op<op_conj_trans<T> >, matrix_op<op_conj_trans<U> >, layout >
- { const static bool value = same_exp<T,U,layout>::value; };
-
- // ------------------------------------------------------------------------------------
-
- struct yes_type
- {
- char ch;
- };
- struct no_type
- {
- yes_type a, b;
- };
-
- // This is a helper that is used below to apply the same_exp template to matrix expressions.
- template <typename T, typename layout, typename U>
- typename enable_if<same_exp<T,U,layout>,yes_type>::type test(U);
- template <typename T, typename layout, typename U>
- typename disable_if<same_exp<T,U,layout>,no_type>::type test(U);
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename dest_exp,
- typename src_exp,
- typename enabled = void
- >
- struct matrix_assign_blas_helper
- {
- // We are in the default version of the blas helper so this
- // means there wasn't any more specific overload. So just
- // let the default matrix assignment happen.
- template <typename EXP>
- static void assign (
- dest_exp& dest,
- const EXP& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- )
- {
- if (transpose == false)
- matrix_assign_default(dest,src,alpha,add_to);
- else
- matrix_assign_default(dest,trans(src),alpha,add_to);
- }
-
- // If we know this is a matrix multiply then apply the
- // default dlib matrix multiply to speed things up a bit more
- // than the above default function would.
- template <typename EXP1, typename EXP2>
- static void assign (
- dest_exp& dest,
- const matrix_multiply_exp<EXP1,EXP2>& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- )
- {
- // At some point I need to improve the default (i.e. non BLAS) matrix
- // multiplication algorithm...
-
- if (alpha == static_cast<typename src_exp::type>(1))
- {
- if (add_to == false)
- {
- zero_matrix(dest);
- }
-
- if (transpose == false)
- default_matrix_multiply(dest, src.lhs, src.rhs);
- else
- default_matrix_multiply(dest, trans(src.rhs), trans(src.lhs));
- }
- else
- {
- if (add_to)
- {
- typename dest_exp::matrix_type temp(dest.nr(),dest.nc());
- zero_matrix(temp);
-
- if (transpose == false)
- default_matrix_multiply(temp, src.lhs, src.rhs);
- else
- default_matrix_multiply(temp, trans(src.rhs), trans(src.lhs));
-
- matrix_assign_default(dest,temp, alpha,true);
- }
- else
- {
- zero_matrix(dest);
-
- if (transpose == false)
- default_matrix_multiply(dest, src.lhs, src.rhs);
- else
- default_matrix_multiply(dest, trans(src.rhs), trans(src.lhs));
-
- matrix_assign_default(dest,dest, alpha, false);
- }
- }
- }
- };
-
- // This is a macro to help us add overloads for the matrix_assign_blas_helper template.
- // Using this macro it is easy to add overloads for arbitrary matrix expressions.
-#define DLIB_ADD_BLAS_BINDING(src_expression) \
- template <typename T, typename L> struct BOOST_JOIN(blas,__LINE__) \
- { const static bool value = sizeof(yes_type) == sizeof(test<T,L>(src_expression)); }; \
- \
- template < typename dest_exp, typename src_exp > \
- struct matrix_assign_blas_helper<dest_exp, src_exp, \
- typename enable_if<BOOST_JOIN(blas,__LINE__)<src_exp,typename dest_exp::layout_type> >::type > { \
- static void assign ( \
- dest_exp& dest, \
- const src_exp& src, \
- typename src_exp::type alpha, \
- bool add_to, \
- bool DLIB_NO_WARN_UNUSED transpose \
- ) { \
- DLIB_NO_WARN_UNUSED typedef typename dest_exp::type T;
-
-#define DLIB_END_BLAS_BINDING }};
-
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
-
- // ------------------- Forward Declarations -------------------
-
- template <
- typename dest_exp,
- typename src_exp
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const src_exp& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- );
- /*!
- requires
- - src.aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- !*/
-
- template <
- typename dest_exp,
- typename src_exp, typename src_exp2
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const matrix_add_exp<src_exp, src_exp2>& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- );
- /*!
- requires
- - src.aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- !*/
-
- template <
- typename dest_exp,
- typename src_exp, bool Sb
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const matrix_mul_scal_exp<src_exp,Sb>& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- );
- /*!
- requires
- - src.aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- !*/
-
- template <
- typename dest_exp,
- typename src_exp
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const matrix_op<op_trans<src_exp> >& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- );
- /*!
- requires
- - src.aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- !*/
-
- template <
- typename dest_exp,
- typename src_exp, typename src_exp2
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const matrix_subtract_exp<src_exp, src_exp2>& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- );
- /*!
- requires
- - src.aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- !*/
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- );
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const matrix_add_exp<matrix<T,NR,NC,MM,L> ,src_exp>& src
- );
- /*!
- This function catches the expressions of the form:
- M = M + exp;
- and converts them into the appropriate matrix_assign_blas() call.
- This is an important case to catch because it is the expression used
- to represent the += matrix operator.
- !*/
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const matrix_add_exp<src_exp, matrix<T,NR,NC,MM,L> >& src
- );
- /*!
- This function catches the expressions of the form:
- M = exp + M;
- and converts them into the appropriate matrix_assign_blas() call.
- This is an important case to catch because it is the expression used
- to represent the += matrix operator.
- !*/
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const matrix_subtract_exp<matrix<T,NR,NC,MM,L> ,src_exp>& src
- );
- /*!
- This function catches the expressions of the form:
- M = M - exp;
- and converts them into the appropriate matrix_assign_blas() call.
- This is an important case to catch because it is the expression used
- to represent the -= matrix operator.
- !*/
-
-
- // End of forward declarations for overloaded matrix_assign_blas functions
-
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
-
- template <
- typename dest_exp,
- typename src_exp
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const src_exp& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- )
- {
- matrix_assign_blas_helper<dest_exp,src_exp>::assign(dest,src,alpha,add_to, transpose);
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename dest_exp,
- typename src_exp, typename src_exp2
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const matrix_add_exp<src_exp, src_exp2>& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- )
- {
- if (has_matrix_multiply<src_exp>::value || has_matrix_multiply<src_exp2>::value)
- {
- matrix_assign_blas_proxy(dest, src.lhs, alpha, add_to, transpose);
- matrix_assign_blas_proxy(dest, src.rhs, alpha, true, transpose);
- }
- else
- {
- if (transpose == false)
- matrix_assign_default(dest, src, alpha, add_to);
- else
- matrix_assign_default(dest, trans(src), alpha, add_to);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename dest_exp,
- typename src_exp, bool Sb
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const matrix_mul_scal_exp<src_exp,Sb>& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- )
- {
- matrix_assign_blas_proxy(dest, src.m, alpha*src.s, add_to, transpose);
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename dest_exp,
- typename src_exp
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const matrix_op<op_trans<src_exp> >& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- )
- {
- matrix_assign_blas_proxy(dest, src.op.m, alpha, add_to, !transpose);
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename dest_exp,
- typename src_exp, typename src_exp2
- >
- void matrix_assign_blas_proxy (
- dest_exp& dest,
- const matrix_subtract_exp<src_exp, src_exp2>& src,
- typename src_exp::type alpha,
- bool add_to,
- bool transpose
- )
- {
-
- if (has_matrix_multiply<src_exp>::value || has_matrix_multiply<src_exp2>::value)
- {
- matrix_assign_blas_proxy(dest, src.lhs, alpha, add_to, transpose);
- matrix_assign_blas_proxy(dest, src.rhs, -alpha, true, transpose);
- }
- else
- {
- if (transpose == false)
- matrix_assign_default(dest, src, alpha, add_to);
- else
- matrix_assign_default(dest, trans(src), alpha, add_to);
- }
- }
-
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
-
- // Once we get into this function it means that we are dealing with a matrix of float,
- // double, complex<float>, or complex<double> and the src_exp contains at least one
- // matrix multiply.
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- long NR2, long NC2, bool Sb
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const matrix_mul_scal_exp<matrix<T,NR2,NC2,MM,L>,Sb>& src
- )
- {
- // It's ok that we don't check for aliasing in this case because there isn't
- // any complex unrolling of successive + or - operators in this expression.
- matrix_assign_blas_proxy(dest,src.m,src.s,false, false);
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- )
- {
- if (src.aliases(dest))
- {
- matrix<T,NR,NC,MM,L> temp(dest.nr(),dest.nc());
- matrix_assign_blas_proxy(temp,src,1,false, false);
- temp.swap(dest);
- }
- else
- {
- matrix_assign_blas_proxy(dest,src,1,false, false);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- assignable_sub_matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- )
- {
- if (src.aliases(dest.m))
- {
- matrix<T,NR,NC,MM,L> temp(dest.nr(),dest.nc());
- matrix_assign_blas_proxy(temp,src,1,false, false);
- matrix_assign_default(dest,temp);
- }
- else
- {
- matrix_assign_blas_proxy(dest,src,1,false, false);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- typename src_exp
- >
- void matrix_assign_blas (
- assignable_ptr_matrix<T>& dest,
- const src_exp& src
- )
- {
- if (src.aliases(mat(dest.ptr,dest.height,dest.width)))
- {
- matrix<T> temp(dest.nr(),dest.nc());
- matrix_assign_blas_proxy(temp,src,1,false, false);
- matrix_assign_default(dest,temp);
- }
- else
- {
- matrix_assign_blas_proxy(dest,src,1,false, false);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- assignable_row_matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- )
- {
- if (src.aliases(dest.m))
- {
- matrix<T,NR,NC,MM,L> temp(dest.nr(),dest.nc());
- matrix_assign_blas_proxy(temp,src,1,false, false);
- matrix_assign_default(dest,temp);
- }
- else
- {
- matrix_assign_blas_proxy(dest,src,1,false, false);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- assignable_col_matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- )
- {
- if (src.aliases(dest.m))
- {
- matrix<T,NR,NC,MM,L> temp(dest.nr(),dest.nc());
- matrix_assign_blas_proxy(temp,src,1,false, false);
- matrix_assign_default(dest,temp);
- }
- else
- {
- matrix_assign_blas_proxy(dest,src,1,false, false);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const matrix_add_exp<matrix<T,NR,NC,MM,L> ,src_exp>& src
- )
- {
- if (src.rhs.aliases(dest) == false)
- {
- if (&src.lhs != &dest)
- {
- dest = src.lhs;
- }
-
- matrix_assign_blas_proxy(dest, src.rhs, 1, true, false);
- }
- else
- {
- matrix<T,NR,NC,MM,L> temp(src.lhs);
- matrix_assign_blas_proxy(temp, src.rhs, 1, true, false);
- temp.swap(dest);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const matrix_add_exp<src_exp, matrix<T,NR,NC,MM,L> >& src
- )
- {
- // Just switch around the left and right hand sides of the incoming
- // add expression and pass it back into matrix_assign_blas() so that
- // the above function will be called.
- typedef matrix_add_exp<matrix<T,NR,NC,MM,L> ,src_exp> swapped_add_exp;
- matrix_assign_blas(dest, swapped_add_exp(src.rhs, src.lhs));
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- void matrix_assign_blas (
- matrix<T,NR,NC,MM,L>& dest,
- const matrix_subtract_exp<matrix<T,NR,NC,MM,L> ,src_exp>& src
- )
- {
- if (src.rhs.aliases(dest) == false)
- {
- if (&src.lhs != &dest)
- {
- dest = src.lhs;
- }
-
- matrix_assign_blas_proxy(dest, src.rhs, -1, true, false);
- }
- else
- {
- matrix<T,NR,NC,MM,L> temp(src.lhs);
- matrix_assign_blas_proxy(temp, src.rhs, -1, true, false);
- temp.swap(dest);
- }
- }
-
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------
-
- } // end of namespace blas_bindings
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- inline typename enable_if_c<(is_same_type<T,float>::value ||
- is_same_type<T,double>::value ||
- is_same_type<T,std::complex<float> >::value ||
- is_same_type<T,std::complex<double> >::value) &&
- blas_bindings::has_matrix_multiply<src_exp>::value
- >::type matrix_assign_big (
- matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- )
- {
- blas_bindings::matrix_assign_blas(dest,src);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- inline typename enable_if_c<(is_same_type<T,float>::value ||
- is_same_type<T,double>::value ||
- is_same_type<T,std::complex<float> >::value ||
- is_same_type<T,std::complex<double> >::value) &&
- blas_bindings::has_matrix_multiply<src_exp>::value
- >::type matrix_assign_big (
- assignable_sub_matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- )
- {
- blas_bindings::matrix_assign_blas(dest,src);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- typename src_exp
- >
- inline typename enable_if_c<(is_same_type<T,float>::value ||
- is_same_type<T,double>::value ||
- is_same_type<T,std::complex<float> >::value ||
- is_same_type<T,std::complex<double> >::value) &&
- blas_bindings::has_matrix_multiply<src_exp>::value
- >::type matrix_assign_big (
- assignable_ptr_matrix<T>& dest,
- const src_exp& src
- )
- {
- blas_bindings::matrix_assign_blas(dest,src);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- inline typename enable_if_c<(is_same_type<T,float>::value ||
- is_same_type<T,double>::value ||
- is_same_type<T,std::complex<float> >::value ||
- is_same_type<T,std::complex<double> >::value) &&
- blas_bindings::has_matrix_multiply<src_exp>::value
- >::type matrix_assign_big (
- assignable_row_matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- )
- {
- blas_bindings::matrix_assign_blas(dest,src);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename MM, typename L,
- typename src_exp
- >
- inline typename enable_if_c<(is_same_type<T,float>::value ||
- is_same_type<T,double>::value ||
- is_same_type<T,std::complex<float> >::value ||
- is_same_type<T,std::complex<double> >::value) &&
- blas_bindings::has_matrix_multiply<src_exp>::value
- >::type matrix_assign_big (
- assignable_col_matrix<T,NR,NC,MM,L>& dest,
- const src_exp& src
- )
- {
- blas_bindings::matrix_assign_blas(dest,src);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_ASSIGn_
-
diff --git a/ml/dlib/dlib/matrix/matrix_assign_fwd.h b/ml/dlib/dlib/matrix/matrix_assign_fwd.h
deleted file mode 100644
index 7d29baf0a..000000000
--- a/ml/dlib/dlib/matrix/matrix_assign_fwd.h
+++ /dev/null
@@ -1,413 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_ASSIGn_FWD_
-#define DLIB_MATRIx_ASSIGn_FWD_
-
-// GCC 4.8 gives false alarms about some variables being uninitialized. Disable these
-// false warnings.
-#if defined(__GNUC__) && ((__GNUC__ >= 4 && __GNUC_MINOR__ >= 8) || (__GNUC__ > 4))
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#endif
-
-#include "../enable_if.h"
-#include "matrix_data_layout.h"
-#include "../algs.h"
-
-namespace dlib
-{
-
- /*
- The point of the matrix_assign() functions is to contain all the various
- optimizations that help the matrix assign a matrix_exp to an actual matrix
- object quickly.
- */
-
-// ----------------------------------------------------------------------------------------
-
- namespace ma
- {
- // This template here controls how big a compile time sized matrix needs
- // to be for it to get passed into the optimized versions of the
- // matrix_assign() function. So small matrices are evaluated with a simple
- // loop like the ones in this file and bigger matrices may get sent to BLAS
- // routines or some other kind of optimized thing.
- template < typename EXP, typename enable = void >
- struct is_small_matrix { static const bool value = false; };
- template < typename EXP >
- struct is_small_matrix<EXP, typename enable_if_c<EXP::NR>=1 && EXP::NC>=1 &&
- EXP::NR<=17 && EXP::NC<=17 && (EXP::cost <= 70)>::type> { static const bool value = true; };
-
- // I wouldn't use this mul object to do the multiply but visual studio 7.1 wouldn't
- // compile otherwise.
- template <long a, long b>
- struct mul { const static long value = a*b; };
-
- template < typename EXP, typename enable = void >
- struct is_very_small_matrix { static const bool value = false; };
- template < typename EXP >
- struct is_very_small_matrix<EXP, typename enable_if_c<EXP::NR>=1 && EXP::NC>=1 &&
- (mul<EXP::NR,EXP::NC>::value <= 16) && (EXP::cost <= 70)>::type> { static const bool value = true; };
-
-
- template < typename EXP, typename enable = void >
- struct has_column_major_layout { static const bool value = false; };
- template < typename EXP >
- struct has_column_major_layout<EXP, typename enable_if<is_same_type<typename EXP::layout_type, column_major_layout> >::type >
- { static const bool value = true; };
-
-
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- class matrix_exp;
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP1, typename EXP2>
- inline typename disable_if<ma::has_column_major_layout<EXP1> >::type
- matrix_assign_default (
- EXP1& dest,
- const EXP2& src
- )
- /*!
- requires
- - src.destructively_aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- ensures
- - #dest == src
- !*/
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- dest(r,c) = src(r,c);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP1, typename EXP2>
- inline typename enable_if<ma::has_column_major_layout<EXP1> >::type
- matrix_assign_default (
- EXP1& dest,
- const EXP2& src
- )
- /*!
- requires
- - src.destructively_aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- ensures
- - #dest == src
- !*/
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- dest(r,c) = src(r,c);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP1, typename EXP2>
- inline typename disable_if<ma::has_column_major_layout<EXP1> >::type
- matrix_assign_default (
- EXP1& dest,
- const EXP2& src,
- typename EXP2::type alpha,
- bool add_to
- )
- /*!
- requires
- - src.destructively_aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- ensures
- - if (add_to == false) then
- - #dest == alpha*src
- - else
- - #dest == dest + alpha*src
- !*/
- {
- if (add_to)
- {
- if (alpha == static_cast<typename EXP2::type>(1))
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- dest(r,c) += src(r,c);
- }
- }
- }
- else if (alpha == static_cast<typename EXP2::type>(-1))
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- dest(r,c) -= src(r,c);
- }
- }
- }
- else
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- dest(r,c) += alpha*src(r,c);
- }
- }
- }
- }
- else
- {
- if (alpha == static_cast<typename EXP2::type>(1))
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- dest(r,c) = src(r,c);
- }
- }
- }
- else
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- dest(r,c) = alpha*src(r,c);
- }
- }
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP1, typename EXP2>
- inline typename enable_if<ma::has_column_major_layout<EXP1> >::type
- matrix_assign_default (
- EXP1& dest,
- const EXP2& src,
- typename EXP2::type alpha,
- bool add_to
- )
- /*!
- requires
- - src.destructively_aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- ensures
- - if (add_to == false) then
- - #dest == alpha*src
- - else
- - #dest == dest + alpha*src
- !*/
- {
- if (add_to)
- {
- if (alpha == static_cast<typename EXP2::type>(1))
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- dest(r,c) += src(r,c);
- }
- }
- }
- else if (alpha == static_cast<typename EXP2::type>(-1))
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- dest(r,c) -= src(r,c);
- }
- }
- }
- else
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- dest(r,c) += alpha*src(r,c);
- }
- }
- }
- }
- else
- {
- if (alpha == static_cast<typename EXP2::type>(1))
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- dest(r,c) = src(r,c);
- }
- }
- }
- else
- {
- for (long c = 0; c < src.nc(); ++c)
- {
- for (long r = 0; r < src.nr(); ++r)
- {
- dest(r,c) = alpha*src(r,c);
- }
- }
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename matrix_dest_type,
- typename src_exp
- >
- void matrix_assign_big (
- matrix_dest_type& dest,
- const matrix_exp<src_exp>& src
- )
- {
- matrix_assign_default(dest,src);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename matrix_dest_type,
- typename src_exp
- >
- inline typename disable_if<ma::is_small_matrix<src_exp> >::type matrix_assign (
- matrix_dest_type& dest,
- const matrix_exp<src_exp>& src
- )
- /*!
- requires
- - src.destructively_aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- ensures
- - #dest == src
- !*/
- {
- // Call src.ref() here so that the derived type of the matrix_exp shows
- // up so we can overload matrix_assign_big() based on various matrix expression
- // types.
- matrix_assign_big(dest,src.ref());
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-// this code is here to perform an unrolled version of the matrix_assign() function
- template < typename DEST, typename SRC, long NR, long NC,
- long R = 0, long C = 0, bool base_case = (R==NR) >
- struct matrix_unroll_helper
- {
- inline static void go ( DEST& dest, const SRC& src)
- {
- dest(R,C) = src(R,C);
- matrix_unroll_helper<DEST,SRC,NR,NC, R + (C+1)/NC, (C+1)%NC>::go(dest,src);
- }
- };
-
- template < typename DEST, typename SRC, long NR, long NC, long R, long C >
- struct matrix_unroll_helper<DEST,SRC,NR,NC,R,C,true>
- { inline static void go ( DEST& , const SRC& ) {} };
-
- template <typename DEST, typename SRC>
- inline void matrix_assign_unrolled (
- DEST& dest,
- const SRC& src
- )
- /*!
- requires
- - src.destructively_aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- ensures
- - #dest == src
- !*/
- {
- COMPILE_TIME_ASSERT(SRC::NR*SRC::NC != 0);
- matrix_unroll_helper<DEST,SRC, SRC::NR, SRC::NC>::go(dest,src);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <
- typename matrix_dest_type,
- typename src_exp
- >
- inline typename enable_if_c<ma::is_small_matrix<src_exp>::value && ma::is_very_small_matrix<src_exp>::value==false >::type matrix_assign (
- matrix_dest_type& dest,
- const matrix_exp<src_exp>& src
- )
- /*!
- requires
- - src.destructively_aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- ensures
- - #dest == src
- !*/
- {
- matrix_assign_default(dest,src.ref());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename matrix_dest_type,
- typename src_exp
- >
- inline typename enable_if_c<ma::is_small_matrix<src_exp>::value && ma::is_very_small_matrix<src_exp>::value==true >::type matrix_assign (
- matrix_dest_type& dest,
- const matrix_exp<src_exp>& src
- )
- /*!
- requires
- - src.destructively_aliases(dest) == false
- - dest.nr() == src.nr()
- - dest.nc() == src.nc()
- ensures
- - #dest == src
- !*/
- {
- matrix_assign_unrolled(dest,src.ref());
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#if defined(__GNUC__) && ((__GNUC__ >= 4 && __GNUC_MINOR__ >= 8) || (__GNUC__ > 4))
-#pragma GCC diagnostic pop
-#endif
-
-#endif // DLIB_MATRIx_ASSIGn_FWD_
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_blas_bindings.h b/ml/dlib/dlib/matrix/matrix_blas_bindings.h
deleted file mode 100644
index b65e29cdd..000000000
--- a/ml/dlib/dlib/matrix/matrix_blas_bindings.h
+++ /dev/null
@@ -1,1637 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_BLAS_BINDINGS_
-#define DLIB_MATRIx_BLAS_BINDINGS_
-
-#ifndef DLIB_USE_BLAS
-#error "DLIB_USE_BLAS should be defined if you want to use the BLAS bindings"
-#endif
-
-#include "matrix_assign.h"
-#include "matrix_conj_trans.h"
-#include "cblas_constants.h"
-
-//#include <iostream>
-//using namespace std;
-
-namespace dlib
-{
-
-
- namespace blas_bindings
- {
-
-#ifdef DLIB_TEST_BLAS_BINDINGS
- int& counter_gemm();
- int& counter_gemv();
- int& counter_ger();
- int& counter_dot();
- int& counter_axpy();
- int& counter_scal();
-
- #define DLIB_TEST_BLAS_BINDING_GEMM ++counter_gemm();
- #define DLIB_TEST_BLAS_BINDING_GEMV ++counter_gemv();
- #define DLIB_TEST_BLAS_BINDING_GER ++counter_ger();
- #define DLIB_TEST_BLAS_BINDING_DOT ++counter_dot();
- #define DLIB_TEST_BLAS_BINDING_AXPY ++counter_axpy();
- #define DLIB_TEST_BLAS_BINDING_SCAL ++counter_scal();
-#else
- #define DLIB_TEST_BLAS_BINDING_GEMM
- #define DLIB_TEST_BLAS_BINDING_GEMV
- #define DLIB_TEST_BLAS_BINDING_GER
- #define DLIB_TEST_BLAS_BINDING_DOT
- #define DLIB_TEST_BLAS_BINDING_AXPY
- #define DLIB_TEST_BLAS_BINDING_SCAL
-#endif
-
-#ifndef CBLAS_H
- extern "C"
- {
- // Here we declare the prototypes for the CBLAS calls used by the BLAS bindings below
-
- void cblas_saxpy(const int N, const float alpha, const float *X,
- const int incX, float *Y, const int incY);
- void cblas_daxpy(const int N, const double alpha, const double *X,
- const int incX, double *Y, const int incY);
- void cblas_caxpy(const int N, const void *alpha, const void *X,
- const int incX, void *Y, const int incY);
- void cblas_zaxpy(const int N, const void *alpha, const void *X,
- const int incX, void *Y, const int incY);
-
- void cblas_sscal(const int N, const float alpha, float *X, const int incX);
- void cblas_dscal(const int N, const double alpha, double *X, const int incX);
- void cblas_cscal(const int N, const void *alpha, void *X, const int incX);
- void cblas_zscal(const int N, const void *alpha, void *X, const int incX);
-
- void cblas_sgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,
- const CBLAS_TRANSPOSE TransB, const int M, const int N,
- const int K, const float alpha, const float *A,
- const int lda, const float *B, const int ldb,
- const float beta, float *C, const int ldc);
- void cblas_dgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,
- const CBLAS_TRANSPOSE TransB, const int M, const int N,
- const int K, const double alpha, const double *A,
- const int lda, const double *B, const int ldb,
- const double beta, double *C, const int ldc);
- void cblas_cgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,
- const CBLAS_TRANSPOSE TransB, const int M, const int N,
- const int K, const void *alpha, const void *A,
- const int lda, const void *B, const int ldb,
- const void *beta, void *C, const int ldc);
- void cblas_zgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,
- const CBLAS_TRANSPOSE TransB, const int M, const int N,
- const int K, const void *alpha, const void *A,
- const int lda, const void *B, const int ldb,
- const void *beta, void *C, const int ldc);
- void cblas_sgemv(const CBLAS_ORDER order,
- const CBLAS_TRANSPOSE TransA, const int M, const int N,
- const float alpha, const float *A, const int lda,
- const float *X, const int incX, const float beta,
- float *Y, const int incY);
- void cblas_dgemv(const CBLAS_ORDER order,
- const CBLAS_TRANSPOSE TransA, const int M, const int N,
- const double alpha, const double *A, const int lda,
- const double *X, const int incX, const double beta,
- double *Y, const int incY);
- void cblas_cgemv(const CBLAS_ORDER order,
- const CBLAS_TRANSPOSE TransA, const int M, const int N,
- const void *alpha, const void *A, const int lda,
- const void *X, const int incX, const void *beta,
- void *Y, const int incY);
- void cblas_zgemv(const CBLAS_ORDER order,
- const CBLAS_TRANSPOSE TransA, const int M, const int N,
- const void *alpha, const void *A, const int lda,
- const void *X, const int incX, const void *beta,
- void *Y, const int incY);
- void cblas_sger(const CBLAS_ORDER order, const int M, const int N,
- const float alpha, const float *X, const int incX,
- const float *Y, const int incY, float *A, const int lda);
- void cblas_dger(const CBLAS_ORDER order, const int M, const int N,
- const double alpha, const double *X, const int incX,
- const double *Y, const int incY, double *A, const int lda);
- void cblas_cgerc(const CBLAS_ORDER order, const int M, const int N,
- const void *alpha, const void *X, const int incX,
- const void *Y, const int incY, void *A, const int lda);
- void cblas_zgerc(const CBLAS_ORDER order, const int M, const int N,
- const void *alpha, const void *X, const int incX,
- const void *Y, const int incY, void *A, const int lda);
- float cblas_sdot(const int N, const float *X, const int incX,
- const float *Y, const int incY);
- double cblas_ddot(const int N, const double *X, const int incX,
- const double *Y, const int incY);
- void cblas_cdotu_sub(const int N, const void *X, const int incX,
- const void *Y, const int incY, void *dotu);
- void cblas_zdotu_sub(const int N, const void *X, const int incX,
- const void *Y, const int incY, void *dotu);
- void cblas_cdotc_sub(const int N, const void *X, const int incX,
- const void *Y, const int incY, void *dotc);
- void cblas_zdotc_sub(const int N, const void *X, const int incX,
- const void *Y, const int incY, void *dotc);
- void cblas_cgeru(const CBLAS_ORDER order, const int M, const int N,
- const void *alpha, const void *X, const int incX,
- const void *Y, const int incY, void *A, const int lda);
- void cblas_zgeru(const CBLAS_ORDER order, const int M, const int N,
- const void *alpha, const void *X, const int incX,
- const void *Y, const int incY, void *A, const int lda);
- }
-#endif // if not CBLAS_H
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- inline void cblas_axpy(const int N, const float alpha, const float *X,
- const int incX, float *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_AXPY;
- cblas_saxpy(N, alpha, X, incX, Y, incY);
- }
-
- inline void cblas_axpy(const int N, const double alpha, const double *X,
- const int incX, double *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_AXPY;
- cblas_daxpy(N, alpha, X, incX, Y, incY);
- }
-
- inline void cblas_axpy(const int N, const std::complex<float>& alpha, const std::complex<float> *X,
- const int incX, std::complex<float> *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_AXPY;
- cblas_caxpy(N, &alpha, X, incX, Y, incY);
- }
-
- inline void cblas_axpy(const int N, const std::complex<double>& alpha, const std::complex<double> *X,
- const int incX, std::complex<double> *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_AXPY;
- cblas_zaxpy(N, &alpha, X, incX, Y, incY);
- }
-
- // ----------------------------------------------------------------------------------------
-
- inline void cblas_scal(const int N, const float alpha, float *X)
- {
- DLIB_TEST_BLAS_BINDING_SCAL;
- cblas_sscal(N, alpha, X, 1);
- }
-
- inline void cblas_scal(const int N, const double alpha, double *X)
- {
- DLIB_TEST_BLAS_BINDING_SCAL;
- cblas_dscal(N, alpha, X, 1);
- }
-
- inline void cblas_scal(const int N, const std::complex<float>& alpha, std::complex<float> *X)
- {
- DLIB_TEST_BLAS_BINDING_SCAL;
- cblas_cscal(N, &alpha, X, 1);
- }
-
- inline void cblas_scal(const int N, const std::complex<double>& alpha, std::complex<double> *X)
- {
- DLIB_TEST_BLAS_BINDING_SCAL;
- cblas_zscal(N, &alpha, X, 1);
- }
-
- // ----------------------------------------------------------------------------------------
-
- inline void cblas_gemm( const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,
- const CBLAS_TRANSPOSE TransB, const int M, const int N,
- const int K, const float alpha, const float *A,
- const int lda, const float *B, const int ldb,
- const float beta, float *C, const int ldc)
- {
- DLIB_TEST_BLAS_BINDING_GEMM;
- cblas_sgemm( Order, TransA, TransB, M, N,
- K, alpha, A, lda, B, ldb, beta, C, ldc);
- }
-
- inline void cblas_gemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,
- const CBLAS_TRANSPOSE TransB, const int M, const int N,
- const int K, const double alpha, const double *A,
- const int lda, const double *B, const int ldb,
- const double beta, double *C, const int ldc)
- {
- DLIB_TEST_BLAS_BINDING_GEMM;
- cblas_dgemm( Order, TransA, TransB, M, N,
- K, alpha, A, lda, B, ldb, beta, C, ldc);
- }
-
- inline void cblas_gemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,
- const CBLAS_TRANSPOSE TransB, const int M, const int N,
- const int K, const std::complex<float>& alpha, const std::complex<float> *A,
- const int lda, const std::complex<float> *B, const int ldb,
- const std::complex<float>& beta, std::complex<float> *C, const int ldc)
- {
- DLIB_TEST_BLAS_BINDING_GEMM;
- cblas_cgemm( Order, TransA, TransB, M, N,
- K, &alpha, A, lda, B, ldb, &beta, C, ldc);
- }
-
- inline void cblas_gemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,
- const CBLAS_TRANSPOSE TransB, const int M, const int N,
- const int K, const std::complex<double>& alpha, const std::complex<double> *A,
- const int lda, const std::complex<double> *B, const int ldb,
- const std::complex<double>& beta, std::complex<double> *C, const int ldc)
- {
- DLIB_TEST_BLAS_BINDING_GEMM;
- cblas_zgemm( Order, TransA, TransB, M, N,
- K, &alpha, A, lda, B, ldb, &beta, C, ldc);
- }
-
- // ----------------------------------------------------------------------------------------
-
- inline void cblas_gemv(const CBLAS_ORDER order,
- const CBLAS_TRANSPOSE TransA, const int M, const int N,
- const float alpha, const float *A, const int lda,
- const float *X, const int incX, const float beta,
- float *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_GEMV;
- cblas_sgemv(order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- }
-
- inline void cblas_gemv(const CBLAS_ORDER order,
- const CBLAS_TRANSPOSE TransA, const int M, const int N,
- const double alpha, const double *A, const int lda,
- const double *X, const int incX, const double beta,
- double *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_GEMV;
- cblas_dgemv(order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- }
-
- inline void cblas_gemv(const CBLAS_ORDER order,
- const CBLAS_TRANSPOSE TransA, const int M, const int N,
- const std::complex<float>& alpha, const std::complex<float> *A, const int lda,
- const std::complex<float> *X, const int incX, const std::complex<float>& beta,
- std::complex<float> *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_GEMV;
- cblas_cgemv(order, TransA, M, N, &alpha, A, lda, X, incX, &beta, Y, incY);
- }
-
- inline void cblas_gemv(const CBLAS_ORDER order,
- const CBLAS_TRANSPOSE TransA, const int M, const int N,
- const std::complex<double>& alpha, const std::complex<double> *A, const int lda,
- const std::complex<double> *X, const int incX, const std::complex<double>& beta,
- std::complex<double> *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_GEMV;
- cblas_zgemv(order, TransA, M, N, &alpha, A, lda, X, incX, &beta, Y, incY);
- }
-
- // ----------------------------------------------------------------------------------------
-
- inline void cblas_ger(const CBLAS_ORDER order, const int M, const int N,
- const std::complex<float>& alpha, const std::complex<float> *X, const int incX,
- const std::complex<float> *Y, const int incY, std::complex<float> *A, const int lda)
- {
- DLIB_TEST_BLAS_BINDING_GER;
- cblas_cgeru (order, M, N, &alpha, X, incX, Y, incY, A, lda);
- }
-
- inline void cblas_ger(const CBLAS_ORDER order, const int M, const int N,
- const std::complex<double>& alpha, const std::complex<double> *X, const int incX,
- const std::complex<double> *Y, const int incY, std::complex<double> *A, const int lda)
- {
- DLIB_TEST_BLAS_BINDING_GER;
- cblas_zgeru (order, M, N, &alpha, X, incX, Y, incY, A, lda);
- }
-
- inline void cblas_ger(const CBLAS_ORDER order, const int M, const int N,
- const float alpha, const float *X, const int incX,
- const float *Y, const int incY, float *A, const int lda)
- {
- DLIB_TEST_BLAS_BINDING_GER;
- cblas_sger (order, M, N, alpha, X, incX, Y, incY, A, lda);
- }
-
- inline void cblas_ger(const CBLAS_ORDER order, const int M, const int N,
- const double alpha, const double *X, const int incX,
- const double *Y, const int incY, double *A, const int lda)
- {
- DLIB_TEST_BLAS_BINDING_GER;
- cblas_dger (order, M, N, alpha, X, incX, Y, incY, A, lda);
- }
-
- // ----------------------------------------------------------------------------------------
-
- inline void cblas_gerc(const CBLAS_ORDER order, const int M, const int N,
- const std::complex<float>& alpha, const std::complex<float> *X, const int incX,
- const std::complex<float> *Y, const int incY, std::complex<float> *A, const int lda)
- {
- DLIB_TEST_BLAS_BINDING_GER;
- cblas_cgerc (order, M, N, &alpha, X, incX, Y, incY, A, lda);
- }
-
- inline void cblas_gerc(const CBLAS_ORDER order, const int M, const int N,
- const std::complex<double>& alpha, const std::complex<double> *X, const int incX,
- const std::complex<double> *Y, const int incY, std::complex<double> *A, const int lda)
- {
- DLIB_TEST_BLAS_BINDING_GER;
- cblas_zgerc (order, M, N, &alpha, X, incX, Y, incY, A, lda);
- }
-
- // ----------------------------------------------------------------------------------------
-
- inline float cblas_dot(const int N, const float *X, const int incX,
- const float *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_DOT;
- return cblas_sdot(N, X, incX, Y, incY);
- }
-
- inline double cblas_dot(const int N, const double *X, const int incX,
- const double *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_DOT;
- return cblas_ddot(N, X, incX, Y, incY);
- }
-
- inline std::complex<float> cblas_dot(const int N, const std::complex<float> *X, const int incX,
- const std::complex<float> *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_DOT;
- std::complex<float> result;
- cblas_cdotu_sub(N, X, incX, Y, incY, &result);
- return result;
- }
-
- inline std::complex<double> cblas_dot(const int N, const std::complex<double> *X, const int incX,
- const std::complex<double> *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_DOT;
- std::complex<double> result;
- cblas_zdotu_sub(N, X, incX, Y, incY, &result);
- return result;
- }
-
- // ----------------------------------------------------------------------------------------
-
- inline std::complex<float> cblas_dotc(const int N, const std::complex<float> *X, const int incX,
- const std::complex<float> *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_DOT;
- std::complex<float> result;
- cblas_cdotc_sub(N, X, incX, Y, incY, &result);
- return result;
- }
-
- inline std::complex<double> cblas_dotc(const int N, const std::complex<double> *X, const int incX,
- const std::complex<double> *Y, const int incY)
- {
- DLIB_TEST_BLAS_BINDING_DOT;
- std::complex<double> result;
- cblas_zdotc_sub(N, X, incX, Y, incY, &result);
- return result;
- }
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // Helpers for determining the data pointer, LDA, and incX arguments to BLAS functions.
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const matrix<T,NR,NC,MM,row_major_layout>& m) { return m.nc(); }
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const matrix<T,NR,NC,MM,column_major_layout>& m) { return m.nr(); }
-
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const matrix_op<op_subm<matrix<T,NR,NC,MM,row_major_layout> > >& m) { return m.op.m.nc(); }
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const matrix_op<op_subm<matrix<T,NR,NC,MM,column_major_layout> > >& m) { return m.op.m.nr(); }
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const assignable_sub_matrix<T,NR,NC,MM,row_major_layout>& m) { return m.m.nc(); }
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const assignable_sub_matrix<T,NR,NC,MM,column_major_layout>& m) { return m.m.nr(); }
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const assignable_col_matrix<T,NR,NC,MM,row_major_layout>& m) { return m.m.nc(); }
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const assignable_col_matrix<T,NR,NC,MM,column_major_layout>& m) { return m.m.nr(); }
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const assignable_row_matrix<T,NR,NC,MM,row_major_layout>& m) { return m.m.nc(); }
-
- template <typename T, long NR, long NC, typename MM>
- int get_ld (const assignable_row_matrix<T,NR,NC,MM,column_major_layout>& m) { return m.m.nr(); }
-
- template <typename T>
- int get_ld (const assignable_ptr_matrix<T>& m) { return m.nc(); }
-
- template <typename T, typename MM>
- int get_ld (const matrix_op<op_array2d_to_mat<array2d<T,MM> > >& m) { return m.nc(); }
- template <typename T, typename MM>
- int get_ld (const matrix_op<op_array_to_mat<array<T,MM> > >& m) { return m.nc(); }
- template < typename value_type, typename alloc >
- int get_ld (const matrix_op<op_std_vect_to_mat<std::vector<value_type,alloc> > >& m) { return m.nc(); }
- template < typename value_type, typename alloc >
- int get_ld (const matrix_op<op_std_vect_to_mat<std_vector_c<value_type,alloc> > >& m) { return m.nc(); }
- template <typename T>
- int get_ld (const matrix_op<op_pointer_to_col_vect<T> >& m) { return m.nc(); }
- template <typename T>
- int get_ld (const matrix_op<op_pointer_to_mat<T> >& m) { return m.op.stride; }
-
- // --------
-
- // get_inc() returns the offset from one element to another. If an object has a
- // non-uniform offset between elements then returns 0 (e.g. a subm() view could
- // have a non-uniform offset between elements).
-
- template <typename T, typename MM>
- int get_inc (const matrix_op<op_array2d_to_mat<array2d<T,MM> > >& ) { return 1; }
- template <typename T, typename MM>
- int get_inc (const matrix_op<op_array_to_mat<array<T,MM> > >& ) { return 1; }
- template < typename value_type, typename alloc >
- int get_inc (const matrix_op<op_std_vect_to_mat<std::vector<value_type,alloc> > >& ) { return 1; }
- template < typename value_type, typename alloc >
- int get_inc (const matrix_op<op_std_vect_to_mat<std_vector_c<value_type,alloc> > >& ) { return 1; }
- template <typename T>
- int get_inc (const matrix_op<op_pointer_to_col_vect<T> >& ) { return 1; }
- template <typename T>
- int get_inc (const matrix_op<op_pointer_to_mat<T> >& m) { return m.op.stride==m.op.cols ? 1 : 0; }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- int get_inc (const matrix<T,NR,NC,MM,L>& ) { return 1; }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc (const matrix_op<op_subm<matrix<T,NR,NC,MM,row_major_layout> > >& m)
- {
- // if the sub-view doesn't cover all the columns then it can't have a uniform
- // layout.
- if (m.nc() < m.op.m.nc())
- return 0;
- else
- return 1;
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc (const matrix_op<op_subm<matrix<T,NR,NC,MM,column_major_layout> > >& m)
- {
- if (m.nr() < m.op.m.nr())
- return 0;
- else
- return 1;
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc (const assignable_sub_matrix<T,NR,NC,MM,row_major_layout>& m)
- {
- if (m.nc() < m.m.nc())
- return 0;
- else
- return 1;
- }
- template <typename T, long NR, long NC, typename MM>
- int get_inc (const assignable_sub_matrix<T,NR,NC,MM,column_major_layout>& m)
- {
- if (m.nr() < m.m.nr())
- return 0;
- else
- return 1;
- }
-
- template <typename T>
- int get_inc (const assignable_ptr_matrix<T>& ) { return 1; }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const matrix_op<op_colm<matrix<T,NR,NC,MM,row_major_layout> > >& m)
- {
- return m.op.m.nc();
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const matrix_op<op_rowm<matrix<T,NR,NC,MM,row_major_layout> > >& )
- {
- return 1;
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const matrix_op<op_colm2<matrix<T,NR,NC,MM,row_major_layout> > >& m)
- {
- return m.op.m.nc();
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const matrix_op<op_rowm2<matrix<T,NR,NC,MM,row_major_layout> > >& )
- {
- return 1;
- }
-
-
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const matrix_op<op_colm<matrix<T,NR,NC,MM,column_major_layout> > >& )
- {
- return 1;
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const matrix_op<op_rowm<matrix<T,NR,NC,MM,column_major_layout> > >& m)
- {
- return m.op.m.nr();
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const matrix_op<op_colm2<matrix<T,NR,NC,MM,column_major_layout> > >& )
- {
- return 1;
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const matrix_op<op_rowm2<matrix<T,NR,NC,MM,column_major_layout> > >& m)
- {
- return m.op.m.nr();
- }
-
-
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const assignable_row_matrix<T,NR,NC,MM,row_major_layout>& )
- {
- return 1;
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const assignable_row_matrix<T,NR,NC,MM,column_major_layout>& m)
- {
- return m.m.nr();
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const assignable_col_matrix<T,NR,NC,MM,row_major_layout>& m)
- {
- return m.m.nc();
- }
-
- template <typename T, long NR, long NC, typename MM>
- int get_inc(const assignable_col_matrix<T,NR,NC,MM,column_major_layout>& )
- {
- return 1;
- }
-
- // --------
-
- template <typename T, long NR, long NC, typename MM, typename L>
- const T* get_ptr (const matrix<T,NR,NC,MM,L>& m) { return &m(0,0); }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- T* get_ptr (matrix<T,NR,NC,MM,L>& m) { return &m(0,0); }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- const T* get_ptr (const matrix_op<op_subm<matrix<T,NR,NC,MM,L> > >& m) { return &m.op.m(m.op.r_,m.op.c_); }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- const T* get_ptr (const matrix_op<op_colm<matrix<T,NR,NC,MM,L> > >& m) { return &m.op.m(0,m.op.col); }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- const T* get_ptr (const matrix_op<op_rowm<matrix<T,NR,NC,MM,L> > >& m) { return &m.op.m(m.op.row,0); }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- const T* get_ptr (const matrix_op<op_colm2<matrix<T,NR,NC,MM,L> > >& m) { return &m.op.m(0,m.op.col); }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- const T* get_ptr (const matrix_op<op_rowm2<matrix<T,NR,NC,MM,L> > >& m) { return &m.op.m(m.op.row,0); }
-
-
- template <typename T, long NR, long NC, typename MM, typename L>
- T* get_ptr (assignable_col_matrix<T,NR,NC,MM,L>& m) { return &m(0,0); }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- T* get_ptr (assignable_row_matrix<T,NR,NC,MM,L>& m) { return &m(0,0); }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- T* get_ptr (assignable_sub_matrix<T,NR,NC,MM,L>& m) { return &m(0,0); }
-
- template <typename T>
- T* get_ptr (assignable_ptr_matrix<T>& m) { return m.ptr; }
-
- template <typename T, typename MM>
- const T* get_ptr (const matrix_op<op_array2d_to_mat<array2d<T,MM> > >& m) { return &m.op.array[0][0]; }
- template <typename T, typename MM>
- const T* get_ptr (const matrix_op<op_array_to_mat<array<T,MM> > >& m) { return &m.op.vect[0]; }
- template < typename T, typename alloc >
- const T* get_ptr (const matrix_op<op_std_vect_to_mat<std::vector<T,alloc> > >& m) { return &m.op.vect[0]; }
- template < typename T, typename alloc >
- const T* get_ptr (const matrix_op<op_std_vect_to_mat<std_vector_c<T,alloc> > >& m) { return &m.op.vect[0]; }
- template <typename T>
- const T* get_ptr (const matrix_op<op_pointer_to_col_vect<T> >& m) { return m.op.ptr; }
- template <typename T>
- const T* get_ptr (const matrix_op<op_pointer_to_mat<T> >& m) { return m.op.ptr; }
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- // Here we declare some matrix objects for use in the DLIB_ADD_BLAS_BINDING macro. These
- // extern declarations don't actually correspond to any real matrix objects. They are
- // simply here so we can build matrix expressions with the DLIB_ADD_BLAS_BINDING marco.
-
-
- // Note that the fact that these are double matrices isn't important, it is just a placeholder in this case.
- extern matrix<double> m; // general matrix
- extern matrix<double,1,0> rv; // general row vector
- extern matrix<double,0,1> cv; // general column vector
- extern const double s;
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // AXPY/SCAL overloads
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- DLIB_ADD_BLAS_BINDING(m)
- {
-
- const int N = static_cast<int>(src.size());
- if (transpose == false && N != 0)
- {
- if (add_to)
- {
- if (get_inc(src) && get_inc(dest))
- cblas_axpy(N, alpha, get_ptr(src), get_inc(src), get_ptr(dest), get_inc(dest));
- else
- matrix_assign_default(dest, src, alpha, add_to);
- }
- else
- {
- if (get_ptr(src) == get_ptr(dest))
- cblas_scal(N, alpha, get_ptr(dest));
- else
- matrix_assign_default(dest, src, alpha, add_to);
- }
- }
- else
- {
- matrix_assign_default(dest, trans(src), alpha, add_to);
- }
-
- } DLIB_END_BLAS_BINDING
-
- DLIB_ADD_BLAS_BINDING(rv)
- {
-
- const int N = static_cast<int>(src.size());
- if (transpose == false && N != 0)
- {
- if (add_to)
- {
- if (get_inc(src) && get_inc(dest))
- cblas_axpy(N, alpha, get_ptr(src), get_inc(src), get_ptr(dest), get_inc(dest));
- else
- matrix_assign_default(dest, src, alpha, add_to);
- }
- else
- {
- if (get_ptr(src) == get_ptr(dest))
- cblas_scal(N, alpha, get_ptr(dest));
- else
- matrix_assign_default(dest, src, alpha, add_to);
- }
- }
- else
- {
- matrix_assign_default(dest, trans(src), alpha, add_to);
- }
-
- } DLIB_END_BLAS_BINDING
-
- DLIB_ADD_BLAS_BINDING(cv)
- {
-
- const int N = static_cast<int>(src.size());
- if (transpose == false && N != 0)
- {
- if (add_to)
- {
- if (get_inc(src) && get_inc(dest))
- cblas_axpy(N, alpha, get_ptr(src), get_inc(src), get_ptr(dest), get_inc(dest));
- else
- matrix_assign_default(dest, src, alpha, add_to);
- }
- else
- {
- if (get_ptr(src) == get_ptr(dest))
- cblas_scal(N, alpha, get_ptr(dest));
- else
- matrix_assign_default(dest, src, alpha, add_to);
- }
- }
- else
- {
- matrix_assign_default(dest, trans(src), alpha, add_to);
- }
-
- } DLIB_END_BLAS_BINDING
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // GEMM overloads
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- DLIB_ADD_BLAS_BINDING(m*m)
- {
- //cout << "BLAS GEMM: m*m" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs);
- const int lda = get_ld(src.lhs);
- const T* B = get_ptr(src.rhs);
- const int ldb = get_ld(src.rhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, CblasNoTrans, CblasNoTrans, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- cblas_gemm(Order, CblasTrans, CblasTrans, N, M, K, alpha, B, ldb, A, lda, beta, C, ldc);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(m)*m)
- {
- //cout << "BLAS GEMM: trans(m)*m" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasTrans;
- const CBLAS_TRANSPOSE TransB = CblasNoTrans;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* B = get_ptr(src.rhs);
- const int ldb = get_ld(src.rhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- cblas_gemm(Order, TransA, TransB, N, M, K, alpha, B, ldb, A, lda, beta, C, ldc);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(m*trans(m))
- {
- //cout << "BLAS GEMM: m*trans(m)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasNoTrans;
- const CBLAS_TRANSPOSE TransB = CblasTrans;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs);
- const int lda = get_ld(src.lhs);
- const T* B = get_ptr(src.rhs.op.m);
- const int ldb = get_ld(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- cblas_gemm(Order, TransA, TransB, N, M, K, alpha, B, ldb, A, lda, beta, C, ldc);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(m)*trans(m))
- {
- //cout << "BLAS GEMM: trans(m)*trans(m)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* B = get_ptr(src.rhs.op.m);
- const int ldb = get_ld(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, CblasTrans, CblasTrans, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- cblas_gemm(Order, CblasNoTrans, CblasNoTrans, N, M, K, alpha, B, ldb, A, lda, beta, C, ldc);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
- // --------------------------------------
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(conj(m))*m)
- {
- //cout << "BLAS GEMM: trans(conj(m))*m" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasConjTrans;
- const CBLAS_TRANSPOSE TransB = CblasNoTrans;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* B = get_ptr(src.rhs);
- const int ldb = get_ld(src.rhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- matrix_assign_default(dest, trans(src), alpha, add_to);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(conj(m))*trans(m))
- {
- //cout << "BLAS GEMM: trans(conj(m))*trans(m)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasConjTrans;
- const CBLAS_TRANSPOSE TransB = CblasTrans;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* B = get_ptr(src.rhs.op.m);
- const int ldb = get_ld(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- matrix_assign_default(dest, trans(src), alpha, add_to);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(m*trans(conj(m)))
- {
- //cout << "BLAS GEMM: m*trans(conj(m))" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasNoTrans;
- const CBLAS_TRANSPOSE TransB = CblasConjTrans;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs);
- const int lda = get_ld(src.lhs);
- const T* B = get_ptr(src.rhs.op.m);
- const int ldb = get_ld(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- matrix_assign_default(dest, trans(src), alpha, add_to);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(m)*trans(conj(m)))
- {
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasTrans;
- const CBLAS_TRANSPOSE TransB = CblasConjTrans;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* B = get_ptr(src.rhs.op.m);
- const int ldb = get_ld(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- matrix_assign_default(dest, trans(src), alpha, add_to);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(conj(m))*trans(conj(m)))
- {
- //cout << "BLAS GEMM: trans(conj(m))*trans(conj(m))" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasConjTrans;
- const CBLAS_TRANSPOSE TransB = CblasConjTrans;
- const int M = static_cast<int>(src.nr());
- const int N = static_cast<int>(src.nc());
- const int K = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* B = get_ptr(src.rhs.op.m);
- const int ldb = get_ld(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* C = get_ptr(dest);
- const int ldc = get_ld(dest);
-
- if (transpose == false)
- cblas_gemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
- else
- matrix_assign_default(dest, trans(src), alpha, add_to);
- } DLIB_END_BLAS_BINDING
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // GEMV overloads
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- DLIB_ADD_BLAS_BINDING(m*cv)
- {
- //cout << "BLAS GEMV: m*cv" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasNoTrans;
- const int M = static_cast<int>(src.lhs.nr());
- const int N = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs);
- const int lda = get_ld(src.lhs);
- const T* X = get_ptr(src.rhs);
- const int incX = get_inc(src.rhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(rv*m)
- {
- // Note that rv*m is the same as trans(m)*trans(rv)
-
- //cout << "BLAS GEMV: rv*m" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasTrans;
- const int M = static_cast<int>(src.rhs.nr());
- const int N = static_cast<int>(src.rhs.nc());
- const T* A = get_ptr(src.rhs);
- const int lda = get_ld(src.rhs);
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(cv)*m)
- {
- // Note that trans(cv)*m is the same as trans(m)*cv
-
- //cout << "BLAS GEMV: trans(cv)*m" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasTrans;
- const int M = static_cast<int>(src.rhs.nr());
- const int N = static_cast<int>(src.rhs.nc());
- const T* A = get_ptr(src.rhs);
- const int lda = get_ld(src.rhs);
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(m*trans(rv))
- {
- //cout << "BLAS GEMV: m*trans(rv)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasNoTrans;
- const int M = static_cast<int>(src.lhs.nr());
- const int N = static_cast<int>(src.lhs.nc());
- const T* A = get_ptr(src.lhs);
- const int lda = get_ld(src.lhs);
- const T* X = get_ptr(src.rhs.op.m);
- const int incX = get_inc(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
- // --------------------------------------
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(m)*cv)
- {
- //cout << "BLAS GEMV: trans(m)*cv" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasTrans;
- const int M = static_cast<int>(src.lhs.op.m.nr());
- const int N = static_cast<int>(src.lhs.op.m.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* X = get_ptr(src.rhs);
- const int incX = get_inc(src.rhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(rv*trans(m))
- {
- // Note that rv*trans(m) is the same as m*trans(rv)
-
- //cout << "BLAS GEMV: rv*trans(m)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasNoTrans;
- const int M = static_cast<int>(src.rhs.op.m.nr());
- const int N = static_cast<int>(src.rhs.op.m.nc());
- const T* A = get_ptr(src.rhs.op.m);
- const int lda = get_ld(src.rhs.op.m);
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(cv)*trans(m))
- {
- // Note that trans(cv)*trans(m) is the same as m*cv
-
- //cout << "BLAS GEMV: trans(cv)*trans(m)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasNoTrans;
- const int M = static_cast<int>(src.rhs.op.m.nr());
- const int N = static_cast<int>(src.rhs.op.m.nc());
- const T* A = get_ptr(src.rhs.op.m);
- const int lda = get_ld(src.rhs.op.m);
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(m)*trans(rv))
- {
- //cout << "BLAS GEMV: trans(m)*trans(rv)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasTrans;
- const int M = static_cast<int>(src.lhs.op.m.nr());
- const int N = static_cast<int>(src.lhs.op.m.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* X = get_ptr(src.rhs.op.m);
- const int incX = get_inc(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
- // --------------------------------------
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(cv)*conj(m))
- {
- // Note that trans(cv)*conj(m) == conj(trans(m))*cv
- //cout << "BLAS GEMV: trans(cv)*conj(m)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasConjTrans;
- const int M = static_cast<int>(src.rhs.op.m.nr());
- const int N = static_cast<int>(src.rhs.op.m.nc());
- const T* A = get_ptr(src.rhs.op.m);
- const int lda = get_ld(src.rhs.op.m);
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(rv*conj(m))
- {
- // Note that rv*conj(m) == conj(trans(m))*cv
- //cout << "BLAS GEMV: rv*conj(m)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasConjTrans;
- const int M = static_cast<int>(src.rhs.op.m.nr());
- const int N = static_cast<int>(src.rhs.op.m.nc());
- const T* A = get_ptr(src.rhs.op.m);
- const int lda = get_ld(src.rhs.op.m);
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(conj(m))*cv)
- {
- //cout << "BLAS GEMV: trans(conj(m))*cv" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasConjTrans;
- const int M = static_cast<int>(src.lhs.op.m.nr());
- const int N = static_cast<int>(src.lhs.op.m.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* X = get_ptr(src.rhs);
- const int incX = get_inc(src.rhs);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(conj(m))*trans(rv))
- {
- //cout << "BLAS GEMV: trans(conj(m))*trans(rv)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const CBLAS_TRANSPOSE TransA = CblasConjTrans;
- const int M = static_cast<int>(src.lhs.op.m.nr());
- const int N = static_cast<int>(src.lhs.op.m.nc());
- const T* A = get_ptr(src.lhs.op.m);
- const int lda = get_ld(src.lhs.op.m);
- const T* X = get_ptr(src.rhs.op.m);
- const int incX = get_inc(src.rhs.op.m);
-
- const T beta = static_cast<T>(add_to?1:0);
- T* Y = get_ptr(dest);
- const int incY = get_inc(dest);
-
- cblas_gemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
- } DLIB_END_BLAS_BINDING
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // GER overloads
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- DLIB_ADD_BLAS_BINDING(cv*rv)
- {
- //cout << "BLAS GER: cv*rv" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(dest.nr());
- const int N = static_cast<int>(dest.nc());
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
- const T* Y = get_ptr(src.rhs);
- const int incY = get_inc(src.rhs);
-
- if (add_to == false)
- zero_matrix(dest);
-
- T* A = get_ptr(dest);
- const int lda = get_ld(dest);
-
- if (transpose == false)
- cblas_ger(Order, M, N, alpha, X, incX, Y, incY, A, lda);
- else
- cblas_ger(Order, M, N, alpha, Y, incY, X, incX, A, lda);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(rv)*rv)
- {
- //cout << "BLAS GER: trans(rv)*rv" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(dest.nr());
- const int N = static_cast<int>(dest.nc());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs);
- const int incY = get_inc(src.rhs);
-
- if (add_to == false)
- zero_matrix(dest);
-
- T* A = get_ptr(dest);
- const int lda = get_ld(dest);
-
- if (transpose == false)
- cblas_ger(Order, M, N, alpha, X, incX, Y, incY, A, lda);
- else
- cblas_ger(Order, M, N, alpha, Y, incY, X, incX, A, lda);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(cv*trans(cv))
- {
- //cout << "BLAS GER: cv*trans(cv)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(dest.nr());
- const int N = static_cast<int>(dest.nc());
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
- if (add_to == false)
- zero_matrix(dest);
-
- T* A = get_ptr(dest);
- const int lda = get_ld(dest);
-
- if (transpose == false)
- cblas_ger(Order, M, N, alpha, X, incX, Y, incY, A, lda);
- else
- cblas_ger(Order, M, N, alpha, Y, incY, X, incX, A, lda);
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(rv)*trans(cv))
- {
- //cout << "BLAS GER: trans(rv)*trans(cv)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(dest.nr());
- const int N = static_cast<int>(dest.nc());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
- if (add_to == false)
- zero_matrix(dest);
-
- T* A = get_ptr(dest);
- const int lda = get_ld(dest);
-
- if (transpose == false)
- cblas_ger(Order, M, N, alpha, X, incX, Y, incY, A, lda);
- else
- cblas_ger(Order, M, N, alpha, Y, incY, X, incX, A, lda);
- } DLIB_END_BLAS_BINDING
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // GERC overloads
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- /*
- DLIB_ADD_BLAS_BINDING(cv*conj(rv))
- {
- //cout << "BLAS GERC: cv*conj(rv)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(dest.nr());
- const int N = static_cast<int>(dest.nc());
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
- if (add_to == false)
- zero_matrix(dest);
-
- T* A = get_ptr(dest);
- const int lda = get_ld(dest);
-
- if (transpose == false)
- cblas_gerc(Order, M, N, alpha, X, incX, Y, incY, A, lda);
- else
- cblas_gerc(Order, M, N, alpha, Y, incY, X, incX, A, lda);
- } DLIB_END_BLAS_BINDING
- */
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(cv*conj(trans(cv)))
- {
- //cout << "BLAS GERC: cv*conj(trans(cv))" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(dest.nr());
- const int N = static_cast<int>(dest.nc());
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
-
- if (transpose == false)
- {
- T* A = get_ptr(dest);
- const int lda = get_ld(dest);
-
- if (add_to == false)
- zero_matrix(dest);
-
- cblas_gerc(Order, M, N, alpha, X, incX, Y, incY, A, lda);
- }
- else
- {
- matrix_assign_default(dest,trans(src),alpha,add_to);
- //cblas_gerc(Order, M, N, alpha, Y, incY, X, incX, A, lda);
- }
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(rv)*conj(trans(cv)))
- {
- //cout << "BLAS GERC: trans(rv)*conj(trans(cv))" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(dest.nr());
- const int N = static_cast<int>(dest.nc());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
-
- if (transpose == false)
- {
- if (add_to == false)
- zero_matrix(dest);
-
- T* A = get_ptr(dest);
- const int lda = get_ld(dest);
-
- cblas_gerc(Order, M, N, alpha, X, incX, Y, incY, A, lda);
- }
- else
- {
- matrix_assign_default(dest,trans(src),alpha,add_to);
- //cblas_gerc(Order, M, N, alpha, Y, incY, X, incX, A, lda);
- }
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- /*
- DLIB_ADD_BLAS_BINDING(trans(rv)*conj(rv))
- {
- //cout << "BLAS GERC: trans(rv)*conj(rv)" << endl;
- const bool is_row_major_order = is_same_type<typename dest_exp::layout_type,row_major_layout>::value;
- const CBLAS_ORDER Order = is_row_major_order ? CblasRowMajor : CblasColMajor;
- const int M = static_cast<int>(dest.nr());
- const int N = static_cast<int>(dest.nc());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
- if (add_to == false)
- zero_matrix(dest);
-
- T* A = get_ptr(dest);
- const int lda = get_ld(dest);
-
- if (transpose == false)
- cblas_gerc(Order, M, N, alpha, X, incX, Y, incY, A, lda);
- else
- cblas_gerc(Order, M, N, alpha, Y, incY, X, incX, A, lda);
- } DLIB_END_BLAS_BINDING
- */
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // DOT overloads
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- DLIB_ADD_BLAS_BINDING(rv*cv)
- {
- //cout << "BLAS DOT: rv*cv" << endl;
- const int N = static_cast<int>(src.lhs.size());
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
- const T* Y = get_ptr(src.rhs);
- const int incY = get_inc(src.rhs);
-
- if (add_to == false)
- dest(0) = alpha*cblas_dot(N, X, incX, Y, incY);
- else
- dest(0) += alpha*cblas_dot(N, X, incX, Y, incY);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(cv)*cv)
- {
- //cout << "BLAS DOT: trans(cv)*cv" << endl;
- const int N = static_cast<int>(src.lhs.size());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs);
- const int incY = get_inc(src.rhs);
-
- if (add_to == false)
- dest(0) = alpha*cblas_dot(N, X, incX, Y, incY);
- else
- dest(0) += alpha*cblas_dot(N, X, incX, Y, incY);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(rv*trans(rv))
- {
- //cout << "BLAS DOT: rv*trans(rv)" << endl;
- const int N = static_cast<int>(src.lhs.size());
- const T* X = get_ptr(src.lhs);
- const int incX = get_inc(src.lhs);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
- if (add_to == false)
- dest(0) = alpha*cblas_dot(N, X, incX, Y, incY);
- else
- dest(0) += alpha*cblas_dot(N, X, incX, Y, incY);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(cv)*trans(rv))
- {
- //cout << "BLAS DOT: trans(cv)*trans(rv)" << endl;
- const int N = static_cast<int>(src.lhs.op.m.size());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
- if (add_to == false)
- dest(0) = alpha*cblas_dot(N, X, incX, Y, incY);
- else
- dest(0) += alpha*cblas_dot(N, X, incX, Y, incY);
-
- } DLIB_END_BLAS_BINDING
-
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // DOTC overloads
- // ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
-
- DLIB_ADD_BLAS_BINDING(conj(rv)*cv)
- {
- //cout << "BLAS DOTC: conj(rv)*cv" << endl;
- const int N = static_cast<int>(src.lhs.op.m.size());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs);
- const int incY = get_inc(src.rhs);
-
- if (add_to == false)
- dest(0) = alpha*cblas_dotc(N, X, incX, Y, incY);
- else
- dest(0) += alpha*cblas_dotc(N, X, incX, Y, incY);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(conj(trans(cv))*cv)
- {
- //cout << "BLAS DOTC: conj(trans(cv))*cv" << endl;
- const int N = static_cast<int>(src.lhs.op.m.size());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs);
- const int incY = get_inc(src.rhs);
-
- if (add_to == false)
- dest(0) = alpha*cblas_dotc(N, X, incX, Y, incY);
- else
- dest(0) += alpha*cblas_dotc(N, X, incX, Y, incY);
-
- } DLIB_END_BLAS_BINDING
-
- // --------------------------------------
-
- DLIB_ADD_BLAS_BINDING(trans(conj(cv))*trans(rv))
- {
- //cout << "BLAS DOTC: trans(conj(cv))*trans(rv)" << endl;
- const int N = static_cast<int>(src.lhs.op.m.size());
- const T* X = get_ptr(src.lhs.op.m);
- const int incX = get_inc(src.lhs.op.m);
- const T* Y = get_ptr(src.rhs.op.m);
- const int incY = get_inc(src.rhs.op.m);
-
- if (add_to == false)
- dest(0) = alpha*cblas_dotc(N, X, incX, Y, incY);
- else
- dest(0) += alpha*cblas_dotc(N, X, incX, Y, incY);
-
- } DLIB_END_BLAS_BINDING
-
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_BLAS_BINDINGS_
-
diff --git a/ml/dlib/dlib/matrix/matrix_cholesky.h b/ml/dlib/dlib/matrix/matrix_cholesky.h
deleted file mode 100644
index fc1140692..000000000
--- a/ml/dlib/dlib/matrix/matrix_cholesky.h
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright (C) 2009 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-// This code was adapted from code from the JAMA part of NIST's TNT library.
-// See: http://math.nist.gov/tnt/
-#ifndef DLIB_MATRIX_CHOLESKY_DECOMPOSITION_H
-#define DLIB_MATRIX_CHOLESKY_DECOMPOSITION_H
-
-#include "matrix.h"
-#include "matrix_utilities.h"
-#include "matrix_subexp.h"
-#include <cmath>
-
-#ifdef DLIB_USE_LAPACK
-#include "lapack/potrf.h"
-#endif
-
-#include "matrix_trsm.h"
-
-namespace dlib
-{
-
- template <
- typename matrix_exp_type
- >
- class cholesky_decomposition
- {
-
- public:
-
- const static long NR = matrix_exp_type::NR;
- const static long NC = matrix_exp_type::NC;
- typedef typename matrix_exp_type::type type;
- typedef typename matrix_exp_type::mem_manager_type mem_manager_type;
- typedef typename matrix_exp_type::layout_type layout_type;
-
- typedef matrix<type,0,0,mem_manager_type,layout_type> matrix_type;
- typedef matrix<type,NR,1,mem_manager_type,layout_type> column_vector_type;
-
- // You have supplied an invalid type of matrix_exp_type. You have
- // to use this object with matrices that contain float or double type data.
- COMPILE_TIME_ASSERT((is_same_type<float, type>::value ||
- is_same_type<double, type>::value ));
-
-
-
- template <typename EXP>
- cholesky_decomposition(
- const matrix_exp<EXP>& A
- );
-
- bool is_spd(
- ) const;
-
- const matrix_type& get_l(
- ) const;
-
- template <typename EXP>
- const typename EXP::matrix_type solve (
- const matrix_exp<EXP>& B
- ) const;
-
- private:
-
- matrix_type L_; // lower triangular factor
- bool isspd; // true if matrix to be factored was SPD
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- bool cholesky_decomposition<matrix_exp_type>::
- is_spd(
- ) const
- {
- return isspd;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename cholesky_decomposition<matrix_exp_type>::matrix_type& cholesky_decomposition<matrix_exp_type>::
- get_l(
- ) const
- {
- return L_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- cholesky_decomposition<matrix_exp_type>::
- cholesky_decomposition(
- const matrix_exp<EXP>& A_
- )
- {
- using std::sqrt;
- COMPILE_TIME_ASSERT((is_same_type<type, typename EXP::type>::value));
-
- // make sure requires clause is not broken
- DLIB_ASSERT(A_.nr() == A_.nc() && A_.size() > 0,
- "\tcholesky_decomposition::cholesky_decomposition(A_)"
- << "\n\tYou can only use this on square matrices"
- << "\n\tA_.nr(): " << A_.nr()
- << "\n\tA_.nc(): " << A_.nc()
- << "\n\tA_.size(): " << A_.size()
- << "\n\tthis: " << this
- );
-
-#ifdef DLIB_USE_LAPACK
- L_ = A_;
- const type eps = max(abs(diag(L_)))*std::sqrt(std::numeric_limits<type>::epsilon())/100;
-
- // check if the matrix is actually symmetric
- bool is_symmetric = true;
- for (long r = 0; r < L_.nr() && is_symmetric; ++r)
- {
- for (long c = r+1; c < L_.nc() && is_symmetric; ++c)
- {
- // this is approximately doing: is_symmetric = is_symmetric && ( L_(k,j) == L_(j,k))
- is_symmetric = is_symmetric && (std::abs(L_(r,c) - L_(c,r)) < eps );
- }
- }
-
- // now compute the actual cholesky decomposition
- int info = lapack::potrf('L', L_);
-
- // check if it's really SPD
- if (info == 0 && is_symmetric && min(abs(diag(L_))) > eps*100)
- isspd = true;
- else
- isspd = false;
-
- L_ = lowerm(L_);
-#else
- const_temp_matrix<EXP> A(A_);
-
-
- isspd = true;
-
- const long n = A.nc();
- L_.set_size(n,n);
-
- const type eps = max(abs(diag(A)))*std::sqrt(std::numeric_limits<type>::epsilon())/100;
-
- // Main loop.
- for (long j = 0; j < n; j++)
- {
- type d(0.0);
- for (long k = 0; k < j; k++)
- {
- type s(0.0);
- for (long i = 0; i < k; i++)
- {
- s += L_(k,i)*L_(j,i);
- }
-
- // if L_(k,k) != 0
- if (std::abs(L_(k,k)) > eps)
- {
- s = (A(j,k) - s)/L_(k,k);
- }
- else
- {
- s = (A(j,k) - s);
- isspd = false;
- }
-
- L_(j,k) = s;
-
- d = d + s*s;
-
- // this is approximately doing: isspd = isspd && ( A(k,j) == A(j,k))
- isspd = isspd && (std::abs(A(k,j) - A(j,k)) < eps );
- }
- d = A(j,j) - d;
- isspd = isspd && (d > eps);
- L_(j,j) = sqrt(d > 0.0 ? d : 0.0);
- for (long k = j+1; k < n; k++)
- {
- L_(j,k) = 0.0;
- }
- }
-#endif
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- const typename EXP::matrix_type cholesky_decomposition<matrix_exp_type>::
- solve(
- const matrix_exp<EXP>& B
- ) const
- {
- COMPILE_TIME_ASSERT((is_same_type<type, typename EXP::type>::value));
-
- // make sure requires clause is not broken
- DLIB_ASSERT(L_.nr() == B.nr(),
- "\tconst matrix cholesky_decomposition::solve(B)"
- << "\n\tInvalid arguments were given to this function."
- << "\n\tL_.nr(): " << L_.nr()
- << "\n\tB.nr(): " << B.nr()
- << "\n\tthis: " << this
- );
-
- matrix<type, NR, EXP::NC, mem_manager_type, layout_type> X(B);
-
- using namespace blas_bindings;
- // Solve L*y = b;
- triangular_solver(CblasLeft, CblasLower, CblasNoTrans, CblasNonUnit, L_, X);
- // Solve L'*X = Y;
- triangular_solver(CblasLeft, CblasLower, CblasTrans, CblasNonUnit, L_, X);
- return X;
- }
-
-// ----------------------------------------------------------------------------------------
-
-
-
-}
-
-#endif // DLIB_MATRIX_CHOLESKY_DECOMPOSITION_H
-
-
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_conj_trans.h b/ml/dlib/dlib/matrix/matrix_conj_trans.h
deleted file mode 100644
index 3c319ccaf..000000000
--- a/ml/dlib/dlib/matrix/matrix_conj_trans.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (C) 2009 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_CONJ_TRANS_FUNCTIONS
-#define DLIB_MATRIx_CONJ_TRANS_FUNCTIONS
-
-#include "matrix_utilities.h"
-#include "matrix_math_functions.h"
-#include "matrix.h"
-#include "../algs.h"
-#include <cmath>
-#include <complex>
-#include <limits>
-
-
-namespace dlib
-{
- /*!
- The point of the two functions defined in this file is to make statements
- of the form conj(trans(m)) and trans(conj(m)) look the same so that it is
- easier to map them to BLAS functions later on.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_conj_trans
- {
- op_conj_trans( const M& m_) : m(m_){}
- const M& m;
-
- const static long cost = M::cost+1;
- const static long NR = M::NC;
- const static long NC = M::NR;
- typedef typename M::type type;
- typedef typename M::type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply (long r, long c) const { return std::conj(m(c,r)); }
-
- long nr () const { return m.nc(); }
- long nc () const { return m.nr(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <typename EXP>
- const matrix_op<op_conj_trans<EXP> > trans (
- const matrix_op<op_conj<EXP> >& m
- )
- {
- typedef op_conj_trans<EXP> op;
- return matrix_op<op>(op(m.op.m));
- }
-
- template <typename EXP>
- const matrix_op<op_conj_trans<EXP> > conj (
- const matrix_op<op_trans<EXP> >& m
- )
- {
- typedef op_conj_trans<EXP> op;
- return matrix_op<op>(op(m.op.m));
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_CONJ_TRANS_FUNCTIONS
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_conv.h b/ml/dlib/dlib/matrix/matrix_conv.h
deleted file mode 100644
index b90c388bc..000000000
--- a/ml/dlib/dlib/matrix/matrix_conv.h
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright (C) 2011 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_CONV_Hh_
-#define DLIB_MATRIx_CONV_Hh_
-
-#include "matrix_conv_abstract.h"
-#include "matrix.h"
-#include "matrix_fft.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename T>
- const T& conj(const T& item) { return item; }
- template <typename T>
- std::complex<T> conj(const std::complex<T>& item) { return std::conj(item); }
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, bool flip_m2 = false>
- struct op_conv
- {
- op_conv( const M1& m1_, const M2& m2_) :
- m1(m1_),
- m2(m2_),
- nr_(m1.nr()+m2.nr()-1),
- nc_(m1.nc()+m2.nc()-1)
- {
- if (nr_ < 0 || m1.size() == 0 || m2.size() == 0)
- nr_ = 0;
- if (nc_ < 0 || m1.size() == 0 || m2.size() == 0)
- nc_ = 0;
- }
-
- const M1& m1;
- const M2& m2;
- long nr_;
- long nc_;
-
- const static long cost = (M1::cost+M2::cost)*10;
- const static long NR = (M1::NR*M2::NR==0) ? (0) : (M1::NR+M2::NR-1);
- const static long NC = (M1::NC*M2::NC==0) ? (0) : (M1::NC+M2::NC-1);
- typedef typename M1::type type;
- typedef type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- const_ret_type apply (long r, long c) const
- {
- type temp = 0;
-
- const long min_rr = std::max<long>(r-m2.nr()+1, 0);
- const long max_rr = std::min<long>(m1.nr()-1, r);
-
- const long min_cc = std::max<long>(c-m2.nc()+1, 0);
- const long max_cc = std::min<long>(m1.nc()-1, c);
-
- for (long rr = min_rr; rr <= max_rr; ++rr)
- {
- for (long cc = min_cc; cc <= max_cc; ++cc)
- {
- if (flip_m2)
- temp += m1(rr,cc)*dlib::impl::conj(m2(m2.nr()-r+rr-1, m2.nc()-c+cc-1));
- else
- temp += m1(rr,cc)*m2(r-rr,c-cc);
- }
- }
-
- return temp;
- }
-
- long nr () const { return nr_; }
- long nc () const { return nc_; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
-
- };
-
- template <
- typename M1,
- typename M2
- >
- const matrix_op<op_conv<M1,M2> > conv (
- const matrix_exp<M1>& m1,
- const matrix_exp<M2>& m2
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
-
- typedef op_conv<M1,M2> op;
- return matrix_op<op>(op(m1.ref(),m2.ref()));
- }
-
- template <
- typename M1,
- typename M2
- >
- const matrix_op<op_conv<M1,M2,true> > xcorr (
- const matrix_exp<M1>& m1,
- const matrix_exp<M2>& m2
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
-
- typedef op_conv<M1,M2,true> op;
- return matrix_op<op>(op(m1.ref(),m2.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- inline size_t bounding_power_of_two (
- size_t n
- )
- {
- size_t s = 1;
- for (unsigned int i = 0; i < sizeof(s)*8 && s < n; ++i)
- s <<= 1;
- return s;
- }
- }
-
- template <
- typename EXP1,
- typename EXP2
- >
- typename EXP1::matrix_type xcorr_fft(
- const matrix_exp<EXP1>& u,
- const matrix_exp<EXP2>& v
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type, typename EXP2::type>::value == true));
- using T = typename EXP1::type;
- COMPILE_TIME_ASSERT((is_same_type<double,T>::value || is_same_type<float,T>::value || is_same_type<long double,T>::value ));
-
- const long pad_nr = impl::bounding_power_of_two(u.nr() + v.nr() - 1);
- const long pad_nc = impl::bounding_power_of_two(u.nc() + v.nc() - 1);
-
- matrix<std::complex<T>> U(pad_nr, pad_nc), V(pad_nr,pad_nc);
-
- U = 0;
- V = 0;
- set_subm(U,U.nr()-u.nr(),U.nc()-u.nc(),u.nr(),u.nc()) = u;
- set_subm(V,get_rect(v)) = v;
-
- fft_inplace(U);
- fft_inplace(V);
-
- return subm(real(ifft(pointwise_multiply(U, conj(V)))),
- U.nr()-u.nr()-v.nr()+1,
- U.nc()-u.nc()-v.nc()+1,
- u.nr()+v.nr()-1,
- u.nc()+v.nc()-1
- );
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, bool flip_m2 = false>
- struct op_conv_same
- {
- op_conv_same( const M1& m1_, const M2& m2_) : m1(m1_),m2(m2_),nr_(m1.nr()),nc_(m1.nc())
- {
- if (m1.size() == 0 || m2.size() == 0)
- nr_ = 0;
- if (m1.size() == 0 || m2.size() == 0)
- nc_ = 0;
- }
-
- const M1& m1;
- const M2& m2;
- long nr_;
- long nc_;
-
- const static long cost = (M1::cost+M2::cost)*10;
- const static long NR = M1::NR;
- const static long NC = M1::NC;
- typedef typename M1::type type;
- typedef type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- const_ret_type apply (long r, long c) const
- {
- r += m2.nr()/2;
- c += m2.nc()/2;
-
- type temp = 0;
-
- const long min_rr = std::max<long>(r-m2.nr()+1, 0);
- const long max_rr = std::min<long>(m1.nr()-1, r);
-
- const long min_cc = std::max<long>(c-m2.nc()+1, 0);
- const long max_cc = std::min<long>(m1.nc()-1, c);
-
- for (long rr = min_rr; rr <= max_rr; ++rr)
- {
- for (long cc = min_cc; cc <= max_cc; ++cc)
- {
- if (flip_m2)
- temp += m1(rr,cc)*dlib::impl::conj(m2(m2.nr()-r+rr-1, m2.nc()-c+cc-1));
- else
- temp += m1(rr,cc)*m2(r-rr,c-cc);
- }
- }
-
- return temp;
- }
-
- long nr () const { return nr_; }
- long nc () const { return nc_; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
-
- };
-
- template <
- typename M1,
- typename M2
- >
- const matrix_op<op_conv_same<M1,M2> > conv_same (
- const matrix_exp<M1>& m1,
- const matrix_exp<M2>& m2
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
-
- typedef op_conv_same<M1,M2> op;
- return matrix_op<op>(op(m1.ref(),m2.ref()));
- }
-
- template <
- typename M1,
- typename M2
- >
- const matrix_op<op_conv_same<M1,M2,true> > xcorr_same (
- const matrix_exp<M1>& m1,
- const matrix_exp<M2>& m2
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
-
- typedef op_conv_same<M1,M2,true> op;
- return matrix_op<op>(op(m1.ref(),m2.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, bool flip_m2 = false>
- struct op_conv_valid
- {
- op_conv_valid( const M1& m1_, const M2& m2_) :
- m1(m1_),m2(m2_),
- nr_(m1.nr()-m2.nr()+1),
- nc_(m1.nc()-m2.nc()+1)
- {
- if (nr_ < 0 || nc_ <= 0 || m1.size() == 0 || m2.size() == 0)
- nr_ = 0;
- if (nc_ < 0 || nr_ <= 0 || m1.size() == 0 || m2.size() == 0)
- nc_ = 0;
- }
-
- const M1& m1;
- const M2& m2;
- long nr_;
- long nc_;
-
- const static long cost = (M1::cost+M2::cost)*10;
- const static long NR = (M1::NR*M2::NR==0) ? (0) : (M1::NR-M2::NR+1);
- const static long NC = (M1::NC*M2::NC==0) ? (0) : (M1::NC-M2::NC+1);
- typedef typename M1::type type;
- typedef type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- const_ret_type apply (long r, long c) const
- {
- r += m2.nr()-1;
- c += m2.nc()-1;
-
- type temp = 0;
-
- const long min_rr = std::max<long>(r-m2.nr()+1, 0);
- const long max_rr = std::min<long>(m1.nr()-1, r);
-
- const long min_cc = std::max<long>(c-m2.nc()+1, 0);
- const long max_cc = std::min<long>(m1.nc()-1, c);
-
- for (long rr = min_rr; rr <= max_rr; ++rr)
- {
- for (long cc = min_cc; cc <= max_cc; ++cc)
- {
- if (flip_m2)
- temp += m1(rr,cc)*dlib::impl::conj(m2(m2.nr()-r+rr-1, m2.nc()-c+cc-1));
- else
- temp += m1(rr,cc)*m2(r-rr,c-cc);
- }
- }
-
- return temp;
- }
-
- long nr () const { return nr_; }
- long nc () const { return nc_; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m1.aliases(item) || m2.aliases(item); }
-
- };
-
- template <
- typename M1,
- typename M2
- >
- const matrix_op<op_conv_valid<M1,M2> > conv_valid (
- const matrix_exp<M1>& m1,
- const matrix_exp<M2>& m2
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
-
- typedef op_conv_valid<M1,M2> op;
- return matrix_op<op>(op(m1.ref(),m2.ref()));
- }
-
- template <
- typename M1,
- typename M2
- >
- const matrix_op<op_conv_valid<M1,M2,true> > xcorr_valid (
- const matrix_exp<M1>& m1,
- const matrix_exp<M2>& m2
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename M1::type,typename M2::type>::value == true));
-
- typedef op_conv_valid<M1,M2,true> op;
- return matrix_op<op>(op(m1.ref(),m2.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_CONV_Hh_
-
diff --git a/ml/dlib/dlib/matrix/matrix_conv_abstract.h b/ml/dlib/dlib/matrix/matrix_conv_abstract.h
deleted file mode 100644
index b342f2668..000000000
--- a/ml/dlib/dlib/matrix/matrix_conv_abstract.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (C) 2011 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_CONV_ABSTRACT_Hh_
-#ifdef DLIB_MATRIx_CONV_ABSTRACT_Hh_
-
-#include "matrix_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp conv (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1 and m2 both contain elements of the same type
- ensures
- - returns a matrix R such that:
- - R is the convolution of m1 with m2. In particular, this function is
- equivalent to performing the following in matlab: R = conv2(m1,m2).
- - R::type == the same type that was in m1 and m2.
- - R.nr() == m1.nr()+m2.nr()-1
- - R.nc() == m1.nc()+m2.nc()-1
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp xcorr (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1 and m2 both contain elements of the same type
- ensures
- - returns a matrix R such that:
- - R is the cross-correlation of m1 with m2. In particular, this
- function returns conv(m1,flip(m2)) if the matrices contain real
- elements and conv(m1,flip(conj(m2))) if they are complex.
- - R::type == the same type that was in m1 and m2.
- - R.nr() == m1.nr()+m2.nr()-1
- - R.nc() == m1.nc()+m2.nc()-1
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp xcorr_fft (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1 and m2 both contain elements of the same type
- - m1 and m2 contain real or complex values and must be double, float, or long
- double valued. (e.g. not integers)
- ensures
- - This function is identical to xcorr() except that it uses a fast Fourier
- transform to do the convolution and is therefore much faster when both m1 and
- m2 are large.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp conv_same (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1 and m2 both contain elements of the same type
- ensures
- - returns a matrix R such that:
- - R is the convolution of m1 with m2. In particular, this function is
- equivalent to performing the following in matlab: R = conv2(m1,m2,'same').
- In particular, this means the result will have the same dimensions as m1 and will
- contain the central part of the full convolution. Therefore, conv_same(m1,m2) is
- equivalent to subm(conv(m1,m2), m2.nr()/2, m2.nc()/2, m1.nr(), m1.nc()).
- - R::type == the same type that was in m1 and m2.
- - R.nr() == m1.nr()
- - R.nc() == m1.nc()
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp xcorr_same (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1 and m2 both contain elements of the same type
- ensures
- - returns a matrix R such that:
- - R is the cross-correlation of m1 with m2. In particular, this
- function returns conv_same(m1,flip(m2)) if the matrices contain real
- elements and conv_same(m1,flip(conj(m2))) if they are complex.
- - R::type == the same type that was in m1 and m2.
- - R.nr() == m1.nr()
- - R.nc() == m1.nc()
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp conv_valid (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1 and m2 both contain elements of the same type
- ensures
- - returns a matrix R such that:
- - R is the convolution of m1 with m2. In particular, this function is
- equivalent to performing the following in matlab: R = conv2(m1,m2,'valid').
- In particular, this means only elements of the convolution which don't require
- zero padding are included in the result.
- - R::type == the same type that was in m1 and m2.
- - if (m1 has larger dimensions than m2) then
- - R.nr() == m1.nr()-m2.nr()+1
- - R.nc() == m1.nc()-m2.nc()+1
- - else
- - R.nr() == 0
- - R.nc() == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp xcorr_valid (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - m1 and m2 both contain elements of the same type
- ensures
- - returns a matrix R such that:
- - R is the cross-correlation of m1 with m2. In particular, this
- function returns conv_valid(m1,flip(m2)) if the matrices contain real
- elements and conv_valid(m1,flip(conj(m2))) if they are complex.
- - R::type == the same type that was in m1 and m2.
- - if (m1 has larger dimensions than m2) then
- - R.nr() == m1.nr()-m2.nr()+1
- - R.nc() == m1.nc()-m2.nc()+1
- - else
- - R.nr() == 0
- - R.nc() == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_CONV_ABSTRACT_Hh_
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_data_layout.h b/ml/dlib/dlib/matrix/matrix_data_layout.h
deleted file mode 100644
index 22891c228..000000000
--- a/ml/dlib/dlib/matrix/matrix_data_layout.h
+++ /dev/null
@@ -1,1271 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_DATA_LAYOUT_
-#define DLIB_MATRIx_DATA_LAYOUT_
-
-#include "../algs.h"
-#include "matrix_fwd.h"
-#include "matrix_data_layout_abstract.h"
-#ifdef MATLAB_MEX_FILE
-#include <mex.h>
-#endif
-
-// GCC 4.8 gives false alarms about some matrix operations going out of bounds. Disable
-// these false warnings.
-#if defined(__GNUC__) && ((__GNUC__ >= 4 && __GNUC_MINOR__ >= 8) || (__GNUC__ > 4))
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Warray-bounds"
-#endif
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- /*!
- A matrix layout object is any object that contains a templated class called "layout"
- with an interface identical to one below:
- (Note that all the template arguments are just the template arguments from the dlib::matrix
- object and the member functions are defined identically to the ones with the same
- signatures inside the matrix object.)
-
- struct matrix_layout
- {
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout
- {
- public:
-
- T& operator() (
- long r,
- long c
- );
-
- const T& operator() (
- long r,
- long c
- );
-
- T& operator() (
- long i
- );
-
- const T& operator() (
- long i
- ) const;
-
- void swap(
- layout& item
- );
-
- long nr (
- ) const;
-
- long nc (
- ) const;
-
- void set_size (
- long nr_,
- long nc_
- );
- };
- };
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- struct row_major_layout
- {
- // if a matrix is bigger than this many bytes then don't put it on the stack
- const static size_t max_stack_based_size = 256;
-
- // this is a hack to avoid a compile time error in visual studio 8. I would just
- // use sizeof(T) and be done with it but that won't compile. The idea here
- // is to avoid using the stack allocation of the layout object if it
- // is going to contain another matrix and also avoid asking for the sizeof()
- // the contained matrix.
- template <typename T>
- struct get_sizeof_helper
- {
- const static std::size_t val = sizeof(T);
- };
-
- template <typename T, long NR, long NC, typename mm, typename l>
- struct get_sizeof_helper<matrix<T,NR,NC,mm,l> >
- {
- const static std::size_t val = 1000000;
- };
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager,
- int val = static_switch <
- // when the sizes are all non zero and small
- (num_rows*num_cols*get_sizeof_helper<T>::val <= max_stack_based_size) && (num_rows != 0 && num_cols != 0),
- // when the sizes are all non zero and big
- (num_rows*num_cols*get_sizeof_helper<T>::val > max_stack_based_size) && (num_rows != 0 && num_cols != 0),
- num_rows == 0 && num_cols != 0,
- num_rows != 0 && num_cols == 0,
- num_rows == 0 && num_cols == 0
- >::value
- >
- class layout ;
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents the actual allocation of space for a matrix.
- Small matrices allocate all their data on the stack and bigger ones
- use a memory_manager to get their memory.
- !*/
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,1> : noncopyable // when the sizes are all non zero and small
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout() {}
-
- T& operator() (
- long r,
- long c
- ) { return *(data+r*num_cols + c); }
-
- const T& operator() (
- long r,
- long c
- ) const { return *(data+r*num_cols + c); }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- for (long r = 0; r < num_rows; ++r)
- {
- for (long c = 0; c < num_cols; ++c)
- {
- exchange((*this)(r,c),item(r,c));
- }
- }
- }
-
- long nr (
- ) const { return num_rows; }
-
- long nc (
- ) const { return num_cols; }
-
- void set_size (
- long ,
- long
- )
- {
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- private:
- T data[num_rows*num_cols];
- };
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,2> : noncopyable // when the sizes are all non zero and big
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ) { data = pool.allocate_array(num_rows*num_cols); }
-
- ~layout ()
- { pool.deallocate_array(data); }
-
- T& operator() (
- long r,
- long c
- ) { return data[r*num_cols + c]; }
-
- const T& operator() (
- long r,
- long c
- ) const { return data[r*num_cols + c]; }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.data,data);
- pool.swap(item.pool);
- }
-
- long nr (
- ) const { return num_rows; }
-
- long nc (
- ) const { return num_cols; }
-
- void set_size (
- long ,
- long
- )
- {
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- private:
-
- T* data;
- typename mem_manager::template rebind<T>::other pool;
- };
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,3> : noncopyable // when num_rows == 0 && num_cols != 0,
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ):data(0), nr_(0) { }
-
- ~layout ()
- {
- if (data)
- pool.deallocate_array(data);
- }
-
- T& operator() (
- long r,
- long c
- ) { return data[r*num_cols + c]; }
-
- const T& operator() (
- long r,
- long c
- ) const { return data[r*num_cols + c]; }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.data,data);
- std::swap(item.nr_,nr_);
- pool.swap(item.pool);
- }
-
- long nr (
- ) const { return nr_; }
-
- long nc (
- ) const { return num_cols; }
-
- void set_size (
- long nr,
- long nc
- )
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- data = pool.allocate_array(nr*nc);
- nr_ = nr;
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- private:
-
- T* data;
- long nr_;
- typename mem_manager::template rebind<T>::other pool;
- };
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,4> : noncopyable // when num_rows != 0 && num_cols == 0
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ):data(0), nc_(0) { }
-
- ~layout ()
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- }
-
- T& operator() (
- long r,
- long c
- ) { return data[r*nc_ + c]; }
-
- const T& operator() (
- long r,
- long c
- ) const { return data[r*nc_ + c]; }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.data,data);
- std::swap(item.nc_,nc_);
- pool.swap(item.pool);
- }
-
- long nr (
- ) const { return num_rows; }
-
- long nc (
- ) const { return nc_; }
-
- void set_size (
- long nr,
- long nc
- )
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- data = pool.allocate_array(nr*nc);
- nc_ = nc;
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- private:
-
- T* data;
- long nc_;
- typename mem_manager::template rebind<T>::other pool;
- };
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ):data(0), nr_(0), nc_(0) { }
-
- ~layout ()
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- }
-
- T& operator() (
- long r,
- long c
- ) { return data[r*nc_ + c]; }
-
- const T& operator() (
- long r,
- long c
- ) const { return data[r*nc_ + c]; }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.data,data);
- std::swap(item.nc_,nc_);
- std::swap(item.nr_,nr_);
- pool.swap(item.pool);
- }
-
- long nr (
- ) const { return nr_; }
-
- long nc (
- ) const { return nc_; }
-
- void set_size (
- long nr,
- long nc
- )
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- data = pool.allocate_array(nr*nc);
- nr_ = nr;
- nc_ = nc;
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
- private:
- T* data;
- long nr_;
- long nc_;
- typename mem_manager::template rebind<T>::other pool;
- };
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- struct column_major_layout
- {
- // if a matrix is bigger than this many bytes then don't put it on the stack
- const static size_t max_stack_based_size = 256;
-
-
- // this is a hack to avoid a compile time error in visual studio 8. I would just
- // use sizeof(T) and be done with it but that won't compile. The idea here
- // is to avoid using the stack allocation of the layout object if it
- // is going to contain another matrix and also avoid asking for the sizeof()
- // the contained matrix.
- template <typename T>
- struct get_sizeof_helper
- {
- const static std::size_t val = sizeof(T);
- };
-
- template <typename T, long NR, long NC, typename mm, typename l>
- struct get_sizeof_helper<matrix<T,NR,NC,mm,l> >
- {
- const static std::size_t val = 1000000;
- };
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager,
- int val = static_switch <
- // when the sizes are all non zero and small
- (num_rows*num_cols*get_sizeof_helper<T>::val <= max_stack_based_size) && (num_rows != 0 && num_cols != 0),
- // when the sizes are all non zero and big
- (num_rows*num_cols*get_sizeof_helper<T>::val > max_stack_based_size) && (num_rows != 0 && num_cols != 0),
- num_rows == 0 && num_cols != 0,
- num_rows != 0 && num_cols == 0,
- num_rows == 0 && num_cols == 0
- >::value
- >
- class layout ;
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents the actual allocation of space for a matrix.
- Small matrices allocate all their data on the stack and bigger ones
- use a memory_manager to get their memory.
- !*/
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,1> : noncopyable // when the sizes are all non zero and small
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout() {}
-
- T& operator() (
- long r,
- long c
- ) { return *(data+c*num_rows + r); }
-
- const T& operator() (
- long r,
- long c
- ) const { return *(data+c*num_rows + r); }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- for (long r = 0; r < num_rows; ++r)
- {
- for (long c = 0; c < num_cols; ++c)
- {
- exchange((*this)(r,c),item(r,c));
- }
- }
- }
-
- long nr (
- ) const { return num_rows; }
-
- long nc (
- ) const { return num_cols; }
-
- void set_size (
- long,
- long
- )
- {
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- private:
- T data[num_cols*num_rows];
- };
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,2> : noncopyable // when the sizes are all non zero and big
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ) { data = pool.allocate_array(num_rows*num_cols); }
-
- ~layout ()
- { pool.deallocate_array(data); }
-
- T& operator() (
- long r,
- long c
- ) { return data[c*num_rows + r]; }
-
- const T& operator() (
- long r,
- long c
- ) const { return data[c*num_rows + r]; }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.data,data);
- pool.swap(item.pool);
- }
-
- long nr (
- ) const { return num_rows; }
-
- long nc (
- ) const { return num_cols; }
-
- void set_size (
- long ,
- long
- )
- {
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- private:
-
- T* data;
- typename mem_manager::template rebind<T>::other pool;
- };
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,3> : noncopyable // when num_rows == 0 && num_cols != 0,
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ):data(0), nr_(0) { }
-
- ~layout ()
- {
- if (data)
- pool.deallocate_array(data);
- }
-
- T& operator() (
- long r,
- long c
- ) { return data[c*nr_ + r]; }
-
- const T& operator() (
- long r,
- long c
- ) const { return data[c*nr_ + r]; }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.data,data);
- std::swap(item.nr_,nr_);
- pool.swap(item.pool);
- }
-
- long nr (
- ) const { return nr_; }
-
- long nc (
- ) const { return num_cols; }
-
- void set_size (
- long nr,
- long nc
- )
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- data = pool.allocate_array(nr*nc);
- nr_ = nr;
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- private:
-
- T* data;
- long nr_;
- typename mem_manager::template rebind<T>::other pool;
- };
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,4> : noncopyable // when num_rows != 0 && num_cols == 0
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ):data(0), nc_(0) { }
-
- ~layout ()
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- }
-
- T& operator() (
- long r,
- long c
- ) { return data[c*num_rows + r]; }
-
- const T& operator() (
- long r,
- long c
- ) const { return data[c*num_rows + r]; }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.data,data);
- std::swap(item.nc_,nc_);
- pool.swap(item.pool);
- }
-
- long nr (
- ) const { return num_rows; }
-
- long nc (
- ) const { return nc_; }
-
- void set_size (
- long nr,
- long nc
- )
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- data = pool.allocate_array(nr*nc);
- nc_ = nc;
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- private:
-
- T* data;
- long nc_;
- typename mem_manager::template rebind<T>::other pool;
- };
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows,
- long num_cols,
- typename mem_manager
- >
- class layout<T,num_rows,num_cols,mem_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ):data(0), nr_(0), nc_(0) { }
-
- ~layout ()
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- }
-
- T& operator() (
- long r,
- long c
- ) { return data[c*nr_ + r]; }
-
- const T& operator() (
- long r,
- long c
- ) const { return data[c*nr_ + r]; }
-
- T& operator() (
- long i
- ) { return data[i]; }
-
- const T& operator() (
- long i
- ) const { return data[i]; }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.data,data);
- std::swap(item.nc_,nc_);
- std::swap(item.nr_,nr_);
- pool.swap(item.pool);
- }
-
-#ifdef MATLAB_MEX_FILE
- void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); }
- mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); }
- void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); }
- bool _private_is_owned_by_matlab() const { return false; }
-#endif
-
- long nr (
- ) const { return nr_; }
-
- long nc (
- ) const { return nc_; }
-
- void set_size (
- long nr,
- long nc
- )
- {
- if (data)
- {
- pool.deallocate_array(data);
- }
- data = pool.allocate_array(nr*nc);
- nr_ = nr;
- nc_ = nc;
- }
-
- private:
- T* data;
- long nr_;
- long nc_;
- typename mem_manager::template rebind<T>::other pool;
- };
-
-#ifdef MATLAB_MEX_FILE
- template <
- long num_rows,
- long num_cols
- >
- class layout<double,num_rows,num_cols,default_memory_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ): data(0), nr_(0), nc_(0), owned_by_matlab(false),set_by_private_set_mxArray(false),mem(0) { }
-
- ~layout ()
- {
- if (owned_by_matlab)
- {
- if (!set_by_private_set_mxArray && mem)
- {
- mxDestroyArray(mem);
- mem = 0;
- data = 0;
- }
- }
- else if (data)
- {
- delete [] data;
- data = 0;
- }
- }
-
- double& operator() (
- long r,
- long c
- ) { return data[c*nr_ + r]; }
-
- const double& operator() (
- long r,
- long c
- ) const { return data[c*nr_ + r]; }
-
- double& operator() (
- long i
- ) { return data[i]; }
-
- const double& operator() (
- long i
- ) const { return data[i]; }
-
- void _private_set_mxArray (
- mxArray* mem_
- )
- {
- DLIB_CASSERT(mem == 0 && data == 0,"You can't call this function on an already allocated matrix.");
- // We don't own the pointer, so make note of that so we won't try to free
- // it.
- set_by_private_set_mxArray = true;
- owned_by_matlab = true;
- mem = mem_;
- data = mxGetPr(mem);
- nr_ = mxGetM(mem);
- nc_ = mxGetN(mem);
- }
-
- mxArray* _private_release_mxArray()
- {
- DLIB_CASSERT(owned_by_matlab,"");
- mxArray* temp = mem;
- mem = 0;
- set_by_private_set_mxArray = false;
- data = 0;
- nr_ = 0;
- nc_ = 0;
- return temp;
- }
-
- void _private_mark_owned_by_matlab()
- {
- DLIB_CASSERT(mem == 0 && data == 0,"You can't say a matrix should be owned by matlab after it's been allocated.");
- owned_by_matlab = true;
- }
- bool _private_is_owned_by_matlab() const
- {
- return owned_by_matlab;
- }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.owned_by_matlab,owned_by_matlab);
- std::swap(item.set_by_private_set_mxArray,set_by_private_set_mxArray);
- std::swap(item.mem,mem);
- std::swap(item.data,data);
- std::swap(item.nc_,nc_);
- std::swap(item.nr_,nr_);
- }
-
- long nr (
- ) const { return nr_; }
-
- long nc (
- ) const { return nc_; }
-
- void set_size (
- long nr,
- long nc
- )
- {
- if (owned_by_matlab)
- {
- if (!set_by_private_set_mxArray && mem)
- {
- mxDestroyArray(mem);
- mem = 0;
- data = 0;
- }
- set_by_private_set_mxArray = false;
-
- mem = mxCreateDoubleMatrix(nr, nc, mxREAL);
- if (mem == 0)
- throw std::bad_alloc();
- data = mxGetPr(mem);
- }
- else
- {
- if (data)
- delete [] data;
- data = new double[nr*nc];
- }
- nr_ = nr;
- nc_ = nc;
- }
-
- private:
- double* data;
- long nr_;
- long nc_;
- bool owned_by_matlab;
- bool set_by_private_set_mxArray;
- mxArray* mem;
- };
-
- template <
- long num_rows,
- long num_cols
- >
- class layout<float,num_rows,num_cols,default_memory_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0
- {
- public:
- const static long NR = num_rows;
- const static long NC = num_cols;
-
- layout (
- ): data(0), nr_(0), nc_(0), owned_by_matlab(false),set_by_private_set_mxArray(false),mem(0) { }
-
- ~layout ()
- {
- if (owned_by_matlab)
- {
- if (!set_by_private_set_mxArray && mem)
- {
- mxDestroyArray(mem);
- mem = 0;
- data = 0;
- }
- }
- else if (data)
- {
- delete [] data;
- data = 0;
- }
- }
-
- float& operator() (
- long r,
- long c
- ) { return data[c*nr_ + r]; }
-
- const float& operator() (
- long r,
- long c
- ) const { return data[c*nr_ + r]; }
-
- float& operator() (
- long i
- ) { return data[i]; }
-
- const float& operator() (
- long i
- ) const { return data[i]; }
-
- void _private_set_mxArray (
- mxArray* mem_
- )
- {
- DLIB_CASSERT(mem == 0 && data == 0,"You can't call this function on an already allocated matrix.");
- // We don't own the pointer, so make note of that so we won't try to free
- // it.
- set_by_private_set_mxArray = true;
- owned_by_matlab = true;
- mem = mem_;
- data = (float*)mxGetData(mem);
- nr_ = mxGetM(mem);
- nc_ = mxGetN(mem);
- }
-
- mxArray* _private_release_mxArray()
- {
- DLIB_CASSERT(owned_by_matlab,"");
- mxArray* temp = mem;
- mem = 0;
- set_by_private_set_mxArray = false;
- data = 0;
- nr_ = 0;
- nc_ = 0;
- return temp;
- }
-
- void _private_mark_owned_by_matlab()
- {
- DLIB_CASSERT(mem == 0 && data == 0,"You can't say a matrix should be owned by matlab after it's been allocated.");
- owned_by_matlab = true;
- }
- bool _private_is_owned_by_matlab() const
- {
- return owned_by_matlab;
- }
-
- void swap(
- layout& item
- )
- {
- std::swap(item.owned_by_matlab,owned_by_matlab);
- std::swap(item.set_by_private_set_mxArray,set_by_private_set_mxArray);
- std::swap(item.mem,mem);
- std::swap(item.data,data);
- std::swap(item.nc_,nc_);
- std::swap(item.nr_,nr_);
- }
-
- long nr (
- ) const { return nr_; }
-
- long nc (
- ) const { return nc_; }
-
- void set_size (
- long nr,
- long nc
- )
- {
- if (owned_by_matlab)
- {
- if (!set_by_private_set_mxArray && mem)
- {
- mxDestroyArray(mem);
- mem = 0;
- data = 0;
- }
- set_by_private_set_mxArray = false;
-
- mem = mxCreateNumericMatrix(nr, nc, mxSINGLE_CLASS, mxREAL);
- if (mem == 0)
- throw std::bad_alloc();
- data = (float*)mxGetData(mem);
- }
- else
- {
- if (data)
- delete [] data;
- data = new float[nr*nc];
- }
- nr_ = nr;
- nc_ = nc;
- }
-
- private:
- float* data;
- long nr_;
- long nc_;
- bool owned_by_matlab;
- bool set_by_private_set_mxArray;
- mxArray* mem;
- };
-#endif
-
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#if defined(__GNUC__) && ((__GNUC__ >= 4 && __GNUC_MINOR__ >= 8) || (__GNUC__ > 4))
-#pragma GCC diagnostic pop
-#endif
-
-#endif // DLIB_MATRIx_DATA_LAYOUT_
-
diff --git a/ml/dlib/dlib/matrix/matrix_data_layout_abstract.h b/ml/dlib/dlib/matrix/matrix_data_layout_abstract.h
deleted file mode 100644
index c3fa02be2..000000000
--- a/ml/dlib/dlib/matrix/matrix_data_layout_abstract.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_DATA_LAYOUT_ABSTRACT_
-#ifdef DLIB_MATRIx_DATA_LAYOUT_ABSTRACT_
-
-#include "../algs.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- struct row_major_layout
- {
- /*!
- This is the default matrix layout. Any matrix object that uses this
- layout will be laid out in memory in row major order. Additionally,
- all elements are contiguous (e.g. there isn't any padding at the ends of
- rows or anything like that)
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
- struct column_major_layout
- {
- /*!
- Any matrix object that uses this layout will be laid out in memory in
- column major order. Additionally, all elements are contiguous (e.g.
- there isn't any padding at the ends of rows or anything like that)
- !*/
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_DATA_LAYOUT_ABSTRACT_
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_default_mul.h b/ml/dlib/dlib/matrix/matrix_default_mul.h
deleted file mode 100644
index 493c641a8..000000000
--- a/ml/dlib/dlib/matrix/matrix_default_mul.h
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_DEFAULT_MULTIPLY_
-#define DLIB_MATRIx_DEFAULT_MULTIPLY_
-
-#include "../geometry/rectangle.h"
-#include "matrix.h"
-#include "matrix_utilities.h"
-#include "../enable_if.h"
-
-namespace dlib
-{
-
-// ------------------------------------------------------------------------------------
-
- namespace ma
- {
- template < typename EXP, typename enable = void >
- struct matrix_is_vector { static const bool value = false; };
- template < typename EXP >
- struct matrix_is_vector<EXP, typename enable_if_c<EXP::NR==1 || EXP::NC==1>::type > { static const bool value = true; };
- }
-
-// ------------------------------------------------------------------------------------
-
- /*! This file defines the default_matrix_multiply() function. It is a function
- that conforms to the following definition:
-
- template <
- typename matrix_dest_type,
- typename EXP1,
- typename EXP2
- >
- void default_matrix_multiply (
- matrix_dest_type& dest,
- const EXP1& lhs,
- const EXP2& rhs
- );
- requires
- - (lhs*rhs).destructively_aliases(dest) == false
- - dest.nr() == (lhs*rhs).nr()
- - dest.nc() == (lhs*rhs).nc()
- ensures
- - #dest == dest + lhs*rhs
- !*/
-
-// ------------------------------------------------------------------------------------
-
- template <
- typename matrix_dest_type,
- typename EXP1,
- typename EXP2
- >
- typename enable_if_c<ma::matrix_is_vector<EXP1>::value == true || ma::matrix_is_vector<EXP2>::value == true>::type
- default_matrix_multiply (
- matrix_dest_type& dest,
- const EXP1& lhs,
- const EXP2& rhs
- )
- {
- matrix_assign_default(dest, lhs*rhs, 1, true);
- }
-
-// ------------------------------------------------------------------------------------
-
- template <
- typename matrix_dest_type,
- typename EXP1,
- typename EXP2
- >
- typename enable_if_c<ma::matrix_is_vector<EXP1>::value == false && ma::matrix_is_vector<EXP2>::value == false>::type
- default_matrix_multiply (
- matrix_dest_type& dest,
- const EXP1& lhs,
- const EXP2& rhs
- )
- {
- const long bs = 90;
-
- // if the matrices are small enough then just use the simple multiply algorithm
- if (lhs.nc() <= 2 || rhs.nc() <= 2 || lhs.nr() <= 2 || rhs.nr() <= 2 || (lhs.size() <= bs*10 && rhs.size() <= bs*10) )
- {
- matrix_assign_default(dest, lhs*rhs, 1, true);
- }
- else
- {
- // if the lhs and rhs matrices are big enough we should use a cache friendly
- // algorithm that computes the matrix multiply in blocks.
-
-
- // Loop over all the blocks in the lhs matrix
- for (long r = 0; r < lhs.nr(); r+=bs)
- {
- for (long c = 0; c < lhs.nc(); c+=bs)
- {
- // make a rect for the block from lhs
- rectangle lhs_block(c, r, std::min(c+bs-1,lhs.nc()-1), std::min(r+bs-1,lhs.nr()-1));
-
- // now loop over all the rhs blocks we have to multiply with the current lhs block
- for (long i = 0; i < rhs.nc(); i += bs)
- {
- // make a rect for the block from rhs
- rectangle rhs_block(i, c, std::min(i+bs-1,rhs.nc()-1), std::min(c+bs-1,rhs.nr()-1));
-
- // make a target rect in res
- rectangle res_block(rhs_block.left(),lhs_block.top(), rhs_block.right(), lhs_block.bottom());
-
- // This loop is optimized assuming that the data is laid out in
- // row major order in memory.
- for (long r = lhs_block.top(); r <= lhs_block.bottom(); ++r)
- {
- for (long c = lhs_block.left(); c<= lhs_block.right(); ++c)
- {
- const typename EXP2::type temp = lhs(r,c);
- for (long i = rhs_block.left(); i <= rhs_block.right(); ++i)
- {
- dest(r,i) += rhs(c,i)*temp;
- }
- }
- }
- }
- }
- }
- }
-
-
- }
-
-// ------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_DEFAULT_MULTIPLY_
-
diff --git a/ml/dlib/dlib/matrix/matrix_eigenvalue.h b/ml/dlib/dlib/matrix/matrix_eigenvalue.h
deleted file mode 100644
index 3dc47e105..000000000
--- a/ml/dlib/dlib/matrix/matrix_eigenvalue.h
+++ /dev/null
@@ -1,1379 +0,0 @@
-// Copyright (C) 2009 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-// This code was adapted from code from the JAMA part of NIST's TNT library.
-// See: http://math.nist.gov/tnt/
-#ifndef DLIB_MATRIX_EIGENVALUE_DECOMPOSITION_H
-#define DLIB_MATRIX_EIGENVALUE_DECOMPOSITION_H
-
-#include "matrix.h"
-#include "matrix_utilities.h"
-#include "matrix_subexp.h"
-#include <algorithm>
-#include <complex>
-#include <cmath>
-
-#ifdef DLIB_USE_LAPACK
-#include "lapack/geev.h"
-#include "lapack/syev.h"
-#include "lapack/syevr.h"
-#endif
-
-#define DLIB_LAPACK_EIGENVALUE_DECOMP_SIZE_THRESH 4
-
-namespace dlib
-{
-
- template <
- typename matrix_exp_type
- >
- class eigenvalue_decomposition
- {
-
- public:
-
- const static long NR = matrix_exp_type::NR;
- const static long NC = matrix_exp_type::NC;
- typedef typename matrix_exp_type::type type;
- typedef typename matrix_exp_type::mem_manager_type mem_manager_type;
- typedef typename matrix_exp_type::layout_type layout_type;
-
- typedef typename matrix_exp_type::matrix_type matrix_type;
- typedef matrix<type,NR,1,mem_manager_type,layout_type> column_vector_type;
-
- typedef matrix<std::complex<type>,0,0,mem_manager_type,layout_type> complex_matrix_type;
- typedef matrix<std::complex<type>,NR,1,mem_manager_type,layout_type> complex_column_vector_type;
-
-
- // You have supplied an invalid type of matrix_exp_type. You have
- // to use this object with matrices that contain float or double type data.
- COMPILE_TIME_ASSERT((is_same_type<float, type>::value ||
- is_same_type<double, type>::value ));
-
-
- template <typename EXP>
- eigenvalue_decomposition(
- const matrix_exp<EXP>& A
- );
-
- template <typename EXP>
- eigenvalue_decomposition(
- const matrix_op<op_make_symmetric<EXP> >& A
- );
-
- long dim (
- ) const;
-
- const complex_column_vector_type get_eigenvalues (
- ) const;
-
- const column_vector_type& get_real_eigenvalues (
- ) const;
-
- const column_vector_type& get_imag_eigenvalues (
- ) const;
-
- const complex_matrix_type get_v (
- ) const;
-
- const complex_matrix_type get_d (
- ) const;
-
- const matrix_type& get_pseudo_v (
- ) const;
-
- const matrix_type get_pseudo_d (
- ) const;
-
- private:
-
- /** Row and column dimension (square matrix). */
- long n;
-
- bool issymmetric;
-
- /** Arrays for internal storage of eigenvalues. */
-
- column_vector_type d; /* real part */
- column_vector_type e; /* img part */
-
- /** Array for internal storage of eigenvectors. */
- matrix_type V;
-
- /** Array for internal storage of nonsymmetric Hessenberg form.
- @serial internal storage of nonsymmetric Hessenberg form.
- */
- matrix_type H;
-
-
- /** Working storage for nonsymmetric algorithm.
- @serial working storage for nonsymmetric algorithm.
- */
- column_vector_type ort;
-
- // Symmetric Householder reduction to tridiagonal form.
- void tred2();
-
-
- // Symmetric tridiagonal QL algorithm.
- void tql2 ();
-
-
- // Nonsymmetric reduction to Hessenberg form.
- void orthes ();
-
-
- // Complex scalar division.
- type cdivr, cdivi;
- void cdiv_(type xr, type xi, type yr, type yi);
-
-
- // Nonsymmetric reduction from Hessenberg to real Schur form.
- void hqr2 ();
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Public member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- eigenvalue_decomposition<matrix_exp_type>::
- eigenvalue_decomposition(
- const matrix_exp<EXP>& A_
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<type, typename EXP::type>::value));
-
-
- const_temp_matrix<EXP> A(A_);
-
- // make sure requires clause is not broken
- DLIB_ASSERT(A.nr() == A.nc() && A.size() > 0,
- "\teigenvalue_decomposition::eigenvalue_decomposition(A)"
- << "\n\tYou can only use this on square matrices"
- << "\n\tA.nr(): " << A.nr()
- << "\n\tA.nc(): " << A.nc()
- << "\n\tA.size(): " << A.size()
- << "\n\tthis: " << this
- );
-
-
- n = A.nc();
- V.set_size(n,n);
- d.set_size(n);
- e.set_size(n);
-
-
- issymmetric = true;
- for (long j = 0; (j < n) && issymmetric; j++)
- {
- for (long i = 0; (i < n) && issymmetric; i++)
- {
- issymmetric = (A(i,j) == A(j,i));
- }
- }
-
- if (issymmetric)
- {
- V = A;
-
-#ifdef DLIB_USE_LAPACK
- if (A.nr() > DLIB_LAPACK_EIGENVALUE_DECOMP_SIZE_THRESH)
- {
- e = 0;
-
- // We could compute the result using syev()
- //lapack::syev('V', 'L', V, d);
-
- // Instead, we use syevr because its faster and maybe more stable.
- matrix_type tempA(A);
- matrix<lapack::integer,0,0,mem_manager_type,layout_type> isupz;
-
- lapack::integer temp;
- lapack::syevr('V','A','L',tempA,0,0,0,0,-1,temp,d,V,isupz);
- return;
- }
-#endif
- // Tridiagonalize.
- tred2();
-
- // Diagonalize.
- tql2();
-
- }
- else
- {
-
-#ifdef DLIB_USE_LAPACK
- if (A.nr() > DLIB_LAPACK_EIGENVALUE_DECOMP_SIZE_THRESH)
- {
- matrix<type,0,0,mem_manager_type, column_major_layout> temp, vl, vr;
- temp = A;
- lapack::geev('N', 'V', temp, d, e, vl, vr);
- V = vr;
- return;
- }
-#endif
- H = A;
-
- ort.set_size(n);
-
- // Reduce to Hessenberg form.
- orthes();
-
- // Reduce Hessenberg to real Schur form.
- hqr2();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- eigenvalue_decomposition<matrix_exp_type>::
- eigenvalue_decomposition(
- const matrix_op<op_make_symmetric<EXP> >& A
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<type, typename EXP::type>::value));
-
-
- // make sure requires clause is not broken
- DLIB_ASSERT(A.nr() == A.nc() && A.size() > 0,
- "\teigenvalue_decomposition::eigenvalue_decomposition(A)"
- << "\n\tYou can only use this on square matrices"
- << "\n\tA.nr(): " << A.nr()
- << "\n\tA.nc(): " << A.nc()
- << "\n\tA.size(): " << A.size()
- << "\n\tthis: " << this
- );
-
-
- n = A.nc();
- V.set_size(n,n);
- d.set_size(n);
- e.set_size(n);
-
-
- V = A;
-
-#ifdef DLIB_USE_LAPACK
- if (A.nr() > DLIB_LAPACK_EIGENVALUE_DECOMP_SIZE_THRESH)
- {
- e = 0;
-
- // We could compute the result using syev()
- //lapack::syev('V', 'L', V, d);
-
- // Instead, we use syevr because its faster and maybe more stable.
- matrix_type tempA(A);
- matrix<lapack::integer,0,0,mem_manager_type,layout_type> isupz;
-
- lapack::integer temp;
- lapack::syevr('V','A','L',tempA,0,0,0,0,-1,temp,d,V,isupz);
- return;
- }
-#endif
- // Tridiagonalize.
- tred2();
-
- // Diagonalize.
- tql2();
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename eigenvalue_decomposition<matrix_exp_type>::matrix_type& eigenvalue_decomposition<matrix_exp_type>::
- get_pseudo_v (
- ) const
- {
- return V;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- long eigenvalue_decomposition<matrix_exp_type>::
- dim (
- ) const
- {
- return V.nr();
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename eigenvalue_decomposition<matrix_exp_type>::complex_column_vector_type eigenvalue_decomposition<matrix_exp_type>::
- get_eigenvalues (
- ) const
- {
- return complex_matrix(get_real_eigenvalues(), get_imag_eigenvalues());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename eigenvalue_decomposition<matrix_exp_type>::column_vector_type& eigenvalue_decomposition<matrix_exp_type>::
- get_real_eigenvalues (
- ) const
- {
- return d;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename eigenvalue_decomposition<matrix_exp_type>::column_vector_type& eigenvalue_decomposition<matrix_exp_type>::
- get_imag_eigenvalues (
- ) const
- {
- return e;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename eigenvalue_decomposition<matrix_exp_type>::complex_matrix_type eigenvalue_decomposition<matrix_exp_type>::
- get_d (
- ) const
- {
- return diagm(complex_matrix(get_real_eigenvalues(), get_imag_eigenvalues()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename eigenvalue_decomposition<matrix_exp_type>::complex_matrix_type eigenvalue_decomposition<matrix_exp_type>::
- get_v (
- ) const
- {
- complex_matrix_type CV(n,n);
-
- for (long i = 0; i < n; i++)
- {
- if (e(i) > 0)
- {
- set_colm(CV,i) = complex_matrix(colm(V,i), colm(V,i+1));
- }
- else if (e(i) < 0)
- {
- set_colm(CV,i) = complex_matrix(colm(V,i), colm(V,i-1));
- }
- else
- {
- set_colm(CV,i) = complex_matrix(colm(V,i), uniform_matrix<type>(n,1,0));
- }
- }
-
- return CV;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename eigenvalue_decomposition<matrix_exp_type>::matrix_type eigenvalue_decomposition<matrix_exp_type>::
- get_pseudo_d (
- ) const
- {
- matrix_type D(n,n);
-
- for (long i = 0; i < n; i++)
- {
- for (long j = 0; j < n; j++)
- {
- D(i,j) = 0.0;
- }
- D(i,i) = d(i);
- if (e(i) > 0)
- {
- D(i,i+1) = e(i);
- }
- else if (e(i) < 0)
- {
- D(i,i-1) = e(i);
- }
- }
-
- return D;
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Private member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-// Symmetric Householder reduction to tridiagonal form.
- template <typename matrix_exp_type>
- void eigenvalue_decomposition<matrix_exp_type>::
- tred2()
- {
- using std::abs;
- using std::sqrt;
-
- // This is derived from the Algol procedures tred2 by
- // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
- // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
- // Fortran subroutine in EISPACK.
-
- for (long j = 0; j < n; j++)
- {
- d(j) = V(n-1,j);
- }
-
- // Householder reduction to tridiagonal form.
-
- for (long i = n-1; i > 0; i--)
- {
-
- // Scale to avoid under/overflow.
-
- type scale = 0.0;
- type h = 0.0;
- for (long k = 0; k < i; k++)
- {
- scale = scale + abs(d(k));
- }
- if (scale == 0.0)
- {
- e(i) = d(i-1);
- for (long j = 0; j < i; j++)
- {
- d(j) = V(i-1,j);
- V(i,j) = 0.0;
- V(j,i) = 0.0;
- }
- }
- else
- {
-
- // Generate Householder vector.
-
- for (long k = 0; k < i; k++)
- {
- d(k) /= scale;
- h += d(k) * d(k);
- }
- type f = d(i-1);
- type g = sqrt(h);
- if (f > 0)
- {
- g = -g;
- }
- e(i) = scale * g;
- h = h - f * g;
- d(i-1) = f - g;
- for (long j = 0; j < i; j++)
- {
- e(j) = 0.0;
- }
-
- // Apply similarity transformation to remaining columns.
-
- for (long j = 0; j < i; j++)
- {
- f = d(j);
- V(j,i) = f;
- g = e(j) + V(j,j) * f;
- for (long k = j+1; k <= i-1; k++)
- {
- g += V(k,j) * d(k);
- e(k) += V(k,j) * f;
- }
- e(j) = g;
- }
- f = 0.0;
- for (long j = 0; j < i; j++)
- {
- e(j) /= h;
- f += e(j) * d(j);
- }
- type hh = f / (h + h);
- for (long j = 0; j < i; j++)
- {
- e(j) -= hh * d(j);
- }
- for (long j = 0; j < i; j++)
- {
- f = d(j);
- g = e(j);
- for (long k = j; k <= i-1; k++)
- {
- V(k,j) -= (f * e(k) + g * d(k));
- }
- d(j) = V(i-1,j);
- V(i,j) = 0.0;
- }
- }
- d(i) = h;
- }
-
- // Accumulate transformations.
-
- for (long i = 0; i < n-1; i++)
- {
- V(n-1,i) = V(i,i);
- V(i,i) = 1.0;
- type h = d(i+1);
- if (h != 0.0)
- {
- for (long k = 0; k <= i; k++)
- {
- d(k) = V(k,i+1) / h;
- }
- for (long j = 0; j <= i; j++)
- {
- type g = 0.0;
- for (long k = 0; k <= i; k++)
- {
- g += V(k,i+1) * V(k,j);
- }
- for (long k = 0; k <= i; k++)
- {
- V(k,j) -= g * d(k);
- }
- }
- }
- for (long k = 0; k <= i; k++)
- {
- V(k,i+1) = 0.0;
- }
- }
- for (long j = 0; j < n; j++)
- {
- d(j) = V(n-1,j);
- V(n-1,j) = 0.0;
- }
- V(n-1,n-1) = 1.0;
- e(0) = 0.0;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- void eigenvalue_decomposition<matrix_exp_type>::
- tql2 ()
- {
- using std::pow;
- using std::min;
- using std::max;
- using std::abs;
-
- // This is derived from the Algol procedures tql2, by
- // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
- // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
- // Fortran subroutine in EISPACK.
-
- for (long i = 1; i < n; i++)
- {
- e(i-1) = e(i);
- }
- e(n-1) = 0.0;
-
- type f = 0.0;
- type tst1 = 0.0;
- const type eps = std::numeric_limits<type>::epsilon();
- for (long l = 0; l < n; l++)
- {
-
- // Find small subdiagonal element
-
- tst1 = max(tst1,abs(d(l)) + abs(e(l)));
- long m = l;
-
- // Original while-loop from Java code
- while (m < n)
- {
- if (abs(e(m)) <= eps*tst1)
- {
- break;
- }
- m++;
- }
- if (m == n)
- --m;
-
-
- // If m == l, d(l) is an eigenvalue,
- // otherwise, iterate.
-
- if (m > l)
- {
- long iter = 0;
- do
- {
- iter = iter + 1; // (Could check iteration count here.)
-
- // Compute implicit shift
-
- type g = d(l);
- type p = (d(l+1) - g) / (2.0 * e(l));
- type r = hypot(p,(type)1.0);
- if (p < 0)
- {
- r = -r;
- }
- d(l) = e(l) / (p + r);
- d(l+1) = e(l) * (p + r);
- type dl1 = d(l+1);
- type h = g - d(l);
- for (long i = l+2; i < n; i++)
- {
- d(i) -= h;
- }
- f = f + h;
-
- // Implicit QL transformation.
-
- p = d(m);
- type c = 1.0;
- type c2 = c;
- type c3 = c;
- type el1 = e(l+1);
- type s = 0.0;
- type s2 = 0.0;
- for (long i = m-1; i >= l; i--)
- {
- c3 = c2;
- c2 = c;
- s2 = s;
- g = c * e(i);
- h = c * p;
- r = hypot(p,e(i));
- e(i+1) = s * r;
- s = e(i) / r;
- c = p / r;
- p = c * d(i) - s * g;
- d(i+1) = h + s * (c * g + s * d(i));
-
- // Accumulate transformation.
-
- for (long k = 0; k < n; k++)
- {
- h = V(k,i+1);
- V(k,i+1) = s * V(k,i) + c * h;
- V(k,i) = c * V(k,i) - s * h;
- }
- }
- p = -s * s2 * c3 * el1 * e(l) / dl1;
- e(l) = s * p;
- d(l) = c * p;
-
- // Check for convergence.
-
- } while (abs(e(l)) > eps*tst1);
- }
- d(l) = d(l) + f;
- e(l) = 0.0;
- }
-
- /*
- The code to sort the eigenvalues and eigenvectors
- has been removed from here since, in the non-symmetric case,
- we can't sort the eigenvalues in a meaningful way. If we left this
- code in here then the user might supply what they thought was a symmetric
- matrix but was actually slightly non-symmetric due to rounding error
- and then they would end up in the non-symmetric eigenvalue solver
- where the eigenvalues don't end up getting sorted. So to avoid
- any possible user confusion I'm just removing this.
- */
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- void eigenvalue_decomposition<matrix_exp_type>::
- orthes ()
- {
- using std::abs;
- using std::sqrt;
-
- // This is derived from the Algol procedures orthes and ortran,
- // by Martin and Wilkinson, Handbook for Auto. Comp.,
- // Vol.ii-Linear Algebra, and the corresponding
- // Fortran subroutines in EISPACK.
-
- long low = 0;
- long high = n-1;
-
- for (long m = low+1; m <= high-1; m++)
- {
-
- // Scale column.
-
- type scale = 0.0;
- for (long i = m; i <= high; i++)
- {
- scale = scale + abs(H(i,m-1));
- }
- if (scale != 0.0)
- {
-
- // Compute Householder transformation.
-
- type h = 0.0;
- for (long i = high; i >= m; i--)
- {
- ort(i) = H(i,m-1)/scale;
- h += ort(i) * ort(i);
- }
- type g = sqrt(h);
- if (ort(m) > 0)
- {
- g = -g;
- }
- h = h - ort(m) * g;
- ort(m) = ort(m) - g;
-
- // Apply Householder similarity transformation
- // H = (I-u*u'/h)*H*(I-u*u')/h)
-
- for (long j = m; j < n; j++)
- {
- type f = 0.0;
- for (long i = high; i >= m; i--)
- {
- f += ort(i)*H(i,j);
- }
- f = f/h;
- for (long i = m; i <= high; i++)
- {
- H(i,j) -= f*ort(i);
- }
- }
-
- for (long i = 0; i <= high; i++)
- {
- type f = 0.0;
- for (long j = high; j >= m; j--)
- {
- f += ort(j)*H(i,j);
- }
- f = f/h;
- for (long j = m; j <= high; j++)
- {
- H(i,j) -= f*ort(j);
- }
- }
- ort(m) = scale*ort(m);
- H(m,m-1) = scale*g;
- }
- }
-
- // Accumulate transformations (Algol's ortran).
-
- for (long i = 0; i < n; i++)
- {
- for (long j = 0; j < n; j++)
- {
- V(i,j) = (i == j ? 1.0 : 0.0);
- }
- }
-
- for (long m = high-1; m >= low+1; m--)
- {
- if (H(m,m-1) != 0.0)
- {
- for (long i = m+1; i <= high; i++)
- {
- ort(i) = H(i,m-1);
- }
- for (long j = m; j <= high; j++)
- {
- type g = 0.0;
- for (long i = m; i <= high; i++)
- {
- g += ort(i) * V(i,j);
- }
- // Double division avoids possible underflow
- g = (g / ort(m)) / H(m,m-1);
- for (long i = m; i <= high; i++)
- {
- V(i,j) += g * ort(i);
- }
- }
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- void eigenvalue_decomposition<matrix_exp_type>::
- cdiv_(type xr, type xi, type yr, type yi)
- {
- using std::abs;
- type r,d;
- if (abs(yr) > abs(yi))
- {
- r = yi/yr;
- d = yr + r*yi;
- cdivr = (xr + r*xi)/d;
- cdivi = (xi - r*xr)/d;
- }
- else
- {
- r = yr/yi;
- d = yi + r*yr;
- cdivr = (r*xr + xi)/d;
- cdivi = (r*xi - xr)/d;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- void eigenvalue_decomposition<matrix_exp_type>::
- hqr2 ()
- {
- using std::pow;
- using std::min;
- using std::max;
- using std::abs;
- using std::sqrt;
-
- // This is derived from the Algol procedure hqr2,
- // by Martin and Wilkinson, Handbook for Auto. Comp.,
- // Vol.ii-Linear Algebra, and the corresponding
- // Fortran subroutine in EISPACK.
-
- // Initialize
-
- long nn = this->n;
- long n = nn-1;
- long low = 0;
- long high = nn-1;
- const type eps = std::numeric_limits<type>::epsilon();
- type exshift = 0.0;
- type p=0,q=0,r=0,s=0,z=0,t,w,x,y;
-
- // Store roots isolated by balanc and compute matrix norm
-
- type norm = 0.0;
- for (long i = 0; i < nn; i++)
- {
- if ((i < low) || (i > high))
- {
- d(i) = H(i,i);
- e(i) = 0.0;
- }
- for (long j = max(i-1,0L); j < nn; j++)
- {
- norm = norm + abs(H(i,j));
- }
- }
-
- // Outer loop over eigenvalue index
-
- long iter = 0;
- while (n >= low)
- {
-
- // Look for single small sub-diagonal element
-
- long l = n;
- while (l > low)
- {
- s = abs(H(l-1,l-1)) + abs(H(l,l));
- if (s == 0.0)
- {
- s = norm;
- }
- if (abs(H(l,l-1)) < eps * s)
- {
- break;
- }
- l--;
- }
-
- // Check for convergence
- // One root found
-
- if (l == n)
- {
- H(n,n) = H(n,n) + exshift;
- d(n) = H(n,n);
- e(n) = 0.0;
- n--;
- iter = 0;
-
- // Two roots found
-
- }
- else if (l == n-1)
- {
- w = H(n,n-1) * H(n-1,n);
- p = (H(n-1,n-1) - H(n,n)) / 2.0;
- q = p * p + w;
- z = sqrt(abs(q));
- H(n,n) = H(n,n) + exshift;
- H(n-1,n-1) = H(n-1,n-1) + exshift;
- x = H(n,n);
-
- // type pair
-
- if (q >= 0)
- {
- if (p >= 0)
- {
- z = p + z;
- }
- else
- {
- z = p - z;
- }
- d(n-1) = x + z;
- d(n) = d(n-1);
- if (z != 0.0)
- {
- d(n) = x - w / z;
- }
- e(n-1) = 0.0;
- e(n) = 0.0;
- x = H(n,n-1);
- s = abs(x) + abs(z);
- p = x / s;
- q = z / s;
- r = sqrt(p * p+q * q);
- p = p / r;
- q = q / r;
-
- // Row modification
-
- for (long j = n-1; j < nn; j++)
- {
- z = H(n-1,j);
- H(n-1,j) = q * z + p * H(n,j);
- H(n,j) = q * H(n,j) - p * z;
- }
-
- // Column modification
-
- for (long i = 0; i <= n; i++)
- {
- z = H(i,n-1);
- H(i,n-1) = q * z + p * H(i,n);
- H(i,n) = q * H(i,n) - p * z;
- }
-
- // Accumulate transformations
-
- for (long i = low; i <= high; i++)
- {
- z = V(i,n-1);
- V(i,n-1) = q * z + p * V(i,n);
- V(i,n) = q * V(i,n) - p * z;
- }
-
- // Complex pair
-
- }
- else
- {
- d(n-1) = x + p;
- d(n) = x + p;
- e(n-1) = z;
- e(n) = -z;
- }
- n = n - 2;
- iter = 0;
-
- // No convergence yet
-
- }
- else
- {
-
- // Form shift
-
- x = H(n,n);
- y = 0.0;
- w = 0.0;
- if (l < n)
- {
- y = H(n-1,n-1);
- w = H(n,n-1) * H(n-1,n);
- }
-
- // Wilkinson's original ad hoc shift
-
- if (iter == 10)
- {
- exshift += x;
- for (long i = low; i <= n; i++)
- {
- H(i,i) -= x;
- }
- s = abs(H(n,n-1)) + abs(H(n-1,n-2));
- x = y = 0.75 * s;
- w = -0.4375 * s * s;
- }
-
- // MATLAB's new ad hoc shift
-
- if (iter == 30)
- {
- s = (y - x) / 2.0;
- s = s * s + w;
- if (s > 0)
- {
- s = sqrt(s);
- if (y < x)
- {
- s = -s;
- }
- s = x - w / ((y - x) / 2.0 + s);
- for (long i = low; i <= n; i++)
- {
- H(i,i) -= s;
- }
- exshift += s;
- x = y = w = 0.964;
- }
- }
-
- iter = iter + 1; // (Could check iteration count here.)
-
- // Look for two consecutive small sub-diagonal elements
-
- long m = n-2;
- while (m >= l)
- {
- z = H(m,m);
- r = x - z;
- s = y - z;
- p = (r * s - w) / H(m+1,m) + H(m,m+1);
- q = H(m+1,m+1) - z - r - s;
- r = H(m+2,m+1);
- s = abs(p) + abs(q) + abs(r);
- p = p / s;
- q = q / s;
- r = r / s;
- if (m == l)
- {
- break;
- }
- if (abs(H(m,m-1)) * (abs(q) + abs(r)) <
- eps * (abs(p) * (abs(H(m-1,m-1)) + abs(z) +
- abs(H(m+1,m+1)))))
- {
- break;
- }
- m--;
- }
-
- for (long i = m+2; i <= n; i++)
- {
- H(i,i-2) = 0.0;
- if (i > m+2)
- {
- H(i,i-3) = 0.0;
- }
- }
-
- // Double QR step involving rows l:n and columns m:n
-
- for (long k = m; k <= n-1; k++)
- {
- long notlast = (k != n-1);
- if (k != m)
- {
- p = H(k,k-1);
- q = H(k+1,k-1);
- r = (notlast ? H(k+2,k-1) : 0.0);
- x = abs(p) + abs(q) + abs(r);
- if (x != 0.0)
- {
- p = p / x;
- q = q / x;
- r = r / x;
- }
- }
- if (x == 0.0)
- {
- break;
- }
- s = sqrt(p * p + q * q + r * r);
- if (p < 0)
- {
- s = -s;
- }
- if (s != 0)
- {
- if (k != m)
- {
- H(k,k-1) = -s * x;
- }
- else if (l != m)
- {
- H(k,k-1) = -H(k,k-1);
- }
- p = p + s;
- x = p / s;
- y = q / s;
- z = r / s;
- q = q / p;
- r = r / p;
-
- // Row modification
-
- for (long j = k; j < nn; j++)
- {
- p = H(k,j) + q * H(k+1,j);
- if (notlast)
- {
- p = p + r * H(k+2,j);
- H(k+2,j) = H(k+2,j) - p * z;
- }
- H(k,j) = H(k,j) - p * x;
- H(k+1,j) = H(k+1,j) - p * y;
- }
-
- // Column modification
-
- for (long i = 0; i <= min(n,k+3); i++)
- {
- p = x * H(i,k) + y * H(i,k+1);
- if (notlast)
- {
- p = p + z * H(i,k+2);
- H(i,k+2) = H(i,k+2) - p * r;
- }
- H(i,k) = H(i,k) - p;
- H(i,k+1) = H(i,k+1) - p * q;
- }
-
- // Accumulate transformations
-
- for (long i = low; i <= high; i++)
- {
- p = x * V(i,k) + y * V(i,k+1);
- if (notlast)
- {
- p = p + z * V(i,k+2);
- V(i,k+2) = V(i,k+2) - p * r;
- }
- V(i,k) = V(i,k) - p;
- V(i,k+1) = V(i,k+1) - p * q;
- }
- } // (s != 0)
- } // k loop
- } // check convergence
- } // while (n >= low)
-
- // Backsubstitute to find vectors of upper triangular form
-
- if (norm == 0.0)
- {
- return;
- }
-
- for (n = nn-1; n >= 0; n--)
- {
- p = d(n);
- q = e(n);
-
- // Real vector
-
- if (q == 0)
- {
- long l = n;
- H(n,n) = 1.0;
- for (long i = n-1; i >= 0; i--)
- {
- w = H(i,i) - p;
- r = 0.0;
- for (long j = l; j <= n; j++)
- {
- r = r + H(i,j) * H(j,n);
- }
- if (e(i) < 0.0)
- {
- z = w;
- s = r;
- }
- else
- {
- l = i;
- if (e(i) == 0.0)
- {
- if (w != 0.0)
- {
- H(i,n) = -r / w;
- }
- else
- {
- H(i,n) = -r / (eps * norm);
- }
-
- // Solve real equations
-
- }
- else
- {
- x = H(i,i+1);
- y = H(i+1,i);
- q = (d(i) - p) * (d(i) - p) + e(i) * e(i);
- t = (x * s - z * r) / q;
- H(i,n) = t;
- if (abs(x) > abs(z))
- {
- H(i+1,n) = (-r - w * t) / x;
- }
- else
- {
- H(i+1,n) = (-s - y * t) / z;
- }
- }
-
- // Overflow control
-
- t = abs(H(i,n));
- if ((eps * t) * t > 1)
- {
- for (long j = i; j <= n; j++)
- {
- H(j,n) = H(j,n) / t;
- }
- }
- }
- }
-
- // Complex vector
-
- }
- else if (q < 0)
- {
- long l = n-1;
-
- // Last vector component imaginary so matrix is triangular
-
- if (abs(H(n,n-1)) > abs(H(n-1,n)))
- {
- H(n-1,n-1) = q / H(n,n-1);
- H(n-1,n) = -(H(n,n) - p) / H(n,n-1);
- }
- else
- {
- cdiv_(0.0,-H(n-1,n),H(n-1,n-1)-p,q);
- H(n-1,n-1) = cdivr;
- H(n-1,n) = cdivi;
- }
- H(n,n-1) = 0.0;
- H(n,n) = 1.0;
- for (long i = n-2; i >= 0; i--)
- {
- type ra,sa,vr,vi;
- ra = 0.0;
- sa = 0.0;
- for (long j = l; j <= n; j++)
- {
- ra = ra + H(i,j) * H(j,n-1);
- sa = sa + H(i,j) * H(j,n);
- }
- w = H(i,i) - p;
-
- if (e(i) < 0.0)
- {
- z = w;
- r = ra;
- s = sa;
- }
- else
- {
- l = i;
- if (e(i) == 0)
- {
- cdiv_(-ra,-sa,w,q);
- H(i,n-1) = cdivr;
- H(i,n) = cdivi;
- }
- else
- {
-
- // Solve complex equations
-
- x = H(i,i+1);
- y = H(i+1,i);
- vr = (d(i) - p) * (d(i) - p) + e(i) * e(i) - q * q;
- vi = (d(i) - p) * 2.0 * q;
- if ((vr == 0.0) && (vi == 0.0))
- {
- vr = eps * norm * (abs(w) + abs(q) +
- abs(x) + abs(y) + abs(z));
- }
- cdiv_(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
- H(i,n-1) = cdivr;
- H(i,n) = cdivi;
- if (abs(x) > (abs(z) + abs(q)))
- {
- H(i+1,n-1) = (-ra - w * H(i,n-1) + q * H(i,n)) / x;
- H(i+1,n) = (-sa - w * H(i,n) - q * H(i,n-1)) / x;
- }
- else
- {
- cdiv_(-r-y*H(i,n-1),-s-y*H(i,n),z,q);
- H(i+1,n-1) = cdivr;
- H(i+1,n) = cdivi;
- }
- }
-
- // Overflow control
-
- t = max(abs(H(i,n-1)),abs(H(i,n)));
- if ((eps * t) * t > 1)
- {
- for (long j = i; j <= n; j++)
- {
- H(j,n-1) = H(j,n-1) / t;
- H(j,n) = H(j,n) / t;
- }
- }
- }
- }
- }
- }
-
- // Vectors of isolated roots
-
- for (long i = 0; i < nn; i++)
- {
- if (i < low || i > high)
- {
- for (long j = i; j < nn; j++)
- {
- V(i,j) = H(i,j);
- }
- }
- }
-
- // Back transformation to get eigenvectors of original matrix
-
- for (long j = nn-1; j >= low; j--)
- {
- for (long i = low; i <= high; i++)
- {
- z = 0.0;
- for (long k = low; k <= min(j,high); k++)
- {
- z = z + V(i,k) * H(k,j);
- }
- V(i,j) = z;
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
-
-}
-
-#endif // DLIB_MATRIX_EIGENVALUE_DECOMPOSITION_H
-
-
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_exp.h b/ml/dlib/dlib/matrix/matrix_exp.h
deleted file mode 100644
index c0afb54c0..000000000
--- a/ml/dlib/dlib/matrix/matrix_exp.h
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_EXP_h_
-#define DLIB_MATRIx_EXP_h_
-
-#include "../algs.h"
-#include "../is_kind.h"
-#include "matrix_fwd.h"
-#include "matrix_exp_abstract.h"
-#include <iterator>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- // We want to return the compile time constant if our NR and NC dimensions
- // aren't zero but if they are then we want to call ref_.nx() and return
- // the correct values.
- template < typename exp_type, long NR >
- struct get_nr_helper
- {
- static inline long get(const exp_type&) { return NR; }
- };
-
- template < typename exp_type >
- struct get_nr_helper<exp_type,0>
- {
- static inline long get(const exp_type& m) { return m.nr(); }
- };
-
- template < typename exp_type, long NC >
- struct get_nc_helper
- {
- static inline long get(const exp_type&) { return NC; }
- };
-
- template < typename exp_type >
- struct get_nc_helper<exp_type,0>
- {
- static inline long get(const exp_type& m) { return m.nc(); }
- };
-
- template <typename EXP>
- struct matrix_traits
- {
- typedef typename EXP::type type;
- typedef typename EXP::const_ret_type const_ret_type;
- typedef typename EXP::mem_manager_type mem_manager_type;
- typedef typename EXP::layout_type layout_type;
- const static long NR = EXP::NR;
- const static long NC = EXP::NC;
- const static long cost = EXP::cost;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP> class matrix_exp;
- template <typename EXP>
- class matrix_exp_iterator : public std::iterator<std::forward_iterator_tag, typename matrix_traits<EXP>::type>
- {
- friend class matrix_exp<EXP>;
- matrix_exp_iterator(const EXP& m_, long r_, long c_)
- {
- r = r_;
- c = c_;
- nc = m_.nc();
- m = &m_;
- }
-
- public:
-
- matrix_exp_iterator() : r(0), c(0), nc(0), m(0) {}
-
- typedef typename matrix_traits<EXP>::type type;
- typedef type value_type;
- typedef typename matrix_traits<EXP>::const_ret_type const_ret_type;
-
-
- bool operator == ( const matrix_exp_iterator& itr) const
- { return r == itr.r && c == itr.c; }
-
- bool operator != ( const matrix_exp_iterator& itr) const
- { return !(*this == itr); }
-
- matrix_exp_iterator& operator++()
- {
- ++c;
- if (c==nc)
- {
- c = 0;
- ++r;
- }
- return *this;
- }
-
- matrix_exp_iterator operator++(int)
- {
- matrix_exp_iterator temp(*this);
- ++(*this);
- return temp;
- }
-
- const_ret_type operator* () const { return (*m)(r,c); }
-
- private:
- long r, c;
- long nc;
- const EXP* m;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- class matrix_exp
- {
- /*!
- REQUIREMENTS ON EXP
- EXP should be something convertible to a matrix_exp. That is,
- it should inherit from matrix_exp
- !*/
-
- public:
- typedef typename matrix_traits<EXP>::type type;
- typedef type value_type;
- typedef typename matrix_traits<EXP>::const_ret_type const_ret_type;
- typedef typename matrix_traits<EXP>::mem_manager_type mem_manager_type;
- typedef typename matrix_traits<EXP>::layout_type layout_type;
- const static long NR = matrix_traits<EXP>::NR;
- const static long NC = matrix_traits<EXP>::NC;
- const static long cost = matrix_traits<EXP>::cost;
-
- typedef matrix<type,NR,NC,mem_manager_type,layout_type> matrix_type;
- typedef EXP exp_type;
- typedef matrix_exp_iterator<EXP> iterator;
- typedef matrix_exp_iterator<EXP> const_iterator;
-
- inline const_ret_type operator() (
- long r,
- long c
- ) const
- {
- DLIB_ASSERT(r < nr() && c < nc() && r >= 0 && c >= 0,
- "\tconst type matrix_exp::operator(r,c)"
- << "\n\tYou must give a valid row and column"
- << "\n\tr: " << r
- << "\n\tc: " << c
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
- return ref()(r,c);
- }
-
- const_ret_type operator() (
- long i
- ) const
- {
- COMPILE_TIME_ASSERT(NC == 1 || NC == 0 || NR == 1 || NR == 0);
- DLIB_ASSERT(nc() == 1 || nr() == 1,
- "\tconst type matrix_exp::operator(i)"
- << "\n\tYou can only use this operator on column or row vectors"
- << "\n\ti: " << i
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
- DLIB_ASSERT( ((nc() == 1 && i < nr()) || (nr() == 1 && i < nc())) && i >= 0,
- "\tconst type matrix_exp::operator(i)"
- << "\n\tYou must give a valid row/column number"
- << "\n\ti: " << i
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
- if (nc() == 1)
- return ref()(i,0);
- else
- return ref()(0,i);
- }
-
- long size (
- ) const { return nr()*nc(); }
-
- long nr (
- ) const { return get_nr_helper<exp_type,NR>::get(ref()); }
-
- long nc (
- ) const { return get_nc_helper<exp_type,NC>::get(ref()); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return ref().aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return ref().destructively_aliases(item); }
-
- inline const exp_type& ref (
- ) const { return *static_cast<const exp_type*>(this); }
-
- inline operator const type (
- ) const
- {
- COMPILE_TIME_ASSERT(NC == 1 || NC == 0);
- COMPILE_TIME_ASSERT(NR == 1 || NR == 0);
- DLIB_ASSERT(nr() == 1 && nc() == 1,
- "\tmatrix_exp::operator const type() const"
- << "\n\tYou can only use this operator on a 1x1 matrix"
- << "\n\tnr(): " << nr()
- << "\n\tnc(): " << nc()
- << "\n\tthis: " << this
- );
-
- // Put the expression contained in this matrix_exp into
- // a temporary 1x1 matrix so that the expression will encounter
- // all the overloads of matrix_assign() and have the chance to
- // go through any applicable optimizations.
- matrix<type,1,1,mem_manager_type,layout_type> temp(ref());
- return temp(0);
- }
-
- const_iterator begin() const { return matrix_exp_iterator<EXP>(ref(),0,0); }
- const_iterator end() const { return matrix_exp_iterator<EXP>(ref(),nr(),0); }
-
- protected:
- matrix_exp() {}
- matrix_exp(const matrix_exp& ) {}
-
- private:
-
- matrix_exp& operator= (const matrix_exp&);
- };
-
-// ----------------------------------------------------------------------------------------
-
- // something is a matrix if it is convertible to a matrix_exp object
- template <typename T>
- struct is_matrix<T, typename enable_if<is_convertible<T, const matrix_exp<typename T::exp_type>& > >::type >
- { static const bool value = true; };
- /*
- is_matrix<T>::value == 1 if T is a matrix type else 0
- */
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- class matrix_diag_exp : public matrix_exp<EXP>
- {
- /*!
- This is a matrix expression type used to represent diagonal matrices.
- That is, square matrices with all off diagonal elements equal to 0.
- !*/
-
- protected:
- matrix_diag_exp() {}
- matrix_diag_exp(const matrix_diag_exp& item ):matrix_exp<EXP>(item) {}
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_EXP_h_
-
diff --git a/ml/dlib/dlib/matrix/matrix_exp_abstract.h b/ml/dlib/dlib/matrix/matrix_exp_abstract.h
deleted file mode 100644
index 14ad143c2..000000000
--- a/ml/dlib/dlib/matrix/matrix_exp_abstract.h
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_EXP_ABSTRACT_
-#ifdef DLIB_MATRIx_EXP_ABSTRACT_
-
-#include "matrix_fwd.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- class matrix_exp
- {
- /*!
- REQUIREMENTS ON EXP
- - must be an object that inherits publicly from matrix_exp (this class).
-
- WHAT THIS OBJECT REPRESENTS
- This object represents an expression that evaluates to a matrix
- of nr() rows and nc() columns.
-
- The reason for having an object that represents an expression is that it
- allows us to use the "expression templates" technique to eliminate the
- temporary matrix objects that would normally be returned from expressions
- such as M = A+B+C+D; Normally each invocation of the + operator would
- construct and return a temporary matrix object but using this technique we
- can avoid creating all of these temporary objects and receive a large
- speed boost.
-
- Note that every time you invoke operator() on this object it recomputes
- its result which may not be what you want to do. For example, if you
- are going to be accessing the same element over and over it might
- be faster to assign the matrix_exp to a temporary matrix and then
- use that temporary.
-
-
- const_ret_type typedef (defined below)
- The purpose of the const_ret_type typedef is to allow matrix expressions
- to return their elements by reference when appropriate. So const_ret_type
- should be one of the following types:
- - const type
- - const type&
- !*/
-
- public:
- typedef typename EXP::type type;
- typedef type value_type; // Redefined for compatibility with the STL
- typedef typename EXP::const_ret_type const_ret_type;
- typedef typename EXP::mem_manager_type mem_manager_type;
- typedef typename EXP::layout_type layout_type;
- const static long cost = EXP::cost;
- const static long NR = EXP::NR;
- const static long NC = EXP::NC;
- typedef matrix<type,NR,NC, mem_manager_type,layout_type> matrix_type;
- typedef EXP exp_type;
- typedef matrix_exp_iterator<EXP> iterator;
- typedef matrix_exp_iterator<EXP> const_iterator;
-
- const_ret_type operator() (
- long r,
- long c
- ) const;
- /*!
- requires
- - 0 <= r < nr()
- - 0 <= c < nc()
- ensures
- - returns ref()(r,c)
- (i.e. returns the value at the given row and column that would be in
- the matrix represented by this matrix expression)
- !*/
-
- const_ret_type operator() (
- long i
- ) const;
- /*!
- requires
- - nc() == 1 || nr() == 1 (i.e. this must be a column or row vector)
- - if (nc() == 1) then
- - 0 <= i < nr()
- - else
- - 0 <= i < nc()
- ensures
- - if (nc() == 1) then
- - returns (*this)(i,0)
- - else
- - returns (*this)(0,i)
- !*/
-
- operator const type (
- ) const;
- /*!
- requires
- - nr() == 1
- - nc() == 1
- ensures
- - returns (*this)(0,0)
- !*/
-
- long nr (
- ) const;
- /*!
- ensures
- - returns the number of rows in this matrix expression.
- !*/
-
- long nc (
- ) const;
- /*!
- ensures
- - returns the number of columns in this matrix expression.
- !*/
-
- long size (
- ) const;
- /*!
- ensures
- - returns nr()*nc()
- !*/
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const;
- /*!
- ensures
- - if (A change to the state of item could cause a change to the state of *this
- matrix_exp object. ) then
- - returns true
- - This happens when this matrix_exp contains item in some way.
- - else
- - returns false
- !*/
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const;
- /*!
- ensures
- - if (aliases(item)) then
- - if (nr() != item.nr() || nc() != item.nc()
- - returns true
- (i.e. if this expression has different dimensions than item then
- we have destructive aliasing)
-
- - returns true if the following assignment would evaluate incorrectly:
- for (long r = 0; r < nr(); ++r)
- for (long c = 0; c < nc(); ++c)
- item(r,c) = (*this)(r,c)
- - That is, if this matrix expression aliases item in such a way that a modification
- to element item(r,c) causes a change in the value of something other than
- (*this)(r,c) then this function returns true.
-
- - returns false if none of the above conditions say we should return true
- - else
- - returns false
- !*/
-
- inline const exp_type& ref (
- ) const;
- /*!
- ensures
- - returns a reference to the expression contained in *this.
- (i.e. returns *static_cast<const exp_type*>(this) )
- !*/
-
- const_iterator begin(
- ) const;
- /*!
- ensures
- - returns a forward access iterator pointing to the first element in this
- matrix expression.
- - Since matrix_exp objects represent immutable views of a matrix, the
- returned iterator does not allow the user to modify the matrix
- expression's elements.
- - The iterator will iterate over the elements of the matrix in row major
- order.
- !*/
-
- const_iterator end(
- ) const;
- /*!
- ensures
- - returns a forward access iterator pointing to one past the end of the
- last element in this matrix expression.
- !*/
-
- protected:
-
- // Only derived classes of matrix_exp may call the matrix_exp constructors.
- matrix_exp(const matrix_exp&);
- matrix_exp();
-
- private:
- // no one may ever use the assignment operator on a matrix_exp
- matrix_exp& operator= (const matrix_exp&);
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_EXP_ABSTRACT_
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_expressions.h b/ml/dlib/dlib/matrix/matrix_expressions.h
deleted file mode 100644
index 9f057d076..000000000
--- a/ml/dlib/dlib/matrix/matrix_expressions.h
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_EXPRESSIONS_H_
-#define DLIB_MATRIx_EXPRESSIONS_H_
-
-#include "matrix_fwd.h"
-
-#ifdef _MSC_VER
-// This #pragma directive is also located in the algs.h file but for whatever
-// reason visual studio 9 just ignores it when it is only there.
-
-// this is to disable the "'this' : used in base member initializer list"
-// warning you get from some of the GUI objects since all the objects
-// require that their parent class be passed into their constructor.
-// In this case though it is totally safe so it is ok to disable this warning.
-#pragma warning(disable : 4355)
-#endif
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Helper templates for making operators used by expression objects
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- class matrix_range_exp;
-
- template <typename T>
- struct matrix_traits<matrix_range_exp<T> >
- {
- typedef T type;
- typedef const T const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- const static long NR = 1;
- const static long NC = 0;
- const static long cost = 1;
- };
-
- template <typename T>
- class matrix_range_exp : public matrix_exp<matrix_range_exp<T> >
- {
- public:
- typedef typename matrix_traits<matrix_range_exp>::type type;
- typedef typename matrix_traits<matrix_range_exp>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_range_exp>::mem_manager_type mem_manager_type;
- const static long NR = matrix_traits<matrix_range_exp>::NR;
- const static long NC = matrix_traits<matrix_range_exp>::NC;
- const static long cost = matrix_traits<matrix_range_exp>::cost;
- typedef typename matrix_traits<matrix_range_exp>::layout_type layout_type;
-
-
- matrix_range_exp (
- T start_,
- T end_
- )
- {
- start = start_;
- if (start_ <= end_)
- inc = 1;
- else
- inc = -1;
- nc_ = std::abs(end_ - start_) + 1;
- }
- matrix_range_exp (
- T start_,
- T inc_,
- T end_
- )
- {
- start = start_;
- nc_ = std::abs(end_ - start_)/inc_ + 1;
- if (start_ <= end_)
- inc = inc_;
- else
- inc = -inc_;
- }
-
- matrix_range_exp (
- T start_,
- T end_,
- long num,
- bool
- )
- {
- start = start_;
- nc_ = num;
- if (num > 1)
- {
- inc = (end_-start_)/(num-1);
- }
- else
- {
- inc = 0;
- start = end_;
- }
-
- }
-
- const_ret_type operator() (
- long,
- long c
- ) const { return start + c*inc; }
-
- const_ret_type operator() (
- long c
- ) const { return start + c*inc; }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>&
- ) const { return false; }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>&
- ) const { return false; }
-
- long nr (
- ) const { return NR; }
-
- long nc (
- ) const { return nc_; }
-
- long nc_;
- T start;
- T inc;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- class matrix_log_range_exp;
-
- template <typename T>
- struct matrix_traits<matrix_log_range_exp<T> >
- {
- typedef T type;
- typedef const T const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- const static long NR = 1;
- const static long NC = 0;
- const static long cost = 1;
- };
-
- template <typename T>
- class matrix_log_range_exp : public matrix_exp<matrix_log_range_exp<T> >
- {
- public:
- typedef typename matrix_traits<matrix_log_range_exp>::type type;
- typedef typename matrix_traits<matrix_log_range_exp>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_log_range_exp>::mem_manager_type mem_manager_type;
- const static long NR = matrix_traits<matrix_log_range_exp>::NR;
- const static long NC = matrix_traits<matrix_log_range_exp>::NC;
- const static long cost = matrix_traits<matrix_log_range_exp>::cost;
- typedef typename matrix_traits<matrix_log_range_exp>::layout_type layout_type;
-
-
- matrix_log_range_exp (
- T start_,
- T end_,
- long num
- )
- {
- start = start_;
- nc_ = num;
- if (num > 1)
- {
- inc = (end_-start_)/(num-1);
- }
- else
- {
- inc = 0;
- start = end_;
- }
-
- }
-
- const_ret_type operator() (
- long,
- long c
- ) const { return std::pow((T)10,start + c*inc); }
-
- const_ret_type operator() (
- long c
- ) const { return std::pow((T)10,start + c*inc); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>&
- ) const { return false; }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>&
- ) const { return false; }
-
- long nr (
- ) const { return NR; }
-
- long nc (
- ) const { return nc_; }
-
- long nc_;
- T start;
- T inc;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <long start, long inc_, long end>
- class matrix_range_static_exp;
-
- template <long start, long inc_, long end>
- struct matrix_traits<matrix_range_static_exp<start,inc_,end> >
- {
- typedef long type;
- typedef const long const_ret_type;
- typedef default_memory_manager mem_manager_type;
- const static long NR = 1;
- const static long NC = tabs<(end - start)>::value/inc_ + 1;
- const static long cost = 1;
- typedef row_major_layout layout_type;
- };
-
- template <long start, long inc_, long end_>
- class matrix_range_static_exp : public matrix_exp<matrix_range_static_exp<start,inc_,end_> >
- {
- public:
- typedef typename matrix_traits<matrix_range_static_exp>::type type;
- typedef typename matrix_traits<matrix_range_static_exp>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_range_static_exp>::mem_manager_type mem_manager_type;
- const static long NR = matrix_traits<matrix_range_static_exp>::NR;
- const static long NC = matrix_traits<matrix_range_static_exp>::NC;
- const static long cost = matrix_traits<matrix_range_static_exp>::cost;
- typedef typename matrix_traits<matrix_range_static_exp>::layout_type layout_type;
-
- const static long inc = (start <= end_)?inc_:-inc_;
-
-
- matrix_range_static_exp (
- ) {}
-
- const_ret_type operator() (
- long ,
- long c
- ) const { return start + c*inc; }
-
- const_ret_type operator() (
- long c
- ) const { return start + c*inc; }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>&
- ) const { return false; }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>&
- ) const { return false; }
-
- long nr (
- ) const { return NR; }
-
- long nc (
- ) const { return NC; }
-
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_EXPRESSIONS_H_
-
diff --git a/ml/dlib/dlib/matrix/matrix_fft.h b/ml/dlib/dlib/matrix/matrix_fft.h
deleted file mode 100644
index fbca6d344..000000000
--- a/ml/dlib/dlib/matrix/matrix_fft.h
+++ /dev/null
@@ -1,846 +0,0 @@
-// Copyright (C) 2013 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_FFt_Hh_
-#define DLIB_FFt_Hh_
-
-#include "matrix_fft_abstract.h"
-#include "matrix_utilities.h"
-#include "../hash.h"
-#include "../algs.h"
-
-#ifdef DLIB_USE_MKL_FFT
-#include <mkl_dfti.h>
-#endif
-
-// No using FFTW until it becomes thread safe!
-#if 0
-#ifdef DLIB_USE_FFTW
-#include <fftw3.h>
-#endif // DLIB_USE_FFTW
-#endif
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- inline bool is_power_of_two (
- const unsigned long& value
- )
- {
- if (value == 0)
- return true;
- else
- return count_bits(value) == 1;
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
-
- // ------------------------------------------------------------------------------------
-
- /*
- The next few functions related to doing FFTs are derived from Stefan
- Gustavson's (stegu@itn.liu.se) public domain 2D Fourier transformation code.
- The code has a long history, originally a FORTRAN implementation published in:
- Programming for Digital Signal Processing, IEEE Press 1979, Section 1, by G. D.
- Bergland and M. T. Dolan. In 2003 it was cleaned up and turned into modern C
- by Steven Gustavson. Davis King then rewrote it in modern C++ in 2014 and also
- changed the transform so that the outputs are identical to those given from FFTW.
- */
-
- // ------------------------------------------------------------------------------------
-
- /* Get binary log of integer argument - exact if n is a power of 2 */
- inline long fastlog2(long n)
- {
- long log = -1;
- while(n) {
- log++;
- n >>= 1;
- }
- return log ;
- }
-
- // ------------------------------------------------------------------------------------
-
- /* Radix-2 iteration subroutine */
- template <typename T>
- void R2TX(int nthpo, std::complex<T> *c0, std::complex<T> *c1)
- {
- for(int k=0; k<nthpo; k+=2)
- {
- std::complex<T> temp = c0[k] + c1[k];
- c1[k] = c0[k] - c1[k];
- c0[k] = temp;
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- /* Radix-4 iteration subroutine */
- template <typename T>
- void R4TX(int nthpo, std::complex<T> *c0, std::complex<T> *c1,
- std::complex<T> *c2, std::complex<T> *c3)
- {
- for(int k=0;k<nthpo;k+=4)
- {
- std::complex<T> t1, t2, t3, t4;
- t1 = c0[k] + c2[k];
- t2 = c0[k] - c2[k];
- t3 = c1[k] + c3[k];
- t4 = c1[k] - c3[k];
-
- c0[k] = t1 + t3;
- c1[k] = t1 - t3;
- c2[k] = std::complex<T>(t2.real()-t4.imag(), t2.imag()+t4.real());
- c3[k] = std::complex<T>(t2.real()+t4.imag(), t2.imag()-t4.real());
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <typename T>
- class twiddles
- {
- /*!
- The point of this object is to cache the twiddle values so we don't
- recompute them over and over inside R8TX().
- !*/
- public:
-
- twiddles()
- {
- data.resize(64);
- }
-
- const std::complex<T>* get_twiddles (
- int p
- )
- /*!
- requires
- - 0 <= p <= 64
- ensures
- - returns a pointer to the twiddle factors needed by R8TX if nxtlt == 2^p
- !*/
- {
- // Compute the twiddle factors for this p value if we haven't done so
- // already.
- if (data[p].size() == 0)
- {
- const int nxtlt = 0x1 << p;
- data[p].reserve(nxtlt*7);
- const T twopi = 6.2831853071795865; /* 2.0 * pi */
- const T scale = twopi/(nxtlt*8.0);
- std::complex<T> cs[7];
- for (int j = 0; j < nxtlt; ++j)
- {
- const T arg = j*scale;
- cs[0] = std::complex<T>(std::cos(arg),std::sin(arg));
- cs[1] = cs[0]*cs[0];
- cs[2] = cs[1]*cs[0];
- cs[3] = cs[1]*cs[1];
- cs[4] = cs[2]*cs[1];
- cs[5] = cs[2]*cs[2];
- cs[6] = cs[3]*cs[2];
- data[p].insert(data[p].end(), cs, cs+7);
- }
- }
-
- return &data[p][0];
- }
-
- private:
- std::vector<std::vector<std::complex<T> > > data;
- };
-
- // ----------------------------------------------------------------------------------------
-
- /* Radix-8 iteration subroutine */
- template <typename T>
- void R8TX(int nxtlt, int nthpo, int length, const std::complex<T>* cs,
- std::complex<T> *cc0, std::complex<T> *cc1, std::complex<T> *cc2, std::complex<T> *cc3,
- std::complex<T> *cc4, std::complex<T> *cc5, std::complex<T> *cc6, std::complex<T> *cc7)
- {
- const T irt2 = 0.707106781186548; /* 1.0/sqrt(2.0) */
-
- for(int j=0; j<nxtlt; j++)
- {
- for(int k=j;k<nthpo;k+=length)
- {
- std::complex<T> a0, a1, a2, a3, a4, a5, a6, a7;
- std::complex<T> b0, b1, b2, b3, b4, b5, b6, b7;
- a0 = cc0[k] + cc4[k];
- a1 = cc1[k] + cc5[k];
- a2 = cc2[k] + cc6[k];
- a3 = cc3[k] + cc7[k];
- a4 = cc0[k] - cc4[k];
- a5 = cc1[k] - cc5[k];
- a6 = cc2[k] - cc6[k];
- a7 = cc3[k] - cc7[k];
-
- b0 = a0 + a2;
- b1 = a1 + a3;
- b2 = a0 - a2;
- b3 = a1 - a3;
-
- b4 = std::complex<T>(a4.real()-a6.imag(), a4.imag()+a6.real());
- b5 = std::complex<T>(a5.real()-a7.imag(), a5.imag()+a7.real());
- b6 = std::complex<T>(a4.real()+a6.imag(), a4.imag()-a6.real());
- b7 = std::complex<T>(a5.real()+a7.imag(), a5.imag()-a7.real());
-
- const std::complex<T> tmp0(-b3.imag(), b3.real());
- const std::complex<T> tmp1(irt2*(b5.real()-b5.imag()), irt2*(b5.real()+b5.imag()));
- const std::complex<T> tmp2(-irt2*(b7.real()+b7.imag()), irt2*(b7.real()-b7.imag()));
-
- cc0[k] = b0 + b1;
- cc1[k] = b0 - b1;
- cc2[k] = b2 + tmp0;
- cc3[k] = b2 - tmp0;
- cc4[k] = b4 + tmp1;
- cc5[k] = b4 - tmp1;
- cc6[k] = b6 + tmp2;
- cc7[k] = b6 - tmp2;
- if(j>0)
- {
- cc1[k] *= cs[3];
- cc2[k] *= cs[1];
- cc3[k] *= cs[5];
- cc4[k] *= cs[0];
- cc5[k] *= cs[4];
- cc6[k] *= cs[2];
- cc7[k] *= cs[6];
- }
- }
-
- cs += 7;
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template <typename T, long NR, long NC, typename MM, typename layout>
- void fft1d_inplace(matrix<std::complex<T>,NR,NC,MM,layout>& data, bool do_backward_fft, twiddles<T>& cs)
- /*!
- requires
- - is_vector(data) == true
- - is_power_of_two(data.size()) == true
- ensures
- - This routine replaces the input std::complex<double> vector by its finite
- discrete complex fourier transform if do_backward_fft==true. It replaces
- the input std::complex<double> vector by its finite discrete complex
- inverse fourier transform if do_backward_fft==false.
-
- The implementation is a radix-2 FFT, but with faster shortcuts for
- radix-4 and radix-8. It performs as many radix-8 iterations as possible,
- and then finishes with a radix-2 or -4 iteration if needed.
- !*/
- {
- COMPILE_TIME_ASSERT((is_same_type<double,T>::value || is_same_type<float,T>::value || is_same_type<long double,T>::value ));
-
- if (data.size() == 0)
- return;
-
- std::complex<T>* const b = &data(0);
- int L[16],L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,L13,L14,L15;
- int j1,j2,j3,j4,j5,j6,j7,j8,j9,j10,j11,j12,j13,j14;
- int j, ij, ji;
- int n2pow, n8pow, nthpo, ipass, nxtlt, length;
-
- n2pow = fastlog2(data.size());
- nthpo = data.size();
-
- n8pow = n2pow/3;
-
- if(n8pow)
- {
- /* Radix 8 iterations */
- for(ipass=1;ipass<=n8pow;ipass++)
- {
- const int p = n2pow - 3*ipass;
- nxtlt = 0x1 << p;
- length = 8*nxtlt;
- R8TX(nxtlt, nthpo, length, cs.get_twiddles(p),
- b, b+nxtlt, b+2*nxtlt, b+3*nxtlt,
- b+4*nxtlt, b+5*nxtlt, b+6*nxtlt, b+7*nxtlt);
- }
- }
-
- if(n2pow%3 == 1)
- {
- /* A final radix 2 iteration is needed */
- R2TX(nthpo, b, b+1);
- }
-
- if(n2pow%3 == 2)
- {
- /* A final radix 4 iteration is needed */
- R4TX(nthpo, b, b+1, b+2, b+3);
- }
-
- for(j=1;j<=15;j++)
- {
- L[j] = 1;
- if(j-n2pow <= 0) L[j] = 0x1 << (n2pow + 1 - j);
- }
-
- L15=L[1];L14=L[2];L13=L[3];L12=L[4];L11=L[5];L10=L[6];L9=L[7];
- L8=L[8];L7=L[9];L6=L[10];L5=L[11];L4=L[12];L3=L[13];L2=L[14];L1=L[15];
-
- ij = 0;
-
- for(j1=0;j1<L1;j1++)
- for(j2=j1;j2<L2;j2+=L1)
- for(j3=j2;j3<L3;j3+=L2)
- for(j4=j3;j4<L4;j4+=L3)
- for(j5=j4;j5<L5;j5+=L4)
- for(j6=j5;j6<L6;j6+=L5)
- for(j7=j6;j7<L7;j7+=L6)
- for(j8=j7;j8<L8;j8+=L7)
- for(j9=j8;j9<L9;j9+=L8)
- for(j10=j9;j10<L10;j10+=L9)
- for(j11=j10;j11<L11;j11+=L10)
- for(j12=j11;j12<L12;j12+=L11)
- for(j13=j12;j13<L13;j13+=L12)
- for(j14=j13;j14<L14;j14+=L13)
- for(ji=j14;ji<L15;ji+=L14)
- {
- if(ij<ji)
- swap(b[ij], b[ji]);
- ij++;
- }
-
-
- // unscramble outputs
- if(!do_backward_fft)
- {
- for(long i=1, j=data.size()-1; i<data.size()/2; i++,j--)
- {
- swap(b[j], b[i]);
- }
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- template < typename T, long NR, long NC, typename MM, typename L >
- void fft2d_inplace(
- matrix<std::complex<T>,NR,NC,MM,L>& data,
- bool do_backward_fft
- )
- {
- if (data.size() == 0)
- return;
-
- matrix<std::complex<double> > buff;
- twiddles<double> cs;
-
- // Compute transform row by row
- for(long r=0; r<data.nr(); ++r)
- {
- buff = matrix_cast<std::complex<double> >(rowm(data,r));
- fft1d_inplace(buff, do_backward_fft, cs);
- set_rowm(data,r) = matrix_cast<std::complex<T> >(buff);
- }
-
- // Compute transform column by column
- for(long c=0; c<data.nc(); ++c)
- {
- buff = matrix_cast<std::complex<double> >(colm(data,c));
- fft1d_inplace(buff, do_backward_fft, cs);
- set_colm(data,c) = matrix_cast<std::complex<T> >(buff);
- }
- }
-
- // ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- typename T
- >
- void fft2d(
- const matrix_exp<EXP>& data,
- matrix<std::complex<T> >& data_out,
- bool do_backward_fft
- )
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t matrix fft(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- if (data.size() == 0)
- return;
-
- matrix<std::complex<double> > buff;
- data_out.set_size(data.nr(), data.nc());
- twiddles<double> cs;
-
- // Compute transform row by row
- for(long r=0; r<data.nr(); ++r)
- {
- buff = matrix_cast<std::complex<double> >(rowm(data,r));
- fft1d_inplace(buff, do_backward_fft, cs);
- set_rowm(data_out,r) = matrix_cast<std::complex<T> >(buff);
- }
-
- // Compute transform column by column
- for(long c=0; c<data_out.nc(); ++c)
- {
- buff = matrix_cast<std::complex<double> >(colm(data_out,c));
- fft1d_inplace(buff, do_backward_fft, cs);
- set_colm(data_out,c) = matrix_cast<std::complex<T> >(buff);
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- } // end namespace impl
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- matrix<typename EXP::type> fft (const matrix_exp<EXP>& data)
- {
- // You have to give a complex matrix
- COMPILE_TIME_ASSERT(is_complex<typename EXP::type>::value);
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t matrix fft(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- if (data.nr() == 1 || data.nc() == 1)
- {
- matrix<typename EXP::type> temp(data);
- impl::twiddles<typename EXP::type::value_type> cs;
- impl::fft1d_inplace(temp, false, cs);
- return temp;
- }
- else
- {
- matrix<typename EXP::type> temp;
- impl::fft2d(data, temp, false);
- return temp;
- }
- }
-
- template <typename EXP>
- matrix<typename EXP::type> ifft (const matrix_exp<EXP>& data)
- {
- // You have to give a complex matrix
- COMPILE_TIME_ASSERT(is_complex<typename EXP::type>::value);
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t matrix ifft(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- matrix<typename EXP::type> temp;
- if (data.size() == 0)
- return temp;
-
- if (data.nr() == 1 || data.nc() == 1)
- {
- temp = data;
- impl::twiddles<typename EXP::type::value_type> cs;
- impl::fft1d_inplace(temp, true, cs);
- }
- else
- {
- impl::fft2d(data, temp, true);
- }
- temp /= data.size();
- return temp;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template < typename T, long NR, long NC, typename MM, typename L >
- typename enable_if_c<NR==1||NC==1>::type fft_inplace (matrix<std::complex<T>,NR,NC,MM,L>& data)
- // Note that we don't divide the outputs by data.size() so this isn't quite the inverse.
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t void fft_inplace(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- impl::twiddles<T> cs;
- impl::fft1d_inplace(data, false, cs);
- }
-
- template < typename T, long NR, long NC, typename MM, typename L >
- typename disable_if_c<NR==1||NC==1>::type fft_inplace (matrix<std::complex<T>,NR,NC,MM,L>& data)
- // Note that we don't divide the outputs by data.size() so this isn't quite the inverse.
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t void fft_inplace(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- impl::fft2d_inplace(data, false);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template < typename T, long NR, long NC, typename MM, typename L >
- typename enable_if_c<NR==1||NC==1>::type ifft_inplace (matrix<std::complex<T>,NR,NC,MM,L>& data)
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t void ifft_inplace(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- impl::twiddles<T> cs;
- impl::fft1d_inplace(data, true, cs);
- }
-
- template < typename T, long NR, long NC, typename MM, typename L >
- typename disable_if_c<NR==1||NC==1>::type ifft_inplace (matrix<std::complex<T>,NR,NC,MM,L>& data)
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t void ifft_inplace(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- impl::fft2d_inplace(data, true);
- }
-
-// ----------------------------------------------------------------------------------------
-
- /*
- I'm disabling any use of the FFTW bindings because FFTW is, as of this writing, not
- threadsafe as a library. This means that if multiple threads were to make
- concurrent calls to these fft routines then the program could crash. If at some
- point FFTW is fixed I'll turn these bindings back on.
-
- See https://github.com/FFTW/fftw3/issues/16
- */
-#if 0
-#ifdef DLIB_USE_FFTW
-
- template <long NR, long NC, typename MM, typename L>
- matrix<std::complex<double>,NR,NC,MM,L> call_fftw_fft(
- const matrix<std::complex<double>,NR,NC,MM,L>& data
- )
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t matrix fft(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- if (data.size() == 0)
- return data;
-
- matrix<std::complex<double>,NR,NC,MM,L> m2(data.nr(),data.nc());
- fftw_complex *in, *out;
- fftw_plan p;
- in = (fftw_complex*)&data(0,0);
- out = (fftw_complex*)&m2(0,0);
- if (data.nr() == 1 || data.nc() == 1)
- p = fftw_plan_dft_1d(data.size(), in, out, FFTW_FORWARD, FFTW_ESTIMATE);
- else
- p = fftw_plan_dft_2d(data.nr(), data.nc(), in, out, FFTW_FORWARD, FFTW_ESTIMATE);
- fftw_execute(p);
- fftw_destroy_plan(p);
- return m2;
- }
-
- template <long NR, long NC, typename MM, typename L>
- matrix<std::complex<double>,NR,NC,MM,L> call_fftw_ifft(
- const matrix<std::complex<double>,NR,NC,MM,L>& data
- )
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t matrix ifft(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- if (data.size() == 0)
- return data;
-
- matrix<std::complex<double>,NR,NC,MM,L> m2(data.nr(),data.nc());
- fftw_complex *in, *out;
- fftw_plan p;
- in = (fftw_complex*)&data(0,0);
- out = (fftw_complex*)&m2(0,0);
- if (data.nr() == 1 || data.nc() == 1)
- p = fftw_plan_dft_1d(data.size(), in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
- else
- p = fftw_plan_dft_2d(data.nr(), data.nc(), in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
- fftw_execute(p);
- fftw_destroy_plan(p);
- return m2;
- }
-
-// ----------------------------------------------------------------------------------------
-
-// call FFTW for these cases:
- inline matrix<std::complex<double>,0,1> fft (const matrix<std::complex<double>,0,1>& data) {return call_fftw_fft(data);}
- inline matrix<std::complex<double>,0,1> ifft(const matrix<std::complex<double>,0,1>& data) {return call_fftw_ifft(data)/data.size();}
- inline matrix<std::complex<double>,1,0> fft (const matrix<std::complex<double>,1,0>& data) {return call_fftw_fft(data);}
- inline matrix<std::complex<double>,1,0> ifft(const matrix<std::complex<double>,1,0>& data) {return call_fftw_ifft(data)/data.size();}
- inline matrix<std::complex<double> > fft (const matrix<std::complex<double> >& data) {return call_fftw_fft(data);}
- inline matrix<std::complex<double> > ifft(const matrix<std::complex<double> >& data) {return call_fftw_ifft(data)/data.size();}
-
- inline void fft_inplace (matrix<std::complex<double>,0,1>& data) {data = call_fftw_fft(data);}
- inline void ifft_inplace(matrix<std::complex<double>,0,1>& data) {data = call_fftw_ifft(data);}
- inline void fft_inplace (matrix<std::complex<double>,1,0>& data) {data = call_fftw_fft(data);}
- inline void ifft_inplace(matrix<std::complex<double>,1,0>& data) {data = call_fftw_ifft(data);}
- inline void fft_inplace (matrix<std::complex<double> >& data) {data = call_fftw_fft(data);}
- inline void ifft_inplace(matrix<std::complex<double> >& data) {data = call_fftw_ifft(data);}
-
-#endif // DLIB_USE_FFTW
-#endif // end of #if 0
-
-// ----------------------------------------------------------------------------------------
-
-#ifdef DLIB_USE_MKL_FFT
-
-#define DLIB_DFTI_CHECK_STATUS(s) \
- if((s) != 0 && !DftiErrorClass((s), DFTI_NO_ERROR)) \
- { \
- throw dlib::error(DftiErrorMessage((s))); \
- }
-
- template < long NR, long NC, typename MM, typename L >
- matrix<std::complex<double>,NR,NC,MM,L> call_mkl_fft(
- const matrix<std::complex<double>,NR,NC,MM,L>& data,
- bool do_backward_fft)
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t matrix fft(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- if (data.size() == 0)
- return data;
-
- DFTI_DESCRIPTOR_HANDLE h;
- MKL_LONG status;
-
- if (data.nr() == 1 || data.nc() == 1)
- {
- status = DftiCreateDescriptor(&h, DFTI_DOUBLE, DFTI_COMPLEX, 1, data.size());
- DLIB_DFTI_CHECK_STATUS(status);
- }
- else
- {
- MKL_LONG size[2];
- size[0] = data.nr();
- size[1] = data.nc();
-
- status = DftiCreateDescriptor(&h, DFTI_DOUBLE, DFTI_COMPLEX, 2, size);
- DLIB_DFTI_CHECK_STATUS(status);
-
- MKL_LONG strides[3];
- strides[0] = 0;
- strides[1] = size[1];
- strides[2] = 1;
-
- status = DftiSetValue(h, DFTI_INPUT_STRIDES, strides);
- DLIB_DFTI_CHECK_STATUS(status);
- status = DftiSetValue(h, DFTI_OUTPUT_STRIDES, strides);
- DLIB_DFTI_CHECK_STATUS(status);
- }
-
- status = DftiSetValue(h, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
- DLIB_DFTI_CHECK_STATUS(status);
-
- // Unless we use sequential mode, the fft results are not correct.
- status = DftiSetValue(h, DFTI_THREAD_LIMIT, 1);
- DLIB_DFTI_CHECK_STATUS(status);
-
- status = DftiCommitDescriptor(h);
- DLIB_DFTI_CHECK_STATUS(status);
-
- matrix<std::complex<double>,NR,NC,MM,L> out(data.nr(), data.nc());
-
- if (do_backward_fft)
- status = DftiComputeBackward(h, (void *)(&data(0, 0)), &out(0,0));
- else
- status = DftiComputeForward(h, (void *)(&data(0, 0)), &out(0,0));
- DLIB_DFTI_CHECK_STATUS(status);
-
- status = DftiFreeDescriptor(&h);
- DLIB_DFTI_CHECK_STATUS(status);
-
- return out;
- }
-
- template < long NR, long NC, typename MM, typename L >
- void call_mkl_fft_inplace(
- matrix<std::complex<double>,NR,NC,MM,L>& data,
- bool do_backward_fft
- )
- {
- // make sure requires clause is not broken
- DLIB_CASSERT(is_power_of_two(data.nr()) && is_power_of_two(data.nc()),
- "\t void ifft_inplace(data)"
- << "\n\t The number of rows and columns must be powers of two."
- << "\n\t data.nr(): "<< data.nr()
- << "\n\t data.nc(): "<< data.nc()
- << "\n\t is_power_of_two(data.nr()): " << is_power_of_two(data.nr())
- << "\n\t is_power_of_two(data.nc()): " << is_power_of_two(data.nc())
- );
-
- if (data.size() == 0)
- return;
-
- DFTI_DESCRIPTOR_HANDLE h;
- MKL_LONG status;
-
- if (data.nr() == 1 || data.nc() == 1)
- {
- status = DftiCreateDescriptor(&h, DFTI_DOUBLE, DFTI_COMPLEX, 1, data.size());
- DLIB_DFTI_CHECK_STATUS(status);
- }
- else
- {
- MKL_LONG size[2];
- size[0] = data.nr();
- size[1] = data.nc();
-
- status = DftiCreateDescriptor(&h, DFTI_DOUBLE, DFTI_COMPLEX, 2, size);
- DLIB_DFTI_CHECK_STATUS(status);
-
- MKL_LONG strides[3];
- strides[0] = 0;
- strides[1] = size[1];
- strides[2] = 1;
-
- status = DftiSetValue(h, DFTI_INPUT_STRIDES, strides);
- DLIB_DFTI_CHECK_STATUS(status);
- }
-
- // Unless we use sequential mode, the fft results are not correct.
- status = DftiSetValue(h, DFTI_THREAD_LIMIT, 1);
- DLIB_DFTI_CHECK_STATUS(status);
-
- status = DftiCommitDescriptor(h);
- DLIB_DFTI_CHECK_STATUS(status);
-
- if (do_backward_fft)
- status = DftiComputeBackward(h, &data(0, 0));
- else
- status = DftiComputeForward(h, &data(0, 0));
- DLIB_DFTI_CHECK_STATUS(status);
-
- status = DftiFreeDescriptor(&h);
- DLIB_DFTI_CHECK_STATUS(status);
-
- return;
- }
-
-// ----------------------------------------------------------------------------------------
-
- // Call the MKL DFTI implementation in these cases
-
- inline matrix<std::complex<double>,0,1> fft (const matrix<std::complex<double>,0,1>& data)
- {
- return call_mkl_fft(data, false);
- }
- inline matrix<std::complex<double>,0,1> ifft(const matrix<std::complex<double>,0,1>& data)
- {
- return call_mkl_fft(data, true) / data.size();
- }
- inline matrix<std::complex<double>,1,0> fft (const matrix<std::complex<double>,1,0>& data)
- {
- return call_mkl_fft(data, false);
- }
- inline matrix<std::complex<double>,1,0> ifft(const matrix<std::complex<double>,1,0>& data)
- {
- return call_mkl_fft(data, true) / data.size();
- }
- inline matrix<std::complex<double> > fft (const matrix<std::complex<double> >& data)
- {
- return call_mkl_fft(data, false);
- }
- inline matrix<std::complex<double> > ifft(const matrix<std::complex<double> >& data)
- {
- return call_mkl_fft(data, true) / data.size();
- }
-
- inline void fft_inplace (matrix<std::complex<double>,0,1>& data)
- {
- call_mkl_fft_inplace(data, false);
- }
- inline void ifft_inplace(matrix<std::complex<double>,0,1>& data)
- {
- call_mkl_fft_inplace(data, true);
- }
- inline void fft_inplace (matrix<std::complex<double>,1,0>& data)
- {
- call_mkl_fft_inplace(data, false);
- }
- inline void ifft_inplace(matrix<std::complex<double>,1,0>& data)
- {
- call_mkl_fft_inplace(data, true);
- }
-
- inline void fft_inplace (matrix<std::complex<double> >& data)
- {
- call_mkl_fft_inplace(data, false);
- }
- inline void ifft_inplace(matrix<std::complex<double> >& data)
- {
- call_mkl_fft_inplace(data, true);
- }
-
-#endif // DLIB_USE_MKL_FFT
-
-// ----------------------------------------------------------------------------------------
-}
-
-#endif // DLIB_FFt_Hh_
-
diff --git a/ml/dlib/dlib/matrix/matrix_fft_abstract.h b/ml/dlib/dlib/matrix/matrix_fft_abstract.h
deleted file mode 100644
index 25cdfcaee..000000000
--- a/ml/dlib/dlib/matrix/matrix_fft_abstract.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (C) 2013 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_FFt_ABSTRACT_Hh_
-#ifdef DLIB_FFt_ABSTRACT_Hh_
-
-#include "matrix_abstract.h"
-#include "../algs.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- bool is_power_of_two (
- const unsigned long& value
- );
- /*!
- ensures
- - returns true if value contains a power of two and false otherwise. As a
- special case, we also consider 0 to be a power of two.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- typename EXP::matrix_type fft (
- const matrix_exp<EXP>& data
- );
- /*!
- requires
- - data contains elements of type std::complex<> that itself contains double, float, or long double.
- - is_power_of_two(data.nr()) == true
- - is_power_of_two(data.nc()) == true
- ensures
- - Computes the 1 or 2 dimensional discrete Fourier transform of the given data
- matrix and returns it. In particular, we return a matrix D such that:
- - D.nr() == data.nr()
- - D.nc() == data.nc()
- - D(0,0) == the DC term of the Fourier transform.
- - starting with D(0,0), D contains progressively higher frequency components
- of the input data.
- - ifft(D) == D
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- typename EXP::matrix_type ifft (
- const matrix_exp<EXP>& data
- );
- /*!
- requires
- - data contains elements of type std::complex<> that itself contains double, float, or long double.
- - is_power_of_two(data.nr()) == true
- - is_power_of_two(data.nc()) == true
- ensures
- - Computes the 1 or 2 dimensional inverse discrete Fourier transform of the
- given data vector and returns it. In particular, we return a matrix D such
- that:
- - D.nr() == data.nr()
- - D.nc() == data.nc()
- - fft(D) == data
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename L
- >
- void fft_inplace (
- matrix<std::complex<T>,NR,NC,MM,L>& data
- );
- /*!
- requires
- - data contains elements of type std::complex<> that itself contains double, float, or long double.
- - is_power_of_two(data.nr()) == true
- - is_power_of_two(data.nc()) == true
- ensures
- - This function is identical to fft() except that it does the FFT in-place.
- That is, after this function executes we will have:
- - #data == fft(data)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename L
- >
- void ifft_inplace (
- matrix<std::complex<T>,NR,NC,MM,L>& data
- );
- /*!
- requires
- - data contains elements of type std::complex<> that itself contains double, float, or long double.
- - is_power_of_two(data.nr()) == true
- - is_power_of_two(data.nc()) == true
- ensures
- - This function is identical to ifft() except that it does the inverse FFT
- in-place. That is, after this function executes we will have:
- - #data == ifft(data)*data.size()
- - Note that the output needs to be divided by data.size() to complete the
- inverse transformation.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_FFt_ABSTRACT_Hh_
-
diff --git a/ml/dlib/dlib/matrix/matrix_fwd.h b/ml/dlib/dlib/matrix/matrix_fwd.h
deleted file mode 100644
index 1f40a17a8..000000000
--- a/ml/dlib/dlib/matrix/matrix_fwd.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_FWD
-#define DLIB_MATRIx_FWD
-
-#include "../algs.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- struct row_major_layout;
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long num_rows = 0,
- long num_cols = 0,
- typename mem_manager = default_memory_manager,
- typename layout = row_major_layout
- >
- class matrix;
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_FWD
-
diff --git a/ml/dlib/dlib/matrix/matrix_generic_image.h b/ml/dlib/dlib/matrix/matrix_generic_image.h
deleted file mode 100644
index 0455af205..000000000
--- a/ml/dlib/dlib/matrix/matrix_generic_image.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (C) 2014 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIX_GENERIC_iMAGE_Hh_
-#define DLIB_MATRIX_GENERIC_iMAGE_Hh_
-
-#include "matrix.h"
-#include "../image_processing/generic_image.h"
-
-namespace dlib
-{
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- struct image_traits<matrix<T,NR,NC,MM> >
- {
- typedef T pixel_type;
- };
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- struct image_traits<const matrix<T,NR,NC,MM> >
- {
- typedef T pixel_type;
- };
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- inline long num_rows( const matrix<T,NR,NC,MM>& img) { return img.nr(); }
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- inline long num_columns( const matrix<T,NR,NC,MM>& img) { return img.nc(); }
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- inline void set_image_size(
- matrix<T,NR,NC,MM>& img,
- long rows,
- long cols
- ) { img.set_size(rows,cols); }
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- inline void* image_data(
- matrix<T,NR,NC,MM>& img
- )
- {
- if (img.size() != 0)
- return &img(0,0);
- else
- return 0;
- }
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- inline const void* image_data(
- const matrix<T,NR,NC,MM>& img
- )
- {
- if (img.size() != 0)
- return &img(0,0);
- else
- return 0;
- }
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- inline long width_step(
- const matrix<T,NR,NC,MM>& img
- )
- {
- return img.nc()*sizeof(T);
- }
-
-}
-
-#endif // DLIB_MATRIX_GENERIC_iMAGE_Hh_
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_la.h b/ml/dlib/dlib/matrix/matrix_la.h
deleted file mode 100644
index 35b5b42e2..000000000
--- a/ml/dlib/dlib/matrix/matrix_la.h
+++ /dev/null
@@ -1,1807 +0,0 @@
-// Copyright (C) 2009 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_LA_FUNCTS_
-#define DLIB_MATRIx_LA_FUNCTS_
-
-#include "matrix_la_abstract.h"
-#include "matrix_utilities.h"
-#include "../sparse_vector.h"
-#include "../optimization/optimization_line_search.h"
-
-// The 4 decomposition objects described in the matrix_la_abstract.h file are
-// actually implemented in the following 4 files.
-#include "matrix_lu.h"
-#include "matrix_qr.h"
-#include "matrix_cholesky.h"
-#include "matrix_eigenvalue.h"
-
-#ifdef DLIB_USE_LAPACK
-#include "lapack/potrf.h"
-#include "lapack/pbtrf.h"
-#include "lapack/gesdd.h"
-#include "lapack/gesvd.h"
-#endif
-
-#include "../threads.h"
-
-#include <iostream>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- enum svd_u_mode
- {
- SVD_NO_U,
- SVD_SKINNY_U,
- SVD_FULL_U
- };
-
- template <
- typename EXP,
- long qN, long qX,
- long uM, long uN,
- long vM, long vN,
- typename MM1,
- typename MM2,
- typename MM3,
- typename L1
- >
- long svd4 (
- svd_u_mode u_mode,
- bool withv,
- const matrix_exp<EXP>& a,
- matrix<typename EXP::type,uM,uN,MM1,L1>& u,
- matrix<typename EXP::type,qN,qX,MM2,L1>& q,
- matrix<typename EXP::type,vM,vN,MM3,L1>& v
- )
- {
- /*
- Singular value decomposition. Translated to 'C' from the
- original Algol code in "Handbook for Automatic Computation,
- vol. II, Linear Algebra", Springer-Verlag. Note that this
- published algorithm is considered to be the best and numerically
- stable approach to computing the real-valued svd and is referenced
- repeatedly in ieee journal papers, etc where the svd is used.
-
- This is almost an exact translation from the original, except that
- an iteration counter is added to prevent stalls. This corresponds
- to similar changes in other translations.
-
- Returns an error code = 0, if no errors and 'k' if a failure to
- converge at the 'kth' singular value.
-
- USAGE: given the singular value decomposition a = u * diagm(q) * trans(v) for an m*n
- matrix a with m >= n ...
- After the svd call u is an m x m matrix which is columnwise
- orthogonal. q will be an n element vector consisting of singular values
- and v an n x n orthogonal matrix. eps and tol are tolerance constants.
- Suitable values are eps=1e-16 and tol=(1e-300)/eps if T == double.
-
- If u_mode == SVD_NO_U then u won't be computed and similarly if withv == false
- then v won't be computed. If u_mode == SVD_SKINNY_U then u will be m x n instead of m x m.
- */
-
-
- DLIB_ASSERT(a.nr() >= a.nc(),
- "\tconst matrix_exp svd4()"
- << "\n\tYou have given an invalidly sized matrix"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- );
-
-
- typedef typename EXP::type T;
-
-#ifdef DLIB_USE_LAPACK
- matrix<typename EXP::type,0,0,MM1,L1> temp(a), vtemp;
-
- char jobu = 'A';
- char jobvt = 'A';
- if (u_mode == SVD_NO_U)
- jobu = 'N';
- else if (u_mode == SVD_SKINNY_U)
- jobu = 'S';
- if (withv == false)
- jobvt = 'N';
-
- int info;
- if (jobu == jobvt)
- {
- info = lapack::gesdd(jobu, temp, q, u, vtemp);
- }
- else
- {
- info = lapack::gesvd(jobu, jobvt, temp, q, u, vtemp);
- }
-
- // pad q with zeros if it isn't the length we want
- if (q.nr() < a.nc())
- q = join_cols(q, zeros_matrix<T>(a.nc()-q.nr(),1));
-
- if (withv)
- v = trans(vtemp);
-
- return info;
-#else
- using std::abs;
- using std::sqrt;
-
- T eps = std::numeric_limits<T>::epsilon();
- T tol = std::numeric_limits<T>::min()/eps;
-
- const long m = a.nr();
- const long n = a.nc();
- long i, j, k, l = 0, l1, iter, retval;
- T c, f, g, h, s, x, y, z;
-
- matrix<T,qN,1,MM2> e(n,1);
- q.set_size(n,1);
- if (u_mode == SVD_FULL_U)
- u.set_size(m,m);
- else
- u.set_size(m,n);
- retval = 0;
-
- if (withv)
- {
- v.set_size(n,n);
- }
-
- /* Copy 'a' to 'u' */
- for (i=0; i<m; i++)
- {
- for (j=0; j<n; j++)
- u(i,j) = a(i,j);
- }
-
- /* Householder's reduction to bidiagonal form. */
- g = x = 0.0;
- for (i=0; i<n; i++)
- {
- e(i) = g;
- s = 0.0;
- l = i + 1;
-
- for (j=i; j<m; j++)
- s += (u(j,i) * u(j,i));
-
- if (s < tol)
- g = 0.0;
- else
- {
- f = u(i,i);
- g = (f < 0) ? sqrt(s) : -sqrt(s);
- h = f * g - s;
- u(i,i) = f - g;
-
- for (j=l; j<n; j++)
- {
- s = 0.0;
-
- for (k=i; k<m; k++)
- s += (u(k,i) * u(k,j));
-
- f = s / h;
-
- for (k=i; k<m; k++)
- u(k,j) += (f * u(k,i));
- } /* end j */
- } /* end s */
-
- q(i) = g;
- s = 0.0;
-
- for (j=l; j<n; j++)
- s += (u(i,j) * u(i,j));
-
- if (s < tol)
- g = 0.0;
- else
- {
- f = u(i,i+1);
- g = (f < 0) ? sqrt(s) : -sqrt(s);
- h = f * g - s;
- u(i,i+1) = f - g;
-
- for (j=l; j<n; j++)
- e(j) = u(i,j) / h;
-
- for (j=l; j<m; j++)
- {
- s = 0.0;
-
- for (k=l; k<n; k++)
- s += (u(j,k) * u(i,k));
-
- for (k=l; k<n; k++)
- u(j,k) += (s * e(k));
- } /* end j */
- } /* end s */
-
- y = abs(q(i)) + abs(e(i));
- if (y > x)
- x = y;
- } /* end i */
-
- /* accumulation of right-hand transformations */
- if (withv)
- {
- for (i=n-1; i>=0; i--)
- {
- if (g != 0.0)
- {
- h = u(i,i+1) * g;
-
- for (j=l; j<n; j++)
- v(j,i) = u(i,j)/h;
-
- for (j=l; j<n; j++)
- {
- s = 0.0;
-
- for (k=l; k<n; k++)
- s += (u(i,k) * v(k,j));
-
- for (k=l; k<n; k++)
- v(k,j) += (s * v(k,i));
- } /* end j */
- } /* end g */
-
- for (j=l; j<n; j++)
- v(i,j) = v(j,i) = 0.0;
-
- v(i,i) = 1.0;
- g = e(i);
- l = i;
- } /* end i */
- } /* end withv, parens added for clarity */
-
- /* accumulation of left-hand transformations */
- if (u_mode != SVD_NO_U)
- {
- for (i=n; i<u.nr(); i++)
- {
- for (j=n;j<u.nc();j++)
- u(i,j) = 0.0;
-
- if (i < u.nc())
- u(i,i) = 1.0;
- }
- }
-
- if (u_mode != SVD_NO_U)
- {
- for (i=n-1; i>=0; i--)
- {
- l = i + 1;
- g = q(i);
-
- for (j=l; j<u.nc(); j++)
- u(i,j) = 0.0;
-
- if (g != 0.0)
- {
- h = u(i,i) * g;
-
- for (j=l; j<u.nc(); j++)
- {
- s = 0.0;
-
- for (k=l; k<m; k++)
- s += (u(k,i) * u(k,j));
-
- f = s / h;
-
- for (k=i; k<m; k++)
- u(k,j) += (f * u(k,i));
- } /* end j */
-
- for (j=i; j<m; j++)
- u(j,i) /= g;
- } /* end g */
- else
- {
- for (j=i; j<m; j++)
- u(j,i) = 0.0;
- }
-
- u(i,i) += 1.0;
- } /* end i*/
- }
-
- /* diagonalization of the bidiagonal form */
- eps *= x;
-
- for (k=n-1; k>=0; k--)
- {
- iter = 0;
-
-test_f_splitting:
-
- for (l=k; l>=0; l--)
- {
- if (abs(e(l)) <= eps)
- goto test_f_convergence;
-
- if (abs(q(l-1)) <= eps)
- goto cancellation;
- } /* end l */
-
- /* cancellation of e(l) if l > 0 */
-
-cancellation:
-
- c = 0.0;
- s = 1.0;
- l1 = l - 1;
-
- for (i=l; i<=k; i++)
- {
- f = s * e(i);
- e(i) *= c;
-
- if (abs(f) <= eps)
- goto test_f_convergence;
-
- g = q(i);
- h = q(i) = sqrt(f*f + g*g);
- c = g / h;
- s = -f / h;
-
- if (u_mode != SVD_NO_U)
- {
- for (j=0; j<m; j++)
- {
- y = u(j,l1);
- z = u(j,i);
- u(j,l1) = y * c + z * s;
- u(j,i) = -y * s + z * c;
- } /* end j */
- }
- } /* end i */
-
-test_f_convergence:
-
- z = q(k);
- if (l == k)
- goto convergence;
-
- /* shift from bottom 2x2 minor */
- iter++;
- if (iter > 300)
- {
- retval = k;
- break;
- }
- x = q(l);
- y = q(k-1);
- g = e(k-1);
- h = e(k);
- f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2 * h * y);
- g = sqrt(f * f + 1.0);
- f = ((x - z) * (x + z) + h * (y / ((f < 0)?(f - g) : (f + g)) - h)) / x;
-
- /* next QR transformation */
- c = s = 1.0;
-
- for (i=l+1; i<=k; i++)
- {
- g = e(i);
- y = q(i);
- h = s * g;
- g *= c;
- e(i-1) = z = sqrt(f * f + h * h);
- c = f / z;
- s = h / z;
- f = x * c + g * s;
- g = -x * s + g * c;
- h = y * s;
- y *= c;
-
- if (withv)
- {
- for (j=0;j<n;j++)
- {
- x = v(j,i-1);
- z = v(j,i);
- v(j,i-1) = x * c + z * s;
- v(j,i) = -x * s + z * c;
- } /* end j */
- } /* end withv, parens added for clarity */
-
- q(i-1) = z = sqrt(f * f + h * h);
- if (z != 0)
- {
- c = f / z;
- s = h / z;
- }
- f = c * g + s * y;
- x = -s * g + c * y;
- if (u_mode != SVD_NO_U)
- {
- for (j=0; j<m; j++)
- {
- y = u(j,i-1);
- z = u(j,i);
- u(j,i-1) = y * c + z * s;
- u(j,i) = -y * s + z * c;
- } /* end j */
- }
- } /* end i */
-
- e(l) = 0.0;
- e(k) = f;
- q(k) = x;
-
- goto test_f_splitting;
-
-convergence:
-
- if (z < 0.0)
- {
- /* q(k) is made non-negative */
- q(k) = -z;
- if (withv)
- {
- for (j=0; j<n; j++)
- v(j,k) = -v(j,k);
- } /* end withv, parens added for clarity */
- } /* end z */
- } /* end k */
-
- return retval;
-#endif
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- long qN, long qX,
- long uM,
- long vN,
- typename MM1,
- typename MM2,
- typename MM3,
- typename L1
- >
- long svd2 (
- bool withu,
- bool withv,
- const matrix_exp<EXP>& a,
- matrix<typename EXP::type,uM,uM,MM1,L1>& u,
- matrix<typename EXP::type,qN,qX,MM2,L1>& q,
- matrix<typename EXP::type,vN,vN,MM3,L1>& v
- )
- {
- const long NR = matrix_exp<EXP>::NR;
- const long NC = matrix_exp<EXP>::NC;
-
- // make sure the output matrices have valid dimensions if they are statically dimensioned
- COMPILE_TIME_ASSERT(qX == 0 || qX == 1);
- COMPILE_TIME_ASSERT(NR == 0 || uM == 0 || NR == uM);
- COMPILE_TIME_ASSERT(NC == 0 || vN == 0 || NC == vN);
-
- DLIB_ASSERT(a.nr() >= a.nc(),
- "\tconst matrix_exp svd4()"
- << "\n\tYou have given an invalidly sized matrix"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- );
-
- if (withu)
- return svd4(SVD_FULL_U, withv, a,u,q,v);
- else
- return svd4(SVD_NO_U, withv, a,u,q,v);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- void orthogonalize (
- matrix<T,NR,NC,MM,row_major_layout>& m
- )
- {
- // We don't really need to use this temporary, but doing it this way runs a lot
- // faster.
- matrix<T,NR,NC,MM,column_major_layout> temp;
- qr_decomposition<matrix<T,NR,NC,MM,row_major_layout>>(m).get_q(temp);
- m = temp;
- }
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- void orthogonalize (
- matrix<T,NR,NC,MM,column_major_layout>& m
- )
- {
- qr_decomposition<matrix<T,NR,NC,MM,column_major_layout>>(m).get_q(m);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long Anr, long Anc,
- typename MM,
- typename L
- >
- void find_matrix_range (
- const matrix<T,Anr,Anc,MM,L>& A,
- unsigned long l,
- matrix<T,Anr,0,MM,L>& Q,
- unsigned long q
- )
- /*!
- requires
- - A.nr() >= l
- ensures
- - #Q.nr() == A.nr()
- - #Q.nc() == l
- - #Q == an orthonormal matrix whose range approximates the range of the
- matrix A.
- - This function implements the randomized subspace iteration defined
- in the algorithm 4.4 box of the paper:
- Finding Structure with Randomness: Probabilistic Algorithms for
- Constructing Approximate Matrix Decompositions by Halko et al.
- - q defines the number of extra subspace iterations this algorithm will
- perform. Often q == 0 is fine, but performing more iterations can lead to a
- more accurate approximation of the range of A if A has slowly decaying
- singular values. In these cases, using a q of 1 or 2 is good.
- !*/
- {
- DLIB_ASSERT(A.nr() >= (long)l, "Invalid inputs were given to this function.");
- Q = A*matrix_cast<T>(gaussian_randm(A.nc(), l));
-
- orthogonalize(Q);
-
- // Do some extra iterations of the power method to make sure we get Q into the
- // span of the most important singular vectors of A.
- if (q != 0)
- {
- for (unsigned long itr = 0; itr < q; ++itr)
- {
- Q = trans(A)*Q;
- orthogonalize(Q);
-
- Q = A*Q;
- orthogonalize(Q);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long Anr, long Anc,
- long Unr, long Unc,
- long Wnr, long Wnc,
- long Vnr, long Vnc,
- typename MM,
- typename L
- >
- void svd_fast (
- const matrix<T,Anr,Anc,MM,L>& A,
- matrix<T,Unr,Unc,MM,L>& u,
- matrix<T,Wnr,Wnc,MM,L>& w,
- matrix<T,Vnr,Vnc,MM,L>& v,
- unsigned long l,
- unsigned long q = 1
- )
- {
- const unsigned long k = std::min(l, std::min<unsigned long>(A.nr(),A.nc()));
-
- DLIB_ASSERT(l > 0 && A.size() > 0,
- "\t void svd_fast()"
- << "\n\t Invalid inputs were given to this function."
- << "\n\t l: " << l
- << "\n\t A.size(): " << A.size()
- );
-
- matrix<T,Anr,0,MM,L> Q;
- find_matrix_range(A, k, Q, q);
-
- // Compute trans(B) = trans(Q)*A. The reason we store B transposed
- // is so that when we take its SVD later using svd3() it doesn't consume
- // a whole lot of RAM. That is, we make sure the square matrix coming out
- // of svd3() has size lxl rather than the potentially much larger nxn.
- matrix<T,0,0,MM,L> B = trans(A)*Q;
- svd3(B, v,w,u);
- u = Q*u;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename sparse_vector_type,
- typename T,
- typename MM,
- typename L
- >
- void find_matrix_range (
- const std::vector<sparse_vector_type>& A,
- unsigned long l,
- matrix<T,0,0,MM,L>& Q,
- unsigned long q
- )
- /*!
- requires
- - A.size() >= l
- ensures
- - #Q.nr() == A.size()
- - #Q.nc() == l
- - #Q == an orthonormal matrix whose range approximates the range of the
- matrix A. In this case, we interpret A as a matrix of A.size() rows,
- where each row is defined by a sparse vector.
- - This function implements the randomized subspace iteration defined
- in the algorithm 4.4 box of the paper:
- Finding Structure with Randomness: Probabilistic Algorithms for
- Constructing Approximate Matrix Decompositions by Halko et al.
- - q defines the number of extra subspace iterations this algorithm will
- perform. Often q == 0 is fine, but performing more iterations can lead to a
- more accurate approximation of the range of A if A has slowly decaying
- singular values. In these cases, using a q of 1 or 2 is good.
- !*/
- {
- DLIB_ASSERT(A.size() >= l, "Invalid inputs were given to this function.");
- Q.set_size(A.size(), l);
-
- // Compute Q = A*gaussian_randm()
- parallel_for(0, Q.nr(), [&](long r)
- {
- for (long c = 0; c < Q.nc(); ++c)
- {
- Q(r,c) = dot(A[r], gaussian_randm(std::numeric_limits<long>::max(), 1, c));
- }
- });
-
- orthogonalize(Q);
-
- // Do some extra iterations of the power method to make sure we get Q into the
- // span of the most important singular vectors of A.
- if (q != 0)
- {
- dlib::mutex mut;
- const unsigned long n = max_index_plus_one(A);
- for (unsigned long itr = 0; itr < q; ++itr)
- {
- matrix<T,0,0,MM> Z;
- // Compute Z = trans(A)*Q
- parallel_for_blocked(0, A.size(), [&](long begin, long end)
- {
- matrix<T,0,0,MM> Zlocal(n,l);
- Zlocal = 0;
- for (long m = begin; m < end; ++m)
- {
- for (unsigned long r = 0; r < l; ++r)
- {
- for (auto& i : A[m])
- {
- const auto c = i.first;
- const auto val = i.second;
-
- Zlocal(c,r) += Q(m,r)*val;
- }
- }
- }
- auto_mutex lock(mut);
- Z += Zlocal;
- },1);
-
- Q.set_size(0,0); // free RAM
- orthogonalize(Z);
-
- // Compute Q = A*Z
- Q.set_size(A.size(), l);
- parallel_for(0, Q.nr(), [&](long r)
- {
- for (long c = 0; c < Q.nc(); ++c)
- {
- Q(r,c) = dot(A[r], colm(Z,c));
- }
- });
-
- Z.set_size(0,0); // free RAM
- orthogonalize(Q);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace simpl
- {
- template <
- typename sparse_vector_type,
- typename T,
- long Unr, long Unc,
- long Wnr, long Wnc,
- long Vnr, long Vnc,
- typename MM,
- typename L
- >
- void svd_fast (
- bool compute_u,
- const std::vector<sparse_vector_type>& A,
- matrix<T,Unr,Unc,MM,L>& u,
- matrix<T,Wnr,Wnc,MM,L>& w,
- matrix<T,Vnr,Vnc,MM,L>& v,
- unsigned long l,
- unsigned long q
- )
- {
- const long n = max_index_plus_one(A);
- const unsigned long k = std::min(l, std::min<unsigned long>(A.size(),n));
-
- DLIB_ASSERT(l > 0 && A.size() > 0 && n > 0,
- "\t void svd_fast()"
- << "\n\t Invalid inputs were given to this function."
- << "\n\t l: " << l
- << "\n\t n (i.e. max_index_plus_one(A)): " << n
- << "\n\t A.size(): " << A.size()
- );
-
- matrix<T,0,0,MM,L> Q;
- find_matrix_range(A, k, Q, q);
-
- // Compute trans(B) = trans(Q)*A. The reason we store B transposed
- // is so that when we take its SVD later using svd3() it doesn't consume
- // a whole lot of RAM. That is, we make sure the square matrix coming out
- // of svd3() has size lxl rather than the potentially much larger nxn.
- matrix<T,0,0,MM> B;
- dlib::mutex mut;
- parallel_for_blocked(0, A.size(), [&](long begin, long end)
- {
- matrix<T,0,0,MM> Blocal(n,k);
- Blocal = 0;
- for (long m = begin; m < end; ++m)
- {
- for (unsigned long r = 0; r < k; ++r)
- {
- for (auto& i : A[m])
- {
- const auto c = i.first;
- const auto val = i.second;
-
- Blocal(c,r) += Q(m,r)*val;
- }
- }
- }
- auto_mutex lock(mut);
- B += Blocal;
- },1);
-
- svd3(B, v,w,u);
- if (compute_u)
- u = Q*u;
- }
- }
-
- template <
- typename sparse_vector_type,
- typename T,
- long Unr, long Unc,
- long Wnr, long Wnc,
- long Vnr, long Vnc,
- typename MM,
- typename L
- >
- void svd_fast (
- const std::vector<sparse_vector_type>& A,
- matrix<T,Unr,Unc,MM,L>& u,
- matrix<T,Wnr,Wnc,MM,L>& w,
- matrix<T,Vnr,Vnc,MM,L>& v,
- unsigned long l,
- unsigned long q = 1
- )
- {
- simpl::svd_fast(true, A,u,w,v,l,q);
- }
-
- template <
- typename sparse_vector_type,
- typename T,
- long Wnr, long Wnc,
- long Vnr, long Vnc,
- typename MM,
- typename L
- >
- void svd_fast (
- const std::vector<sparse_vector_type>& A,
- matrix<T,Wnr,Wnc,MM,L>& w,
- matrix<T,Vnr,Vnc,MM,L>& v,
- unsigned long l,
- unsigned long q = 1
- )
- {
- matrix<T,0,0,MM,L> u;
- simpl::svd_fast(false, A,u,w,v,l,q);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- long N
- >
- struct inv_helper
- {
- static const typename matrix_exp<EXP>::matrix_type inv (
- const matrix_exp<EXP>& m
- )
- {
- // you can't invert a non-square matrix
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC ||
- matrix_exp<EXP>::NR == 0 ||
- matrix_exp<EXP>::NC == 0);
- DLIB_ASSERT(m.nr() == m.nc(),
- "\tconst matrix_exp::type inv(const matrix_exp& m)"
- << "\n\tYou can only apply inv() to a square matrix"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- typedef typename matrix_exp<EXP>::type type;
-
- lu_decomposition<EXP> lu(m);
- return lu.solve(identity_matrix<type>(m.nr()));
- }
- };
-
- template <
- typename EXP
- >
- struct inv_helper<EXP,1>
- {
- static const typename matrix_exp<EXP>::matrix_type inv (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC);
- typedef typename matrix_exp<EXP>::type type;
-
- matrix<type, 1, 1, typename EXP::mem_manager_type> a;
- // if m is invertible
- if (m(0) != 0)
- a(0) = 1/m(0);
- else
- a(0) = 1;
- return a;
- }
- };
-
- template <
- typename EXP
- >
- struct inv_helper<EXP,2>
- {
- static const typename matrix_exp<EXP>::matrix_type inv (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC);
- typedef typename matrix_exp<EXP>::type type;
-
- matrix<type, 2, 2, typename EXP::mem_manager_type> a;
- type d = det(m);
- if (d != 0)
- {
- d = static_cast<type>(1.0/d);
- a(0,0) = m(1,1)*d;
- a(0,1) = m(0,1)*-d;
- a(1,0) = m(1,0)*-d;
- a(1,1) = m(0,0)*d;
- }
- else
- {
- // Matrix isn't invertible so just return the identity matrix.
- a = identity_matrix<type,2>();
- }
- return a;
- }
- };
-
- template <
- typename EXP
- >
- struct inv_helper<EXP,3>
- {
- static const typename matrix_exp<EXP>::matrix_type inv (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC);
- typedef typename matrix_exp<EXP>::type type;
-
- matrix<type, 3, 3, typename EXP::mem_manager_type> ret;
- type de = det(m);
- if (de != 0)
- {
- de = static_cast<type>(1.0/de);
- const type a = m(0,0);
- const type b = m(0,1);
- const type c = m(0,2);
- const type d = m(1,0);
- const type e = m(1,1);
- const type f = m(1,2);
- const type g = m(2,0);
- const type h = m(2,1);
- const type i = m(2,2);
-
- ret(0,0) = (e*i - f*h)*de;
- ret(1,0) = (f*g - d*i)*de;
- ret(2,0) = (d*h - e*g)*de;
-
- ret(0,1) = (c*h - b*i)*de;
- ret(1,1) = (a*i - c*g)*de;
- ret(2,1) = (b*g - a*h)*de;
-
- ret(0,2) = (b*f - c*e)*de;
- ret(1,2) = (c*d - a*f)*de;
- ret(2,2) = (a*e - b*d)*de;
- }
- else
- {
- ret = identity_matrix<type,3>();
- }
-
- return ret;
- }
- };
-
- template <
- typename EXP
- >
- struct inv_helper<EXP,4>
- {
- static const typename matrix_exp<EXP>::matrix_type inv (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC);
- typedef typename matrix_exp<EXP>::type type;
-
- matrix<type, 4, 4, typename EXP::mem_manager_type> ret;
- type de = det(m);
- if (de != 0)
- {
- de = static_cast<type>(1.0/de);
- ret(0,0) = det(removerc<0,0>(m));
- ret(0,1) = -det(removerc<0,1>(m));
- ret(0,2) = det(removerc<0,2>(m));
- ret(0,3) = -det(removerc<0,3>(m));
-
- ret(1,0) = -det(removerc<1,0>(m));
- ret(1,1) = det(removerc<1,1>(m));
- ret(1,2) = -det(removerc<1,2>(m));
- ret(1,3) = det(removerc<1,3>(m));
-
- ret(2,0) = det(removerc<2,0>(m));
- ret(2,1) = -det(removerc<2,1>(m));
- ret(2,2) = det(removerc<2,2>(m));
- ret(2,3) = -det(removerc<2,3>(m));
-
- ret(3,0) = -det(removerc<3,0>(m));
- ret(3,1) = det(removerc<3,1>(m));
- ret(3,2) = -det(removerc<3,2>(m));
- ret(3,3) = det(removerc<3,3>(m));
-
- return trans(ret)*de;
- }
- else
- {
- return identity_matrix<type,4>();
- }
- }
- };
-
- template <
- typename EXP
- >
- inline const typename matrix_exp<EXP>::matrix_type inv (
- const matrix_exp<EXP>& m
- ) { return inv_helper<EXP,matrix_exp<EXP>::NR>::inv(m); }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_diag_inv
- {
- template <typename EXP>
- op_diag_inv( const matrix_exp<EXP>& m_) : m(m_){}
-
-
- const static long cost = 1;
- const static long NR = ((M::NC!=0)&&(M::NR!=0))? (tmax<M::NR,M::NC>::value) : (0);
- const static long NC = NR;
- typedef typename M::type type;
- typedef const type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
-
- // hold the matrix by value
- const matrix<type,NR,1,mem_manager_type,layout_type> m;
-
- const_ret_type apply ( long r, long c) const
- {
- if (r==c)
- return m(r);
- else
- return 0;
- }
-
- long nr () const { return m.size(); }
- long nc () const { return m.size(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_diag_op<op_diag_inv<EXP> > inv (
- const matrix_diag_exp<EXP>& m
- )
- {
- typedef op_diag_inv<EXP> op;
- return matrix_diag_op<op>(op(reciprocal(diag(m))));
- }
-
- template <
- typename EXP
- >
- const matrix_diag_op<op_diag_inv<EXP> > pinv (
- const matrix_diag_exp<EXP>& m
- )
- {
- typedef op_diag_inv<EXP> op;
- return matrix_diag_op<op>(op(reciprocal(diag(m))));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix_diag_op<op_diag_inv<EXP> > pinv (
- const matrix_diag_exp<EXP>& m,
- double tol
- )
- {
- DLIB_ASSERT(tol >= 0,
- "\tconst matrix_exp::type pinv(const matrix_exp& m)"
- << "\n\t tol can't be negative"
- << "\n\t tol: "<<tol
- );
- typedef op_diag_inv<EXP> op;
- return matrix_diag_op<op>(op(reciprocal(round_zeros(diag(m),tol))));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- const typename matrix_exp<EXP>::matrix_type inv_lower_triangular (
- const matrix_exp<EXP>& A
- )
- {
- DLIB_ASSERT(A.nr() == A.nc(),
- "\tconst matrix inv_lower_triangular(const matrix_exp& A)"
- << "\n\tA must be a square matrix"
- << "\n\tA.nr(): " << A.nr()
- << "\n\tA.nc(): " << A.nc()
- );
-
- typedef typename matrix_exp<EXP>::matrix_type matrix_type;
-
- matrix_type m(A);
-
- for(long c = 0; c < m.nc(); ++c)
- {
- if( m(c,c) == 0 )
- {
- // there isn't an inverse so just give up
- return m;
- }
-
- // compute m(c,c)
- m(c,c) = 1/m(c,c);
-
- // compute the values in column c that are below m(c,c).
- // We do this by just doing the same thing we do for upper triangular
- // matrices because we take the transpose of m which turns m into an
- // upper triangular matrix.
- for(long r = 0; r < c; ++r)
- {
- const long n = c-r;
- m(c,r) = -m(c,c)*subm(trans(m),r,r,1,n)*subm(trans(m),r,c,n,1);
- }
- }
-
- return m;
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- const typename matrix_exp<EXP>::matrix_type inv_upper_triangular (
- const matrix_exp<EXP>& A
- )
- {
- DLIB_ASSERT(A.nr() == A.nc(),
- "\tconst matrix inv_upper_triangular(const matrix_exp& A)"
- << "\n\tA must be a square matrix"
- << "\n\tA.nr(): " << A.nr()
- << "\n\tA.nc(): " << A.nc()
- );
-
- typedef typename matrix_exp<EXP>::matrix_type matrix_type;
-
- matrix_type m(A);
-
- for(long c = 0; c < m.nc(); ++c)
- {
- if( m(c,c) == 0 )
- {
- // there isn't an inverse so just give up
- return m;
- }
-
- // compute m(c,c)
- m(c,c) = 1/m(c,c);
-
- // compute the values in column c that are above m(c,c)
- for(long r = 0; r < c; ++r)
- {
- const long n = c-r;
- m(r,c) = -m(c,c)*subm(m,r,r,1,n)*subm(m,r,c,n,1);
- }
- }
-
- return m;
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- inline const typename matrix_exp<EXP>::matrix_type chol (
- const matrix_exp<EXP>& A
- )
- {
- DLIB_ASSERT(A.nr() == A.nc(),
- "\tconst matrix chol(const matrix_exp& A)"
- << "\n\tYou can only apply the chol to a square matrix"
- << "\n\tA.nr(): " << A.nr()
- << "\n\tA.nc(): " << A.nc()
- );
- typename matrix_exp<EXP>::matrix_type L(A.nr(),A.nc());
-
- typedef typename EXP::type T;
-
- bool banded = false;
- long bandwidth = 0;
-
- if (A.nr() > 4) // Only test for banded matrix if matrix is big enough
- {
- // Detect if matrix is banded and, if so, matrix bandwidth
- banded = true;
- for (long r = 0; r < A.nr(); ++r)
- for (long c = (r + bandwidth + 1); c < A.nc(); ++c)
- if (A(r, c) != 0)
- {
- bandwidth = c - r;
- if (bandwidth > A.nr() / 2)
- {
- banded = false;
- goto escape_banded_detection;
- }
- }
- }
-escape_banded_detection:
-
- if (banded)
- {
- // Store in compact form - use column major for LAPACK
- matrix<T,0,0,default_memory_manager,column_major_layout> B(bandwidth + 1, A.nc());
- set_all_elements(B, 0);
-
- for (long r = 0; r < A.nr(); ++r)
- for (long c = r; c < std::min(r + bandwidth + 1, A.nc()); ++c)
- B(c - r, r) = A(r, c);
-
-#ifdef DLIB_USE_LAPACK
-
- lapack::pbtrf('L', B);
-
-#else
-
- // Peform compact Cholesky
- for (long k = 0; k < A.nr(); ++k)
- {
- long last = std::min(k + bandwidth, A.nr() - 1) - k;
- for (long j = 1; j <= last; ++j)
- {
- long i = k + j;
- for (long c = 0; c <= (last - j); ++c)
- B(c, i) -= B(j, k) / B(0, k) * B(c + j, k);
- }
- T norm = std::sqrt(B(0, k));
- for (long i = 0; i <= bandwidth; ++i)
- B(i, k) /= norm;
- }
- for (long c = A.nc() - bandwidth + 1; c < A.nc(); ++c)
- B(bandwidth, c) = 0;
-
-#endif
-
- // Unpack lower triangular area
- set_all_elements(L, 0);
- for (long c = 0; c < A.nc(); ++c)
- for (long i = 0; i <= bandwidth; ++i)
- {
- long ind = c + i;
- if (ind < A.nc())
- L(ind, c) = B(i, c);
- }
-
- return L;
- }
-
-#ifdef DLIB_USE_LAPACK
- // Only call LAPACK if the matrix is big enough. Otherwise,
- // our own code is faster, especially for statically dimensioned
- // matrices.
- if (A.nr() > 4)
- {
- L = A;
- lapack::potrf('L', L);
- // mask out upper triangular area
- return lowerm(L);
- }
-#endif
- set_all_elements(L,0);
-
- // do nothing if the matrix is empty
- if (A.size() == 0)
- return L;
-
- const T eps = std::numeric_limits<T>::epsilon();
-
- // compute the upper left corner
- if (A(0,0) > 0)
- L(0,0) = std::sqrt(A(0,0));
-
- // compute the first column
- for (long r = 1; r < A.nr(); ++r)
- {
- // if (L(0,0) > 0)
- if (L(0,0) > eps*std::abs(A(r,0)))
- L(r,0) = A(r,0)/L(0,0);
- else
- return L;
- }
-
- // now compute all the other columns
- for (long c = 1; c < A.nc(); ++c)
- {
- // compute the diagonal element
- T temp = A(c,c);
- for (long i = 0; i < c; ++i)
- {
- temp -= L(c,i)*L(c,i);
- }
- if (temp > 0)
- L(c,c) = std::sqrt(temp);
-
- // compute the non diagonal elements
- for (long r = c+1; r < A.nr(); ++r)
- {
- temp = A(r,c);
- for (long i = 0; i < c; ++i)
- {
- temp -= L(r,i)*L(c,i);
- }
-
- // if (L(c,c) > 0)
- if (L(c,c) > eps*std::abs(temp))
- L(r,c) = temp/L(c,c);
- else
- return L;
- }
- }
-
- return L;
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- long uNR,
- long uNC,
- long wN,
- long vN,
- long wX,
- typename MM1,
- typename MM2,
- typename MM3,
- typename L1
- >
- inline void svd3 (
- const matrix_exp<EXP>& m,
- matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1,L1>& u,
- matrix<typename matrix_exp<EXP>::type, wN, wX,MM2,L1>& w,
- matrix<typename matrix_exp<EXP>::type, vN, vN,MM3,L1>& v
- )
- {
- typedef typename matrix_exp<EXP>::type T;
- const long NR = matrix_exp<EXP>::NR;
- const long NC = matrix_exp<EXP>::NC;
-
- // make sure the output matrices have valid dimensions if they are statically dimensioned
- COMPILE_TIME_ASSERT(NR == 0 || uNR == 0 || NR == uNR);
- COMPILE_TIME_ASSERT(NC == 0 || uNC == 0 || NC == uNC);
- COMPILE_TIME_ASSERT(NC == 0 || wN == 0 || NC == wN);
- COMPILE_TIME_ASSERT(NC == 0 || vN == 0 || NC == vN);
- COMPILE_TIME_ASSERT(wX == 0 || wX == 1);
-
-#ifdef DLIB_USE_LAPACK
- // use LAPACK but only if it isn't a really small matrix we are taking the SVD of.
- if (NR*NC == 0 || NR*NC > 3*3)
- {
- matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1,L1> temp(m);
- lapack::gesvd('S','A', temp, w, u, v);
- v = trans(v);
- // if u isn't the size we want then pad it (and v) with zeros
- if (u.nc() < m.nc())
- {
- w = join_cols(w, zeros_matrix<T>(m.nc()-u.nc(),1));
- u = join_rows(u, zeros_matrix<T>(u.nr(), m.nc()-u.nc()));
- }
- return;
- }
-#endif
- if (m.nr() >= m.nc())
- {
- svd4(SVD_SKINNY_U,true, m, u,w,v);
- }
- else
- {
- svd4(SVD_FULL_U,true, trans(m), v,w,u);
-
- // if u isn't the size we want then pad it (and v) with zeros
- if (u.nc() < m.nc())
- {
- w = join_cols(w, zeros_matrix<T>(m.nc()-u.nc(),1));
- u = join_rows(u, zeros_matrix<T>(u.nr(), m.nc()-u.nc()));
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix<typename EXP::type,EXP::NC,EXP::NR,typename EXP::mem_manager_type> pinv_helper (
- const matrix_exp<EXP>& m,
- double tol
- )
- /*!
- ensures
- - computes the results of pinv(m) but does so using a method that is fastest
- when m.nc() <= m.nr(). So if m.nc() > m.nr() then it is best to use
- trans(pinv_helper(trans(m))) to compute pinv(m).
- !*/
- {
- typename matrix_exp<EXP>::matrix_type u;
- typedef typename EXP::mem_manager_type MM1;
- typedef typename EXP::layout_type layout_type;
- matrix<typename EXP::type, EXP::NC, EXP::NC,MM1, layout_type > v;
-
- typedef typename matrix_exp<EXP>::type T;
-
- matrix<T,matrix_exp<EXP>::NC,1,MM1, layout_type> w;
-
- svd3(m, u,w,v);
-
- const double machine_eps = std::numeric_limits<typename EXP::type>::epsilon();
- // compute a reasonable epsilon below which we round to zero before doing the
- // reciprocal. Unless a non-zero tol is given then we just use tol*max(w).
- const double eps = (tol!=0) ? tol*max(w) : machine_eps*std::max(m.nr(),m.nc())*max(w);
-
- // now compute the pseudoinverse
- return tmp(scale_columns(v,reciprocal(round_zeros(w,eps))))*trans(u);
- }
-
- template <
- typename EXP
- >
- const matrix<typename EXP::type,EXP::NC,EXP::NR,typename EXP::mem_manager_type> pinv (
- const matrix_exp<EXP>& m,
- double tol = 0
- )
- {
- DLIB_ASSERT(tol >= 0,
- "\tconst matrix_exp::type pinv(const matrix_exp& m)"
- << "\n\t tol can't be negative"
- << "\n\t tol: "<<tol
- );
- // if m has more columns then rows then it is more efficient to
- // compute the pseudo-inverse of its transpose (given the way I'm doing it below).
- if (m.nc() > m.nr())
- return trans(pinv_helper(trans(m),tol));
- else
- return pinv_helper(m,tol);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- long uNR,
- long uNC,
- long wN,
- long vN,
- typename MM1,
- typename MM2,
- typename MM3,
- typename L1
- >
- inline void svd (
- const matrix_exp<EXP>& m,
- matrix<typename matrix_exp<EXP>::type, uNR, uNC,MM1,L1>& u,
- matrix<typename matrix_exp<EXP>::type, wN, wN,MM2,L1>& w,
- matrix<typename matrix_exp<EXP>::type, vN, vN,MM3,L1>& v
- )
- {
- typedef typename matrix_exp<EXP>::type T;
- const long NR = matrix_exp<EXP>::NR;
- const long NC = matrix_exp<EXP>::NC;
-
- // make sure the output matrices have valid dimensions if they are statically dimensioned
- COMPILE_TIME_ASSERT(NR == 0 || uNR == 0 || NR == uNR);
- COMPILE_TIME_ASSERT(NC == 0 || uNC == 0 || NC == uNC);
- COMPILE_TIME_ASSERT(NC == 0 || wN == 0 || NC == wN);
- COMPILE_TIME_ASSERT(NC == 0 || vN == 0 || NC == vN);
-
- matrix<T,matrix_exp<EXP>::NC,1,MM1, L1> W;
- svd3(m,u,W,v);
- w = diagm(W);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const typename matrix_exp<EXP>::type trace (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC ||
- matrix_exp<EXP>::NR == 0 ||
- matrix_exp<EXP>::NC == 0
- );
- DLIB_ASSERT(m.nr() == m.nc(),
- "\tconst matrix_exp::type trace(const matrix_exp& m)"
- << "\n\tYou can only apply trace() to a square matrix"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- return sum(diag(m));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- long N = EXP::NR
- >
- struct det_helper
- {
- static const typename matrix_exp<EXP>::type det (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC ||
- matrix_exp<EXP>::NR == 0 ||
- matrix_exp<EXP>::NC == 0
- );
- DLIB_ASSERT(m.nr() == m.nc(),
- "\tconst matrix_exp::type det(const matrix_exp& m)"
- << "\n\tYou can only apply det() to a square matrix"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
-
- return lu_decomposition<EXP>(m).det();
- }
- };
-
- template <
- typename EXP
- >
- struct det_helper<EXP,1>
- {
- static const typename matrix_exp<EXP>::type det (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC);
-
- return m(0);
- }
- };
-
- template <
- typename EXP
- >
- struct det_helper<EXP,2>
- {
- static const typename matrix_exp<EXP>::type det (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC);
-
- return m(0,0)*m(1,1) - m(0,1)*m(1,0);
- }
- };
-
- template <
- typename EXP
- >
- struct det_helper<EXP,3>
- {
- static const typename matrix_exp<EXP>::type det (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC);
- typedef typename matrix_exp<EXP>::type type;
-
- type temp = m(0,0)*(m(1,1)*m(2,2) - m(1,2)*m(2,1)) -
- m(0,1)*(m(1,0)*m(2,2) - m(1,2)*m(2,0)) +
- m(0,2)*(m(1,0)*m(2,1) - m(1,1)*m(2,0));
- return temp;
- }
- };
-
-
- template <
- typename EXP
- >
- inline const typename matrix_exp<EXP>::type det (
- const matrix_exp<EXP>& m
- ) { return det_helper<EXP>::det(m); }
-
-
- template <
- typename EXP
- >
- struct det_helper<EXP,4>
- {
- static const typename matrix_exp<EXP>::type det (
- const matrix_exp<EXP>& m
- )
- {
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NR == matrix_exp<EXP>::NC);
- typedef typename matrix_exp<EXP>::type type;
-
- type temp = m(0,0)*(dlib::det(removerc<0,0>(m))) -
- m(0,1)*(dlib::det(removerc<0,1>(m))) +
- m(0,2)*(dlib::det(removerc<0,2>(m))) -
- m(0,3)*(dlib::det(removerc<0,3>(m)));
- return temp;
- }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- const matrix<typename EXP::type, EXP::NR, 1, typename EXP::mem_manager_type, typename EXP::layout_type> real_eigenvalues (
- const matrix_exp<EXP>& m
- )
- {
- // You can only use this function with matrices that contain float or double values
- COMPILE_TIME_ASSERT((is_same_type<typename EXP::type, float>::value ||
- is_same_type<typename EXP::type, double>::value));
-
- DLIB_ASSERT(m.nr() == m.nc(),
- "\tconst matrix real_eigenvalues()"
- << "\n\tYou have given an invalidly sized matrix"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
-
- if (m.nr() == 2)
- {
- typedef typename EXP::type T;
- const T m00 = m(0,0);
- const T m01 = m(0,1);
- const T m10 = m(1,0);
- const T m11 = m(1,1);
-
- const T b = -(m00 + m11);
- const T c = m00*m11 - m01*m10;
- matrix<T,EXP::NR,1, typename EXP::mem_manager_type, typename EXP::layout_type> v(2);
-
-
- T disc = b*b - 4*c;
- if (disc >= 0)
- disc = std::sqrt(disc);
- else
- disc = 0;
-
- v(0) = (-b + disc)/2;
- v(1) = (-b - disc)/2;
- return v;
- }
- else
- {
- // Call .ref() so that the symmetric matrix overload can take effect if m
- // has the appropriate type.
- return eigenvalue_decomposition<EXP>(m.ref()).get_real_eigenvalues();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- dlib::vector<double,2> max_point_interpolated (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0,
- "\tdlib::vector<double,2> point max_point_interpolated(const matrix_exp& m)"
- << "\n\tm can't be empty"
- << "\n\tm.size(): " << m.size()
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- const point p = max_point(m);
-
- // If this is a column vector then just do interpolation along a line.
- if (m.nc()==1)
- {
- const long pos = p.y();
- if (0 < pos && pos+1 < m.nr())
- {
- double v1 = dlib::impl::magnitude(m(pos-1));
- double v2 = dlib::impl::magnitude(m(pos));
- double v3 = dlib::impl::magnitude(m(pos+1));
- double y = lagrange_poly_min_extrap(pos-1,pos,pos+1, -v1, -v2, -v3);
- return vector<double,2>(0,y);
- }
- }
- // If this is a row vector then just do interpolation along a line.
- if (m.nr()==1)
- {
- const long pos = p.x();
- if (0 < pos && pos+1 < m.nc())
- {
- double v1 = dlib::impl::magnitude(m(pos-1));
- double v2 = dlib::impl::magnitude(m(pos));
- double v3 = dlib::impl::magnitude(m(pos+1));
- double x = lagrange_poly_min_extrap(pos-1,pos,pos+1, -v1, -v2, -v3);
- return vector<double,2>(x,0);
- }
- }
-
-
- // If it's on the border then just return the regular max point.
- if (shrink_rect(get_rect(m),1).contains(p) == false)
- return p;
-
- //matrix<double> A(9,6);
- //matrix<double,0,1> G(9);
-
- matrix<double,9,1> pix;
- long i = 0;
- for (long r = -1; r <= +1; ++r)
- {
- for (long c = -1; c <= +1; ++c)
- {
- pix(i) = dlib::impl::magnitude(m(p.y()+r,p.y()+c));
- /*
- A(i,0) = c*c;
- A(i,1) = c*r;
- A(i,2) = r*r;
- A(i,3) = c;
- A(i,4) = r;
- A(i,5) = 1;
- G(i) = std::exp(-1*(r*r+c*c)/2.0); // Use a gaussian windowing function around p.
- */
- ++i;
- }
- }
-
- // This bit of code is how we generated the derivative_filters matrix below.
- //A = diagm(G)*A;
- //std::cout << std::setprecision(20) << inv(trans(A)*A)*trans(A)*diagm(G) << std::endl; exit(1);
-
- const double m10 = 0.10597077880854270659;
- const double m21 = 0.21194155761708535768;
- const double m28 = 0.28805844238291455905;
- const double m57 = 0.57611688476582878504;
- // So this derivative_filters finds the parameters of the quadratic surface that best fits
- // the 3x3 region around p. Then we find the maximizer of that surface within that
- // small region and return that as the maximum location.
- const double derivative_filters[] = {
- // xx
- m10,-m21,m10,
- m28,-m57,m28,
- m10,-m21,m10,
-
- // xy
- 0.25 ,0,-0.25,
- 0 ,0, 0,
- -0.25,0,0.25,
-
- // yy
- m10, m28, m10,
- -m21,-m57,-m21,
- m10, m28, m10,
-
- // x
- -m10,0,m10,
- -m28,0,m28,
- -m10,0,m10,
-
- // y
- -m10,-m28,-m10,
- 0, 0, 0,
- m10, m28, m10
- };
- const matrix<double,5,9> filt(derivative_filters);
- // Now w contains the parameters of the quadratic surface
- const matrix<double,5,1> w = filt*pix;
-
-
- // Now newton step to the max point on the surface
- matrix<double,2,2> H;
- matrix<double,2,1> g;
- H = 2*w(0), w(1),
- w(1), 2*w(2);
- g = w(3),
- w(4);
- const dlib::vector<double,2> delta = -inv(H)*g;
-
- // if delta isn't in an ascent direction then just use the normal max point.
- if (dot(delta, g) < 0)
- return p;
- else
- return vector<double,2>(p)+dlib::clamp(delta, -1, 1);
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_LA_FUNCTS_
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_la_abstract.h b/ml/dlib/dlib/matrix/matrix_la_abstract.h
deleted file mode 100644
index df6a5fd33..000000000
--- a/ml/dlib/dlib/matrix/matrix_la_abstract.h
+++ /dev/null
@@ -1,1005 +0,0 @@
-// Copyright (C) 2009 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_LA_FUNCTS_ABSTRACT_
-#ifdef DLIB_MATRIx_LA_FUNCTS_ABSTRACT_
-
-#include "matrix_abstract.h"
-#include <complex>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Global linear algebra functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::matrix_type inv (
- const matrix_exp& m
- );
- /*!
- requires
- - m is a square matrix
- ensures
- - returns the inverse of m
- (Note that if m is singular or so close to being singular that there
- is a lot of numerical error then the returned matrix will be bogus.
- You can check by seeing if m*inv(m) is an identity matrix)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix pinv (
- const matrix_exp& m,
- double tol = 0
- );
- /*!
- requires
- - tol >= 0
- ensures
- - returns the Moore-Penrose pseudoinverse of m.
- - The returned matrix has m.nc() rows and m.nr() columns.
- - if (tol == 0) then
- - singular values less than max(m.nr(),m.nc()) times the machine epsilon
- times the largest singular value are ignored.
- - else
- - singular values less than tol*max(singular value in m) are ignored.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- void svd (
- const matrix_exp& m,
- matrix<matrix_exp::type>& u,
- matrix<matrix_exp::type>& w,
- matrix<matrix_exp::type>& v
- );
- /*!
- ensures
- - computes the singular value decomposition of m
- - m == #u*#w*trans(#v)
- - trans(#u)*#u == identity matrix
- - trans(#v)*#v == identity matrix
- - diag(#w) == the singular values of the matrix m in no
- particular order. All non-diagonal elements of #w are
- set to 0.
- - #u.nr() == m.nr()
- - #u.nc() == m.nc()
- - #w.nr() == m.nc()
- - #w.nc() == m.nc()
- - #v.nr() == m.nc()
- - #v.nc() == m.nc()
- - if DLIB_USE_LAPACK is #defined then the xGESVD routine
- from LAPACK is used to compute the SVD.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- long svd2 (
- bool withu,
- bool withv,
- const matrix_exp& m,
- matrix<matrix_exp::type>& u,
- matrix<matrix_exp::type>& w,
- matrix<matrix_exp::type>& v
- );
- /*!
- requires
- - m.nr() >= m.nc()
- ensures
- - computes the singular value decomposition of matrix m
- - m == subm(#u,get_rect(m))*diagm(#w)*trans(#v)
- - trans(#u)*#u == identity matrix
- - trans(#v)*#v == identity matrix
- - #w == the singular values of the matrix m in no
- particular order.
- - #u.nr() == m.nr()
- - #u.nc() == m.nr()
- - #w.nr() == m.nc()
- - #w.nc() == 1
- - #v.nr() == m.nc()
- - #v.nc() == m.nc()
- - if (widthu == false) then
- - ignore the above regarding #u, it isn't computed and its
- output state is undefined.
- - if (widthv == false) then
- - ignore the above regarding #v, it isn't computed and its
- output state is undefined.
- - returns an error code of 0, if no errors and 'k' if we fail to
- converge at the 'kth' singular value.
- - if (DLIB_USE_LAPACK is #defined) then
- - if (withu == withv) then
- - the xGESDD routine from LAPACK is used to compute the SVD.
- - else
- - the xGESVD routine from LAPACK is used to compute the SVD.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- void svd3 (
- const matrix_exp& m,
- matrix<matrix_exp::type>& u,
- matrix<matrix_exp::type>& w,
- matrix<matrix_exp::type>& v
- );
- /*!
- ensures
- - computes the singular value decomposition of m
- - m == #u*diagm(#w)*trans(#v)
- - trans(#u)*#u == identity matrix
- - trans(#v)*#v == identity matrix
- - #w == the singular values of the matrix m in no
- particular order.
- - #u.nr() == m.nr()
- - #u.nc() == m.nc()
- - #w.nr() == m.nc()
- - #w.nc() == 1
- - #v.nr() == m.nc()
- - #v.nc() == m.nc()
- - if DLIB_USE_LAPACK is #defined then the xGESVD routine
- from LAPACK is used to compute the SVD.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- void svd_fast (
- const matrix<T>& A,
- matrix<T>& u,
- matrix<T>& w,
- matrix<T>& v,
- unsigned long l,
- unsigned long q = 1
- );
- /*!
- requires
- - l > 0
- - A.size() > 0
- (i.e. A can't be an empty matrix)
- ensures
- - computes the singular value decomposition of A.
- - Lets define some constants we use to document the behavior of svd_fast():
- - Let m = A.nr()
- - Let n = A.nc()
- - Let k = min(l, min(m,n))
- - Therefore, A represents an m by n matrix and svd_fast() is designed
- to find a rank-k representation of it.
- - if (the rank of A is <= k) then
- - A == #u*diagm(#w)*trans(#v)
- - else
- - A is approximated by #u*diagm(#w)*trans(#v)
- (i.e. In this case A can't be represented with a rank-k matrix, so the
- matrix you get by trying to reconstruct A from the output of the SVD is
- not exactly the same.)
- - trans(#u)*#u == identity matrix
- - trans(#v)*#v == identity matrix
- - #w == the top k singular values of the matrix A (in no particular order).
- - #u.nr() == m
- - #u.nc() == k
- - #w.nr() == k
- - #w.nc() == 1
- - #v.nr() == n
- - #v.nc() == k
- - This function implements the randomized subspace iteration defined in the
- algorithm 4.4 and 5.1 boxes of the paper:
- Finding Structure with Randomness: Probabilistic Algorithms for
- Constructing Approximate Matrix Decompositions by Halko et al.
- Therefore, it is very fast and suitable for use with very large matrices.
- Moreover, q is the number of subspace iterations performed. Larger
- values of q might increase the accuracy of the solution but the default
- value should be good for many problems.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename sparse_vector_type,
- typename T
- >
- void svd_fast (
- const std::vector<sparse_vector_type>& A,
- matrix<T>& u,
- matrix<T>& w,
- matrix<T>& v,
- unsigned long l,
- unsigned long q = 1
- );
- /*!
- requires
- - A contains a set of sparse vectors. See dlib/svm/sparse_vector_abstract.h
- for a definition of what constitutes a sparse vector.
- - l > 0
- - max_index_plus_one(A) > 0
- (i.e. A can't be an empty matrix)
- ensures
- - computes the singular value decomposition of A. In this case, we interpret A
- as a matrix of A.size() rows, where each row is defined by a sparse vector.
- - Lets define some constants we use to document the behavior of svd_fast():
- - Let m = A.size()
- - Let n = max_index_plus_one(A)
- - Let k = min(l, min(m,n))
- - Therefore, A represents an m by n matrix and svd_fast() is designed
- to find a rank-k representation of it.
- - if (the rank of A is <= k) then
- - A == #u*diagm(#w)*trans(#v)
- - else
- - A is approximated by #u*diagm(#w)*trans(#v)
- (i.e. In this case A can't be represented with a rank-k matrix, so the
- matrix you get by trying to reconstruct A from the output of the SVD is
- not exactly the same.)
- - trans(#u)*#u == identity matrix
- - trans(#v)*#v == identity matrix
- - #w == the top k singular values of the matrix A (in no particular order).
- - #u.nr() == m
- - #u.nc() == k
- - #w.nr() == k
- - #w.nc() == 1
- - #v.nr() == n
- - #v.nc() == k
- - This function implements the randomized subspace iteration defined in the
- algorithm 4.4 and 5.1 boxes of the paper:
- Finding Structure with Randomness: Probabilistic Algorithms for
- Constructing Approximate Matrix Decompositions by Halko et al.
- Therefore, it is very fast and suitable for use with very large matrices.
- Moreover, q is the number of subspace iterations performed. Larger
- values of q might increase the accuracy of the solution but the default
- value should be good for many problems.
- !*/
-
- template <
- typename sparse_vector_type,
- typename T
- >
- void svd_fast (
- const std::vector<sparse_vector_type>& A,
- matrix<T>& w,
- matrix<T>& v,
- unsigned long l,
- unsigned long q = 1
- );
- /*!
- This function is identical to the above svd_fast() except it doesn't compute u.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename L
- >
- void orthogonalize (
- matrix<T,NR,NC,MM,L>& m
- );
- /*!
- requires
- - m.nr() >= m.nc()
- - m.size() > 0
- ensures
- - #m == an orthogonal matrix with the same dimensions as m. In particular,
- the columns of #m have the same span as the columns of m.
- - trans(#m)*#m == identity matrix
- - This function is just shorthand for computing the QR decomposition of m
- and then storing the Q factor into #m.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix real_eigenvalues (
- const matrix_exp& m
- );
- /*!
- requires
- - m.nr() == m.nc()
- - matrix_exp::type == float or double
- ensures
- - returns a matrix E such that:
- - E.nr() == m.nr()
- - E.nc() == 1
- - E contains the real part of all eigenvalues of the matrix m.
- (note that the eigenvalues are not sorted)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type det (
- const matrix_exp& m
- );
- /*!
- requires
- - m is a square matrix
- ensures
- - returns the determinant of m
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type trace (
- const matrix_exp& m
- );
- /*!
- requires
- - m is a square matrix
- ensures
- - returns the trace of m
- (i.e. returns sum(diag(m)))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::matrix_type chol (
- const matrix_exp& A
- );
- /*!
- requires
- - A is a square matrix
- ensures
- - if (A has a Cholesky Decomposition) then
- - returns the decomposition of A. That is, returns a matrix L
- such that L*trans(L) == A. L will also be lower triangular.
- - else
- - returns a matrix with the same dimensions as A but it
- will have a bogus value. I.e. it won't be a decomposition.
- In this case the algorithm returns a partial decomposition.
- - You can tell when chol fails by looking at the lower right
- element of the returned matrix. If it is 0 then it means
- A does not have a cholesky decomposition.
-
- - If DLIB_USE_LAPACK is defined then the LAPACK routine xPOTRF
- is used to compute the cholesky decomposition.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::matrix_type inv_lower_triangular (
- const matrix_exp& A
- );
- /*!
- requires
- - A is a square matrix
- ensures
- - if (A is lower triangular) then
- - returns the inverse of A.
- - else
- - returns a matrix with the same dimensions as A but it
- will have a bogus value. I.e. it won't be an inverse.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::matrix_type inv_upper_triangular (
- const matrix_exp& A
- );
- /*!
- requires
- - A is a square matrix
- ensures
- - if (A is upper triangular) then
- - returns the inverse of A.
- - else
- - returns a matrix with the same dimensions as A but it
- will have a bogus value. I.e. it won't be an inverse.
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Matrix decomposition classes
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <
- typename matrix_exp_type
- >
- class lu_decomposition
- {
- /*!
- REQUIREMENTS ON matrix_exp_type
- must be some kind of matrix expression as defined in the
- dlib/matrix/matrix_abstract.h file. (e.g. a dlib::matrix object)
- The matrix type must also contain float or double values.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents something that can compute an LU
- decomposition of a real valued matrix. That is, for any
- matrix A it computes matrices L, U, and a pivot vector P such
- that rowm(A,P) == L*U.
-
- The LU decomposition with pivoting always exists, even if the matrix is
- singular, so the constructor will never fail. The primary use of the
- LU decomposition is in the solution of square systems of simultaneous
- linear equations. This will fail if is_singular() returns true (or
- if A is very nearly singular).
-
- If DLIB_USE_LAPACK is defined then the LAPACK routine xGETRF
- is used to compute the LU decomposition.
- !*/
-
- public:
-
- const static long NR = matrix_exp_type::NR;
- const static long NC = matrix_exp_type::NC;
- typedef typename matrix_exp_type::type type;
- typedef typename matrix_exp_type::mem_manager_type mem_manager_type;
- typedef typename matrix_exp_type::layout_type layout_type;
-
- typedef matrix<type,0,0,mem_manager_type,layout_type> matrix_type;
- typedef matrix<type,NR,1,mem_manager_type,layout_type> column_vector_type;
- typedef matrix<long,NR,1,mem_manager_type,layout_type> pivot_column_vector_type;
-
- template <typename EXP>
- lu_decomposition (
- const matrix_exp<EXP> &A
- );
- /*!
- requires
- - EXP::type == lu_decomposition::type
- - A.size() > 0
- ensures
- - #nr() == A.nr()
- - #nc() == A.nc()
- - #is_square() == (A.nr() == A.nc())
- - computes the LU factorization of the given A matrix.
- !*/
-
- bool is_square (
- ) const;
- /*!
- ensures
- - if (the input A matrix was a square matrix) then
- - returns true
- - else
- - returns false
- !*/
-
- bool is_singular (
- ) const;
- /*!
- requires
- - is_square() == true
- ensures
- - if (the input A matrix is singular) then
- - returns true
- - else
- - returns false
- !*/
-
- long nr(
- ) const;
- /*!
- ensures
- - returns the number of rows in the input matrix
- !*/
-
- long nc(
- ) const;
- /*!
- ensures
- - returns the number of columns in the input matrix
- !*/
-
- const matrix_type get_l (
- ) const;
- /*!
- ensures
- - returns the lower triangular L factor of the LU factorization.
- - L.nr() == nr()
- - L.nc() == min(nr(),nc())
- !*/
-
- const matrix_type get_u (
- ) const;
- /*!
- ensures
- - returns the upper triangular U factor of the LU factorization.
- - U.nr() == min(nr(),nc())
- - U.nc() == nc()
- !*/
-
- const pivot_column_vector_type& get_pivot (
- ) const;
- /*!
- ensures
- - returns the pivot permutation vector. That is,
- if A is the input matrix then this function
- returns a vector P such that:
- - rowm(A,P) == get_l()*get_u()
- - P.nr() == A.nr()
- !*/
-
- type det (
- ) const;
- /*!
- requires
- - is_square() == true
- ensures
- - computes and returns the determinant of the input
- matrix using LU factors.
- !*/
-
- template <typename EXP>
- const matrix_type solve (
- const matrix_exp<EXP> &B
- ) const;
- /*!
- requires
- - EXP::type == lu_decomposition::type
- - is_square() == true
- - B.nr() == nr()
- ensures
- - Let A denote the input matrix to this class's constructor.
- Then this function solves A*X == B for X and returns X.
- - Note that if A is singular (or very close to singular) then
- the X returned by this function won't fit A*X == B very well (if at all).
- !*/
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename matrix_exp_type
- >
- class cholesky_decomposition
- {
- /*!
- REQUIREMENTS ON matrix_exp_type
- must be some kind of matrix expression as defined in the
- dlib/matrix/matrix_abstract.h file. (e.g. a dlib::matrix object)
- The matrix type must also contain float or double values.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents something that can compute a cholesky
- decomposition of a real valued matrix. That is, for any
- symmetric, positive definite matrix A, it computes a lower
- triangular matrix L such that A == L*trans(L).
-
- If the matrix is not symmetric or positive definite, the function
- computes only a partial decomposition. This can be tested with
- the is_spd() flag.
-
- If DLIB_USE_LAPACK is defined then the LAPACK routine xPOTRF
- is used to compute the cholesky decomposition.
- !*/
-
- public:
-
- const static long NR = matrix_exp_type::NR;
- const static long NC = matrix_exp_type::NC;
- typedef typename matrix_exp_type::type type;
- typedef typename matrix_exp_type::mem_manager_type mem_manager_type;
- typedef typename matrix_exp_type::layout_type layout_type;
-
- typedef typename matrix_exp_type::matrix_type matrix_type;
- typedef matrix<type,NR,1,mem_manager_type,layout_type> column_vector_type;
-
- template <typename EXP>
- cholesky_decomposition(
- const matrix_exp<EXP>& A
- );
- /*!
- requires
- - EXP::type == cholesky_decomposition::type
- - A.size() > 0
- - A.nr() == A.nc()
- (i.e. A must be a square matrix)
- ensures
- - if (A is symmetric positive-definite) then
- - #is_spd() == true
- - Constructs a lower triangular matrix L, such that L*trans(L) == A.
- and #get_l() == L
- - else
- - #is_spd() == false
- !*/
-
- bool is_spd(
- ) const;
- /*!
- ensures
- - if (the input matrix was symmetric positive-definite) then
- - returns true
- - else
- - returns false
- !*/
-
- const matrix_type& get_l(
- ) const;
- /*!
- ensures
- - returns the lower triangular factor, L, such that L*trans(L) == A
- (where A is the input matrix to this class's constructor)
- - Note that if A is not symmetric positive definite or positive semi-definite
- then the equation L*trans(L) == A won't hold.
- !*/
-
- template <typename EXP>
- const matrix solve (
- const matrix_exp<EXP>& B
- ) const;
- /*!
- requires
- - EXP::type == cholesky_decomposition::type
- - B.nr() == get_l().nr()
- (i.e. the number of rows in B must match the number of rows in the
- input matrix A)
- ensures
- - Let A denote the input matrix to this class's constructor. Then
- this function solves A*X = B for X and returns X.
- - Note that if is_spd() == false or A was really close to being
- non-SPD then the solver will fail to find an accurate solution.
- !*/
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename matrix_exp_type
- >
- class qr_decomposition
- {
- /*!
- REQUIREMENTS ON matrix_exp_type
- must be some kind of matrix expression as defined in the
- dlib/matrix/matrix_abstract.h file. (e.g. a dlib::matrix object)
- The matrix type must also contain float or double values.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents something that can compute a classical
- QR decomposition of an m-by-n real valued matrix A with m >= n.
-
- The QR decomposition is an m-by-n orthogonal matrix Q and an
- n-by-n upper triangular matrix R so that A == Q*R. The QR decomposition
- always exists, even if the matrix does not have full rank, so the
- constructor will never fail. The primary use of the QR decomposition
- is in the least squares solution of non-square systems of simultaneous
- linear equations. This will fail if is_full_rank() returns false or
- A is very nearly not full rank.
-
- The Q and R factors can be retrieved via the get_q() and get_r()
- methods. Furthermore, a solve() method is provided to find the
- least squares solution of Ax=b using the QR factors.
-
- If DLIB_USE_LAPACK is #defined then the xGEQRF routine
- from LAPACK is used to compute the QR decomposition.
- !*/
-
- public:
-
- const static long NR = matrix_exp_type::NR;
- const static long NC = matrix_exp_type::NC;
- typedef typename matrix_exp_type::type type;
- typedef typename matrix_exp_type::mem_manager_type mem_manager_type;
- typedef typename matrix_exp_type::layout_type layout_type;
-
- typedef matrix<type,0,0,mem_manager_type,layout_type> matrix_type;
-
- template <typename EXP>
- qr_decomposition(
- const matrix_exp<EXP>& A
- );
- /*!
- requires
- - EXP::type == qr_decomposition::type
- - A.nr() >= A.nc()
- - A.size() > 0
- ensures
- - #nr() == A.nr()
- - #nc() == A.nc()
- - computes the QR decomposition of the given A matrix.
- !*/
-
- bool is_full_rank(
- ) const;
- /*!
- ensures
- - if (the input A matrix had full rank) then
- - returns true
- - else
- - returns false
- !*/
-
- long nr(
- ) const;
- /*!
- ensures
- - returns the number of rows in the input matrix
- !*/
-
- long nc(
- ) const;
- /*!
- ensures
- - returns the number of columns in the input matrix
- !*/
-
- const matrix_type get_r (
- ) const;
- /*!
- ensures
- - returns a matrix R such that:
- - R is the upper triangular factor, R, of the QR factorization
- - get_q()*R == input matrix A
- - R.nr() == nc()
- - R.nc() == nc()
- !*/
-
- const matrix_type get_q (
- ) const;
- /*!
- ensures
- - returns a matrix Q such that:
- - Q is the economy-sized orthogonal factor Q from the QR
- factorization.
- - trans(Q)*Q == identity matrix
- - Q*get_r() == input matrix A
- - Q.nr() == nr()
- - Q.nc() == nc()
- !*/
-
- void get_q (
- matrix_type& Q
- ) const;
- /*!
- ensures
- - #Q == get_q()
- - This function exists to allow a user to get the Q matrix without the
- overhead of returning a matrix by value.
- !*/
-
- template <typename EXP>
- const matrix_type solve (
- const matrix_exp<EXP>& B
- ) const;
- /*!
- requires
- - EXP::type == qr_decomposition::type
- - B.nr() == nr()
- ensures
- - Let A denote the input matrix to this class's constructor.
- Then this function finds the least squares solution to the equation A*X = B
- and returns X. X has the following properties:
- - X is the matrix that minimizes the two norm of A*X-B. That is, it
- minimizes sum(squared(A*X - B)).
- - X.nr() == nc()
- - X.nc() == B.nc()
- - Note that this function will fail to output a good solution if is_full_rank() == false
- or the A matrix is close to not being full rank.
- !*/
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename matrix_exp_type
- >
- class eigenvalue_decomposition
- {
- /*!
- REQUIREMENTS ON matrix_exp_type
- must be some kind of matrix expression as defined in the
- dlib/matrix/matrix_abstract.h file. (e.g. a dlib::matrix object)
- The matrix type must also contain float or double values.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents something that can compute an eigenvalue
- decomposition of a real valued matrix. So it gives
- you the set of eigenvalues and eigenvectors for a matrix.
-
- Let A denote the input matrix to this object's constructor. Then
- what this object does is it finds two matrices, D and V, such that
- - A*V == V*D
- Where V is a square matrix that contains all the eigenvectors
- of the A matrix (each column of V is an eigenvector) and
- D is a diagonal matrix containing the eigenvalues of A.
-
-
- It is important to note that if A is symmetric or non-symmetric you
- get somewhat different results. If A is a symmetric matrix (i.e. A == trans(A))
- then:
- - All the eigenvalues and eigenvectors of A are real numbers.
- - Because of this there isn't really any point in using the
- part of this class's interface that returns complex matrices.
- All you need are the get_real_eigenvalues() and
- get_pseudo_v() functions.
- - V*trans(V) should be equal to the identity matrix. That is, all the
- eigenvectors in V should be orthonormal.
- - So A == V*D*trans(V)
- - If DLIB_USE_LAPACK is #defined then this object uses the xSYEVR LAPACK
- routine.
-
- On the other hand, if A is not symmetric then:
- - Some of the eigenvalues and eigenvectors might be complex numbers.
- - An eigenvalue is complex if and only if its corresponding eigenvector
- is complex. So you can check for this case by just checking
- get_imag_eigenvalues() to see if any values are non-zero. You don't
- have to check the V matrix as well.
- - V*trans(V) won't be equal to the identity matrix but it is usually
- invertible. So A == V*D*inv(V) is usually a valid statement but
- A == V*D*trans(V) won't be.
- - If DLIB_USE_LAPACK is #defined then this object uses the xGEEV LAPACK
- routine.
- !*/
-
- public:
-
- const static long NR = matrix_exp_type::NR;
- const static long NC = matrix_exp_type::NC;
- typedef typename matrix_exp_type::type type;
- typedef typename matrix_exp_type::mem_manager_type mem_manager_type;
- typedef typename matrix_exp_type::layout_type layout_type;
-
- typedef typename matrix_exp_type::matrix_type matrix_type;
- typedef matrix<type,NR,1,mem_manager_type,layout_type> column_vector_type;
-
- typedef matrix<std::complex<type>,0,0,mem_manager_type,layout_type> complex_matrix_type;
- typedef matrix<std::complex<type>,NR,1,mem_manager_type,layout_type> complex_column_vector_type;
-
-
- template <typename EXP>
- eigenvalue_decomposition(
- const matrix_exp<EXP>& A
- );
- /*!
- requires
- - A.nr() == A.nc()
- - A.size() > 0
- - EXP::type == eigenvalue_decomposition::type
- ensures
- - #dim() == A.nr()
- - computes the eigenvalue decomposition of A.
- - #get_eigenvalues() == the eigenvalues of A
- - #get_v() == all the eigenvectors of A
- !*/
-
- template <typename EXP>
- eigenvalue_decomposition(
- const matrix_op<op_make_symmetric<EXP> >& A
- );
- /*!
- requires
- - A.nr() == A.nc()
- - A.size() > 0
- - EXP::type == eigenvalue_decomposition::type
- ensures
- - #dim() == A.nr()
- - computes the eigenvalue decomposition of the symmetric matrix A. Does so
- using a method optimized for symmetric matrices.
- - #get_eigenvalues() == the eigenvalues of A
- - #get_v() == all the eigenvectors of A
- - moreover, since A is symmetric there won't be any imaginary eigenvalues. So
- we will have:
- - #get_imag_eigenvalues() == 0
- - #get_real_eigenvalues() == the eigenvalues of A
- - #get_pseudo_v() == all the eigenvectors of A
- - diagm(#get_real_eigenvalues()) == #get_pseudo_d()
-
- Note that the symmetric matrix operator is created by the
- dlib::make_symmetric() function. This function simply reflects
- the lower triangular part of a square matrix into the upper triangular
- part to create a symmetric matrix. It can also be used to denote that a
- matrix is already symmetric using the C++ type system.
- !*/
-
- long dim (
- ) const;
- /*!
- ensures
- - dim() == the number of rows/columns in the input matrix A
- !*/
-
- const complex_column_vector_type get_eigenvalues (
- ) const;
- /*!
- ensures
- - returns diag(get_d()). That is, returns a
- vector that contains the eigenvalues of the input
- matrix.
- - the returned vector has dim() rows
- - the eigenvalues are not sorted in any particular way
- !*/
-
- const column_vector_type& get_real_eigenvalues (
- ) const;
- /*!
- ensures
- - returns the real parts of the eigenvalues. That is,
- returns real(get_eigenvalues())
- - the returned vector has dim() rows
- - the eigenvalues are not sorted in any particular way
- !*/
-
- const column_vector_type& get_imag_eigenvalues (
- ) const;
- /*!
- ensures
- - returns the imaginary parts of the eigenvalues. That is,
- returns imag(get_eigenvalues())
- - the returned vector has dim() rows
- - the eigenvalues are not sorted in any particular way
- !*/
-
- const complex_matrix_type get_v (
- ) const;
- /*!
- ensures
- - returns the eigenvector matrix V that is
- dim() rows by dim() columns
- - Each column in V is one of the eigenvectors of the input
- matrix
- !*/
-
- const complex_matrix_type get_d (
- ) const;
- /*!
- ensures
- - returns a matrix D such that:
- - D.nr() == dim()
- - D.nc() == dim()
- - diag(D) == get_eigenvalues()
- (i.e. the diagonal of D contains all the eigenvalues in the input matrix)
- - all off diagonal elements of D are set to 0
- !*/
-
- const matrix_type& get_pseudo_v (
- ) const;
- /*!
- ensures
- - returns a matrix that is dim() rows by dim() columns
- - Let A denote the input matrix given to this object's constructor.
- - if (A has any imaginary eigenvalues) then
- - returns the pseudo-eigenvector matrix V
- - The matrix V returned by this function is structured such that:
- - A*V == V*get_pseudo_d()
- - else
- - returns the eigenvector matrix V with A's eigenvectors as
- the columns of V
- - A*V == V*diagm(get_real_eigenvalues())
- !*/
-
- const matrix_type get_pseudo_d (
- ) const;
- /*!
- ensures
- - The returned matrix is dim() rows by dim() columns
- - Computes and returns the block diagonal eigenvalue matrix.
- If the original matrix A is not symmetric, then the eigenvalue
- matrix D is block diagonal with the real eigenvalues in 1-by-1
- blocks and any complex eigenvalues,
- a + i*b, in 2-by-2 blocks, (a, b; -b, a). That is, if the complex
- eigenvalues look like
-
- u + iv . . . . .
- . u - iv . . . .
- . . a + ib . . .
- . . . a - ib . .
- . . . . x .
- . . . . . y
-
- Then D looks like
-
- u v . . . .
- -v u . . . .
- . . a b . .
- . . -b a . .
- . . . . x .
- . . . . . y
-
- This keeps V (The V you get from get_pseudo_v()) a real matrix in both
- symmetric and non-symmetric cases, and A*V = V*D.
- - the eigenvalues are not sorted in any particular way
- !*/
-
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_LA_FUNCTS_ABSTRACT_
-
diff --git a/ml/dlib/dlib/matrix/matrix_lu.h b/ml/dlib/dlib/matrix/matrix_lu.h
deleted file mode 100644
index 3e49cd653..000000000
--- a/ml/dlib/dlib/matrix/matrix_lu.h
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright (C) 2009 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-// This code was adapted from code from the JAMA part of NIST's TNT library.
-// See: http://math.nist.gov/tnt/
-#ifndef DLIB_MATRIX_LU_DECOMPOSITION_H
-#define DLIB_MATRIX_LU_DECOMPOSITION_H
-
-#include "matrix.h"
-#include "matrix_utilities.h"
-#include "matrix_subexp.h"
-#include "matrix_trsm.h"
-#include <algorithm>
-
-#ifdef DLIB_USE_LAPACK
-#include "lapack/getrf.h"
-#endif
-
-
-namespace dlib
-{
-
- template <
- typename matrix_exp_type
- >
- class lu_decomposition
- {
- public:
-
- const static long NR = matrix_exp_type::NR;
- const static long NC = matrix_exp_type::NC;
- typedef typename matrix_exp_type::type type;
- typedef typename matrix_exp_type::mem_manager_type mem_manager_type;
- typedef typename matrix_exp_type::layout_type layout_type;
-
- typedef matrix<type,0,0,mem_manager_type,layout_type> matrix_type;
- typedef matrix<type,NR,1,mem_manager_type,layout_type> column_vector_type;
- typedef matrix<long,NR,1,mem_manager_type,layout_type> pivot_column_vector_type;
-
- // You have supplied an invalid type of matrix_exp_type. You have
- // to use this object with matrices that contain float or double type data.
- COMPILE_TIME_ASSERT((is_same_type<float, type>::value ||
- is_same_type<double, type>::value ));
-
- template <typename EXP>
- lu_decomposition (
- const matrix_exp<EXP> &A
- );
-
- bool is_square (
- ) const;
-
- bool is_singular (
- ) const;
-
- long nr(
- ) const;
-
- long nc(
- ) const;
-
- const matrix_type get_l (
- ) const;
-
- const matrix_type get_u (
- ) const;
-
- const pivot_column_vector_type& get_pivot (
- ) const;
-
- type det (
- ) const;
-
- template <typename EXP>
- const matrix_type solve (
- const matrix_exp<EXP> &B
- ) const;
-
- private:
-
- /* Array for internal storage of decomposition. */
- matrix<type,0,0,mem_manager_type,column_major_layout> LU;
- long m, n, pivsign;
- pivot_column_vector_type piv;
-
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Public member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- lu_decomposition<matrix_exp_type>::
- lu_decomposition (
- const matrix_exp<EXP>& A
- ) :
- LU(A),
- m(A.nr()),
- n(A.nc())
- {
- using namespace std;
- using std::abs;
-
- COMPILE_TIME_ASSERT((is_same_type<type, typename EXP::type>::value));
-
- // make sure requires clause is not broken
- DLIB_ASSERT(A.size() > 0,
- "\tlu_decomposition::lu_decomposition(A)"
- << "\n\tInvalid inputs were given to this function"
- << "\n\tA.size(): " << A.size()
- << "\n\tthis: " << this
- );
-
-#ifdef DLIB_USE_LAPACK
- matrix<lapack::integer,0,1,mem_manager_type,layout_type> piv_temp;
- lapack::getrf(LU, piv_temp);
-
- pivsign = 1;
-
- // Turn the piv_temp vector into a more useful form. This way we will have the identity
- // rowm(A,piv) == L*U. The permutation vector that comes out of LAPACK is somewhat
- // different.
- piv = trans(range(0,m-1));
- for (long i = 0; i < piv_temp.size(); ++i)
- {
- // -1 because FORTRAN is indexed starting with 1 instead of 0
- if (piv(piv_temp(i)-1) != piv(i))
- {
- std::swap(piv(i), piv(piv_temp(i)-1));
- pivsign = -pivsign;
- }
- }
-
-#else
-
- // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
-
-
- piv = trans(range(0,m-1));
- pivsign = 1;
-
- column_vector_type LUcolj(m);
-
- // Outer loop.
- for (long j = 0; j < n; j++)
- {
-
- // Make a copy of the j-th column to localize references.
- LUcolj = colm(LU,j);
-
- // Apply previous transformations.
- for (long i = 0; i < m; i++)
- {
- // Most of the time is spent in the following dot product.
- const long kmax = std::min(i,j);
- type s;
- if (kmax > 0)
- s = rowm(LU,i, kmax)*colm(LUcolj,0,kmax);
- else
- s = 0;
-
- LU(i,j) = LUcolj(i) -= s;
- }
-
- // Find pivot and exchange if necessary.
- long p = j;
- for (long i = j+1; i < m; i++)
- {
- if (abs(LUcolj(i)) > abs(LUcolj(p)))
- {
- p = i;
- }
- }
- if (p != j)
- {
- long k=0;
- for (k = 0; k < n; k++)
- {
- type t = LU(p,k);
- LU(p,k) = LU(j,k);
- LU(j,k) = t;
- }
- k = piv(p);
- piv(p) = piv(j);
- piv(j) = k;
- pivsign = -pivsign;
- }
-
- // Compute multipliers.
- if ((j < m) && (LU(j,j) != 0.0))
- {
- for (long i = j+1; i < m; i++)
- {
- LU(i,j) /= LU(j,j);
- }
- }
- }
-
-#endif
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- bool lu_decomposition<matrix_exp_type>::
- is_square (
- ) const
- {
- return m == n;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- long lu_decomposition<matrix_exp_type>::
- nr (
- ) const
- {
- return m;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- long lu_decomposition<matrix_exp_type>::
- nc (
- ) const
- {
- return n;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- bool lu_decomposition<matrix_exp_type>::
- is_singular (
- ) const
- {
- /* Is the matrix singular?
- if upper triangular factor U (and hence A) is singular, false otherwise.
- */
- // make sure requires clause is not broken
- DLIB_ASSERT(is_square() == true,
- "\tbool lu_decomposition::is_singular()"
- << "\n\tYou can only use this on square matrices"
- << "\n\tthis: " << this
- );
-
- type max_val, min_val;
- find_min_and_max (abs(diag(LU)), min_val, max_val);
- type eps = max_val;
- if (eps != 0)
- eps *= std::sqrt(std::numeric_limits<type>::epsilon())/10;
- else
- eps = 1; // there is no max so just use 1
-
- return min_val < eps;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename lu_decomposition<matrix_exp_type>::matrix_type lu_decomposition<matrix_exp_type>::
- get_l (
- ) const
- {
- if (LU.nr() >= LU.nc())
- return lowerm(LU,1.0);
- else
- return lowerm(subm(LU,0,0,m,m), 1.0);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename lu_decomposition<matrix_exp_type>::matrix_type lu_decomposition<matrix_exp_type>::
- get_u (
- ) const
- {
- if (LU.nr() >= LU.nc())
- return upperm(subm(LU,0,0,n,n));
- else
- return upperm(LU);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename lu_decomposition<matrix_exp_type>::pivot_column_vector_type& lu_decomposition<matrix_exp_type>::
- get_pivot (
- ) const
- {
- return piv;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- typename lu_decomposition<matrix_exp_type>::type lu_decomposition<matrix_exp_type>::
- det (
- ) const
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(is_square() == true,
- "\ttype lu_decomposition::det()"
- << "\n\tYou can only use this on square matrices"
- << "\n\tthis: " << this
- );
-
- // Check if it is singular and if it is just return 0.
- // We want to do this because a prod() operation can easily
- // overcome a single diagonal element that is effectively 0 when
- // LU is a big enough matrix.
- if (is_singular())
- return 0;
-
- return prod(diag(LU))*static_cast<type>(pivsign);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- const typename lu_decomposition<matrix_exp_type>::matrix_type lu_decomposition<matrix_exp_type>::
- solve (
- const matrix_exp<EXP> &B
- ) const
- {
- COMPILE_TIME_ASSERT((is_same_type<type, typename EXP::type>::value));
-
- // make sure requires clause is not broken
- DLIB_ASSERT(is_square() == true && B.nr() == nr(),
- "\ttype lu_decomposition::solve()"
- << "\n\tInvalid arguments to this function"
- << "\n\tis_square(): " << (is_square()? "true":"false" )
- << "\n\tB.nr(): " << B.nr()
- << "\n\tnr(): " << nr()
- << "\n\tthis: " << this
- );
-
- // Copy right hand side with pivoting
- matrix<type,0,0,mem_manager_type,column_major_layout> X(rowm(B, piv));
-
- using namespace blas_bindings;
- // Solve L*Y = B(piv,:)
- triangular_solver(CblasLeft, CblasLower, CblasNoTrans, CblasUnit, LU, X);
- // Solve U*X = Y;
- triangular_solver(CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, LU, X);
- return X;
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIX_LU_DECOMPOSITION_H
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_mat.h b/ml/dlib/dlib/matrix/matrix_mat.h
deleted file mode 100644
index 803d7d999..000000000
--- a/ml/dlib/dlib/matrix/matrix_mat.h
+++ /dev/null
@@ -1,733 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_MAT_Hh_
-#define DLIB_MATRIx_MAT_Hh_
-
-#include "matrix_mat_abstract.h"
-#include "../stl_checked.h"
-#include <vector>
-#include "matrix_op.h"
-#include "../array2d.h"
-#include "../array.h"
-#include "../image_processing/generic_image.h"
-
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix_exp<EXP>& mat (
- const matrix_exp<EXP>& m
- )
- {
- return m;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename image_type, typename pixel_type>
- struct op_image_to_mat : does_not_alias
- {
- op_image_to_mat( const image_type& img) : imgview(img){}
-
- const_image_view<image_type> imgview;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 0;
- typedef pixel_type type;
- typedef const pixel_type& const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long c ) const { return imgview[r][c]; }
-
- long nr () const { return imgview.nr(); }
- long nc () const { return imgview.nc(); }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename image_type
- > // The reason we disable this if it is a matrix is because this matrix_op claims
- // to not alias any matrix. But obviously that would be a problem if we let it
- // take a matrix.
- const typename disable_if<is_matrix<image_type>,matrix_op<op_image_to_mat<image_type, typename image_traits<image_type>::pixel_type> > >::type mat (
- const image_type& img
- )
- {
- typedef op_image_to_mat<image_type, typename image_traits<image_type>::pixel_type> op;
- return matrix_op<op>(op(img));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename image_type>
- struct op_image_view_to_mat : does_not_alias
- {
- op_image_view_to_mat( const image_view<image_type>& img) : imgview(img){}
-
- typedef typename image_traits<image_type>::pixel_type pixel_type;
-
- const image_view<image_type>& imgview;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 0;
- typedef pixel_type type;
- typedef const pixel_type& const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long c ) const { return imgview[r][c]; }
-
- long nr () const { return imgview.nr(); }
- long nc () const { return imgview.nc(); }
- };
-
- template <
- typename image_type
- >
- const matrix_op<op_image_view_to_mat<image_type> > mat (
- const image_view<image_type>& img
- )
- {
- typedef op_image_view_to_mat<image_type> op;
- return matrix_op<op>(op(img));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename image_type>
- struct op_const_image_view_to_mat : does_not_alias
- {
- op_const_image_view_to_mat( const const_image_view<image_type>& img) : imgview(img){}
-
- typedef typename image_traits<image_type>::pixel_type pixel_type;
-
- const const_image_view<image_type>& imgview;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 0;
- typedef pixel_type type;
- typedef const pixel_type& const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long c ) const { return imgview[r][c]; }
-
- long nr () const { return imgview.nr(); }
- long nc () const { return imgview.nc(); }
- };
-
- template <
- typename image_type
- >
- const matrix_op<op_const_image_view_to_mat<image_type> > mat (
- const const_image_view<image_type>& img
- )
- {
- typedef op_const_image_view_to_mat<image_type> op;
- return matrix_op<op>(op(img));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- struct op_array_to_mat : does_not_alias
- {
- op_array_to_mat( const T& vect_) : vect(vect_){}
-
- const T& vect;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 1;
- typedef typename T::type type;
- typedef const typename T::type& const_ret_type;
- typedef typename T::mem_manager_type mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long ) const { return vect[r]; }
-
- long nr () const { return vect.size(); }
- long nc () const { return 1; }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- typename MM
- >
- const matrix_op<op_array_to_mat<array<T,MM> > > mat (
- const array<T,MM>& m
- )
- {
- typedef op_array_to_mat<array<T,MM> > op;
- return matrix_op<op>(op(m));
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename U>
- struct not_bool { typedef U type; };
- template <>
- struct not_bool<const bool&> { typedef bool type; };
- }
-
- template <typename T>
- struct op_std_vect_to_mat : does_not_alias
- {
- op_std_vect_to_mat( const T& vect_) : vect(vect_){}
-
- const T& vect;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 1;
- typedef typename T::value_type type;
- // Since std::vector returns a proxy for bool types we need to make sure we don't
- // return an element by reference if it is a bool type.
- typedef typename impl::not_bool<const typename T::value_type&>::type const_ret_type;
-
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long ) const { return vect[r]; }
-
- long nr () const { return vect.size(); }
- long nc () const { return 1; }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename value_type,
- typename alloc
- >
- const matrix_op<op_std_vect_to_mat<std::vector<value_type,alloc> > > mat (
- const std::vector<value_type,alloc>& vector
- )
- {
- typedef op_std_vect_to_mat<std::vector<value_type,alloc> > op;
- return matrix_op<op>(op(vector));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename value_type,
- typename alloc
- >
- const matrix_op<op_std_vect_to_mat<std_vector_c<value_type,alloc> > > mat (
- const std_vector_c<value_type,alloc>& vector
- )
- {
- typedef op_std_vect_to_mat<std_vector_c<value_type,alloc> > op;
- return matrix_op<op>(op(vector));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- struct op_pointer_to_mat;
-
- template <typename T>
- struct op_pointer_to_col_vect
- {
- op_pointer_to_col_vect(
- const T* ptr_,
- const long size_
- ) : ptr(ptr_), size(size_){}
-
- const T* ptr;
- const long size;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 1;
- typedef T type;
- typedef const T& const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long ) const { return ptr[r]; }
-
- long nr () const { return size; }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& ) const { return false; }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& ) const { return false; }
-
- template <long num_rows, long num_cols, typename mem_manager, typename layout>
- bool aliases (
- const matrix_exp<matrix<T,num_rows,num_cols, mem_manager,layout> >& item
- ) const
- {
- if (item.size() == 0)
- return false;
- else
- return (ptr == &item(0,0));
- }
-
- inline bool aliases (
- const matrix_exp<matrix_op<op_pointer_to_mat<T> > >& item
- ) const;
-
- bool aliases (
- const matrix_exp<matrix_op<op_pointer_to_col_vect<T> > >& item
- ) const
- {
- return item.ref().op.ptr == ptr;
- }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_op<op_pointer_to_col_vect<T> > mat (
- const T* ptr,
- long nr
- )
- {
- DLIB_ASSERT(nr >= 0 ,
- "\tconst matrix_exp mat(ptr, nr)"
- << "\n\t nr must be >= 0"
- << "\n\t nr: " << nr
- );
- typedef op_pointer_to_col_vect<T> op;
- return matrix_op<op>(op(ptr, nr));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- struct op_pointer_to_mat
- {
- op_pointer_to_mat(
- const T* ptr_,
- const long nr_,
- const long nc_
- ) : ptr(ptr_), rows(nr_), cols(nc_), stride(nc_){}
-
- op_pointer_to_mat(
- const T* ptr_,
- const long nr_,
- const long nc_,
- const long stride_
- ) : ptr(ptr_), rows(nr_), cols(nc_), stride(stride_){}
-
- const T* ptr;
- const long rows;
- const long cols;
- const long stride;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 0;
- typedef T type;
- typedef const T& const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long c) const { return ptr[r*stride + c]; }
-
- long nr () const { return rows; }
- long nc () const { return cols; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& ) const { return false; }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& ) const { return false; }
-
- template <long num_rows, long num_cols, typename mem_manager, typename layout>
- bool aliases (
- const matrix_exp<matrix<T,num_rows,num_cols, mem_manager,layout> >& item
- ) const
- {
- if (item.size() == 0)
- return false;
- else
- return (ptr == &item(0,0));
- }
-
- bool aliases (
- const matrix_exp<matrix_op<op_pointer_to_mat<T> > >& item
- ) const
- {
- return item.ref().op.ptr == ptr;
- }
-
- bool aliases (
- const matrix_exp<matrix_op<op_pointer_to_col_vect<T> > >& item
- ) const
- {
- return item.ref().op.ptr == ptr;
- }
- };
-
- template <typename T>
- bool op_pointer_to_col_vect<T>::
- aliases (
- const matrix_exp<matrix_op<op_pointer_to_mat<T> > >& item
- ) const
- {
- return item.ref().op.ptr == ptr;
- }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- bool matrix<T,NR,NC,MM,L>::aliases (
- const matrix_exp<matrix_op<op_pointer_to_mat<T> > >& item
- ) const
- {
- if (size() != 0)
- return item.ref().op.ptr == &data(0,0);
- else
- return false;
- }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- bool matrix<T,NR,NC,MM,L>::aliases (
- const matrix_exp<matrix_op<op_pointer_to_col_vect<T> > >& item
- ) const
- {
- if (size() != 0)
- return item.ref().op.ptr == &data(0,0);
- else
- return false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_op<op_pointer_to_mat<T> > mat (
- const T* ptr,
- long nr,
- long nc
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0 ,
- "\tconst matrix_exp mat(ptr, nr, nc)"
- << "\n\t nr and nc must be >= 0"
- << "\n\t nr: " << nr
- << "\n\t nc: " << nc
- );
- typedef op_pointer_to_mat<T> op;
- return matrix_op<op>(op(ptr,nr,nc));
- }
-
- template <
- typename T
- >
- const matrix_op<op_pointer_to_mat<T> > mat (
- const T* ptr,
- long nr,
- long nc,
- long stride
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0 && stride > 0 ,
- "\tconst matrix_exp mat(ptr, nr, nc, stride)"
- << "\n\t nr and nc must be >= 0 while stride > 0"
- << "\n\t nr: " << nr
- << "\n\t nc: " << nc
- << "\n\t stride: " << stride
- );
- typedef op_pointer_to_mat<T> op;
- return matrix_op<op>(op(ptr,nr,nc,stride));
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-namespace arma
-{
- template <typename T> class Mat;
-}
-namespace dlib
-{
- template <typename T>
- struct op_arma_Mat_to_mat : does_not_alias
- {
- op_arma_Mat_to_mat( const T& array_) : array(array_){}
-
- const T& array;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 0;
- typedef typename T::elem_type type;
- typedef typename T::elem_type const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long c ) const { return array(r,c); }
-
- long nr () const { return array.n_rows; }
- long nc () const { return array.n_cols; }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_op<op_arma_Mat_to_mat< ::arma::Mat<T> > > mat (
- const ::arma::Mat<T>& array
- )
- {
- typedef op_arma_Mat_to_mat< ::arma::Mat<T> > op;
- return matrix_op<op>(op(array));
- }
-}
-
-namespace Eigen
-{
- template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
- class Matrix;
-}
-
-namespace dlib
-{
- template <typename T, int _Rows, int _Cols>
- struct op_eigen_Matrix_to_mat : does_not_alias
- {
- op_eigen_Matrix_to_mat( const T& array_) : m(array_){}
-
- const T& m;
-
- const static long cost = 1;
- const static long NR = (_Rows > 0) ? _Rows : 0;
- const static long NC = (_Cols > 0) ? _Cols : 0;
- typedef typename T::Scalar type;
- typedef typename T::Scalar const_ret_type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long c ) const { return m(r,c); }
-
- long nr () const { return m.rows(); }
- long nc () const { return m.cols(); }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols
- >
- const matrix_op<op_eigen_Matrix_to_mat< ::Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols>,_Rows,_Cols > > mat (
- const ::Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols>& m
- )
- {
- typedef op_eigen_Matrix_to_mat< ::Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols>,_Rows,_Cols > op;
- return matrix_op<op>(op(m));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// DEPRECATED FUNCTIONS
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-// vector_to_matrix(), array_to_matrix(), pointer_to_matrix(), and
-// pointer_to_column_vector() have been deprecated in favor of the more uniform mat()
-// function. But they are here for backwards compatibility.
-
- template <
- typename vector_type
- >
- const typename disable_if<is_matrix<vector_type>, matrix_op<op_array_to_mat<vector_type> > >::type
- vector_to_matrix (
- const vector_type& vector
- )
- {
- typedef op_array_to_mat<vector_type> op;
- return matrix_op<op>(op(vector));
- }
-
- template <
- typename vector_type
- >
- const typename enable_if<is_matrix<vector_type>,vector_type>::type& vector_to_matrix (
- const vector_type& vector
- )
- /*!
- This overload catches the case where the argument to this function is
- already a matrix.
- !*/
- {
- return vector;
- }
-
- template <
- typename value_type,
- typename alloc
- >
- const matrix_op<op_std_vect_to_mat<std::vector<value_type,alloc> > > vector_to_matrix (
- const std::vector<value_type,alloc>& vector
- )
- {
- typedef op_std_vect_to_mat<std::vector<value_type,alloc> > op;
- return matrix_op<op>(op(vector));
- }
-
- template <
- typename value_type,
- typename alloc
- >
- const matrix_op<op_std_vect_to_mat<std_vector_c<value_type,alloc> > > vector_to_matrix (
- const std_vector_c<value_type,alloc>& vector
- )
- {
- typedef op_std_vect_to_mat<std_vector_c<value_type,alloc> > op;
- return matrix_op<op>(op(vector));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename array_type
- >
- const typename enable_if<is_matrix<array_type>,array_type>::type&
- array_to_matrix (
- const array_type& array
- )
- {
- return array;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- struct op_array2d_to_mat : does_not_alias
- {
- op_array2d_to_mat( const T& array_) : array(array_){}
-
- const T& array;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 0;
- typedef typename T::type type;
- typedef const typename T::type& const_ret_type;
- typedef typename T::mem_manager_type mem_manager_type;
- typedef row_major_layout layout_type;
-
- const_ret_type apply (long r, long c ) const { return array[r][c]; }
-
- long nr () const { return array.nr(); }
- long nc () const { return array.nc(); }
- };
-
- // Note that we have this version of mat() because it's slightly faster executing
- // than the general one that handles any generic image. This is because it avoids
- // calling image_data() which for array2d involves a single if statement but this
- // version here has no if statement in its construction.
- template < typename T, typename MM >
- const matrix_op<op_array2d_to_mat<array2d<T,MM> > > mat (
- const array2d<T,MM>& array
- )
- {
- typedef op_array2d_to_mat<array2d<T,MM> > op;
- return matrix_op<op>(op(array));
- }
-
- template <
- typename array_type
- >
- const typename disable_if<is_matrix<array_type>,matrix_op<op_array2d_to_mat<array_type> > >::type
- array_to_matrix (
- const array_type& array
- )
- {
- typedef op_array2d_to_mat<array_type> op;
- return matrix_op<op>(op(array));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_op<op_pointer_to_mat<T> > pointer_to_matrix (
- const T* ptr,
- long nr,
- long nc
- )
- {
- DLIB_ASSERT(nr > 0 && nc > 0 ,
- "\tconst matrix_exp pointer_to_matrix(ptr, nr, nc)"
- << "\n\t nr and nc must be bigger than 0"
- << "\n\t nr: " << nr
- << "\n\t nc: " << nc
- );
- typedef op_pointer_to_mat<T> op;
- return matrix_op<op>(op(ptr,nr,nc));
- }
-
- template <
- typename T
- >
- const matrix_op<op_pointer_to_col_vect<T> > pointer_to_column_vector (
- const T* ptr,
- long nr
- )
- {
- DLIB_ASSERT(nr > 0 ,
- "\tconst matrix_exp pointer_to_column_vector(ptr, nr)"
- << "\n\t nr must be bigger than 0"
- << "\n\t nr: " << nr
- );
- typedef op_pointer_to_col_vect<T> op;
- return matrix_op<op>(op(ptr, nr));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- inline matrix<double,1,1> mat (
- double value
- )
- {
- matrix<double,1,1> temp;
- temp(0) = value;
- return temp;
- }
-
- inline matrix<float,1,1> mat (
- float value
- )
- {
- matrix<float,1,1> temp;
- temp(0) = value;
- return temp;
- }
-
- inline matrix<long double,1,1> mat (
- long double value
- )
- {
- matrix<long double,1,1> temp;
- temp(0) = value;
- return temp;
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_MAT_Hh_
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_mat_abstract.h b/ml/dlib/dlib/matrix/matrix_mat_abstract.h
deleted file mode 100644
index 7026f60a1..000000000
--- a/ml/dlib/dlib/matrix/matrix_mat_abstract.h
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_MAT_ABSTRACT_Hh_
-#ifdef DLIB_MATRIx_MAT_ABSTRACT_Hh_
-
-#include "matrix_abstract.h"
-#inclue <vector>
-#include "../array/array_kernel_abstract.h"
-#include "../array2d/array2d_kernel_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix_exp<EXP>& mat (
- const matrix_exp<EXP>& m
- );
- /*!
- ensures
- - returns m
- (i.e. this function just returns the input matrix without any modifications)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename image_type
- >
- const matrix_exp mat (
- const image_type& img
- );
- /*!
- requires
- - image_type == an image object that implements the interface defined in
- dlib/image_processing/generic_image.h or image_type is a image_view or
- const_image_view object.
- ensures
- - This function converts any kind of generic image object into a dlib::matrix
- expression. Therefore, it is capable of converting objects like dlib::array2d
- of dlib::cv_image.
- - returns a matrix R such that:
- - R.nr() == array.nr()
- - R.nc() == array.nc()
- - for all valid r and c:
- R(r, c) == array[r][c]
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- typename MM
- >
- const matrix_exp mat (
- const array<T,MM>& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - is_col_vector(R) == true
- - R.size() == m.size()
- - for all valid r:
- R(r) == m[r]
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename value_type,
- typename alloc
- >
- const matrix_exp mat (
- const std::vector<value_type,alloc>& vector
- );
- /*!
- ensures
- - returns a matrix R such that:
- - is_col_vector(R) == true
- - R.size() == vector.size()
- - for all valid r:
- R(r) == vector[r]
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename value_type,
- typename alloc
- >
- const matrix_exp mat (
- const std_vector_c<value_type,alloc>& vector
- );
- /*!
- ensures
- - returns a matrix R such that:
- - is_col_vector(R) == true
- - R.size() == vector.size()
- - for all valid r:
- R(r) == vector[r]
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_exp mat (
- const T* ptr,
- long nr
- );
- /*!
- requires
- - nr >= 0
- - ptr == a pointer to at least nr T objects (or the NULL pointer if nr==0)
- ensures
- - returns a matrix M such that:
- - M.nr() == nr
- - m.nc() == 1
- - for all valid i:
- M(i) == ptr[i]
- - Note that the returned matrix doesn't take "ownership" of
- the pointer and thus will not delete or free it.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_exp mat (
- const T* ptr,
- long nr,
- long nc
- );
- /*!
- requires
- - nr >= 0
- - nc >= 0
- - ptr == a pointer to at least nr*nc T objects (or the NULL pointer if nr*nc==0)
- ensures
- - returns a matrix M such that:
- - M.nr() == nr
- - m.nc() == nc
- - for all valid r and c:
- M(r,c) == ptr[r*nc + c]
- (i.e. the pointer is interpreted as a matrix laid out in memory
- in row major order)
- - Note that the returned matrix doesn't take "ownership" of
- the pointer and thus will not delete or free it.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_exp mat (
- const T* ptr,
- long nr,
- long nc,
- long stride
- );
- /*!
- requires
- - nr >= 0
- - nc >= 0
- - stride > 0
- - ptr == a pointer to at least (nr-1)*stride+nc T objects (or the NULL pointer if nr*nc==0)
- ensures
- - returns a matrix M such that:
- - M.nr() == nr
- - m.nc() == nc
- - for all valid r and c:
- M(r,c) == ptr[r*stride + c]
- (i.e. the pointer is interpreted as a matrix laid out in memory
- in row major order, with a row stride of the given stride amount.)
- - Note that the returned matrix doesn't take "ownership" of
- the pointer and thus will not delete or free it.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_exp mat (
- const ::arma::Mat<T>& m
- );
- /*!
- ensures
- - Converts a matrix from the Armadillo library into a dlib matrix.
- - returns a matrix R such that:
- - R.nr() == m.n_rows
- - R.nc() == m.n_cols
- - for all valid r:
- R(r,c) == m(r,c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename _Scalar,
- int _Rows,
- int _Cols,
- int _Options,
- int _MaxRows,
- int _MaxCols
- >
- const matrix_exp mat (
- const ::Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols>& m
- );
- /*!
- ensures
- - Converts a matrix from the Eigen library into a dlib matrix.
- - returns a matrix R such that:
- - R.nr() == m.rows()
- - R.nc() == m.cols()
- - for all valid r:
- R(r,c) == m(r,c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- matrix<double,1,1> mat (double value);
- matrix<float,1,1> mat (float value);
- matrix<long double,1,1> mat (long double value);
- /*!
- ensures
- - Converts a scalar into a matrix containing just that scalar and returns the
- results.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_MAT_ABSTRACT_Hh_
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_math_functions.h b/ml/dlib/dlib/matrix/matrix_math_functions.h
deleted file mode 100644
index d1db3ed14..000000000
--- a/ml/dlib/dlib/matrix/matrix_math_functions.h
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_MATH_FUNCTIONS
-#define DLIB_MATRIx_MATH_FUNCTIONS
-
-#include "matrix_math_functions_abstract.h"
-#include "matrix_op.h"
-#include "matrix_utilities.h"
-#include "matrix.h"
-#include "../algs.h"
-#include <cmath>
-#include <complex>
-#include <limits>
-
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- DLIB_DEFINE_FUNCTION_M(op_sqrt, sqrt, std::sqrt ,7);
- DLIB_DEFINE_FUNCTION_M(op_log, log, std::log ,7);
- DLIB_DEFINE_FUNCTION_M(op_log10, log10, std::log10 ,7);
- DLIB_DEFINE_FUNCTION_M(op_exp, exp, std::exp ,7);
-
- DLIB_DEFINE_FUNCTION_M(op_conj, conj, std::conj ,2);
-
- DLIB_DEFINE_FUNCTION_M(op_ceil, ceil, std::ceil ,7);
- DLIB_DEFINE_FUNCTION_M(op_floor, floor, std::floor ,7);
-
- DLIB_DEFINE_FUNCTION_M(op_sin, sin, std::sin ,7);
- DLIB_DEFINE_FUNCTION_M(op_cos, cos, std::cos ,7);
- DLIB_DEFINE_FUNCTION_M(op_tan, tan, std::tan ,7);
- DLIB_DEFINE_FUNCTION_M(op_sinh, sinh, std::sinh ,7);
- DLIB_DEFINE_FUNCTION_M(op_cosh, cosh, std::cosh ,7);
- DLIB_DEFINE_FUNCTION_M(op_tanh, tanh, std::tanh ,7);
- DLIB_DEFINE_FUNCTION_M(op_asin, asin, std::asin ,7);
- DLIB_DEFINE_FUNCTION_M(op_acos, acos, std::acos ,7);
- DLIB_DEFINE_FUNCTION_M(op_atan, atan, std::atan ,7);
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename type>
- inline type sigmoid (const type& val)
- {
- return static_cast<type>(1/(1 + std::exp(-val)));
- }
-
- template <typename type, typename S>
- inline type round_zeros_eps (const type& val, const S& eps)
- {
- // you can only round matrices that contain built in scalar types like double, long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<type>::value);
-
- if (val >= eps || val <= -eps)
- return val;
- else
- return 0;
- }
-
- template <typename type>
- inline type round_zeros (const type& val)
- {
- // you can only round matrices that contain built in scalar types like double, long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<type>::value);
-
- const type eps = 10*std::numeric_limits<type>::epsilon();
- if (val >= eps || val <= -eps)
- return val;
- else
- return 0;
- }
-
- template <typename type>
- inline type squared (const type& val)
- {
- return val*val;
- }
-
- template <typename type>
- inline type sign (const type& val)
- {
- if (val >= 0)
- return +1;
- else
- return -1;
- }
-
- template <typename type>
- type cubed (const type& val)
- {
- return val*val*val;
- }
-
- template <typename type, typename S>
- inline type pow1 (const type& val, const S& s)
- {
- // you can only call pow() on matrices that contain floats, doubles or long doubles.
- COMPILE_TIME_ASSERT((
- is_same_type<type,float>::value == true ||
- is_same_type<type,double>::value == true ||
- is_same_type<type,long double>::value == true
- ));
-
- return std::pow(val,static_cast<type>(s));
- }
-
- template <typename type, typename S>
- inline type pow2 (const S& s, const type& val)
- {
- // you can only call pow() on matrices that contain floats, doubles or long doubles.
- COMPILE_TIME_ASSERT((
- is_same_type<type,float>::value == true ||
- is_same_type<type,double>::value == true ||
- is_same_type<type,long double>::value == true
- ));
-
- return std::pow(static_cast<type>(s),val);
- }
-
- template <typename type>
- inline type reciprocal (const type& val)
- {
- // you can only compute reciprocal matrices that contain floats, doubles or long doubles.
- COMPILE_TIME_ASSERT((
- is_same_type<type,float>::value == true ||
- is_same_type<type,double>::value == true ||
- is_same_type<type,long double>::value == true ||
- is_same_type<type,std::complex<float> >::value == true ||
- is_same_type<type,std::complex<double> >::value == true ||
- is_same_type<type,std::complex<long double> >::value == true
- ));
-
- if (val != static_cast<type>(0))
- return static_cast<type>((type)1.0/val);
- else
- return 0;
- }
-
- template <typename type>
- inline type reciprocal_max (const type& val)
- {
- // you can only compute reciprocal_max matrices that contain floats, doubles or long doubles.
- COMPILE_TIME_ASSERT((
- is_same_type<type,float>::value == true ||
- is_same_type<type,double>::value == true ||
- is_same_type<type,long double>::value == true
- ));
-
- if (val != static_cast<type>(0))
- return static_cast<type>((type)1.0/val);
- else
- return std::numeric_limits<type>::max();
- }
-
- }
-
- DLIB_DEFINE_FUNCTION_M(op_sigmoid, sigmoid, impl::sigmoid, 7);
- DLIB_DEFINE_FUNCTION_MS(op_round_zeros, round_zeros, impl::round_zeros_eps, 7);
- DLIB_DEFINE_FUNCTION_M(op_round_zeros2, round_zeros, impl::round_zeros, 7);
- DLIB_DEFINE_FUNCTION_M(op_cubed, cubed, impl::cubed, 7);
- DLIB_DEFINE_FUNCTION_M(op_squared, squared, impl::squared, 6);
- DLIB_DEFINE_FUNCTION_M(op_sign, sign, impl::sign, 6);
- DLIB_DEFINE_FUNCTION_MS(op_pow1, pow, impl::pow1, 7);
- DLIB_DEFINE_FUNCTION_SM(op_pow2, pow, impl::pow2, 7);
- DLIB_DEFINE_FUNCTION_M(op_reciprocal, reciprocal, impl::reciprocal, 6);
- DLIB_DEFINE_FUNCTION_M(op_reciprocal_max, reciprocal_max, impl::reciprocal_max, 6);
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, typename enabled = void>
- struct op_round : basic_op_m<M>
- {
- op_round( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost+7;
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- const_ret_type apply (long r, long c) const
- {
- return static_cast<type>(std::floor(this->m(r,c)+0.5));
- }
- };
-
- template <typename M>
- struct op_round<M,typename enable_if_c<std::numeric_limits<typename M::type>::is_integer>::type >
- : basic_op_m<M>
- {
- op_round( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- const_ret_type apply (long r, long c) const
- {
- return this->m(r,c);
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_round<EXP> > round (
- const matrix_exp<EXP>& m
- )
- {
- // you can only round matrices that contain built in scalar types like double, long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_round<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_normalize : basic_op_m<M>
- {
- typedef typename M::type type;
-
- op_normalize( const M& m_, const type& s_) : basic_op_m<M>(m_), s(s_){}
-
- const type s;
-
- const static long cost = M::cost+5;
- typedef const typename M::type const_ret_type;
- const_ret_type apply (long r, long c) const
- {
- return this->m(r,c)*s;
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_normalize<EXP> > normalize (
- const matrix_exp<EXP>& m
- )
- {
- // you can only compute normalized matrices that contain floats, doubles or long doubles.
- COMPILE_TIME_ASSERT((
- is_same_type<typename EXP::type,float>::value == true ||
- is_same_type<typename EXP::type,double>::value == true ||
- is_same_type<typename EXP::type,long double>::value == true
- ));
-
-
- typedef op_normalize<EXP> op;
- typename EXP::type temp = std::sqrt(sum(squared(m)));
- if (temp != 0.0)
- temp = 1.0/temp;
-
- return matrix_op<op>(op(m.ref(),temp));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, typename return_type = typename M::type>
- struct op_abs : basic_op_m<M>
- {
- op_abs( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost+7;
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- const_ret_type apply ( long r, long c) const
- {
- return static_cast<type>(std::abs(this->m(r,c)));
- }
- };
-
- template <typename M, typename T>
- struct op_abs<M, std::complex<T> > : basic_op_m<M>
- {
- op_abs( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost;
- typedef T type;
- typedef const T const_ret_type;
- const_ret_type apply ( long r, long c) const
- {
- return static_cast<type>(std::abs(this->m(r,c)));
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_abs<EXP> > abs (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_abs<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_complex_matrix : basic_op_m<M>
- {
- op_complex_matrix( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost+1;
- typedef std::complex<typename M::type> type;
- typedef const std::complex<typename M::type> const_ret_type;
- const_ret_type apply ( long r, long c) const
- {
- return type(this->m(r,c));
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_complex_matrix<EXP> > complex_matrix (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_complex_matrix<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_complex_matrix2 : basic_op_mm<M1,M2>
- {
- op_complex_matrix2( const M1& m1_, const M2& m2_) : basic_op_mm<M1,M2>(m1_,m2_){}
-
- const static long cost = M1::cost+M2::cost+1;
- typedef std::complex<typename M1::type> type;
- typedef const std::complex<typename M1::type> const_ret_type;
-
- const_ret_type apply ( long r, long c) const
- { return type(this->m1(r,c), this->m2(r,c)); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- const matrix_op<op_complex_matrix2<EXP1,EXP2> > complex_matrix (
- const matrix_exp<EXP1>& real_part,
- const matrix_exp<EXP2>& imag_part
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0);
-
- DLIB_ASSERT(real_part.nr() == imag_part.nr() &&
- real_part.nc() == imag_part.nc(),
- "\tconst matrix_exp::type complex_matrix(real_part, imag_part)"
- << "\n\tYou can only make a complex matrix from two equally sized matrices"
- << "\n\treal_part.nr(): " << real_part.nr()
- << "\n\treal_part.nc(): " << real_part.nc()
- << "\n\timag_part.nr(): " << imag_part.nr()
- << "\n\timag_part.nc(): " << imag_part.nc()
- );
-
- typedef op_complex_matrix2<EXP1,EXP2> op;
- return matrix_op<op>(op(real_part.ref(),imag_part.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_norm : basic_op_m<M>
- {
- op_norm( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost+6;
- typedef typename M::type::value_type type;
- typedef const typename M::type::value_type const_ret_type;
- const_ret_type apply ( long r, long c) const
- { return std::norm(this->m(r,c)); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_norm<EXP> > norm (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_norm<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_real : basic_op_m<M>
- {
- op_real( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost;
- typedef typename M::type::value_type type;
- typedef const typename M::type::value_type const_ret_type;
- const_ret_type apply ( long r, long c) const
- { return std::real(this->m(r,c)); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_real<EXP> > real (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_real<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_imag : basic_op_m<M>
- {
- op_imag( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost;
- typedef typename M::type::value_type type;
- typedef const typename M::type::value_type const_ret_type;
- const_ret_type apply (long r, long c) const
- { return std::imag(this->m(r,c)); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_imag<EXP> > imag (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_imag<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_MATH_FUNCTIONS
-
diff --git a/ml/dlib/dlib/matrix/matrix_math_functions_abstract.h b/ml/dlib/dlib/matrix/matrix_math_functions_abstract.h
deleted file mode 100644
index 09210270d..000000000
--- a/ml/dlib/dlib/matrix/matrix_math_functions_abstract.h
+++ /dev/null
@@ -1,595 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_MATH_FUNCTIONS_ABSTRACT_
-#ifdef DLIB_MATRIx_MATH_FUNCTIONS_ABSTRACT_
-
-#include "matrix_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Exponential Functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp exp (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::exp(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp log10 (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::log10(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp log (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::log(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp sqrt (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == sqrt(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- const matrix_exp pow (
- const matrix_exp& m,
- const T& e
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == pow(m(r,c),e)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- const matrix_exp pow (
- const T& b,
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == pow(b, m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp squared (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == m(r,c)*m(r,c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp cubed (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == m(r,c)*m(r,c)*m(r,c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Miscellaneous
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp sign (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix that tells the sign of each element in m. In particular:
- returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (m(r,c) >= 0) then
- - R(r,c) == +1
- - else
- - R(r,c) == -1
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp sigmoid (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == 1/(1 + exp(-m(r,c)))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp abs (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - if (m contains std::complex<T> objects) then
- - R::type == T
- - else
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::abs(m(r,c))
- (note that if m is complex then std::abs(val) performs sqrt(std::norm(val))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp reciprocal (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, long double, std::complex<float>,
- std::complex<double>, or std::complex<long double>
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (m(r,c) != 0) then
- - R(r,c) == 1.0/m(r,c)
- - else
- - R(r,c) == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp reciprocal_max (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (m(r,c) != 0) then
- - R(r,c) == 1.0/m(r,c)
- - else
- - R(r,c) == std::numeric_limits<R::type>::max()
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp normalize (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - if (sqrt(sum(squared(m))) != 0) then
- - returns m/sqrt(sum(squared(m)))
- - else
- - returns m
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Rounding numbers one way or another
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp round (
- const matrix_exp& m
- );
- /*!
- requires
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- (i.e. m must contain a type like int, float, double, long, etc.)
- ensures
- - if (m contains integers) then
- - returns m unmodified
- - else
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == m(r,c) rounded to the nearest integral value
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp ceil (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::ceil(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp floor (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::floor(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp round_zeros (
- const matrix_exp& m
- );
- /*!
- requires
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- (i.e. m must contain a type like int, float, double, long, etc.)
- ensures
- - if (m contains integers) then
- - returns m unmodified
- - else
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - let eps == 10*std::numeric_limits<matrix_exp::type>::epsilon()
- - for all valid r and c:
- - if (abs(m(r,c)) >= eps) then
- - R(r,c) == m(r,c)
- - else
- - R(r,c) == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp round_zeros (
- const matrix_exp& m,
- matrix_exp::type eps
- );
- /*!
- requires
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- (i.e. m must contain a type like int, float, double, long, etc.)
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (abs(m(r,c)) >= eps) then
- - R(r,c) == m(r,c)
- - else
- - R(r,c) == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Complex number utility functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp conj (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == std::complex<T>
- ensures
- - returns a matrix R such that:
- - R::type == std::complex<T>
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::conj(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp norm (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == std::complex<T>
- ensures
- - returns a matrix R such that:
- - R::type == T
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::norm(m(r,c))
- (note that std::norm(val) == val.real()*val.real() + val.imag()*val.imag())
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp imag (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == std::complex<T>
- ensures
- - returns a matrix R such that:
- - R::type == T
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::imag(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp real (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == std::complex<T>
- ensures
- - returns a matrix R such that:
- - R::type == T
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::real(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp complex_matrix (
- const matrix_exp& real_part
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == std::complex<T> where T is whatever type real_part used.
- - R has the same dimensions as real_part.
- - for all valid r and c:
- R(r,c) == std::complex(real_part(r,c), 0)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp complex_matrix (
- const matrix_exp& real_part,
- const matrix_exp& imag_part
- );
- /*!
- requires
- - real_part.nr() == imag_part.nr()
- - real_part.nc() == imag_part.nc()
- - real_part and imag_part both contain the same type of element
- ensures
- - returns a matrix R such that:
- - R::type == std::complex<T> where T is whatever type real_part and imag_part used.
- - R has the same dimensions as real_part and imag_part
- - for all valid r and c:
- R(r,c) == std::complex(real_part(r,c),imag_part(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Trigonometric Functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp sin (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::sin(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp cos (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::cos(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp tan (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::tan(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp asin (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::asin(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp acos (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::acos(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp atan (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::atan(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp sinh (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::sinh(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp cosh (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::cosh(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp tanh (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == float, double, or long double
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R(r,c) == std::tanh(m(r,c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_MATH_FUNCTIONS_ABSTRACT_
-
diff --git a/ml/dlib/dlib/matrix/matrix_op.h b/ml/dlib/dlib/matrix/matrix_op.h
deleted file mode 100644
index 524a775eb..000000000
--- a/ml/dlib/dlib/matrix/matrix_op.h
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_OP_H_
-#define DLIB_MATRIx_OP_H_
-
-#include "matrix_exp.h"
-
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <typename OP >
- class matrix_op;
-
- template < typename OP >
- struct matrix_traits<matrix_op<OP> >
- {
- typedef typename OP::type type;
- typedef typename OP::const_ret_type const_ret_type;
- typedef typename OP::mem_manager_type mem_manager_type;
- typedef typename OP::layout_type layout_type;
- const static long NR = OP::NR;
- const static long NC = OP::NC;
- const static long cost = OP::cost;
- };
-
- template <
- typename OP
- >
- class matrix_op : public matrix_exp<matrix_op<OP> >
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- The matrix_op is simply a tool for reducing the amount of boilerplate
- you need to write when creating matrix expressions.
- !*/
-
- public:
- typedef typename matrix_traits<matrix_op>::type type;
- typedef typename matrix_traits<matrix_op>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_op>::mem_manager_type mem_manager_type;
- typedef typename matrix_traits<matrix_op>::layout_type layout_type;
- const static long NR = matrix_traits<matrix_op>::NR;
- const static long NC = matrix_traits<matrix_op>::NC;
- const static long cost = matrix_traits<matrix_op>::cost;
-
- private:
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of object.
- template <typename T1>
- matrix_op (T1);
- public:
-
- matrix_op (
- const OP& op_
- ) :
- op(op_)
- {}
-
- const_ret_type operator() (
- long r,
- long c
- ) const { return op.apply(r,c); }
-
- const_ret_type operator() ( long i ) const
- { return matrix_exp<matrix_op>::operator()(i); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return op.aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return op.destructively_aliases(item); }
-
- long nr (
- ) const { return op.nr(); }
-
- long nc (
- ) const { return op.nc(); }
-
-
- const OP op;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename OP >
- class matrix_diag_op;
-
- template < typename OP >
- struct matrix_traits<matrix_diag_op<OP> >
- {
- typedef typename OP::type type;
- typedef typename OP::const_ret_type const_ret_type;
- typedef typename OP::mem_manager_type mem_manager_type;
- typedef typename OP::layout_type layout_type;
- const static long NR = OP::NR;
- const static long NC = OP::NC;
- const static long cost = OP::cost;
- };
-
- template <
- typename OP
- >
- class matrix_diag_op : public matrix_diag_exp<matrix_diag_op<OP> >
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- The matrix_diag_op is simply a tool for reducing the amount of boilerplate
- you need to write when creating matrix expressions.
- !*/
-
- public:
- typedef typename matrix_traits<matrix_diag_op>::type type;
- typedef typename matrix_traits<matrix_diag_op>::const_ret_type const_ret_type;
- typedef typename matrix_traits<matrix_diag_op>::mem_manager_type mem_manager_type;
- typedef typename matrix_traits<matrix_diag_op>::layout_type layout_type;
- const static long NR = matrix_traits<matrix_diag_op>::NR;
- const static long NC = matrix_traits<matrix_diag_op>::NC;
- const static long cost = matrix_traits<matrix_diag_op>::cost;
-
- private:
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of object.
- template <typename T1>
- matrix_diag_op (T1);
- public:
-
- matrix_diag_op (
- const OP& op_
- ) :
- op(op_)
- {}
-
- const_ret_type operator() (
- long r,
- long c
- ) const { return op.apply(r,c); }
-
- const_ret_type operator() ( long i ) const
- { return matrix_exp<matrix_diag_op>::operator()(i); }
-
- template <typename U>
- bool aliases (
- const matrix_exp<U>& item
- ) const { return op.aliases(item); }
-
- template <typename U>
- bool destructively_aliases (
- const matrix_exp<U>& item
- ) const { return op.destructively_aliases(item); }
-
- long nr (
- ) const { return op.nr(); }
-
- long nc (
- ) const { return op.nc(); }
-
-
- const OP op;
- };
-
-// ----------------------------------------------------------------------------------------
-
- struct does_not_alias
- {
- /*!
- This is a partial implementation of a matrix operator that never aliases
- another expression.
- !*/
-
- template <typename U> bool aliases ( const U& ) const { return false; }
- template <typename U> bool destructively_aliases ( const U& ) const { return false; }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct basic_op_m
- {
- /*!
- This is a partial implementation of a matrix operator that preserves
- the dimensions of its argument and doesn't have destructive aliasing.
- !*/
-
- private:
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of object.
- template <typename T1>
- basic_op_m (T1);
- public:
-
- basic_op_m(
- const M& m_
- ) : m(m_){}
-
- const M& m;
-
- const static long NR = M::NR;
- const static long NC = M::NC;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m.destructively_aliases(item); }
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct basic_op_mm
- {
- /*!
- This is a partial implementation of a matrix operator that preserves
- the dimensions of its arguments and doesn't have destructive aliasing.
- !*/
-
- private:
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of object.
- template <typename T1, typename T2>
- basic_op_mm (T1, T2);
- public:
-
- basic_op_mm(
- const M1& m1_,
- const M2& m2_
- ) : m1(m1_), m2(m2_){}
-
- const M1& m1;
- const M2& m2;
-
- const static long NR = M1::NR;
- const static long NC = M1::NC;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- long nr () const { return m1.nr(); }
- long nc () const { return m1.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.destructively_aliases(item) || m2.destructively_aliases(item); }
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, typename M3>
- struct basic_op_mmm
- {
- /*!
- This is a partial implementation of a matrix operator that preserves
- the dimensions of its arguments and doesn't have destructive aliasing.
- !*/
-
- private:
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of object.
- template <typename T1, typename T2, typename T3>
- basic_op_mmm (T1, T2, T3);
- public:
-
- basic_op_mmm(
- const M1& m1_,
- const M2& m2_,
- const M3& m3_
- ) : m1(m1_), m2(m2_), m3(m3_){}
-
- const M1& m1;
- const M2& m2;
- const M3& m3;
-
- const static long NR = M1::NR;
- const static long NC = M1::NC;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- long nr () const { return m1.nr(); }
- long nc () const { return m1.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.destructively_aliases(item) || m2.destructively_aliases(item) ||
- m3.destructively_aliases(item);}
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, typename M3, typename M4>
- struct basic_op_mmmm
- {
- /*!
- This is a partial implementation of a matrix operator that preserves
- the dimensions of its arguments and doesn't have destructive aliasing.
- !*/
-
- private:
- // This constructor exists simply for the purpose of causing a compile time error if
- // someone tries to create an instance of this object with the wrong kind of object.
- template <typename T1, typename T2, typename T3, typename T4>
- basic_op_mmmm (T1, T2, T3, T4);
- public:
-
- basic_op_mmmm(
- const M1& m1_,
- const M2& m2_,
- const M3& m3_,
- const M4& m4_
- ) : m1(m1_), m2(m2_), m3(m3_), m4(m4_){}
-
- const M1& m1;
- const M2& m2;
- const M3& m3;
- const M4& m4;
-
- const static long NR = M1::NR;
- const static long NC = M1::NC;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- long nr () const { return m1.nr(); }
- long nc () const { return m1.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) || m4.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.destructively_aliases(item) || m2.destructively_aliases(item) ||
- m3.destructively_aliases(item) || m4.destructively_aliases(item);}
-
- };
-
-// ----------------------------------------------------------------------------------------
-
-#define DLIB_DEFINE_OP_M(op_name, function, extra_cost) \
- template <typename M> \
- struct op_name \
- { \
- op_name( \
- const M& m_ \
- ) : m(m_){} \
- \
- const M& m; \
- \
- const static long cost = M::cost+(extra_cost); \
- const static long NR = M::NR; \
- const static long NC = M::NC; \
- typedef typename M::type type; \
- typedef const typename M::type const_ret_type; \
- typedef typename M::mem_manager_type mem_manager_type; \
- typedef typename M::layout_type layout_type; \
- \
- const_ret_type apply (long r, long c) const { return function(m(r,c)); } \
- \
- long nr () const { return m.nr(); } \
- long nc () const { return m.nc(); } \
- \
- template <typename U> bool aliases ( const matrix_exp<U>& item) const \
- { return m.aliases(item); } \
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const \
- { return m.destructively_aliases(item); } \
- \
- }
-
-#define DLIB_DEFINE_FUNCTION_M(op_name, name, function, extra_cost) \
- DLIB_DEFINE_OP_M(op_name, function, extra_cost); \
- template < typename M > \
- const matrix_op<op_name<M> > name ( const matrix_exp<M>& m) \
- { \
- typedef op_name<M> op; \
- return matrix_op<op>(op(m.ref())); \
- }
-
-// ----------------------------------------------------------------------------------------
-
-#define DLIB_DEFINE_OP_MS(op_name, function, extra_cost) \
- template <typename M, typename S> \
- struct op_name \
- { \
- op_name( \
- const M& m_, \
- const S& s_ \
- ) : m(m_), s(s_){} \
- \
- const M& m; \
- const S s; \
- \
- const static long cost = M::cost+(extra_cost); \
- const static long NR = M::NR; \
- const static long NC = M::NC; \
- typedef typename M::type type; \
- typedef const typename M::type const_ret_type; \
- typedef typename M::mem_manager_type mem_manager_type; \
- typedef typename M::layout_type layout_type; \
- \
- const_ret_type apply (long r, long c) const { return function(m(r,c), s); } \
- \
- long nr () const { return m.nr(); } \
- long nc () const { return m.nc(); } \
- \
- template <typename U> bool aliases ( const matrix_exp<U>& item) const \
- { return m.aliases(item); } \
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const \
- { return m.destructively_aliases(item); } \
- \
- }
-
-#define DLIB_DEFINE_FUNCTION_MS(op_name, name, function, extra_cost) \
- DLIB_DEFINE_OP_MS(op_name, function, extra_cost); \
- template < typename M, typename S > \
- const matrix_op<op_name<M, S> > name ( const matrix_exp<M>& m, const S& s) \
- { \
- typedef op_name<M, S> op; \
- return matrix_op<op>(op(m.ref(), s)); \
- }
-
-// ----------------------------------------------------------------------------------------
-
-#define DLIB_DEFINE_OP_SM(op_name, function, extra_cost) \
- template <typename S, typename M> \
- struct op_name \
- { \
- op_name( \
- const S& s_, \
- const M& m_ \
- ) : m(m_), s(s_){} \
- \
- const M& m; \
- const S s; \
- \
- const static long cost = M::cost+(extra_cost); \
- const static long NR = M::NR; \
- const static long NC = M::NC; \
- typedef typename M::type type; \
- typedef const typename M::type const_ret_type; \
- typedef typename M::mem_manager_type mem_manager_type; \
- typedef typename M::layout_type layout_type; \
- \
- const_ret_type apply (long r, long c) const { return function(s, m(r,c)); } \
- \
- long nr () const { return m.nr(); } \
- long nc () const { return m.nc(); } \
- \
- template <typename U> bool aliases ( const matrix_exp<U>& item) const \
- { return m.aliases(item); } \
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const \
- { return m.destructively_aliases(item); } \
- \
- }
-
-#define DLIB_DEFINE_FUNCTION_SM(op_name, name, function, extra_cost) \
- DLIB_DEFINE_OP_SM(op_name, function, extra_cost); \
- template < typename S, typename M > \
- const matrix_op<op_name<S, M> > name (const S& s, const matrix_exp<M>& m) \
- { \
- typedef op_name<S, M> op; \
- return matrix_op<op>(op(s, m.ref())); \
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_OP_H_
-
diff --git a/ml/dlib/dlib/matrix/matrix_qr.h b/ml/dlib/dlib/matrix/matrix_qr.h
deleted file mode 100644
index 086d481f1..000000000
--- a/ml/dlib/dlib/matrix/matrix_qr.h
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright (C) 2009 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-// This code was adapted from code from the JAMA part of NIST's TNT library.
-// See: http://math.nist.gov/tnt/
-#ifndef DLIB_MATRIX_QR_DECOMPOSITION_H
-#define DLIB_MATRIX_QR_DECOMPOSITION_H
-
-#include "matrix.h"
-#include "matrix_utilities.h"
-#include "matrix_subexp.h"
-
-#ifdef DLIB_USE_LAPACK
-#include "lapack/geqrf.h"
-#include "lapack/ormqr.h"
-#endif
-
-#include "matrix_trsm.h"
-
-namespace dlib
-{
-
- template <
- typename matrix_exp_type
- >
- class qr_decomposition
- {
-
- public:
-
- const static long NR = matrix_exp_type::NR;
- const static long NC = matrix_exp_type::NC;
- typedef typename matrix_exp_type::type type;
- typedef typename matrix_exp_type::mem_manager_type mem_manager_type;
- typedef typename matrix_exp_type::layout_type layout_type;
-
- typedef matrix<type,0,0,mem_manager_type,layout_type> matrix_type;
-
- // You have supplied an invalid type of matrix_exp_type. You have
- // to use this object with matrices that contain float or double type data.
- COMPILE_TIME_ASSERT((is_same_type<float, type>::value ||
- is_same_type<double, type>::value ));
-
-
-
- template <typename EXP>
- qr_decomposition(
- const matrix_exp<EXP>& A
- );
-
- bool is_full_rank(
- ) const;
-
- long nr(
- ) const;
-
- long nc(
- ) const;
-
- const matrix_type get_r (
- ) const;
-
- const matrix_type get_q (
- ) const;
-
- template <typename T, long R, long C, typename MM, typename L>
- void get_q (
- matrix<T,R,C,MM,L>& Q
- ) const;
-
- template <typename EXP>
- const matrix_type solve (
- const matrix_exp<EXP>& B
- ) const;
-
- private:
-
-#ifndef DLIB_USE_LAPACK
- template <typename EXP>
- const matrix_type solve_mat (
- const matrix_exp<EXP>& B
- ) const;
-
- template <typename EXP>
- const matrix_type solve_vect (
- const matrix_exp<EXP>& B
- ) const;
-#endif
-
-
- /** Array for internal storage of decomposition.
- @serial internal array storage.
- */
- matrix<type,0,0,mem_manager_type,column_major_layout> QR_;
-
- /** Row and column dimensions.
- @serial column dimension.
- @serial row dimension.
- */
- long m, n;
-
- /** Array for internal storage of diagonal of R.
- @serial diagonal of R.
- */
- typedef matrix<type,0,1,mem_manager_type,column_major_layout> column_vector_type;
- column_vector_type tau;
- column_vector_type Rdiag;
-
-
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- qr_decomposition<matrix_exp_type>::
- qr_decomposition(
- const matrix_exp<EXP>& A
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<type, typename EXP::type>::value));
-
- // make sure requires clause is not broken
- DLIB_ASSERT(A.nr() >= A.nc() && A.size() > 0,
- "\tqr_decomposition::qr_decomposition(A)"
- << "\n\tInvalid inputs were given to this function"
- << "\n\tA.nr(): " << A.nr()
- << "\n\tA.nc(): " << A.nc()
- << "\n\tA.size(): " << A.size()
- << "\n\tthis: " << this
- );
-
-
- QR_ = A;
- m = A.nr();
- n = A.nc();
-
-#ifdef DLIB_USE_LAPACK
-
- lapack::geqrf(QR_, tau);
- Rdiag = diag(QR_);
-
-#else
- Rdiag.set_size(n);
- long i=0, j=0, k=0;
-
- // Main loop.
- for (k = 0; k < n; k++)
- {
- // Compute 2-norm of k-th column without under/overflow.
- type nrm = 0;
- for (i = k; i < m; i++)
- {
- nrm = hypot(nrm,QR_(i,k));
- }
-
- if (nrm != 0.0)
- {
- // Form k-th Householder vector.
- if (QR_(k,k) < 0)
- {
- nrm = -nrm;
- }
- for (i = k; i < m; i++)
- {
- QR_(i,k) /= nrm;
- }
- QR_(k,k) += 1.0;
-
- // Apply transformation to remaining columns.
- for (j = k+1; j < n; j++)
- {
- type s = 0.0;
- for (i = k; i < m; i++)
- {
- s += QR_(i,k)*QR_(i,j);
- }
- s = -s/QR_(k,k);
- for (i = k; i < m; i++)
- {
- QR_(i,j) += s*QR_(i,k);
- }
- }
- }
- Rdiag(k) = -nrm;
- }
-#endif
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- long qr_decomposition<matrix_exp_type>::
- nr (
- ) const
- {
- return m;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- long qr_decomposition<matrix_exp_type>::
- nc (
- ) const
- {
- return n;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- bool qr_decomposition<matrix_exp_type>::
- is_full_rank(
- ) const
- {
- type eps = max(abs(Rdiag));
- if (eps != 0)
- eps *= std::sqrt(std::numeric_limits<type>::epsilon())/100;
- else
- eps = 1; // there is no max so just use 1
-
- // check if any of the elements of Rdiag are effectively 0
- return min(abs(Rdiag)) > eps;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename qr_decomposition<matrix_exp_type>::matrix_type qr_decomposition<matrix_exp_type>::
- get_r(
- ) const
- {
- matrix_type R(n,n);
- for (long i = 0; i < n; i++)
- {
- for (long j = 0; j < n; j++)
- {
- if (i < j)
- {
- R(i,j) = QR_(i,j);
- }
- else if (i == j)
- {
- R(i,j) = Rdiag(i);
- }
- else
- {
- R(i,j) = 0.0;
- }
- }
- }
- return R;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- const typename qr_decomposition<matrix_exp_type>::matrix_type qr_decomposition<matrix_exp_type>::
- get_q(
- ) const
- {
- matrix_type Q;
- get_q(Q);
- return Q;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename T, long R, long C, typename MM, typename L>
- void qr_decomposition<matrix_exp_type>::
- get_q(
- matrix<T,R,C,MM,L>& X
- ) const
- {
-#ifdef DLIB_USE_LAPACK
- // Take only the first n columns of an identity matrix. This way
- // X ends up being an m by n matrix.
- X = colm(identity_matrix<type>(m), range(0,n-1));
-
- // Compute Y = Q*X
- lapack::ormqr('L','N', QR_, tau, X);
-
-#else
- long i=0, j=0, k=0;
-
- X.set_size(m,n);
- for (k = n-1; k >= 0; k--)
- {
- for (i = 0; i < m; i++)
- {
- X(i,k) = 0.0;
- }
- X(k,k) = 1.0;
- for (j = k; j < n; j++)
- {
- if (QR_(k,k) != 0)
- {
- type s = 0.0;
- for (i = k; i < m; i++)
- {
- s += QR_(i,k)*X(i,j);
- }
- s = -s/QR_(k,k);
- for (i = k; i < m; i++)
- {
- X(i,j) += s*QR_(i,k);
- }
- }
- }
- }
-#endif
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- const typename qr_decomposition<matrix_exp_type>::matrix_type qr_decomposition<matrix_exp_type>::
- solve(
- const matrix_exp<EXP>& B
- ) const
- {
- COMPILE_TIME_ASSERT((is_same_type<type, typename EXP::type>::value));
-
- // make sure requires clause is not broken
- DLIB_ASSERT(B.nr() == nr(),
- "\tconst matrix_type qr_decomposition::solve(B)"
- << "\n\tInvalid inputs were given to this function"
- << "\n\tB.nr(): " << B.nr()
- << "\n\tnr(): " << nr()
- << "\n\tthis: " << this
- );
-
-#ifdef DLIB_USE_LAPACK
-
- using namespace blas_bindings;
- matrix<type,0,0,mem_manager_type,column_major_layout> X(B);
- // Compute Y = transpose(Q)*B
- lapack::ormqr('L','T',QR_, tau, X);
- // Solve R*X = Y;
- triangular_solver(CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, QR_, X, n);
-
- /* return n x nx portion of X */
- return subm(X,0,0,n,B.nc());
-
-#else
- // just call the right version of the solve function
- if (B.nc() == 1)
- return solve_vect(B);
- else
- return solve_mat(B);
-#endif
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Private member functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-#ifndef DLIB_USE_LAPACK
-
- template <typename matrix_exp_type>
- template <typename EXP>
- const typename qr_decomposition<matrix_exp_type>::matrix_type qr_decomposition<matrix_exp_type>::
- solve_vect(
- const matrix_exp<EXP>& B
- ) const
- {
-
- column_vector_type x(B);
-
- // Compute Y = transpose(Q)*B
- for (long k = 0; k < n; k++)
- {
- type s = 0.0;
- for (long i = k; i < m; i++)
- {
- s += QR_(i,k)*x(i);
- }
- s = -s/QR_(k,k);
- for (long i = k; i < m; i++)
- {
- x(i) += s*QR_(i,k);
- }
- }
- // Solve R*X = Y;
- for (long k = n-1; k >= 0; k--)
- {
- x(k) /= Rdiag(k);
- for (long i = 0; i < k; i++)
- {
- x(i) -= x(k)*QR_(i,k);
- }
- }
-
-
- /* return n x 1 portion of x */
- return colm(x,0,n);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename matrix_exp_type>
- template <typename EXP>
- const typename qr_decomposition<matrix_exp_type>::matrix_type qr_decomposition<matrix_exp_type>::
- solve_mat(
- const matrix_exp<EXP>& B
- ) const
- {
- const long nx = B.nc();
- matrix_type X(B);
- long i=0, j=0, k=0;
-
- // Compute Y = transpose(Q)*B
- for (k = 0; k < n; k++)
- {
- for (j = 0; j < nx; j++)
- {
- type s = 0.0;
- for (i = k; i < m; i++)
- {
- s += QR_(i,k)*X(i,j);
- }
- s = -s/QR_(k,k);
- for (i = k; i < m; i++)
- {
- X(i,j) += s*QR_(i,k);
- }
- }
- }
- // Solve R*X = Y;
- for (k = n-1; k >= 0; k--)
- {
- for (j = 0; j < nx; j++)
- {
- X(k,j) /= Rdiag(k);
- }
- for (i = 0; i < k; i++)
- {
- for (j = 0; j < nx; j++)
- {
- X(i,j) -= X(k,j)*QR_(i,k);
- }
- }
- }
-
- /* return n x nx portion of X */
- return subm(X,0,0,n,nx);
- }
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_USE_LAPACK not defined
-
-}
-
-#endif // DLIB_MATRIX_QR_DECOMPOSITION_H
-
-
-
diff --git a/ml/dlib/dlib/matrix/matrix_read_from_istream.h b/ml/dlib/dlib/matrix/matrix_read_from_istream.h
deleted file mode 100644
index 3aced3584..000000000
--- a/ml/dlib/dlib/matrix/matrix_read_from_istream.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (C) 2013 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_READ_FROM_ISTREAM_H_h_
-#define DLIB_MATRIx_READ_FROM_ISTREAM_H_h_
-
-#include "matrix.h"
-#include <vector>
-#include <iostream>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- inline bool next_is_whitespace (
- std::istream& in
- )
- {
- return in.peek() == '\n' ||
- in.peek() == ' ' ||
- in.peek() == ',' ||
- in.peek() == '\t' ||
- in.peek() == '\r';
- }
- }
-
- template <typename T, long NR, long NC, typename MM, typename L>
- std::istream& operator>> (
- std::istream& in,
- matrix<T,NR,NC,MM,L>& m
- )
- {
- using namespace dlib::impl;
- long num_rows = 0;
- std::vector<T> buf;
- buf.reserve(100);
-
- // eat any leading whitespace
- while (next_is_whitespace(in))
- in.get();
-
- bool at_start_of_line = true;
- bool stop = false;
- while(!stop && in.peek() != EOF)
- {
- T temp;
- in >> temp;
- if (!in)
- return in;
-
- buf.push_back(temp);
- if (at_start_of_line)
- {
- at_start_of_line = false;
- ++num_rows;
- }
-
- // Eat next block of whitespace but also note if we hit the start of the next
- // line.
- while (next_is_whitespace(in))
- {
- if (at_start_of_line && in.peek() == '\n')
- {
- stop = true;
- break;
- }
-
- if (in.get() == '\n')
- at_start_of_line = true;
- }
- }
-
- // It's an error for there to not be any matrix data in the input stream
- if (num_rows == 0)
- {
- in.clear(in.rdstate() | std::ios::failbit);
- return in;
- }
-
- const long num_cols = buf.size()/num_rows;
- // It's also an error if the sizes don't make sense.
- if (num_rows*num_cols != (long)buf.size() ||
- (NR != 0 && NR != num_rows) ||
- (NC != 0 && NC != num_cols))
- {
- in.clear(in.rdstate() | std::ios::failbit);
- return in;
- }
-
-
- m = reshape(mat(buf),num_rows, buf.size()/num_rows);
-
- if (in.eof())
- {
- // Clear the eof and fail bits since this is caused by peeking at the EOF.
- // But in the current case, we have successfully read the matrix.
- in.clear(in.rdstate() & (~(std::ios::eofbit | std::ios::failbit)));
- }
- return in;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_MATRIx_READ_FROM_ISTREAM_H_h_
-
diff --git a/ml/dlib/dlib/matrix/matrix_subexp.h b/ml/dlib/dlib/matrix/matrix_subexp.h
deleted file mode 100644
index 668e57496..000000000
--- a/ml/dlib/dlib/matrix/matrix_subexp.h
+++ /dev/null
@@ -1,1566 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_SUBEXP_
-#define DLIB_MATRIx_SUBEXP_
-
-#include "matrix_subexp_abstract.h"
-#include "matrix_op.h"
-#include "matrix.h"
-#include "../geometry/rectangle.h"
-#include "matrix_expressions.h"
-#include "matrix_mat.h"
-
-
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <long start, long inc, long end>
- const matrix_range_static_exp<start,inc,end> range (
- )
- {
- COMPILE_TIME_ASSERT(inc > 0);
- return matrix_range_static_exp<start,inc,end>();
- }
-
- template <long start, long end>
- const matrix_range_static_exp<start,1,end> range (
- )
- {
- return matrix_range_static_exp<start,1,end>();
- }
-
- inline const matrix_range_exp<long> range (
- long start,
- long end
- )
- {
- return matrix_range_exp<long>(start,end);
- }
-
- inline const matrix_range_exp<long> range (
- long start,
- long inc,
- long end
- )
- {
- DLIB_ASSERT(inc > 0,
- "\tconst matrix_exp range(start, inc, end)"
- << "\n\tInvalid inputs to this function"
- << "\n\tstart: " << start
- << "\n\tinc: " << inc
- << "\n\tend: " << end
- );
-
- return matrix_range_exp<long>(start,inc,end);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_subm
- {
- op_subm (
- const M& m_x,
- const long& r_x,
- const long& c_x,
- const long& nr_x,
- const long& nc_x
- ) : m(m_x), r_(r_x), c_(c_x), nr_(nr_x), nc_(nc_x) { }
-
- const M& m;
- const long r_;
- const long c_;
- const long nr_;
- const long nc_;
-
- const static long cost = M::cost+1;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const static long NR = 0;
- const static long NC = 0;
-
- const_ret_type apply ( long r, long c) const { return m(r+r_,c+c_); }
-
- long nr () const { return nr_; }
- long nc () const { return nc_; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_subm<EXP> > subm (
- const matrix_exp<EXP>& m,
- long r,
- long c,
- long nr,
- long nc
- )
- {
- DLIB_ASSERT(r >= 0 && c >= 0 && nr >= 0 && nc >= 0 && r+nr <= m.nr() && c+nc <= m.nc(),
- "\tconst matrix_exp subm(const matrix_exp& m, r, c, nr, nc)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tr: " << r
- << "\n\tc: " << c
- << "\n\tnr: " << nr
- << "\n\tnc: " << nc
- );
-
- typedef op_subm<EXP> op;
- return matrix_op<op>(op(m.ref(),r,c,nr,nc));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix_op<op_subm<EXP> > subm_clipped (
- const matrix_exp<EXP>& m,
- long r,
- long c,
- long nr,
- long nc
- )
- {
- rectangle box(c,r,c+nc-1,r+nr-1);
- box = box.intersect(get_rect(m));
- typedef op_subm<EXP> op;
- return matrix_op<op>(op(m.ref(),box.top(),box.left(),box.height(),box.width()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix_op<op_subm<EXP> > subm (
- const matrix_exp<EXP>& m,
- const rectangle& rect
- )
- {
- DLIB_ASSERT(get_rect(m).contains(rect) == true,
- "\tconst matrix_exp subm(const matrix_exp& m, const rectangle& rect)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\trect.left(): " << rect.left()
- << "\n\trect.top(): " << rect.top()
- << "\n\trect.right(): " << rect.right()
- << "\n\trect.bottom(): " << rect.bottom()
- );
-
- typedef op_subm<EXP> op;
- return matrix_op<op>(op(m.ref(),rect.top(),rect.left(),rect.height(),rect.width()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix_op<op_subm<EXP> > subm_clipped (
- const matrix_exp<EXP>& m,
- rectangle rect
- )
- {
- rect = rect.intersect(get_rect(m));
-
- typedef op_subm<EXP> op;
- return matrix_op<op>(op(m.ref(),rect.top(),rect.left(),rect.height(),rect.width()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, typename M3>
- struct op_subm_range
- {
- op_subm_range( const M1& m1_, const M2& rows_, const M3& cols_) :
- m1(m1_), rows(rows_), cols(cols_) {}
- const M1& m1;
- const M2& rows;
- const M3& cols;
-
- const static long cost = M1::cost+M2::cost+M3::cost;
- typedef typename M1::type type;
- typedef typename M1::const_ret_type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
- const static long NR = M2::NC*M2::NR;
- const static long NC = M3::NC*M3::NR;
-
- const_ret_type apply ( long r, long c) const { return m1(rows(r),cols(c)); }
-
- long nr () const { return rows.size(); }
- long nc () const { return cols.size(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || rows.aliases(item) || cols.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || rows.aliases(item) || cols.aliases(item); }
- };
-
- template <
- typename EXP,
- typename EXPr,
- typename EXPc
- >
- const matrix_op<op_subm_range<EXP,EXPr,EXPc> > subm (
- const matrix_exp<EXP>& m,
- const matrix_exp<EXPr>& rows,
- const matrix_exp<EXPc>& cols
- )
- {
- // the rows and cols matrices must contain integer elements
- COMPILE_TIME_ASSERT(std::numeric_limits<typename EXPr::type>::is_integer);
- COMPILE_TIME_ASSERT(std::numeric_limits<typename EXPc::type>::is_integer);
-
- DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && 0 <= min(cols) && max(cols) < m.nc() &&
- (rows.nr() == 1 || rows.nc() == 1) && (cols.nr() == 1 || cols.nc() == 1),
- "\tconst matrix_exp subm(const matrix_exp& m, const matrix_exp& rows, const matrix_exp& cols)"
- << "\n\tYou have given invalid arguments to this function"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tmin(rows): " << min(rows)
- << "\n\tmax(rows): " << max(rows)
- << "\n\tmin(cols): " << min(cols)
- << "\n\tmax(cols): " << max(cols)
- << "\n\trows.nr(): " << rows.nr()
- << "\n\trows.nc(): " << rows.nc()
- << "\n\tcols.nr(): " << cols.nr()
- << "\n\tcols.nc(): " << cols.nc()
- );
-
- typedef op_subm_range<EXP,EXPr,EXPc> op;
- return matrix_op<op>(op(m.ref(),rows.ref(),cols.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_rowm
- {
- op_rowm(const M& m_, const long& row_) : m(m_), row(row_) {}
- const M& m;
- const long row;
-
- const static long cost = M::cost;
- const static long NR = 1;
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long, long c) const { return m(row,c); }
-
- long nr () const { return 1; }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_rowm<EXP> > rowm (
- const matrix_exp<EXP>& m,
- long row
- )
- {
- DLIB_ASSERT(row >= 0 && row < m.nr(),
- "\tconst matrix_exp rowm(const matrix_exp& m, row)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\trow: " << row
- );
-
- typedef op_rowm<EXP> op;
- return matrix_op<op>(op(m.ref(),row));
- }
-
- template <typename EXP>
- struct rowm_exp
- {
- typedef matrix_op<op_rowm<EXP> > type;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_rowm2
- {
- op_rowm2(const M& m_, const long& row_, const long& len) : m(m_), row(row_), length(len) {}
- const M& m;
- const long row;
- const long length;
-
- const static long cost = M::cost;
- const static long NR = 1;
- const static long NC = 0;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long , long c) const { return m(row,c); }
-
- long nr () const { return 1; }
- long nc () const { return length; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_rowm2<EXP> > rowm (
- const matrix_exp<EXP>& m,
- long row,
- long length
- )
- {
- DLIB_ASSERT(row >= 0 && row < m.nr() &&
- length >= 0 && length <= m.nc(),
- "\tconst matrix_exp rowm(const matrix_exp& m, row, length)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\trow: " << row
- << "\n\tlength: " << length
- );
-
- typedef op_rowm2<EXP> op;
- return matrix_op<op>(op(m.ref(), row, length));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_rowm_range
- {
- op_rowm_range( const M1& m1_, const M2& rows_) : m1(m1_), rows(rows_) {}
- const M1& m1;
- const M2& rows;
-
- const static long cost = M1::cost+M2::cost;
- typedef typename M1::type type;
- typedef typename M1::const_ret_type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
- const static long NR = M2::NC*M2::NR;
- const static long NC = M1::NC;
-
- const_ret_type apply ( long r, long c) const { return m1(rows(r),c); }
-
- long nr () const { return rows.size(); }
- long nc () const { return m1.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || rows.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || rows.aliases(item); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- const matrix_op<op_rowm_range<EXP1,EXP2> > rowm (
- const matrix_exp<EXP1>& m,
- const matrix_exp<EXP2>& rows
- )
- {
- // the rows matrix must contain integer elements
- COMPILE_TIME_ASSERT(std::numeric_limits<typename EXP2::type>::is_integer);
-
- DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && (rows.nr() == 1 || rows.nc() == 1),
- "\tconst matrix_exp rowm(const matrix_exp& m, const matrix_exp& rows)"
- << "\n\tYou have given invalid arguments to this function"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tmin(rows): " << min(rows)
- << "\n\tmax(rows): " << max(rows)
- << "\n\trows.nr(): " << rows.nr()
- << "\n\trows.nc(): " << rows.nc()
- );
-
- typedef op_rowm_range<EXP1,EXP2> op;
- return matrix_op<op>(op(m.ref(),rows.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_colm
- {
- op_colm(const M& m_, const long& col_) : m(m_), col(col_) {}
- const M& m;
- const long col;
-
- const static long cost = M::cost;
- const static long NR = M::NR;
- const static long NC = 1;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long) const { return m(r,col); }
-
- long nr () const { return m.nr(); }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_colm<EXP> > colm (
- const matrix_exp<EXP>& m,
- long col
- )
- {
- DLIB_ASSERT(col >= 0 && col < m.nc(),
- "\tconst matrix_exp colm(const matrix_exp& m, row)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tcol: " << col
- );
-
- typedef op_colm<EXP> op;
- return matrix_op<op>(op(m.ref(),col));
- }
-
- template <typename EXP>
- struct colm_exp
- {
- typedef matrix_op<op_colm<EXP> > type;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_colm2
- {
- op_colm2(const M& m_, const long& col_, const long& len) : m(m_), col(col_), length(len) {}
- const M& m;
- const long col;
- const long length;
-
- const static long cost = M::cost;
- const static long NR = 0;
- const static long NC = 1;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long ) const { return m(r,col); }
-
- long nr () const { return length; }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_colm2<EXP> > colm (
- const matrix_exp<EXP>& m,
- long col,
- long length
- )
- {
- DLIB_ASSERT(col >= 0 && col < m.nc() &&
- length >= 0 && length <= m.nr(),
- "\tconst matrix_exp colm(const matrix_exp& m, col, length)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tcol: " << col
- << "\n\tlength: " << length
- );
-
- typedef op_colm2<EXP> op;
- return matrix_op<op>(op(m.ref(),col, length));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_colm_range
- {
- op_colm_range( const M1& m1_, const M2& cols_) : m1(m1_), cols(cols_) {}
- const M1& m1;
- const M2& cols;
-
- typedef typename M1::type type;
- typedef typename M1::const_ret_type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
- const static long NR = M1::NR;
- const static long NC = M2::NC*M2::NR;
- const static long cost = M1::cost+M2::cost;
-
- const_ret_type apply (long r, long c) const { return m1(r,cols(c)); }
-
- long nr () const { return m1.nr(); }
- long nc () const { return cols.size(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || cols.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || cols.aliases(item); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- const matrix_op<op_colm_range<EXP1,EXP2> > colm (
- const matrix_exp<EXP1>& m,
- const matrix_exp<EXP2>& cols
- )
- {
- // the rows matrix must contain integer elements
- COMPILE_TIME_ASSERT(std::numeric_limits<typename EXP2::type>::is_integer);
-
- DLIB_ASSERT(0 <= min(cols) && max(cols) < m.nc() && (cols.nr() == 1 || cols.nc() == 1),
- "\tconst matrix_exp colm(const matrix_exp& m, const matrix_exp& cols)"
- << "\n\tYou have given invalid arguments to this function"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tmin(cols): " << min(cols)
- << "\n\tmax(cols): " << max(cols)
- << "\n\tcols.nr(): " << cols.nr()
- << "\n\tcols.nc(): " << cols.nc()
- );
-
- typedef op_colm_range<EXP1,EXP2> op;
- return matrix_op<op>(op(m.ref(),cols.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- class assignable_ptr_matrix
- {
- public:
- typedef T type;
- typedef row_major_layout layout_type;
- typedef matrix<T,0,0,default_memory_manager,layout_type> matrix_type;
-
- assignable_ptr_matrix(
- T* ptr_,
- long nr_,
- long nc_
- ) : ptr(ptr_), height(nr_), width(nc_){}
-
- T& operator() (
- long r,
- long c
- )
- {
- return ptr[r*width + c];
- }
-
- const T& operator() (
- long r,
- long c
- ) const
- {
- return ptr[r*width + c];
- }
-
- long nr() const { return height; }
- long nc() const { return width; }
-
- template <typename EXP>
- assignable_ptr_matrix& operator= (
- const matrix_exp<EXP>& exp
- )
- {
- // You can only assign to a set_ptrm() expression with a source matrix that
- // contains the same type of elements as the target (i.e. you can't mix double
- // and float types).
- COMPILE_TIME_ASSERT((is_same_type<T, typename EXP::type>::value == true));
-
- DLIB_ASSERT( exp.nr() == height && exp.nc() == width,
- "\tassignable_matrix_expression set_ptrm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\twidth (target matrix): " << width
- << "\n\theight (target matrix): " << height
- );
-
- if (exp.destructively_aliases(mat(ptr,height,width)) == false)
- {
- matrix_assign(*this, exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to ptr to
- // avoid aliasing issues during the copy
- this->operator=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_ptr_matrix& operator+= (
- const matrix_exp<EXP>& exp
- )
- {
- // You can only assign to a set_ptrm() expression with a source matrix that
- // contains the same type of elements as the target (i.e. you can't mix double
- // and float types).
- COMPILE_TIME_ASSERT((is_same_type<T, typename EXP::type>::value == true));
-
- DLIB_ASSERT( exp.nr() == height && exp.nc() == width,
- "\tassignable_matrix_expression set_ptrm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\twidth (target matrix): " << width
- << "\n\theight (target matrix): " << height
- );
-
- if (exp.destructively_aliases(mat(ptr,height,width)) == false)
- {
- matrix_assign(*this, mat(ptr,height,width)+exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to ptr to
- // avoid aliasing issues during the copy
- this->operator+=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_ptr_matrix& operator-= (
- const matrix_exp<EXP>& exp
- )
- {
- // You can only assign to a set_ptrm() expression with a source matrix that
- // contains the same type of elements as the target (i.e. you can't mix double
- // and float types).
- COMPILE_TIME_ASSERT((is_same_type<T, typename EXP::type>::value == true));
-
- DLIB_ASSERT( exp.nr() == height && exp.nc() == width,
- "\tassignable_matrix_expression set_ptrm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\twidth (target matrix): " << width
- << "\n\theight (target matrix): " << height
- );
-
- if (exp.destructively_aliases(mat(ptr,height,width)) == false)
- {
- matrix_assign(*this, mat(ptr,height,width)-exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to ptr to
- // avoid aliasing issues during the copy
- this->operator-=(tmp(exp));
- }
-
- return *this;
- }
-
- assignable_ptr_matrix& operator= (
- const T& value
- )
- {
- const long size = width*height;
- for (long i = 0; i < size; ++i)
- ptr[i] = value;
-
- return *this;
- }
-
- assignable_ptr_matrix& operator+= (
- const T& value
- )
- {
- const long size = width*height;
- for (long i = 0; i < size; ++i)
- ptr[i] += value;
-
- return *this;
- }
-
- assignable_ptr_matrix& operator-= (
- const T& value
- )
- {
- const long size = width*height;
- for (long i = 0; i < size; ++i)
- ptr[i] -= value;
-
- return *this;
- }
-
-
- T* ptr;
- const long height;
- const long width;
- };
-
-
- template <typename T>
- assignable_ptr_matrix<T> set_ptrm (
- T* ptr,
- long nr,
- long nc = 1
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0,
- "\t assignable_matrix_expression set_ptrm(T* ptr, long nr, long nc)"
- << "\n\t The dimensions can't be negative."
- << "\n\t nr: " << nr
- << "\n\t nc: " << nc
- );
-
-
- return assignable_ptr_matrix<T>(ptr,nr,nc);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T, long NR, long NC, typename mm, typename l>
- class assignable_sub_matrix
- {
- public:
- typedef T type;
- typedef l layout_type;
- typedef matrix<T,NR,NC,mm,l> matrix_type;
-
- assignable_sub_matrix(
- matrix<T,NR,NC,mm,l>& m_,
- long top_,
- long left_,
- long height_,
- long width_
- ) : m(m_), left(left_), top(top_), width(width_), height(height_) {}
-
- T& operator() (
- long r,
- long c
- )
- {
- return m(r+top,c+left);
- }
-
- const T& operator() (
- long r,
- long c
- ) const
- {
- return m(r+top,c+left);
- }
-
- long nr() const { return height; }
- long nc() const { return width; }
-
- template <typename EXP>
- assignable_sub_matrix& operator= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == height && exp.nc() == width,
- "\tassignable_matrix_expression set_subm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\twidth (target matrix): " << width
- << "\n\theight (target matrix): " << height
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_sub_matrix& operator+= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == height && exp.nc() == width,
- "\tassignable_matrix_expression set_subm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\twidth (target matrix): " << width
- << "\n\theight (target matrix): " << height
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, subm(m,top,left,height,width)+exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator+=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_sub_matrix& operator-= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == height && exp.nc() == width,
- "\tassignable_matrix_expression set_subm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\twidth (target matrix): " << width
- << "\n\theight (target matrix): " << height
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, subm(m,top,left,height,width)-exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator-=(tmp(exp));
- }
-
- return *this;
- }
-
- assignable_sub_matrix& operator= (
- const T& value
- )
- {
- const long bottom = top+height-1;
- const long right = left+width-1;
- for (long r = top; r <= bottom; ++r)
- {
- for (long c = left; c <= right; ++c)
- {
- m(r,c) = value;
- }
- }
-
- return *this;
- }
-
- assignable_sub_matrix& operator+= (
- const T& value
- )
- {
- const long bottom = top+height-1;
- const long right = left+width-1;
- for (long r = top; r <= bottom; ++r)
- {
- for (long c = left; c <= right; ++c)
- {
- m(r,c) += value;
- }
- }
-
- return *this;
- }
-
- assignable_sub_matrix& operator-= (
- const T& value
- )
- {
- const long bottom = top+height-1;
- const long right = left+width-1;
- for (long r = top; r <= bottom; ++r)
- {
- for (long c = left; c <= right; ++c)
- {
- m(r,c) -= value;
- }
- }
-
- return *this;
- }
-
-
- matrix<T,NR,NC,mm,l>& m;
- const long left, top, width, height;
- };
-
-
- template <typename T, long NR, long NC, typename mm, typename l>
- assignable_sub_matrix<T,NR,NC,mm,l> set_subm (
- matrix<T,NR,NC,mm,l>& m,
- const rectangle& rect
- )
- {
- DLIB_ASSERT(get_rect(m).contains(rect) == true,
- "\tassignable_matrix_expression set_subm(matrix& m, const rectangle& rect)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\trect.left(): " << rect.left()
- << "\n\trect.top(): " << rect.top()
- << "\n\trect.right(): " << rect.right()
- << "\n\trect.bottom(): " << rect.bottom()
- );
-
-
- return assignable_sub_matrix<T,NR,NC,mm,l>(m,rect.top(), rect.left(), rect.height(), rect.width());
- }
-
-
- template <typename T, long NR, long NC, typename mm, typename l>
- assignable_sub_matrix<T,NR,NC,mm,l> set_subm (
- matrix<T,NR,NC,mm,l>& m,
- long r,
- long c,
- long nr,
- long nc
- )
- {
- DLIB_ASSERT(r >= 0 && c >= 0 && nr >= 0 && nc >= 0 && r+nr <= m.nr() && c+nc <= m.nc(),
- "\tassignable_matrix_expression set_subm(matrix& m, r, c, nr, nc)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tr: " << r
- << "\n\tc: " << c
- << "\n\tnr: " << nr
- << "\n\tnc: " << nc
- );
-
- return assignable_sub_matrix<T,NR,NC,mm,l>(m,r,c, nr, nc);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T, long NR, long NC, typename mm, typename l, typename EXPr, typename EXPc>
- class assignable_sub_range_matrix
- {
- public:
- typedef T type;
- typedef l layout_type;
- typedef matrix<T,NR,NC,mm,l> matrix_type;
-
- assignable_sub_range_matrix(
- matrix<T,NR,NC,mm,l>& m_,
- const EXPr& rows_,
- const EXPc& cols_
- ) : m(m_), rows(rows_), cols(cols_) {}
-
- T& operator() (
- long r,
- long c
- )
- {
- return m(rows(r),cols(c));
- }
-
- long nr() const { return rows.size(); }
- long nc() const { return cols.size(); }
-
-
- template <typename EXP>
- assignable_sub_range_matrix& operator= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == rows.size() && exp.nc() == cols.size(),
- "\tassignable_matrix_expression set_subm(matrix& m, const matrix_exp rows, const matrix_exp cols)"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\trows.size() (target matrix): " << rows.size()
- << "\n\tcols.size() (target matrix): " << cols.size()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_sub_range_matrix& operator+= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == rows.size() && exp.nc() == cols.size(),
- "\tassignable_matrix_expression set_subm(matrix& m, const matrix_exp rows, const matrix_exp cols)"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\trows.size() (target matrix): " << rows.size()
- << "\n\tcols.size() (target matrix): " << cols.size()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, subm(m,rows,cols)+exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator+=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_sub_range_matrix& operator-= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == rows.size() && exp.nc() == cols.size(),
- "\tassignable_matrix_expression set_subm(matrix& m, const matrix_exp rows, const matrix_exp cols)"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\trows.size() (target matrix): " << rows.size()
- << "\n\tcols.size() (target matrix): " << cols.size()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, subm(m,rows,cols)-exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator-=(tmp(exp));
- }
-
- return *this;
- }
-
- assignable_sub_range_matrix& operator= (
- const T& value
- )
- {
- for (long r = 0; r < rows.size(); ++r)
- {
- for (long c = 0; c < cols.size(); ++c)
- {
- m(rows(r),cols(c)) = value;
- }
- }
-
- return *this;
- }
-
- assignable_sub_range_matrix& operator+= (
- const T& value
- )
- {
- for (long r = 0; r < rows.size(); ++r)
- {
- for (long c = 0; c < cols.size(); ++c)
- {
- m(rows(r),cols(c)) += value;
- }
- }
-
- return *this;
- }
-
- assignable_sub_range_matrix& operator-= (
- const T& value
- )
- {
- for (long r = 0; r < rows.size(); ++r)
- {
- for (long c = 0; c < cols.size(); ++c)
- {
- m(rows(r),cols(c)) -= value;
- }
- }
-
- return *this;
- }
-
- private:
-
- matrix<T,NR,NC,mm,l>& m;
- const EXPr rows;
- const EXPc cols;
- };
-
- template <typename T, long NR, long NC, typename mm, typename l, typename EXPr, typename EXPc>
- assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,EXPc > set_subm (
- matrix<T,NR,NC,mm,l>& m,
- const matrix_exp<EXPr>& rows,
- const matrix_exp<EXPc>& cols
- )
- {
- DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && 0 <= min(cols) && max(cols) < m.nc() &&
- (rows.nr() == 1 || rows.nc() == 1) && (cols.nr() == 1 || cols.nc() == 1),
- "\tassignable_matrix_expression set_subm(matrix& m, const matrix_exp& rows, const matrix_exp& cols)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tmin(rows): " << min(rows)
- << "\n\tmax(rows): " << max(rows)
- << "\n\tmin(cols): " << min(cols)
- << "\n\tmax(cols): " << max(cols)
- << "\n\trows.nr(): " << rows.nr()
- << "\n\trows.nc(): " << rows.nc()
- << "\n\tcols.nr(): " << cols.nr()
- << "\n\tcols.nc(): " << cols.nc()
- );
-
- return assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,EXPc >(m,rows.ref(),cols.ref());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T, long NR, long NC, typename mm, typename l, typename EXPr>
- assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,matrix_range_exp<long> > set_rowm (
- matrix<T,NR,NC,mm,l>& m,
- const matrix_exp<EXPr>& rows
- )
- {
- DLIB_ASSERT(0 <= min(rows) && max(rows) < m.nr() && (rows.nr() == 1 || rows.nc() == 1),
- "\tassignable_matrix_expression set_rowm(matrix& m, const matrix_exp& rows)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tmin(rows): " << min(rows)
- << "\n\tmax(rows): " << max(rows)
- << "\n\trows.nr(): " << rows.nr()
- << "\n\trows.nc(): " << rows.nc()
- );
-
- return assignable_sub_range_matrix<T,NR,NC,mm,l,EXPr,matrix_range_exp<long> >(m,rows.ref(),range(0,m.nc()-1));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T, long NR, long NC, typename mm, typename l, typename EXPc>
- assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_range_exp<long>,EXPc > set_colm (
- matrix<T,NR,NC,mm,l>& m,
- const matrix_exp<EXPc>& cols
- )
- {
- DLIB_ASSERT(0 <= min(cols) && max(cols) < m.nc() && (cols.nr() == 1 || cols.nc() == 1),
- "\tassignable_matrix_expression set_colm(matrix& m, const matrix_exp& cols)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tmin(cols): " << min(cols)
- << "\n\tmax(cols): " << max(cols)
- << "\n\tcols.nr(): " << cols.nr()
- << "\n\tcols.nc(): " << cols.nc()
- );
-
- return assignable_sub_range_matrix<T,NR,NC,mm,l,matrix_range_exp<long>,EXPc >(m,range(0,m.nr()-1),cols.ref());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T, long NR, long NC, typename mm, typename l>
- class assignable_col_matrix
- {
- public:
- typedef T type;
- typedef l layout_type;
- typedef matrix<T,NR,NC,mm,l> matrix_type;
-
- assignable_col_matrix(
- matrix<T,NR,NC,mm,l>& m_,
- const long col_
- ) : m(m_), col(col_) {}
-
- T& operator() (
- long r,
- long
- )
- {
- return m(r,col);
- }
-
- const T& operator() (
- long r,
- long
- ) const
- {
- return m(r,col);
- }
-
- long nr() const { return m.nr(); }
- long nc() const { return 1; }
-
- template <typename EXP>
- assignable_col_matrix& operator= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nc() == 1 && exp.nr() == m.nr(),
- "\tassignable_matrix_expression set_colm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\tm.nr() (target matrix): " << m.nr()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_col_matrix& operator+= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nc() == 1 && exp.nr() == m.nr(),
- "\tassignable_matrix_expression set_colm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\tm.nr() (target matrix): " << m.nr()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, colm(m,col)+exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator+=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_col_matrix& operator-= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nc() == 1 && exp.nr() == m.nr(),
- "\tassignable_matrix_expression set_colm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\tm.nr() (target matrix): " << m.nr()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, colm(m,col)-exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator-=(tmp(exp));
- }
-
- return *this;
- }
-
- assignable_col_matrix& operator= (
- const T& value
- )
- {
- for (long i = 0; i < m.nr(); ++i)
- {
- m(i,col) = value;
- }
-
- return *this;
- }
-
- assignable_col_matrix& operator+= (
- const T& value
- )
- {
- for (long i = 0; i < m.nr(); ++i)
- {
- m(i,col) += value;
- }
-
- return *this;
- }
-
- assignable_col_matrix& operator-= (
- const T& value
- )
- {
- for (long i = 0; i < m.nr(); ++i)
- {
- m(i,col) -= value;
- }
-
- return *this;
- }
-
-
- matrix<T,NR,NC,mm,l>& m;
- const long col;
- };
-
-
- template <typename T, long NR, long NC, typename mm, typename l>
- assignable_col_matrix<T,NR,NC,mm,l> set_colm (
- matrix<T,NR,NC,mm,l>& m,
- const long col
- )
- {
- DLIB_ASSERT(col >= 0 && col < m.nc(),
- "\tassignable_matrix_expression set_colm(matrix& m, col)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tcol: " << col
- );
-
-
- return assignable_col_matrix<T,NR,NC,mm,l>(m,col);
- }
-
-// ----------------------------------------------------------------------------------------
-
-
- template <typename T, long NR, long NC, typename mm, typename l>
- class assignable_row_matrix
- {
- public:
- typedef T type;
- typedef l layout_type;
- typedef matrix<T,NR,NC,mm,l> matrix_type;
-
- assignable_row_matrix(
- matrix<T,NR,NC,mm,l>& m_,
- const long row_
- ) : m(m_), row(row_) {}
-
-
- T& operator() (
- long ,
- long c
- )
- {
- return m(row,c);
- }
-
- const T& operator() (
- long ,
- long c
- ) const
- {
- return m(row,c);
- }
-
- long nr() const { return 1; }
- long nc() const { return m.nc(); }
-
-
- template <typename EXP>
- assignable_row_matrix& operator= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == 1 && exp.nc() == m.nc(),
- "\tassignable_matrix_expression set_rowm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\tm.nc() (target matrix): " << m.nc()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_row_matrix& operator+= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == 1 && exp.nc() == m.nc(),
- "\tassignable_matrix_expression set_rowm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\tm.nc() (target matrix): " << m.nc()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, rowm(m,row)+exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator+=(tmp(exp));
- }
-
- return *this;
- }
-
- template <typename EXP>
- assignable_row_matrix& operator-= (
- const matrix_exp<EXP>& exp
- )
- {
- DLIB_ASSERT( exp.nr() == 1 && exp.nc() == m.nc(),
- "\tassignable_matrix_expression set_rowm()"
- << "\n\tYou have tried to assign to this object using a matrix that isn't the right size"
- << "\n\texp.nr() (source matrix): " << exp.nr()
- << "\n\texp.nc() (source matrix): " << exp.nc()
- << "\n\tm.nc() (target matrix): " << m.nc()
- );
-
- if (exp.destructively_aliases(m) == false)
- {
- matrix_assign(*this, rowm(m,row)-exp);
- }
- else
- {
- // make a temporary copy of the matrix we are going to assign to m to
- // avoid aliasing issues during the copy
- this->operator-=(tmp(exp));
- }
-
- return *this;
- }
-
- assignable_row_matrix& operator= (
- const T& value
- )
- {
- for (long i = 0; i < m.nc(); ++i)
- {
- m(row,i) = value;
- }
-
- return *this;
- }
-
- assignable_row_matrix& operator+= (
- const T& value
- )
- {
- for (long i = 0; i < m.nc(); ++i)
- {
- m(row,i) += value;
- }
-
- return *this;
- }
-
- assignable_row_matrix& operator-= (
- const T& value
- )
- {
- for (long i = 0; i < m.nc(); ++i)
- {
- m(row,i) -= value;
- }
-
- return *this;
- }
-
-
- matrix<T,NR,NC,mm,l>& m;
- const long row;
- };
-
-
- template <typename T, long NR, long NC, typename mm, typename l>
- assignable_row_matrix<T,NR,NC,mm,l> set_rowm (
- matrix<T,NR,NC,mm,l>& m,
- const long row
- )
- {
- DLIB_ASSERT(row >= 0 && row < m.nr(),
- "\tassignable_matrix_expression set_rowm(matrix& m, row)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\trow: " << row
- );
-
-
- return assignable_row_matrix<T,NR,NC,mm,l>(m,row);
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_SUBEXP_
-
diff --git a/ml/dlib/dlib/matrix/matrix_subexp_abstract.h b/ml/dlib/dlib/matrix/matrix_subexp_abstract.h
deleted file mode 100644
index 2665d1b99..000000000
--- a/ml/dlib/dlib/matrix/matrix_subexp_abstract.h
+++ /dev/null
@@ -1,570 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_SUBEXP_ABSTRACT_
-#ifdef DLIB_MATRIx_SUBEXP_ABSTRACT_
-
-#include "matrix_abstract.h"
-#include "../geometry/rectangle.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <long start, long inc, long end>
- const matrix_exp range (
- );
- /*!
- requires
- - inc > 0
- ensures
- - returns a matrix R such that:
- - R::type == long
- - R.nr() == 1
- - R.nc() == abs(end - start)/inc + 1
- - if (start <= end) then
- - R(i) == start + i*inc
- - else
- - R(i) == start - i*inc
- !*/
-
- template <long start, long end>
- const matrix_exp range (
- ) { return range<start,1,end>(); }
-
- const matrix_exp range (
- long start,
- long inc,
- long end
- );
- /*!
- requires
- - inc > 0
- ensures
- - returns a matrix R such that:
- - R::type == long
- - R.nr() == 1
- - R.nc() == abs(end - start)/inc + 1
- - if (start <= end) then
- - R(i) == start + i*inc
- - else
- - R(i) == start - i*inc
- !*/
-
- const matrix_exp range (
- long start,
- long end
- ) { return range(start,1,end); }
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp subm (
- const matrix_exp& m,
- const matrix_exp& rows,
- const matrix_exp& cols,
- );
- /*!
- requires
- - rows and cols contain integral elements (e.g. int, long)
- - 0 <= min(rows) && max(rows) < m.nr()
- - 0 <= min(cols) && max(cols) < m.nc()
- - rows.nr() == 1 || rows.nc() == 1
- - cols.nr() == 1 || cols.nc() == 1
- (i.e. rows and cols must be vectors)
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R.nr() == rows.size()
- - R.nc() == cols.size()
- - for all valid r and c:
- R(r,c) == m(rows(r),cols(c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp subm (
- const matrix_exp& m,
- long row,
- long col,
- long nr,
- long nc
- );
- /*!
- requires
- - row >= 0
- - col >= 0
- - nr >= 0
- - nc >= 0
- - row + nr <= m.nr()
- - col + nc <= m.nc()
- ensures
- - returns a matrix R such that:
- - R.nr() == nr
- - R.nc() == nc
- - for all valid r and c:
- R(r, c) == m(r+row,c+col)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp subm (
- const matrix_exp& m,
- const rectangle& rect
- );
- /*!
- requires
- - get_rect(m).contains(rect) == true
- (i.e. rect is a region inside the matrix m)
- ensures
- - returns a matrix R such that:
- - R.nr() == rect.height()
- - R.nc() == rect.width()
- - for all valid r and c:
- R(r, c) == m(r+rect.top(), c+rect.left())
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp subm_clipped (
- const matrix_exp& m,
- long row,
- long col,
- long nr,
- long nc
- );
- /*!
- ensures
- - This function is just like subm() except that it will automatically clip the
- indicated sub matrix window so that it does not extend outside m.
- In particular:
- - Let box = rectangle(col,row,col+nc-1,row+nr-1)
- (i.e. the box that contains the indicated sub matrix)
- - Let box_clipped = box.intersect(get_rect(m))
- - Then this function returns a matrix R such that:
- - R.nr() == box_clipped.height()
- - R.nc() == box_clipped.width()
- - for all valid r and c:
- R(r, c) == m(r+box_clipped.top(),c+box_clipped.left())
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp subm_clipped (
- const matrix_exp& m,
- const rectangle& rect
- );
- /*!
- ensures
- - Let box_clipped == rect.intersect(get_rect(m))
- - returns a matrix R such that:
- - R.nr() == box_clipped.height()
- - R.nc() == box_clipped.width()
- - for all valid r and c:
- R(r, c) == m(r+box_clipped.top(), c+box_clipped.left())
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp rowm (
- const matrix_exp& m,
- long row
- );
- /*!
- requires
- - 0 <= row < m.nr()
- ensures
- - returns a matrix R such that:
- - R.nr() == 1
- - R.nc() == m.nc()
- - for all valid i:
- R(i) == m(row,i)
- !*/
-
- template <typename EXP>
- struct rowm_exp
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This struct allows you to determine the type of matrix expression
- object returned from the rowm(m,row) function. An example makes its
- use clear:
-
- template <typename EXP>
- void do_something( const matrix_exp<EXP>& mat)
- {
- // r is a matrix expression that aliases mat.
- typename rowm_exp<EXP>::type r = rowm(mat,0);
-
- // Print the first row of mat. So we see that by using
- // rowm_exp we can save the object returned by rowm() in
- // a local variable.
- cout << r << endl;
-
- // Note that you can only save the return value of rowm() to
- // a local variable if the argument to rowm() has a lifetime
- // beyond the rowm() expression. The example shown above is
- // OK but the following would result in undefined behavior:
- typename rowm_exp<EXP>::type bad = rowm(mat + mat,0);
- }
- !*/
- typedef type_of_expression_returned_by_rowm type;
- };
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp rowm (
- const matrix_exp& m,
- long row,
- long length
- );
- /*!
- requires
- - 0 <= row < m.nr()
- - 0 <= length <= m.nc()
- ensures
- - returns a matrix R such that:
- - R.nr() == 1
- - R.nc() == length
- - for all valid i:
- R(i) == m(row,i)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp rowm (
- const matrix_exp& m,
- const matrix_exp& rows
- );
- /*!
- requires
- - rows contains integral elements (e.g. int, long)
- - 0 <= min(rows) && max(rows) < m.nr()
- - rows.nr() == 1 || rows.nc() == 1
- (i.e. rows must be a vector)
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R.nr() == rows.size()
- - R.nc() == m.nc()
- - for all valid r and c:
- R(r,c) == m(rows(r),c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp colm (
- const matrix_exp& m,
- long col
- );
- /*!
- requires
- - 0 <= col < m.nc()
- ensures
- - returns a matrix R such that:
- - R.nr() == m.nr()
- - R.nc() == 1
- - for all valid i:
- R(i) == m(i,col)
- !*/
-
- template <typename EXP>
- struct colm_exp
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This struct allows you to determine the type of matrix expression
- object returned from the colm(m,col) function. An example makes its
- use clear:
-
- template <typename EXP>
- void do_something( const matrix_exp<EXP>& mat)
- {
- // c is a matrix expression that aliases mat.
- typename colm_exp<EXP>::type c = colm(mat,0);
-
- // Print the first column of mat. So we see that by using
- // colm_exp we can save the object returned by colm() in
- // a local variable.
- cout << c << endl;
-
- // Note that you can only save the return value of colm() to
- // a local variable if the argument to colm() has a lifetime
- // beyond the colm() expression. The example shown above is
- // OK but the following would result in undefined behavior:
- typename colm_exp<EXP>::type bad = colm(mat + mat,0);
- }
- !*/
- typedef type_of_expression_returned_by_colm type;
- };
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp colm (
- const matrix_exp& m,
- long col,
- long length
- );
- /*!
- requires
- - 0 <= col < m.nc()
- - 0 <= length <= m.nr()
- ensures
- - returns a matrix R such that:
- - R.nr() == length
- - R.nc() == 1
- - for all valid i:
- R(i) == m(i,col)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp colm (
- const matrix_exp& m,
- const matrix_exp& cols
- );
- /*!
- requires
- - cols contains integral elements (e.g. int, long)
- - 0 <= min(cols) && max(cols) < m.nc()
- - cols.nr() == 1 || cols.nc() == 1
- (i.e. cols must be a vector)
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R.nr() == m.nr()
- - R.nc() == cols.size()
- - for all valid r and c:
- R(r,c) == m(r,cols(c))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- assignable_matrix_expression set_ptrm (
- T* ptr,
- long nr,
- long nc = 1
- );
- /*!
- requires
- - ptr == a pointer to nr*nc elements of type T
- - nr >= 0
- - nc >= 0
- ensures
- - statements of the following form:
- - set_ptrm(ptr,nr,nc) = some_matrix;
- result in it being the case that:
- - mat(ptr,nr,nc) == some_matrix.
-
- - statements of the following form:
- - set_ptrm(ptr,nr,nc) = scalar_value;
- result in it being the case that:
- - mat(ptr,nr,nc) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
-
- - In addition to the normal assignment statements using the = symbol, you may
- also use the usual += and -= versions of the assignment operator. In these
- cases, they have their usual effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- assignable_matrix_expression set_subm (
- matrix& m,
- long row,
- long col,
- long nr,
- long nc
- );
- /*!
- requires
- - row >= 0
- - col >= 0
- - nr >= 0
- - nc >= 0
- - row + nr <= m.nr()
- - col + nc <= m.nc()
- ensures
- - statements of the following form:
- - set_subm(m,row,col,nr,nc) = some_matrix;
- result in it being the case that:
- - subm(m,row,col,nr,nc) == some_matrix.
-
- - statements of the following form:
- - set_subm(m,row,col,nr,nc) = scalar_value;
- result in it being the case that:
- - subm(m,row,col,nr,nc) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
-
- - In addition to the normal assignment statements using the = symbol, you may
- also use the usual += and -= versions of the assignment operator. In these
- cases, they have their usual effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- assignable_matrix_expression set_subm (
- matrix& m,
- const rectangle& rect
- );
- /*!
- requires
- - get_rect(m).contains(rect) == true
- (i.e. rect is a region inside the matrix m)
- ensures
- - statements of the following form:
- - set_subm(m,rect) = some_matrix;
- result in it being the case that:
- - subm(m,rect) == some_matrix.
-
- - statements of the following form:
- - set_subm(m,rect) = scalar_value;
- result in it being the case that:
- - subm(m,rect) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
-
- - In addition to the normal assignment statements using the = symbol, you may
- also use the usual += and -= versions of the assignment operator. In these
- cases, they have their usual effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- assignable_matrix_expression set_subm (
- matrix& m,
- const matrix_exp& rows,
- const matrix_exp& cols
- );
- /*!
- requires
- - rows and cols contain integral elements (e.g. int, long)
- - 0 <= min(rows) && max(rows) < m.nr()
- - 0 <= min(cols) && max(cols) < m.nc()
- - rows.nr() == 1 || rows.nc() == 1
- - cols.nr() == 1 || cols.nc() == 1
- (i.e. rows and cols must be vectors)
- ensures
- - statements of the following form:
- - set_subm(m,rows,cols) = some_matrix;
- result in it being the case that:
- - subm(m,rows,cols) == some_matrix.
-
- - statements of the following form:
- - set_subm(m,rows,cols) = scalar_value;
- result in it being the case that:
- - subm(m,rows,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
-
- - In addition to the normal assignment statements using the = symbol, you may
- also use the usual += and -= versions of the assignment operator. In these
- cases, they have their usual effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- assignable_matrix_expression set_rowm (
- matrix& m,
- long row
- );
- /*!
- requires
- - 0 <= row < m.nr()
- ensures
- - statements of the following form:
- - set_rowm(m,row) = some_matrix;
- result in it being the case that:
- - rowm(m,row) == some_matrix.
-
- - statements of the following form:
- - set_rowm(m,row) = scalar_value;
- result in it being the case that:
- - rowm(m,row) == uniform_matrix<matrix::type>(1,nc,scalar_value).
-
- - In addition to the normal assignment statements using the = symbol, you may
- also use the usual += and -= versions of the assignment operator. In these
- cases, they have their usual effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- assignable_matrix_expression set_rowm (
- matrix& m,
- const matrix_exp& rows
- );
- /*!
- requires
- - rows contains integral elements (e.g. int, long)
- - 0 <= min(rows) && max(rows) < m.nr()
- - rows.nr() == 1 || rows.nc() == 1
- (i.e. rows must be a vector)
- ensures
- - statements of the following form:
- - set_rowm(m,rows) = some_matrix;
- result in it being the case that:
- - rowm(m,rows) == some_matrix.
-
- - statements of the following form:
- - set_rowm(m,rows) = scalar_value;
- result in it being the case that:
- - rowm(m,rows) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
-
- - In addition to the normal assignment statements using the = symbol, you may
- also use the usual += and -= versions of the assignment operator. In these
- cases, they have their usual effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- assignable_matrix_expression set_colm (
- matrix& m,
- long col
- );
- /*!
- requires
- - 0 <= col < m.nr()
- ensures
- - statements of the following form:
- - set_colm(m,col) = some_matrix;
- result in it being the case that:
- - colm(m,col) == some_matrix.
-
- - statements of the following form:
- - set_colm(m,col) = scalar_value;
- result in it being the case that:
- - colm(m,col) == uniform_matrix<matrix::type>(nr,1,scalar_value).
-
- - In addition to the normal assignment statements using the = symbol, you may
- also use the usual += and -= versions of the assignment operator. In these
- cases, they have their usual effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- assignable_matrix_expression set_colm (
- matrix& m,
- const matrix_exp& cols
- );
- /*!
- requires
- - cols contains integral elements (e.g. int, long)
- - 0 <= min(cols) && max(cols) < m.nc()
- - cols.nr() == 1 || cols.nc() == 1
- (i.e. cols must be a vector)
- ensures
- - statements of the following form:
- - set_colm(m,cols) = some_matrix;
- result in it being the case that:
- - colm(m,cols) == some_matrix.
-
- - statements of the following form:
- - set_colm(m,cols) = scalar_value;
- result in it being the case that:
- - colm(m,cols) == uniform_matrix<matrix::type>(nr,nc,scalar_value).
-
- - In addition to the normal assignment statements using the = symbol, you may
- also use the usual += and -= versions of the assignment operator. In these
- cases, they have their usual effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_SUBEXP_ABSTRACT_
-
diff --git a/ml/dlib/dlib/matrix/matrix_trsm.h b/ml/dlib/dlib/matrix/matrix_trsm.h
deleted file mode 100644
index ef5ec5ed9..000000000
--- a/ml/dlib/dlib/matrix/matrix_trsm.h
+++ /dev/null
@@ -1,654 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRiX_TRSM_Hh_
-#define DLIB_MATRiX_TRSM_Hh_
-#include "lapack/fortran_id.h"
-#include "cblas_constants.h"
-
-namespace dlib
-{
- namespace blas_bindings
- {
-#ifdef DLIB_USE_BLAS
-#ifndef CBLAS_H
- extern "C"
- {
- void cblas_strsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag, const int M, const int N,
- const float alpha, const float *A, const int lda,
- float *B, const int ldb);
-
- void cblas_dtrsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag, const int M, const int N,
- const double alpha, const double *A, const int lda,
- double *B, const int ldb);
- }
-#endif // if not CBLAS_H
-#endif // if DLIB_USE_BLAS
-
- // ------------------------------------------------------------------------------------
-
-/* Purpose */
-/* ======= */
-
-/* DTRSM solves one of the matrix equations */
-
-/* op( A )*X = alpha*B, or X*op( A ) = alpha*B, */
-
-/* where alpha is a scalar, X and B are m by n matrices, A is a unit, or */
-/* non-unit, upper or lower triangular matrix and op( A ) is one of */
-
-/* op( A ) = A or op( A ) = A'. */
-
-/* The matrix X is overwritten on B. */
-
-/* Arguments */
-/* ========== */
-
-/* SIDE - CHARACTER*1. */
-/* On entry, SIDE specifies whether op( A ) appears on the left */
-/* or right of X as follows: */
-
-/* SIDE = 'L' or 'l' op( A )*X = alpha*B. */
-
-/* SIDE = 'R' or 'r' X*op( A ) = alpha*B. */
-
-/* Unchanged on exit. */
-
-/* UPLO - CHARACTER*1. */
-/* On entry, UPLO specifies whether the matrix A is an upper or */
-/* lower triangular matrix as follows: */
-
-/* UPLO = 'U' or 'u' A is an upper triangular matrix. */
-
-/* UPLO = 'L' or 'l' A is a lower triangular matrix. */
-
-/* Unchanged on exit. */
-
-/* TRANSA - CHARACTER*1. */
-/* On entry, TRANSA specifies the form of op( A ) to be used in */
-/* the matrix multiplication as follows: */
-
-/* TRANSA = 'N' or 'n' op( A ) = A. */
-
-/* TRANSA = 'T' or 't' op( A ) = A'. */
-
-/* TRANSA = 'C' or 'c' op( A ) = A'. */
-
-/* Unchanged on exit. */
-
-/* DIAG - CHARACTER*1. */
-/* On entry, DIAG specifies whether or not A is unit triangular */
-/* as follows: */
-
-/* DIAG = 'U' or 'u' A is assumed to be unit triangular. */
-
-/* DIAG = 'N' or 'n' A is not assumed to be unit */
-/* triangular. */
-
-/* Unchanged on exit. */
-
-/* M - INTEGER. */
-/* On entry, M specifies the number of rows of B. M must be at */
-/* least zero. */
-/* Unchanged on exit. */
-
-/* N - INTEGER. */
-/* On entry, N specifies the number of columns of B. N must be */
-/* at least zero. */
-/* Unchanged on exit. */
-
-/* ALPHA - DOUBLE PRECISION. */
-/* On entry, ALPHA specifies the scalar alpha. When alpha is */
-/* zero then A is not referenced and B need not be set before */
-/* entry. */
-/* Unchanged on exit. */
-
-/* A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m */
-/* when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. */
-/* Before entry with UPLO = 'U' or 'u', the leading k by k */
-/* upper triangular part of the array A must contain the upper */
-/* triangular matrix and the strictly lower triangular part of */
-/* A is not referenced. */
-/* Before entry with UPLO = 'L' or 'l', the leading k by k */
-/* lower triangular part of the array A must contain the lower */
-/* triangular matrix and the strictly upper triangular part of */
-/* A is not referenced. */
-/* Note that when DIAG = 'U' or 'u', the diagonal elements of */
-/* A are not referenced either, but are assumed to be unity. */
-/* Unchanged on exit. */
-
-/* LDA - INTEGER. */
-/* On entry, LDA specifies the first dimension of A as declared */
-/* in the calling (sub) program. When SIDE = 'L' or 'l' then */
-/* LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' */
-/* then LDA must be at least max( 1, n ). */
-/* Unchanged on exit. */
-
-/* B - DOUBLE PRECISION array of DIMENSION ( LDB, n ). */
-/* Before entry, the leading m by n part of the array B must */
-/* contain the right-hand side matrix B, and on exit is */
-/* overwritten by the solution matrix X. */
-
-/* LDB - INTEGER. */
-/* On entry, LDB specifies the first dimension of B as declared */
-/* in the calling (sub) program. LDB must be at least */
-/* max( 1, m ). */
-/* Unchanged on exit. */
-
-
-/* Level 3 Blas routine. */
-
-
-/* -- Written on 8-February-1989. */
-/* Jack Dongarra, Argonne National Laboratory. */
-/* Iain Duff, AERE Harwell. */
-/* Jeremy Du Croz, Numerical Algorithms Group Ltd. */
-/* Sven Hammarling, Numerical Algorithms Group Ltd. */
-
- template <typename T>
- void local_trsm(
- const CBLAS_ORDER Order,
- CBLAS_SIDE Side,
- CBLAS_UPLO Uplo,
- const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag,
- long m,
- long n,
- T alpha,
- const T *a,
- long lda,
- T *b,
- long ldb
- )
- /*!
- This is a copy of the dtrsm routine from the netlib.org BLAS which was run though
- f2c and converted into this form for use when a BLAS library is not available.
- !*/
- {
- if (Order == CblasRowMajor)
- {
- // since row major ordering looks like transposition to FORTRAN we need to flip a
- // few things.
- if (Side == CblasLeft)
- Side = CblasRight;
- else
- Side = CblasLeft;
-
- if (Uplo == CblasUpper)
- Uplo = CblasLower;
- else
- Uplo = CblasUpper;
-
- std::swap(m,n);
- }
-
- /* System generated locals */
- long a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
-
- /* Local variables */
- long i__, j, k, info;
- T temp;
- bool lside;
- long nrowa;
- bool upper;
- bool nounit;
-
- /* Parameter adjustments */
- a_dim1 = lda;
- a_offset = 1 + a_dim1;
- a -= a_offset;
- b_dim1 = ldb;
- b_offset = 1 + b_dim1;
- b -= b_offset;
-
- /* Function Body */
- lside = (Side == CblasLeft);
- if (lside)
- {
- nrowa = m;
- } else
- {
- nrowa = n;
- }
- nounit = (Diag == CblasNonUnit);
- upper = (Uplo == CblasUpper);
-
- info = 0;
- if (! lside && ! (Side == CblasRight)) {
- info = 1;
- } else if (! upper && !(Uplo == CblasLower) ) {
- info = 2;
- } else if (!(TransA == CblasNoTrans) &&
- !(TransA == CblasTrans) &&
- !(TransA == CblasConjTrans)) {
- info = 3;
- } else if (!(Diag == CblasUnit) &&
- !(Diag == CblasNonUnit) ) {
- info = 4;
- } else if (m < 0) {
- info = 5;
- } else if (n < 0) {
- info = 6;
- } else if (lda < std::max<long>(1,nrowa)) {
- info = 9;
- } else if (ldb < std::max<long>(1,m)) {
- info = 11;
- }
- DLIB_CASSERT( info == 0, "Invalid inputs given to local_trsm");
-
- /* Quick return if possible. */
-
- if (m == 0 || n == 0) {
- return;
- }
-
- /* And when alpha.eq.zero. */
-
- if (alpha == 0.) {
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + j * b_dim1] = 0.;
- /* L10: */
- }
- /* L20: */
- }
- return;
- }
-
- /* Start the operations. */
-
- if (lside) {
- if (TransA == CblasNoTrans) {
-
- /* Form B := alpha*inv( A )*B. */
-
- if (upper) {
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
- if (alpha != 1.) {
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + j * b_dim1] = alpha * b[i__ + j * b_dim1]
- ;
- /* L30: */
- }
- }
- for (k = m; k >= 1; --k) {
- if (b[k + j * b_dim1] != 0.) {
- if (nounit) {
- b[k + j * b_dim1] /= a[k + k * a_dim1];
- }
- i__2 = k - 1;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + j * b_dim1] -= b[k + j * b_dim1] * a[
- i__ + k * a_dim1];
- /* L40: */
- }
- }
- /* L50: */
- }
- /* L60: */
- }
- } else {
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
- if (alpha != 1.) {
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + j * b_dim1] = alpha * b[i__ + j * b_dim1]
- ;
- /* L70: */
- }
- }
- i__2 = m;
- for (k = 1; k <= i__2; ++k) {
- if (b[k + j * b_dim1] != 0.) {
- if (nounit) {
- b[k + j * b_dim1] /= a[k + k * a_dim1];
- }
- i__3 = m;
- for (i__ = k + 1; i__ <= i__3; ++i__) {
- b[i__ + j * b_dim1] -= b[k + j * b_dim1] * a[
- i__ + k * a_dim1];
- /* L80: */
- }
- }
- /* L90: */
- }
- /* L100: */
- }
- }
- } else {
-
- /* Form B := alpha*inv( A' )*B. */
-
- if (upper) {
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp = alpha * b[i__ + j * b_dim1];
- i__3 = i__ - 1;
- for (k = 1; k <= i__3; ++k) {
- temp -= a[k + i__ * a_dim1] * b[k + j * b_dim1];
- /* L110: */
- }
- if (nounit) {
- temp /= a[i__ + i__ * a_dim1];
- }
- b[i__ + j * b_dim1] = temp;
- /* L120: */
- }
- /* L130: */
- }
- } else {
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
- for (i__ = m; i__ >= 1; --i__) {
- temp = alpha * b[i__ + j * b_dim1];
- i__2 = m;
- for (k = i__ + 1; k <= i__2; ++k) {
- temp -= a[k + i__ * a_dim1] * b[k + j * b_dim1];
- /* L140: */
- }
- if (nounit) {
- temp /= a[i__ + i__ * a_dim1];
- }
- b[i__ + j * b_dim1] = temp;
- /* L150: */
- }
- /* L160: */
- }
- }
- }
- } else {
- if (TransA == CblasNoTrans) {
-
- /* Form B := alpha*B*inv( A ). */
-
- if (upper) {
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
- if (alpha != 1.) {
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + j * b_dim1] = alpha * b[i__ + j * b_dim1]
- ;
- /* L170: */
- }
- }
- i__2 = j - 1;
- for (k = 1; k <= i__2; ++k) {
- if (a[k + j * a_dim1] != 0.) {
- i__3 = m;
- for (i__ = 1; i__ <= i__3; ++i__) {
- b[i__ + j * b_dim1] -= a[k + j * a_dim1] * b[
- i__ + k * b_dim1];
- /* L180: */
- }
- }
- /* L190: */
- }
- if (nounit) {
- temp = 1. / a[j + j * a_dim1];
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
- /* L200: */
- }
- }
- /* L210: */
- }
- } else {
- for (j = n; j >= 1; --j) {
- if (alpha != 1.) {
- i__1 = m;
- for (i__ = 1; i__ <= i__1; ++i__) {
- b[i__ + j * b_dim1] = alpha * b[i__ + j * b_dim1]
- ;
- /* L220: */
- }
- }
- i__1 = n;
- for (k = j + 1; k <= i__1; ++k) {
- if (a[k + j * a_dim1] != 0.) {
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + j * b_dim1] -= a[k + j * a_dim1] * b[
- i__ + k * b_dim1];
- /* L230: */
- }
- }
- /* L240: */
- }
- if (nounit) {
- temp = 1. / a[j + j * a_dim1];
- i__1 = m;
- for (i__ = 1; i__ <= i__1; ++i__) {
- b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
- /* L250: */
- }
- }
- /* L260: */
- }
- }
- } else {
-
- /* Form B := alpha*B*inv( A' ). */
-
- if (upper) {
- for (k = n; k >= 1; --k) {
- if (nounit) {
- temp = 1. / a[k + k * a_dim1];
- i__1 = m;
- for (i__ = 1; i__ <= i__1; ++i__) {
- b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
- /* L270: */
- }
- }
- i__1 = k - 1;
- for (j = 1; j <= i__1; ++j) {
- if (a[j + k * a_dim1] != 0.) {
- temp = a[j + k * a_dim1];
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + j * b_dim1] -= temp * b[i__ + k *
- b_dim1];
- /* L280: */
- }
- }
- /* L290: */
- }
- if (alpha != 1.) {
- i__1 = m;
- for (i__ = 1; i__ <= i__1; ++i__) {
- b[i__ + k * b_dim1] = alpha * b[i__ + k * b_dim1]
- ;
- /* L300: */
- }
- }
- /* L310: */
- }
- } else {
- i__1 = n;
- for (k = 1; k <= i__1; ++k) {
- if (nounit) {
- temp = 1. / a[k + k * a_dim1];
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
- /* L320: */
- }
- }
- i__2 = n;
- for (j = k + 1; j <= i__2; ++j) {
- if (a[j + k * a_dim1] != 0.) {
- temp = a[j + k * a_dim1];
- i__3 = m;
- for (i__ = 1; i__ <= i__3; ++i__) {
- b[i__ + j * b_dim1] -= temp * b[i__ + k *
- b_dim1];
- /* L330: */
- }
- }
- /* L340: */
- }
- if (alpha != 1.) {
- i__2 = m;
- for (i__ = 1; i__ <= i__2; ++i__) {
- b[i__ + k * b_dim1] = alpha * b[i__ + k * b_dim1]
- ;
- /* L350: */
- }
- }
- /* L360: */
- }
- }
- }
- }
- }
-
- // ------------------------------------------------------------------------------------
-
- inline void cblas_trsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag, const int M, const int N,
- const float alpha, const float *A, const int lda,
- float *B, const int ldb)
- {
-#ifdef DLIB_USE_BLAS
- if (M > 4)
- {
- cblas_strsm(Order, Side, Uplo, TransA, Diag, M, N, alpha, A, lda, B, ldb);
- return;
- }
-#endif
- local_trsm(Order, Side, Uplo, TransA, Diag, M, N, alpha, A, lda, B, ldb);
- }
-
- inline void cblas_trsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag, const int M, const int N,
- const double alpha, const double *A, const int lda,
- double *B, const int ldb)
- {
-#ifdef DLIB_USE_BLAS
- if (M > 4)
- {
- cblas_dtrsm(Order, Side, Uplo, TransA, Diag, M, N, alpha, A, lda, B, ldb);
- return;
- }
-#endif
- local_trsm(Order, Side, Uplo, TransA, Diag, M, N, alpha, A, lda, B, ldb);
- }
-
- inline void cblas_trsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag, const int M, const int N,
- const long double alpha, const long double *A, const int lda,
- long double *B, const int ldb)
- {
- local_trsm(Order, Side, Uplo, TransA, Diag, M, N, alpha, A, lda, B, ldb);
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2,
- long NC1, long NC2,
- typename MM
- >
- inline void triangular_solver (
- const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo,
- const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag,
- const matrix<T,NR1,NC1,MM,row_major_layout>& A,
- const T alpha,
- matrix<T,NR2,NC2,MM,row_major_layout>& B
- )
- {
- cblas_trsm(CblasRowMajor, Side, Uplo, TransA, Diag, B.nr(), B.nc(),
- alpha, &A(0,0), A.nc(), &B(0,0), B.nc());
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2,
- long NC1, long NC2,
- typename MM
- >
- inline void triangular_solver (
- const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo,
- const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag,
- const matrix<T,NR1,NC1,MM,column_major_layout>& A,
- const T alpha,
- matrix<T,NR2,NC2,MM,column_major_layout>& B
- )
- {
- cblas_trsm(CblasColMajor, Side, Uplo, TransA, Diag, B.nr(), B.nc(),
- alpha, &A(0,0), A.nr(), &B(0,0), B.nr());
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2,
- long NC1, long NC2,
- typename MM
- >
- inline void triangular_solver (
- const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo,
- const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag,
- const matrix<T,NR1,NC1,MM,column_major_layout>& A,
- matrix<T,NR2,NC2,MM,column_major_layout>& B,
- long rows_of_B
- )
- {
- const T alpha = 1;
- cblas_trsm(CblasColMajor, Side, Uplo, TransA, Diag, rows_of_B, B.nc(),
- alpha, &A(0,0), A.nr(), &B(0,0), B.nr());
- }
-
- // ------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR1, long NR2,
- long NC1, long NC2,
- typename MM,
- typename layout
- >
- inline void triangular_solver (
- const CBLAS_SIDE Side,
- const CBLAS_UPLO Uplo,
- const CBLAS_TRANSPOSE TransA,
- const CBLAS_DIAG Diag,
- const matrix<T,NR1,NC1,MM,layout>& A,
- matrix<T,NR2,NC2,MM,layout>& B
- )
- {
- const T alpha = 1;
- triangular_solver(Side, Uplo, TransA, Diag, A, alpha, B);
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-}
-
-#endif // DLIB_MATRiX_TRSM_Hh_
-
diff --git a/ml/dlib/dlib/matrix/matrix_utilities.h b/ml/dlib/dlib/matrix/matrix_utilities.h
deleted file mode 100644
index 0c5091a4b..000000000
--- a/ml/dlib/dlib/matrix/matrix_utilities.h
+++ /dev/null
@@ -1,4544 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MATRIx_UTILITIES_
-#define DLIB_MATRIx_UTILITIES_
-
-#include "matrix_utilities_abstract.h"
-#include "matrix.h"
-#include <cmath>
-#include <complex>
-#include <limits>
-#include "../pixel.h"
-#include "../stl_checked.h"
-#include <vector>
-#include <algorithm>
-#include "../std_allocator.h"
-#include "matrix_expressions.h"
-#include "matrix_math_functions.h"
-#include "matrix_op.h"
-#include "../general_hash/random_hashing.h"
-#include "matrix_mat.h"
-
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- /*!A is_complex
- This is a template that can be used to determine if a type is a specialization
- of the std::complex template class.
-
- For example:
- is_complex<float>::value == false
- is_complex<std::complex<float> >::value == true
- !*/
-
- template <typename T>
- struct is_complex { static const bool value = false; };
-
- template <typename T>
- struct is_complex<std::complex<T> > { static const bool value = true; };
- template <typename T>
- struct is_complex<std::complex<T>& > { static const bool value = true; };
- template <typename T>
- struct is_complex<const std::complex<T>& > { static const bool value = true; };
- template <typename T>
- struct is_complex<const std::complex<T> > { static const bool value = true; };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- inline bool is_row_vector (
- const matrix_exp<EXP>& m
- ) { return m.nr() == 1; }
-
- template <typename EXP>
- inline bool is_col_vector (
- const matrix_exp<EXP>& m
- ) { return m.nc() == 1; }
-
- template <typename EXP>
- inline bool is_vector (
- const matrix_exp<EXP>& m
- ) { return is_row_vector(m) || is_col_vector(m); }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- inline bool is_finite (
- const matrix_exp<EXP>& m
- )
- {
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- if (!is_finite(m(r,c)))
- return false;
- }
- }
- return true;
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename T>
- const T& magnitude (const T& item) { return item; }
- template <typename T>
- T magnitude (const std::complex<T>& item) { return std::norm(item); }
- }
-
- template <
- typename EXP
- >
- void find_min_and_max (
- const matrix_exp<EXP>& m,
- typename EXP::type& min_val,
- typename EXP::type& max_val
- )
- {
- DLIB_ASSERT(m.size() > 0,
- "\ttype find_min_and_max(const matrix_exp& m, min_val, max_val)"
- << "\n\tYou can't ask for the min and max of an empty matrix"
- << "\n\tm.size(): " << m.size()
- );
- typedef typename matrix_exp<EXP>::type type;
-
- min_val = m(0,0);
- max_val = min_val;
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- type temp = m(r,c);
- if (dlib::impl::magnitude(temp) > dlib::impl::magnitude(max_val))
- max_val = temp;
- if (dlib::impl::magnitude(temp) < dlib::impl::magnitude(min_val))
- min_val = temp;
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- point max_point (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0,
- "\tpoint max_point(const matrix_exp& m)"
- << "\n\tm can't be empty"
- << "\n\tm.size(): " << m.size()
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- typedef typename matrix_exp<EXP>::type type;
-
- point best_point(0,0);
- type val = m(0,0);
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- type temp = m(r,c);
- if (dlib::impl::magnitude(temp) > dlib::impl::magnitude(val))
- {
- val = temp;
- best_point = point(c,r);
- }
- }
- }
- return best_point;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- point min_point (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0,
- "\tpoint min_point(const matrix_exp& m)"
- << "\n\tm can't be empty"
- << "\n\tm.size(): " << m.size()
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- typedef typename matrix_exp<EXP>::type type;
-
- point best_point(0,0);
- type val = m(0,0);
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- type temp = m(r,c);
- if (dlib::impl::magnitude(temp) < dlib::impl::magnitude(val))
- {
- val = temp;
- best_point = point(c,r);
- }
- }
- }
- return best_point;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- long index_of_max (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0 && is_vector(m) == true,
- "\tlong index_of_max(const matrix_exp& m)"
- << "\n\tm must be a row or column matrix"
- << "\n\tm.size(): " << m.size()
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- typedef typename matrix_exp<EXP>::type type;
-
- type val = m(0);
- long best_idx = 0;
- for (long i = 1; i < m.size(); ++i)
- {
- type temp = m(i);
- if (dlib::impl::magnitude(temp) > dlib::impl::magnitude(val))
- {
- val = temp;
- best_idx = i;
- }
- }
- return best_idx;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- long index_of_min (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0 && is_vector(m),
- "\tlong index_of_min(const matrix_exp& m)"
- << "\n\tm must be a row or column matrix"
- << "\n\tm.size(): " << m.size()
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- typedef typename matrix_exp<EXP>::type type;
-
- type val = m(0);
- long best_idx = 0;
- for (long i = 1; i < m.size(); ++i)
- {
- type temp = m(i);
- if (dlib::impl::magnitude(temp) < dlib::impl::magnitude(val))
- {
- val = temp;
- best_idx = i;
- }
- }
- return best_idx;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const typename matrix_exp<EXP>::type max (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0,
- "\ttype max(const matrix_exp& m)"
- << "\n\tYou can't ask for the max() of an empty matrix"
- << "\n\tm.size(): " << m.size()
- );
- typedef typename matrix_exp<EXP>::type type;
-
- type val = m(0,0);
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- type temp = m(r,c);
- if (dlib::impl::magnitude(temp) > dlib::impl::magnitude(val))
- val = temp;
- }
- }
- return val;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const typename matrix_exp<EXP>::type min (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0,
- "\ttype min(const matrix_exp& m)"
- << "\n\tYou can't ask for the min() of an empty matrix"
- << "\n\tm.size(): " << m.size()
- );
- typedef typename matrix_exp<EXP>::type type;
-
- type val = m(0,0);
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- type temp = m(r,c);
- if (dlib::impl::magnitude(temp) < dlib::impl::magnitude(val))
- val = temp;
- }
- }
- return val;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_binary_min : basic_op_mm<M1,M2>
- {
- op_binary_min( const M1& m1_, const M2& m2_) : basic_op_mm<M1,M2>(m1_,m2_){}
-
- typedef typename M1::type type;
- typedef const type const_ret_type;
- const static long cost = M1::cost + M2::cost + 1;
-
- const_ret_type apply ( long r, long c) const
- { return std::min(this->m1(r,c),this->m2(r,c)); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_op<op_binary_min<EXP1,EXP2> > min_pointwise (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0);
- DLIB_ASSERT(a.nr() == b.nr() &&
- a.nc() == b.nc(),
- "\t const matrix_exp min_pointwise(const matrix_exp& a, const matrix_exp& b)"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nr(): " << b.nr()
- << "\n\tb.nc(): " << b.nc()
- );
- typedef op_binary_min<EXP1,EXP2> op;
- return matrix_op<op>(op(a.ref(),b.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, typename M3>
- struct op_min_pointwise3 : basic_op_mmm<M1,M2,M3>
- {
- op_min_pointwise3( const M1& m1_, const M2& m2_, const M3& m3_) :
- basic_op_mmm<M1,M2,M3>(m1_,m2_,m3_){}
-
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- const static long cost = M1::cost + M2::cost + M3::cost + 2;
-
- const_ret_type apply (long r, long c) const
- { return std::min(this->m1(r,c),std::min(this->m2(r,c),this->m3(r,c))); }
- };
-
- template <
- typename EXP1,
- typename EXP2,
- typename EXP3
- >
- inline const matrix_op<op_min_pointwise3<EXP1,EXP2,EXP3> >
- min_pointwise (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b,
- const matrix_exp<EXP3>& c
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,typename EXP3::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NR == 0 || EXP2::NC == 0);
- COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0);
- COMPILE_TIME_ASSERT(EXP2::NC == EXP3::NC || EXP2::NC == 0 || EXP3::NC == 0);
- DLIB_ASSERT(a.nr() == b.nr() &&
- a.nc() == b.nc() &&
- b.nr() == c.nr() &&
- b.nc() == c.nc(),
- "\tconst matrix_exp min_pointwise(a,b,c)"
- << "\n\tYou can only make a do a pointwise min between equally sized matrices"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nr(): " << b.nr()
- << "\n\tb.nc(): " << b.nc()
- << "\n\tc.nr(): " << c.nr()
- << "\n\tc.nc(): " << c.nc()
- );
-
- typedef op_min_pointwise3<EXP1,EXP2,EXP3> op;
- return matrix_op<op>(op(a.ref(),b.ref(),c.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_binary_max : basic_op_mm<M1,M2>
- {
- op_binary_max( const M1& m1_, const M2& m2_) : basic_op_mm<M1,M2>(m1_,m2_){}
-
- typedef typename M1::type type;
- typedef const type const_ret_type;
- const static long cost = M1::cost + M2::cost + 1;
-
- const_ret_type apply ( long r, long c) const
- { return std::max(this->m1(r,c),this->m2(r,c)); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_op<op_binary_max<EXP1,EXP2> > max_pointwise (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0);
- DLIB_ASSERT(a.nr() == b.nr() &&
- a.nc() == b.nc(),
- "\t const matrix_exp max_pointwise(const matrix_exp& a, const matrix_exp& b)"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nr(): " << b.nr()
- << "\n\tb.nc(): " << b.nc()
- );
- typedef op_binary_max<EXP1,EXP2> op;
- return matrix_op<op>(op(a.ref(),b.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, typename M3>
- struct op_max_pointwise3 : basic_op_mmm<M1,M2,M3>
- {
- op_max_pointwise3( const M1& m1_, const M2& m2_, const M3& m3_) :
- basic_op_mmm<M1,M2,M3>(m1_,m2_,m3_){}
-
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- const static long cost = M1::cost + M2::cost + M3::cost + 2;
-
- const_ret_type apply (long r, long c) const
- { return std::max(this->m1(r,c),std::max(this->m2(r,c),this->m3(r,c))); }
- };
-
- template <
- typename EXP1,
- typename EXP2,
- typename EXP3
- >
- inline const matrix_op<op_max_pointwise3<EXP1,EXP2,EXP3> >
- max_pointwise (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b,
- const matrix_exp<EXP3>& c
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,typename EXP3::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NR == 0 || EXP2::NC == 0);
- COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0);
- COMPILE_TIME_ASSERT(EXP2::NC == EXP3::NC || EXP2::NC == 0 || EXP3::NC == 0);
- DLIB_ASSERT(a.nr() == b.nr() &&
- a.nc() == b.nc() &&
- b.nr() == c.nr() &&
- b.nc() == c.nc(),
- "\tconst matrix_exp max_pointwise(a,b,c)"
- << "\n\tYou can only make a do a pointwise max between equally sized matrices"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nr(): " << b.nr()
- << "\n\tb.nc(): " << b.nc()
- << "\n\tc.nr(): " << c.nr()
- << "\n\tc.nc(): " << c.nc()
- );
-
- typedef op_max_pointwise3<EXP1,EXP2,EXP3> op;
- return matrix_op<op>(op(a.ref(),b.ref(),c.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- typename enable_if_c<std::numeric_limits<typename EXP::type>::is_integer, double>::type length (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(is_vector(m) == true,
- "\ttype length(const matrix_exp& m)"
- << "\n\tm must be a row or column vector"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
-
- return std::sqrt(static_cast<double>(sum(squared(m))));
- }
-
- template <
- typename EXP
- >
- typename disable_if_c<std::numeric_limits<typename EXP::type>::is_integer, const typename EXP::type>::type length (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(is_vector(m) == true,
- "\ttype length(const matrix_exp& m)"
- << "\n\tm must be a row or column vector"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- return std::sqrt(sum(squared(m)));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const typename matrix_exp<EXP>::type length_squared (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(is_vector(m) == true,
- "\ttype length_squared(const matrix_exp& m)"
- << "\n\tm must be a row or column vector"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- return sum(squared(m));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_trans
- {
- op_trans( const M& m_) : m(m_){}
-
- const M& m;
-
- const static long cost = M::cost;
- const static long NR = M::NC;
- const static long NC = M::NR;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- const_ret_type apply (long r, long c) const { return m(c,r); }
-
- long nr () const { return m.nc(); }
- long nc () const { return m.nr(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
-
- };
-
- template <
- typename M
- >
- const matrix_op<op_trans<M> > trans (
- const matrix_exp<M>& m
- )
- {
- typedef op_trans<M> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
-// don't to anything at all for diagonal matrices
- template <
- typename M
- >
- const matrix_diag_exp<M>& trans (
- const matrix_diag_exp<M>& m
- )
- {
- return m;
- }
-
-// ----------------------------------------------------------------------------------------
-
-// I introduced this struct because it avoids an inane compiler warning from gcc
- template <typename EXP>
- struct is_not_ct_vector{ static const bool value = (EXP::NR != 1 && EXP::NC != 1); };
-
- template <
- typename EXP1,
- typename EXP2
- >
- typename enable_if_c<(is_not_ct_vector<EXP1>::value) || (is_not_ct_vector<EXP2>::value),
- typename EXP1::type>::type
- dot (
- const matrix_exp<EXP1>& m1,
- const matrix_exp<EXP2>& m2
- )
- {
- // You are getting an error on this line because you are trying to
- // compute the dot product between two matrices that aren't both vectors (i.e.
- // they aren't column or row matrices).
- COMPILE_TIME_ASSERT(EXP1::NR*EXP1::NC == 0 ||
- EXP2::NR*EXP2::NC == 0);
-
- DLIB_ASSERT(is_vector(m1) && is_vector(m2) && m1.size() == m2.size() &&
- m1.size() > 0,
- "\t type dot(const matrix_exp& m1, const matrix_exp& m2)"
- << "\n\t You can only compute the dot product between non-empty vectors of equal length."
- << "\n\t is_vector(m1): " << is_vector(m1)
- << "\n\t is_vector(m2): " << is_vector(m2)
- << "\n\t m1.size(): " << m1.size()
- << "\n\t m2.size(): " << m2.size()
- );
-
- if (is_col_vector(m1) && is_col_vector(m2)) return (trans(m1)*m2)(0);
- if (is_col_vector(m1) && is_row_vector(m2)) return (m2*m1)(0);
- if (is_row_vector(m1) && is_col_vector(m2)) return (m1*m2)(0);
-
- //if (is_row_vector(m1) && is_row_vector(m2))
- return (m1*trans(m2))(0);
- }
-
- template < typename EXP1, typename EXP2 >
- typename enable_if_c<EXP1::NR == 1 && EXP2::NR == 1 && EXP1::NC != 1 && EXP2::NC != 1, typename EXP1::type>::type
- dot ( const matrix_exp<EXP1>& m1, const matrix_exp<EXP2>& m2)
- {
- DLIB_ASSERT(m1.size() == m2.size(),
- "\t type dot(const matrix_exp& m1, const matrix_exp& m2)"
- << "\n\t You can only compute the dot product between vectors of equal length"
- << "\n\t m1.size(): " << m1.size()
- << "\n\t m2.size(): " << m2.size()
- );
-
- return m1*trans(m2);
- }
-
- template < typename EXP1, typename EXP2 >
- typename enable_if_c<EXP1::NR == 1 && EXP2::NC == 1 && EXP1::NC != 1 && EXP2::NR != 1, typename EXP1::type>::type
- dot ( const matrix_exp<EXP1>& m1, const matrix_exp<EXP2>& m2)
- {
- DLIB_ASSERT(m1.size() == m2.size(),
- "\t type dot(const matrix_exp& m1, const matrix_exp& m2)"
- << "\n\t You can only compute the dot product between vectors of equal length"
- << "\n\t m1.size(): " << m1.size()
- << "\n\t m2.size(): " << m2.size()
- );
-
- return m1*m2;
- }
-
- template < typename EXP1, typename EXP2 >
- typename enable_if_c<EXP1::NC == 1 && EXP2::NR == 1 && EXP1::NR != 1 && EXP2::NC != 1, typename EXP1::type>::type
- dot ( const matrix_exp<EXP1>& m1, const matrix_exp<EXP2>& m2)
- {
- DLIB_ASSERT(m1.size() == m2.size(),
- "\t type dot(const matrix_exp& m1, const matrix_exp& m2)"
- << "\n\t You can only compute the dot product between vectors of equal length"
- << "\n\t m1.size(): " << m1.size()
- << "\n\t m2.size(): " << m2.size()
- );
-
- return m2*m1;
- }
-
- template < typename EXP1, typename EXP2 >
- typename enable_if_c<EXP1::NC == 1 && EXP2::NC == 1 && EXP1::NR != 1 && EXP2::NR != 1, typename EXP1::type>::type
- dot ( const matrix_exp<EXP1>& m1, const matrix_exp<EXP2>& m2)
- {
- DLIB_ASSERT(m1.size() == m2.size(),
- "\t type dot(const matrix_exp& m1, const matrix_exp& m2)"
- << "\n\t You can only compute the dot product between vectors of equal length"
- << "\n\t m1.size(): " << m1.size()
- << "\n\t m2.size(): " << m2.size()
- );
-
- return trans(m1)*m2;
- }
-
- template < typename EXP1, typename EXP2 >
- typename enable_if_c<(EXP1::NC*EXP1::NR == 1) || (EXP2::NC*EXP2::NR == 1), typename EXP1::type>::type
- dot ( const matrix_exp<EXP1>& m1, const matrix_exp<EXP2>& m2)
- {
- DLIB_ASSERT(m1.size() == m2.size(),
- "\t type dot(const matrix_exp& m1, const matrix_exp& m2)"
- << "\n\t You can only compute the dot product between vectors of equal length"
- << "\n\t m1.size(): " << m1.size()
- << "\n\t m2.size(): " << m2.size()
- );
-
- return m1(0)*m2(0);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, long R, long C>
- struct op_removerc
- {
- op_removerc( const M& m_) : m(m_){}
-
- const M& m;
-
- const static long cost = M::cost+2;
- const static long NR = (M::NR==0) ? 0 : (M::NR - 1);
- const static long NC = (M::NC==0) ? 0 : (M::NC - 1);
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply (long r, long c) const
- {
- if (r < R)
- {
- if (c < C)
- return m(r,c);
- else
- return m(r,c+1);
- }
- else
- {
- if (c < C)
- return m(r+1,c);
- else
- return m(r+1,c+1);
- }
- }
-
- long nr () const { return m.nr() - 1; }
- long nc () const { return m.nc() - 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <typename M>
- struct op_removerc2
- {
- op_removerc2( const M& m_, const long R_, const long C_) : m(m_), R(R_), C(C_){}
- const M& m;
- const long R;
- const long C;
-
- const static long cost = M::cost+2;
- const static long NR = (M::NR==0) ? 0 : (M::NR - 1);
- const static long NC = (M::NC==0) ? 0 : (M::NC - 1);
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply (long r, long c) const
- {
- if (r < R)
- {
- if (c < C)
- return m(r,c);
- else
- return m(r,c+1);
- }
- else
- {
- if (c < C)
- return m(r+1,c);
- else
- return m(r+1,c+1);
- }
- }
-
- long nr () const { return m.nr() - 1; }
- long nc () const { return m.nc() - 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- long R,
- long C,
- typename EXP
- >
- const matrix_op<op_removerc<EXP,R,C> > removerc (
- const matrix_exp<EXP>& m
- )
- {
- // you can't remove a row from a matrix with only one row
- COMPILE_TIME_ASSERT((EXP::NR > R && R >= 0) || EXP::NR == 0);
- // you can't remove a column from a matrix with only one column
- COMPILE_TIME_ASSERT((EXP::NC > C && C >= 0) || EXP::NR == 0);
- DLIB_ASSERT(m.nr() > R && R >= 0 && m.nc() > C && C >= 0,
- "\tconst matrix_exp removerc<R,C>(const matrix_exp& m)"
- << "\n\tYou can't remove a row/column from a matrix if it doesn't have that row/column"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tR: " << R
- << "\n\tC: " << C
- );
- typedef op_removerc<EXP,R,C> op;
- return matrix_op<op>(op(m.ref()));
- }
-
- template <
- typename EXP
- >
- const matrix_op<op_removerc2<EXP> > removerc (
- const matrix_exp<EXP>& m,
- long R,
- long C
- )
- {
- DLIB_ASSERT(m.nr() > R && R >= 0 && m.nc() > C && C >= 0,
- "\tconst matrix_exp removerc(const matrix_exp& m,R,C)"
- << "\n\tYou can't remove a row/column from a matrix if it doesn't have that row/column"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tR: " << R
- << "\n\tC: " << C
- );
- typedef op_removerc2<EXP> op;
- return matrix_op<op>(op(m.ref(),R,C));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, long C>
- struct op_remove_col
- {
- op_remove_col( const M& m_) : m(m_){}
- const M& m;
-
- const static long cost = M::cost+2;
- const static long NR = M::NR;
- const static long NC = (M::NC==0) ? 0 : (M::NC - 1);
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long c) const
- {
- if (c < C)
- {
- return m(r,c);
- }
- else
- {
- return m(r,c+1);
- }
- }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc() - 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <typename M>
- struct op_remove_col2
- {
- op_remove_col2( const M& m_, const long C_) : m(m_), C(C_){}
- const M& m;
- const long C;
-
- const static long cost = M::cost+2;
- const static long NR = M::NR;
- const static long NC = (M::NC==0) ? 0 : (M::NC - 1);
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long c) const
- {
- if (c < C)
- {
- return m(r,c);
- }
- else
- {
- return m(r,c+1);
- }
- }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc() - 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- long C,
- typename EXP
- >
- const matrix_op<op_remove_col<EXP, C> > remove_col (
- const matrix_exp<EXP>& m
- )
- {
- // You can't remove the given column from the matrix because the matrix doesn't
- // have a column with that index.
- COMPILE_TIME_ASSERT((EXP::NC > C && C >= 0) || EXP::NC == 0);
- DLIB_ASSERT(m.nc() > C && C >= 0 ,
- "\tconst matrix_exp remove_col<C>(const matrix_exp& m)"
- << "\n\tYou can't remove a col from a matrix if it doesn't have it"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tC: " << C
- );
- typedef op_remove_col<EXP,C> op;
- return matrix_op<op>(op(m.ref()));
- }
-
- template <
- typename EXP
- >
- const matrix_op<op_remove_col2<EXP> > remove_col (
- const matrix_exp<EXP>& m,
- long C
- )
- {
- DLIB_ASSERT(m.nc() > C && C >= 0 ,
- "\tconst matrix_exp remove_col(const matrix_exp& m,C)"
- << "\n\tYou can't remove a col from a matrix if it doesn't have it"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tC: " << C
- );
- typedef op_remove_col2<EXP> op;
- return matrix_op<op>(op(m.ref(),C));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, long R>
- struct op_remove_row
- {
- op_remove_row( const M& m_) : m(m_){}
- const M& m;
-
- const static long cost = M::cost+2;
- const static long NR = (M::NR==0) ? 0 : (M::NR - 1);
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r < R)
- {
- return m(r,c);
- }
- else
- {
- return m(r+1,c);
- }
- }
-
- long nr () const { return m.nr() - 1; }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <typename M>
- struct op_remove_row2
- {
- op_remove_row2( const M& m_, const long R_) : m(m_), R(R_){}
- const M& m;
- const long R;
-
- const static long cost = M::cost+2;
- const static long NR = (M::NR==0) ? 0 : (M::NR - 1);
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r < R)
- {
- return m(r,c);
- }
- else
- {
- return m(r+1,c);
- }
- }
-
- long nr () const { return m.nr() - 1; }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- long R,
- typename EXP
- >
- const matrix_op<op_remove_row<EXP,R> > remove_row (
- const matrix_exp<EXP>& m
- )
- {
- // You can't remove the given row from the matrix because the matrix doesn't
- // have a row with that index.
- COMPILE_TIME_ASSERT((EXP::NR > R && R >= 0) || EXP::NR == 0);
- DLIB_ASSERT(m.nr() > R && R >= 0,
- "\tconst matrix_exp remove_row<R>(const matrix_exp& m)"
- << "\n\tYou can't remove a row from a matrix if it doesn't have it"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tR: " << R
- );
- typedef op_remove_row<EXP,R> op;
- return matrix_op<op>(op(m.ref()));
- }
-
- template <
- typename EXP
- >
- const matrix_op<op_remove_row2<EXP> > remove_row (
- const matrix_exp<EXP>& m,
- long R
- )
- {
- DLIB_ASSERT(m.nr() > R && R >= 0,
- "\tconst matrix_exp remove_row(const matrix_exp& m, long R)"
- << "\n\tYou can't remove a row from a matrix if it doesn't have it"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tR: " << R
- );
- typedef op_remove_row2<EXP> op;
- return matrix_op<op>(op(m.ref(),R));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_diagm
- {
- op_diagm( const M& m_) : m(m_){}
- const M& m;
-
- const static long cost = M::cost+2;
- const static long N = M::NC*M::NR;
- const static long NR = N;
- const static long NC = N;
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r==c)
- return m(r);
- else
- return 0;
- }
-
- long nr () const { return (m.nr()>m.nc())? m.nr():m.nc(); }
- long nc () const { return (m.nr()>m.nc())? m.nr():m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_diag_op<op_diagm<EXP> > diagm (
- const matrix_exp<EXP>& m
- )
- {
- // You can only make a diagonal matrix out of a row or column vector
- COMPILE_TIME_ASSERT(EXP::NR == 0 || EXP::NR == 1 || EXP::NC == 1 || EXP::NC == 0);
- DLIB_ASSERT(is_vector(m),
- "\tconst matrix_exp diagm(const matrix_exp& m)"
- << "\n\tYou can only apply diagm() to a row or column matrix"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- typedef op_diagm<EXP> op;
- return matrix_diag_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_diagm_mult : basic_op_mm<M1,M2>
- {
- op_diagm_mult( const M1& m1_, const M2& m2_) : basic_op_mm<M1,M2>(m1_,m2_){}
-
- typedef typename M1::type type;
- typedef const type const_ret_type;
- const static long cost = M1::cost + M2::cost + 1;
-
- const_ret_type apply ( long r, long c) const
- {
- if (r == c)
- return this->m1(r,c)*this->m2(r,c);
- else
- return 0;
- }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_diag_op<op_diagm_mult<EXP1,EXP2> > operator* (
- const matrix_diag_exp<EXP1>& a,
- const matrix_diag_exp<EXP2>& b
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type, typename EXP2::type>::value));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0);
- DLIB_ASSERT(a.nr() == b.nr() &&
- a.nc() == b.nc(),
- "\tconst matrix_exp operator(const matrix_diag_exp& a, const matrix_diag_exp& b)"
- << "\n\tYou can only multiply diagonal matrices together if they are the same size"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nr(): " << b.nr()
- << "\n\tb.nc(): " << b.nc()
- );
- typedef op_diagm_mult<EXP1,EXP2> op;
- return matrix_diag_op<op>(op(a.ref(),b.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_diag
- {
- op_diag( const M& m_) : m(m_){}
- const M& m;
-
- const static long cost = M::cost;
- const static long NR = tmin<M::NR,M::NC>::value;
- const static long NC = 1;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long ) const { return m(r,r); }
-
- long nr () const { return std::min(m.nc(),m.nr()); }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_diag<EXP> > diag (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_diag<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
- template <typename EXP>
- struct diag_exp
- {
- typedef matrix_op<op_diag<EXP> > type;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, typename target_type>
- struct op_cast
- {
- op_cast( const M& m_) : m(m_){}
- const M& m;
-
- const static long cost = M::cost+2;
- const static long NR = M::NR;
- const static long NC = M::NC;
- typedef target_type type;
- typedef const target_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long c) const { return static_cast<target_type>(m(r,c)); }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.destructively_aliases(item); }
- };
-
- template <
- typename target_type,
- typename EXP
- >
- const matrix_op<op_cast<EXP, target_type> > matrix_cast (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_cast<EXP, target_type> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename type, typename S>
- inline type lessthan(const type& val, const S& s)
- {
- if (val < s)
- return 1;
- else
- return 0;
- }
-
- }
- DLIB_DEFINE_OP_MS(op_lessthan, impl::lessthan, 1);
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_lessthan<EXP,S> > >::type operator< (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_lessthan<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_lessthan<EXP,S> > >::type operator> (
- const S& s,
- const matrix_exp<EXP>& m
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_lessthan<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename type, typename S>
- inline type lessthan_eq(const type& val, const S& s)
- {
- if (val <= s)
- return 1;
- else
- return 0;
- }
-
- }
- DLIB_DEFINE_OP_MS(op_lessthan_eq, impl::lessthan_eq, 1);
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_lessthan_eq<EXP,S> > >::type operator<= (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_lessthan_eq<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_lessthan_eq<EXP,S> > >::type operator>= (
- const S& s,
- const matrix_exp<EXP>& m
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_lessthan_eq<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename type, typename S>
- inline type greaterthan(const type& val, const S& s)
- {
- if (val > s)
- return 1;
- else
- return 0;
- }
-
- }
- DLIB_DEFINE_OP_MS(op_greaterthan, impl::greaterthan, 1);
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_greaterthan<EXP,S> > >::type operator> (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_greaterthan<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_greaterthan<EXP,S> > >::type operator< (
- const S& s,
- const matrix_exp<EXP>& m
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_greaterthan<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename type, typename S>
- inline type greaterthan_eq(const type& val, const S& s)
- {
- if (val >= s)
- return 1;
- else
- return 0;
- }
-
- }
- DLIB_DEFINE_OP_MS(op_greaterthan_eq, impl::greaterthan_eq, 1);
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_greaterthan_eq<EXP,S> > >::type operator>= (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_greaterthan_eq<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_greaterthan_eq<EXP,S> > >::type operator<= (
- const S& s,
- const matrix_exp<EXP>& m
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_greaterthan_eq<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename type, typename S>
- inline type equal_to(const type& val, const S& s)
- {
- if (val == s)
- return 1;
- else
- return 0;
- }
-
- }
- DLIB_DEFINE_OP_MS(op_equal_to, impl::equal_to, 1);
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_equal_to<EXP,S> > >::type operator== (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT( is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_equal_to<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_equal_to<EXP,S> > >::type operator== (
- const S& s,
- const matrix_exp<EXP>& m
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT( is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_equal_to<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename type, typename S>
- inline type not_equal_to(const type& val, const S& s)
- {
- if (val != s)
- return 1;
- else
- return 0;
- }
-
- }
- DLIB_DEFINE_OP_MS(op_not_equal_to, impl::not_equal_to, 1);
-
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_not_equal_to<EXP,S> > >::type operator!= (
- const matrix_exp<EXP>& m,
- const S& s
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_not_equal_to<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
- template <
- typename EXP,
- typename S
- >
- const typename enable_if<is_built_in_scalar_type<S>, matrix_op<op_not_equal_to<EXP,S> > >::type operator!= (
- const S& s,
- const matrix_exp<EXP>& m
- )
- {
- // you can only use this relational operator with the built in scalar types like
- // long, float, etc.
- COMPILE_TIME_ASSERT(is_built_in_scalar_type<typename EXP::type>::value);
-
- typedef op_not_equal_to<EXP,S> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename U,
- typename L
- >
- typename disable_if<is_matrix<U>,void>::type set_all_elements (
- matrix<T,NR,NC,MM,L>& m,
- const U& value
- )
- {
- // The value you are trying to assign to each element of the m matrix
- // doesn't have the appropriate type.
- COMPILE_TIME_ASSERT(is_matrix<T>::value == is_matrix<U>::value);
-
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- m(r,c) = static_cast<T>(value);
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename U,
- typename L
- >
- typename enable_if<is_matrix<U>,void>::type set_all_elements (
- matrix<T,NR,NC,MM,L>& m,
- const U& value
- )
- {
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- m(r,c) = value;
- }
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- inline const typename matrix_exp<EXP>::matrix_type tmp (
- const matrix_exp<EXP>& m
- )
- {
- return typename matrix_exp<EXP>::matrix_type (m);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- constexpr bool is_row_major (
- const matrix_exp<EXP>&
- )
- {
- return is_same_type<typename EXP::layout_type,row_major_layout>::value;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const typename lazy_disable_if<is_matrix<typename EXP::type>, EXP>::type sum (
- const matrix_exp<EXP>& m
- )
- {
- typedef typename matrix_exp<EXP>::type type;
-
- type val = 0;
- if (is_row_major(m))
- {
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- val += m(r,c);
- }
- }
- }
- else
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- for (long r = 0; r < m.nr(); ++r)
- {
- val += m(r,c);
- }
- }
- }
- return val;
- }
-
- template <
- typename EXP
- >
- const typename lazy_enable_if<is_matrix<typename EXP::type>, EXP>::type sum (
- const matrix_exp<EXP>& m
- )
- {
- typedef typename matrix_exp<EXP>::type type;
-
- type val;
- if (m.size() > 0)
- val.set_size(m(0,0).nr(),m(0,0).nc());
- set_all_elements(val,0);
-
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- val += m(r,c);
- }
- }
- return val;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_sumr
- {
- op_sumr(const M& m_) : m(m_) {}
- const M& m;
-
- const static long cost = M::cost+10;
- const static long NR = 1;
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long , long c) const
- {
- type temp = m(0,c);
- for (long r = 1; r < m.nr(); ++r)
- temp += m(r,c);
- return temp;
- }
-
- long nr () const { return 1; }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_sumr<EXP> > sum_rows (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0 ,
- "\tconst matrix_exp sum_rows(m)"
- << "\n\t The matrix can't be empty"
- << "\n\t m.size(): " << m.size()
- );
- typedef op_sumr<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_sumc
- {
- op_sumc(const M& m_) : m(m_) {}
- const M& m;
-
- const static long cost = M::cost + 10;
- const static long NR = M::NR;
- const static long NC = 1;
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long ) const
- {
- type temp = m(r,0);
- for (long c = 1; c < m.nc(); ++c)
- temp += m(r,c);
- return temp;
- }
-
- long nr () const { return m.nr(); }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_sumc<EXP> > sum_cols (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.size() > 0 ,
- "\tconst matrix_exp sum_cols(m)"
- << "\n\t The matrix can't be empty"
- << "\n\t m.size(): " << m.size()
- );
- typedef op_sumc<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- inline const typename disable_if<is_complex<typename EXP::type>, typename matrix_exp<EXP>::type>::type mean (
- const matrix_exp<EXP>& m
- )
- {
- return sum(m)/(m.nr()*m.nc());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- inline const typename enable_if<is_complex<typename EXP::type>, typename matrix_exp<EXP>::type>::type mean (
- const matrix_exp<EXP>& m
- )
- {
- typedef typename EXP::type::value_type type;
- return sum(m)/(type)(m.nr()*m.nc());
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const typename matrix_exp<EXP>::type variance (
- const matrix_exp<EXP>& m
- )
- {
- using std::pow;
- using dlib::pow;
- const typename matrix_exp<EXP>::type avg = mean(m);
-
- typedef typename matrix_exp<EXP>::type type;
-
- type val;
- val = 0;
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- val += pow(m(r,c) - avg,2);
- }
- }
-
- if (m.nr() * m.nc() <= 1)
- {
- return val;
- }
- else
- {
- // Note, for some reason, in gcc 4.1 performing this division using a
- // double instead of a long value avoids a segmentation fault. That is,
- // using 1.0 instead of 1 does the trick.
- return val/(m.nr()*m.nc() - 1.0);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const typename matrix_exp<EXP>::type stddev (
- const matrix_exp<EXP>& m
- )
- {
- using std::sqrt;
- using dlib::sqrt;
- return sqrt(variance(m));
- }
-
-// ----------------------------------------------------------------------------------------
-
-// this is a workaround for a bug in visual studio 7.1
- template <typename EXP>
- struct visual_studio_sucks_cov_helper
- {
- typedef typename EXP::type inner_type;
- typedef matrix<typename inner_type::type, inner_type::NR, inner_type::NR, typename EXP::mem_manager_type> type;
- };
-
- template <
- typename EXP
- >
- const typename visual_studio_sucks_cov_helper<EXP>::type covariance (
- const matrix_exp<EXP>& m
- )
- {
- // perform static checks to make sure m is a column vector
- COMPILE_TIME_ASSERT(EXP::NR == 0 || EXP::NR > 1);
- COMPILE_TIME_ASSERT(EXP::NC == 1 || EXP::NC == 0);
-
- // perform static checks to make sure the matrices contained in m are column vectors
- COMPILE_TIME_ASSERT(EXP::type::NC == 1 || EXP::type::NC == 0 );
-
- DLIB_ASSERT(m.size() > 1 && is_col_vector(m),
- "\tconst matrix covariance(const matrix_exp& m)"
- << "\n\tYou can only apply covariance() to a column matrix"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
-#ifdef ENABLE_ASSERTS
- for (long i = 0; i < m.nr(); ++i)
- {
- DLIB_ASSERT(m(0).size() == m(i).size() && m(i).size() > 0 && is_col_vector(m(i)),
- "\tconst matrix covariance(const matrix_exp& m)"
- << "\n\tYou can only apply covariance() to a column matrix of column matrices"
- << "\n\tm(0).size(): " << m(0).size()
- << "\n\tm(i).size(): " << m(i).size()
- << "\n\tis_col_vector(m(i)): " << (is_col_vector(m(i)) ? "true" : "false")
- << "\n\ti: " << i
- );
- }
-#endif
-
- // now perform the actual calculation of the covariance matrix.
- typename visual_studio_sucks_cov_helper<EXP>::type cov(m(0).nr(),m(0).nr());
- set_all_elements(cov,0);
-
- const typename EXP::type avg = mean(m);
-
- for (long r = 0; r < m.nr(); ++r)
- {
- cov += (m(r) - avg)*trans(m(r) - avg);
- }
-
- cov *= 1.0 / (m.nr() - 1.0);
- return cov;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const typename matrix_exp<EXP>::type prod (
- const matrix_exp<EXP>& m
- )
- {
- typedef typename matrix_exp<EXP>::type type;
-
- type val = 1;
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- val *= m(r,c);
- }
- }
- return val;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- struct op_uniform_matrix_3 : does_not_alias
- {
- op_uniform_matrix_3(const long& rows_, const long& cols_, const T& val_ ) :
- rows(rows_), cols(cols_), val(val_) {}
-
- const long rows;
- const long cols;
- const T val;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 0;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- typedef T type;
- typedef const T& const_ret_type;
- const_ret_type apply (long, long ) const { return val; }
-
- long nr() const { return rows; }
- long nc() const { return cols; }
- };
-
- template <
- typename T
- >
- const matrix_op<op_uniform_matrix_3<T> > uniform_matrix (
- long nr,
- long nc,
- const T& val
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0,
- "\tconst matrix_exp uniform_matrix<T>(nr, nc, val)"
- << "\n\tnr and nc have to be bigger than 0"
- << "\n\tnr: " << nr
- << "\n\tnc: " << nc
- );
- typedef op_uniform_matrix_3<T> op;
- return matrix_op<op>(op(nr, nc, val));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_op<op_uniform_matrix_3<T> > zeros_matrix (
- long nr,
- long nc
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0,
- "\tconst matrix_exp zeros_matrix<T>(nr, nc)"
- << "\n\tnr and nc have to be >= 0"
- << "\n\tnr: " << nr
- << "\n\tnc: " << nc
- );
- typedef op_uniform_matrix_3<T> op;
- return matrix_op<op>(op(nr, nc, 0));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix_op<op_uniform_matrix_3<typename EXP::type> > zeros_matrix (
- const matrix_exp<EXP>& mat
- )
- {
- DLIB_ASSERT(mat.nr() >= 0 && mat.nc() >= 0,
- "\tconst matrix_exp zeros_matrix(mat)"
- << "\n\t nr and nc have to be >= 0"
- << "\n\t mat.nr(): " << mat.nr()
- << "\n\t mat.nc(): " << mat.nc()
- );
- typedef typename EXP::type T;
- typedef op_uniform_matrix_3<T> op;
- return matrix_op<op>(op(mat.nr(), mat.nc(), 0));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_op<op_uniform_matrix_3<T> > ones_matrix (
- long nr,
- long nc
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0,
- "\tconst matrix_exp ones_matrix<T>(nr, nc)"
- << "\n\tnr and nc have to be >= 0"
- << "\n\tnr: " << nr
- << "\n\tnc: " << nc
- );
- typedef op_uniform_matrix_3<T> op;
- return matrix_op<op>(op(nr, nc, 1));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP
- >
- const matrix_op<op_uniform_matrix_3<typename EXP::type> > ones_matrix (
- const matrix_exp<EXP>& mat
- )
- {
- DLIB_ASSERT(mat.nr() >= 0 && mat.nc() >= 0,
- "\tconst matrix_exp ones_matrix(mat)"
- << "\n\t nr and nc have to be >= 0"
- << "\n\t mat.nr(): " << mat.nr()
- << "\n\t mat.nc(): " << mat.nc()
- );
- typedef typename EXP::type T;
- typedef op_uniform_matrix_3<T> op;
- return matrix_op<op>(op(mat.nr(), mat.nc(), 1));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR_,
- long NC_
- >
- struct op_uniform_matrix_2 : does_not_alias
- {
- op_uniform_matrix_2( const T& val_ ) : val(val_) {}
- const T val;
-
- const static long cost = 1;
- const static long NR = NR_;
- const static long NC = NC_;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- typedef T type;
- typedef const T& const_ret_type;
-
- const_ret_type apply (long , long ) const { return val; }
-
- long nr() const { return NR; }
- long nc() const { return NC; }
- };
-
- template <
- typename T,
- long NR,
- long NC
- >
- const matrix_op<op_uniform_matrix_2<T,NR,NC> > uniform_matrix (
- const T& val
- )
- {
- COMPILE_TIME_ASSERT(NR > 0 && NC > 0);
-
- typedef op_uniform_matrix_2<T,NR,NC> op;
- return matrix_op<op>(op(val));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR_,
- long NC_,
- T val
- >
- struct op_uniform_matrix : does_not_alias
- {
- const static long cost = 1;
- const static long NR = NR_;
- const static long NC = NC_;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- typedef T type;
- typedef const T const_ret_type;
- const_ret_type apply ( long , long ) const { return val; }
-
- long nr() const { return NR; }
- long nc() const { return NC; }
- };
-
- template <
- typename T,
- long NR,
- long NC,
- T val
- >
- const matrix_op<op_uniform_matrix<T,NR,NC,val> > uniform_matrix (
- )
- {
- COMPILE_TIME_ASSERT(NR > 0 && NC > 0);
- typedef op_uniform_matrix<T,NR,NC,val> op;
- return matrix_op<op>(op());
- }
-
-// ----------------------------------------------------------------------------------------
-
- struct op_gaussian_randm : does_not_alias
- {
- op_gaussian_randm (
- long nr_,
- long nc_,
- unsigned long seed_
- ) :_nr(nr_), _nc(nc_), seed(seed_){}
-
- const long _nr;
- const long _nc;
- const unsigned long seed;
-
- const static long cost = 100;
- const static long NR = 0;
- const static long NC = 0;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- typedef double type;
- typedef double const_ret_type;
- const_ret_type apply ( long r, long c) const { return gaussian_random_hash(r,c,seed); }
-
- long nr() const { return _nr; }
- long nc() const { return _nc; }
- };
-
- inline const matrix_op<op_gaussian_randm> gaussian_randm (
- long nr,
- long nc,
- unsigned long seed = 0
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0,
- "\tmatrix_exp gaussian_randm(nr, nc, seed)"
- << "\n\tInvalid inputs to this function"
- << "\n\tnr: " << nr
- << "\n\tnc: " << nc
- );
-
- typedef op_gaussian_randm op;
- return matrix_op<op>(op(nr,nc,seed));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_add_diag
- {
- op_add_diag( const M& m_, const typename M::type& value_) : m(m_), value(value_){}
- const M& m;
- const typename M::type value;
-
- const static long cost = M::cost+1;
- const static long NR = M::NR;
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r==c)
- return m(r,c)+value;
- else
- return m(r,c);
- }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.destructively_aliases(item); }
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- struct op_identity_matrix_2 : does_not_alias
- {
- op_identity_matrix_2(const long& size_) : size(size_) {}
-
- const long size;
-
- const static long cost = 1;
- const static long NR = 0;
- const static long NC = 0;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- typedef T type;
- typedef const T const_ret_type;
- const_ret_type apply (long r, long c) const { return static_cast<type>(r == c); }
-
- long nr() const { return size; }
- long nc() const { return size; }
- };
-
- template <
- typename T,
- typename U
- >
- const matrix_diag_op<op_identity_matrix_2<T> > identity_matrix (
- const U& size
- )
- {
- // the size argument must be some scalar value, not a matrix!
- COMPILE_TIME_ASSERT(is_matrix<U>::value == false);
-
- DLIB_ASSERT(size > 0,
- "\tconst matrix_exp identity_matrix<T>(size)"
- << "\n\tsize must be bigger than 0"
- << "\n\tsize: " << size
- );
- typedef op_identity_matrix_2<T> op;
- return matrix_diag_op<op>(op(size));
- }
-
- template <
- typename EXP
- >
- const matrix_diag_op<op_identity_matrix_2<typename EXP::type> > identity_matrix (
- const matrix_exp<EXP>& mat
- )
- {
- DLIB_ASSERT(mat.nr() == mat.nc(),
- "\tconst matrix_exp identity_matrix(mat)"
- << "\n\t mat must be a square matrix."
- << "\n\t mat.nr(): " << mat.nr()
- << "\n\t mat.nc(): " << mat.nc()
- );
- typedef typename EXP::type T;
- typedef op_identity_matrix_2<T> op;
- return matrix_diag_op<op>(op(mat.nr()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- typename T
- >
- const matrix_op<op_add_diag<EXP> > operator+ (
- const matrix_exp<EXP>& lhs,
- const matrix_exp<matrix_diag_op<op_identity_matrix_2<T> > >& DLIB_IF_ASSERT(rhs)
- )
- {
- // both matrices must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<T,typename EXP::type>::value == true));
-
- // You can only add matrices together if they both have the same number of rows and columns.
- DLIB_ASSERT(lhs.nc() == rhs.nc() &&
- lhs.nr() == rhs.nr(),
- "\tconst matrix_exp operator+(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to add two incompatible matrices together"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
-
- typedef op_add_diag<EXP> op;
- return matrix_op<op>(op(lhs.ref(),1));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- typename T
- >
- const matrix_op<op_add_diag<EXP> > operator+ (
- const matrix_exp<matrix_diag_op<op_identity_matrix_2<T> > >& DLIB_IF_ASSERT(lhs),
- const matrix_exp<EXP>& rhs
- )
- {
- // both matrices must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<T,typename EXP::type>::value == true));
-
- // You can only add matrices together if they both have the same number of rows and columns.
- DLIB_ASSERT(lhs.nc() == rhs.nc() &&
- lhs.nr() == rhs.nr(),
- "\tconst matrix_exp operator+(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to add two incompatible matrices together"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
-
- typedef op_add_diag<EXP> op;
- return matrix_op<op>(op(rhs.ref(),1));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long N
- >
- struct op_const_diag_matrix : does_not_alias
- {
- op_const_diag_matrix(const long& size_, const T& value_) : size(size_),value(value_) {}
-
- const long size;
- const T value;
-
- const static long cost = 1;
- const static long NR = N;
- const static long NC = N;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- typedef T type;
- typedef const T const_ret_type;
- const_ret_type apply (long r, long c) const
- {
- if (r == c)
- return value;
- else
- return 0;
- }
-
- long nr() const { return size; }
- long nc() const { return size; }
- };
-
- template <
- typename T,
- typename U
- >
- const typename disable_if<is_matrix<U>, matrix_diag_op<op_const_diag_matrix<T,0> > >::type operator* (
- const matrix_exp<matrix_diag_op<op_identity_matrix_2<T> > >& m,
- const U& value
- )
- {
- typedef op_const_diag_matrix<T,0> op;
- return matrix_diag_op<op>(op(m.nr(), value));
- }
-
- template <
- typename T,
- typename U
- >
- const typename disable_if<is_matrix<U>, matrix_diag_op<op_const_diag_matrix<T,0> > >::type operator* (
- const U& value,
- const matrix_exp<matrix_diag_op<op_identity_matrix_2<T> > >& m
- )
- {
- typedef op_const_diag_matrix<T,0> op;
- return matrix_diag_op<op>(op(m.nr(), value));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- typename T,
- long N
- >
- const matrix_op<op_add_diag<EXP> > operator+ (
- const matrix_exp<EXP>& lhs,
- const matrix_exp<matrix_diag_op<op_const_diag_matrix<T,N> > >& rhs
- )
- {
- // both matrices must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<T,typename EXP::type>::value == true));
-
- // You can only add matrices together if they both have the same number of rows and columns.
- DLIB_ASSERT(lhs.nc() == rhs.nc() &&
- lhs.nr() == rhs.nr(),
- "\tconst matrix_exp operator+(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to add two incompatible matrices together"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
-
- typedef op_add_diag<EXP> op;
- return matrix_op<op>(op(lhs.ref(),rhs.ref().op.value));
- }
-
- template <
- typename EXP,
- typename T,
- long N
- >
- const matrix_op<op_add_diag<EXP> > operator+ (
- const matrix_exp<matrix_diag_op<op_const_diag_matrix<T,N> > >& lhs,
- const matrix_exp<EXP>& rhs
- )
- {
- // both matrices must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<T,typename EXP::type>::value == true));
-
- // You can only add matrices together if they both have the same number of rows and columns.
- DLIB_ASSERT(lhs.nc() == rhs.nc() &&
- lhs.nr() == rhs.nr(),
- "\tconst matrix_exp operator+(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to add two incompatible matrices together"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
-
- typedef op_add_diag<EXP> op;
- return matrix_op<op>(op(rhs.ref(),lhs.ref().op.value));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long N
- >
- struct op_identity_matrix : does_not_alias
- {
- const static long cost = 1;
- const static long NR = N;
- const static long NC = N;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
- typedef T type;
- typedef const T const_ret_type;
- const_ret_type apply ( long r, long c) const { return static_cast<type>(r == c); }
-
- long nr () const { return NR; }
- long nc () const { return NC; }
- };
-
- template <
- typename T,
- long N
- >
- const matrix_diag_op<op_identity_matrix<T,N> > identity_matrix (
- )
- {
- COMPILE_TIME_ASSERT(N > 0);
-
- typedef op_identity_matrix<T,N> op;
- return matrix_diag_op<op>(op());
- }
-
- template <
- typename T,
- typename U,
- long N
- >
- const typename disable_if<is_matrix<U>, matrix_diag_op<op_const_diag_matrix<T,N> > >::type operator* (
- const matrix_exp<matrix_diag_op<op_identity_matrix<T,N> > >& m,
- const U& value
- )
- {
- typedef op_const_diag_matrix<T,N> op;
- return matrix_diag_op<op>(op(m.nr(), value));
- }
-
- template <
- typename T,
- typename U,
- long N
- >
- const typename disable_if<is_matrix<U>, matrix_diag_op<op_const_diag_matrix<T,N> > >::type operator* (
- const U& value,
- const matrix_exp<matrix_diag_op<op_identity_matrix<T,N> > >& m
- )
- {
- typedef op_const_diag_matrix<T,N> op;
- return matrix_diag_op<op>(op(m.nr(), value));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- typename T,
- long N
- >
- const matrix_op<op_add_diag<EXP> > operator+ (
- const matrix_exp<matrix_diag_op<op_identity_matrix<T,N> > >& DLIB_IF_ASSERT(lhs),
- const matrix_exp<EXP>& rhs
- )
- {
- // both matrices must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<T,typename EXP::type>::value == true));
-
- // You can only add matrices together if they both have the same number of rows and columns.
- DLIB_ASSERT(lhs.nc() == rhs.nc() &&
- lhs.nr() == rhs.nr(),
- "\tconst matrix_exp operator+(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to add two incompatible matrices together"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
-
- typedef op_add_diag<EXP> op;
- return matrix_op<op>(op(rhs.ref(),1));
- }
-
- template <
- typename EXP,
- typename T,
- long N
- >
- const matrix_op<op_add_diag<EXP> > operator+ (
- const matrix_exp<EXP>& lhs,
- const matrix_exp<matrix_diag_op<op_identity_matrix<T,N> > >& DLIB_IF_ASSERT(rhs)
- )
- {
- // both matrices must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<T,typename EXP::type>::value == true));
-
- // You can only add matrices together if they both have the same number of rows and columns.
- DLIB_ASSERT(lhs.nc() == rhs.nc() &&
- lhs.nr() == rhs.nr(),
- "\tconst matrix_exp operator+(const matrix_exp& lhs, const matrix_exp& rhs)"
- << "\n\tYou are trying to add two incompatible matrices together"
- << "\n\tlhs.nr(): " << lhs.nr()
- << "\n\tlhs.nc(): " << lhs.nc()
- << "\n\trhs.nr(): " << rhs.nr()
- << "\n\trhs.nc(): " << rhs.nc()
- << "\n\t&lhs: " << &lhs
- << "\n\t&rhs: " << &rhs
- );
-
-
- typedef op_add_diag<EXP> op;
- return matrix_op<op>(op(lhs.ref(),1));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, long R, long C>
- struct op_rotate
- {
- op_rotate(const M& m_) : m(m_) {}
- const M& m;
-
- const static long cost = M::cost + 2;
- const static long NR = M::NR;
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- const_ret_type apply ( long r, long c) const { return m((r+R)%m.nr(),(c+C)%m.nc()); }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- long R,
- long C,
- typename EXP
- >
- const matrix_op<op_rotate<EXP,R,C> > rotate (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_rotate<EXP,R,C> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- // A template to tell me if two types can be multiplied together in a sensible way. Here
- // I'm saying it is ok if they are both the same type or one is the complex version of the other.
- template <typename T, typename U> struct compatible { static const bool value = false; typedef T type; };
- template <typename T> struct compatible<T,T> { static const bool value = true; typedef T type; };
- template <typename T> struct compatible<std::complex<T>,T> { static const bool value = true; typedef std::complex<T> type; };
- template <typename T> struct compatible<T,std::complex<T> > { static const bool value = true; typedef std::complex<T> type; };
- }
-
-
- template <typename M1, typename M2>
- struct op_pointwise_multiply : basic_op_mm<M1,M2>
- {
- op_pointwise_multiply( const M1& m1_, const M2& m2_) : basic_op_mm<M1,M2>(m1_,m2_){}
-
- typedef typename impl::compatible<typename M1::type, typename M2::type>::type type;
- typedef const type const_ret_type;
- const static long cost = M1::cost + M2::cost + 1;
-
- const_ret_type apply ( long r, long c) const
- { return this->m1(r,c)*this->m2(r,c); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_op<op_pointwise_multiply<EXP1,EXP2> > pointwise_multiply (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b
- )
- {
- COMPILE_TIME_ASSERT((impl::compatible<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0);
- DLIB_ASSERT(a.nr() == b.nr() &&
- a.nc() == b.nc(),
- "\tconst matrix_exp pointwise_multiply(const matrix_exp& a, const matrix_exp& b)"
- << "\n\tYou can only make a do a pointwise multiply with two equally sized matrices"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nr(): " << b.nr()
- << "\n\tb.nc(): " << b.nc()
- );
- typedef op_pointwise_multiply<EXP1,EXP2> op;
- return matrix_op<op>(op(a.ref(),b.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, typename M3>
- struct op_pointwise_multiply3 : basic_op_mmm<M1,M2,M3>
- {
- op_pointwise_multiply3( const M1& m1_, const M2& m2_, const M3& m3_) :
- basic_op_mmm<M1,M2,M3>(m1_,m2_,m3_){}
-
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- const static long cost = M1::cost + M2::cost + M3::cost + 2;
-
- const_ret_type apply (long r, long c) const
- { return this->m1(r,c)*this->m2(r,c)*this->m3(r,c); }
- };
-
- template <
- typename EXP1,
- typename EXP2,
- typename EXP3
- >
- inline const matrix_op<op_pointwise_multiply3<EXP1,EXP2,EXP3> >
- pointwise_multiply (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b,
- const matrix_exp<EXP3>& c
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,typename EXP3::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NR == 0 || EXP2::NC == 0);
- COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0);
- COMPILE_TIME_ASSERT(EXP2::NC == EXP3::NC || EXP2::NC == 0 || EXP3::NC == 0);
- DLIB_ASSERT(a.nr() == b.nr() &&
- a.nc() == b.nc() &&
- b.nr() == c.nr() &&
- b.nc() == c.nc(),
- "\tconst matrix_exp pointwise_multiply(a,b,c)"
- << "\n\tYou can only make a do a pointwise multiply between equally sized matrices"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nr(): " << b.nr()
- << "\n\tb.nc(): " << b.nc()
- << "\n\tc.nr(): " << c.nr()
- << "\n\tc.nc(): " << c.nc()
- );
-
- typedef op_pointwise_multiply3<EXP1,EXP2,EXP3> op;
- return matrix_op<op>(op(a.ref(),b.ref(),c.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, typename M3, typename M4>
- struct op_pointwise_multiply4 : basic_op_mmmm<M1,M2,M3,M4>
- {
- op_pointwise_multiply4( const M1& m1_, const M2& m2_, const M3& m3_, const M4& m4_) :
- basic_op_mmmm<M1,M2,M3,M4>(m1_,m2_,m3_,m4_){}
-
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- const static long cost = M1::cost + M2::cost + M3::cost + M4::cost + 3;
-
- const_ret_type apply (long r, long c) const
- { return this->m1(r,c)*this->m2(r,c)*this->m3(r,c)*this->m4(r,c); }
- };
-
-
- template <
- typename EXP1,
- typename EXP2,
- typename EXP3,
- typename EXP4
- >
- inline const matrix_op<op_pointwise_multiply4<EXP1,EXP2,EXP3,EXP4> > pointwise_multiply (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b,
- const matrix_exp<EXP3>& c,
- const matrix_exp<EXP4>& d
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,typename EXP3::type>::value == true));
- COMPILE_TIME_ASSERT((is_same_type<typename EXP3::type,typename EXP4::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NC == 0 || EXP2::NC == 0 );
- COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0);
- COMPILE_TIME_ASSERT(EXP2::NC == EXP3::NC || EXP2::NC == 0 || EXP3::NC == 0);
- COMPILE_TIME_ASSERT(EXP3::NR == EXP4::NR || EXP3::NR == 0 || EXP4::NR == 0);
- COMPILE_TIME_ASSERT(EXP3::NC == EXP4::NC || EXP3::NC == 0 || EXP4::NC == 0);
- DLIB_ASSERT(a.nr() == b.nr() &&
- a.nc() == b.nc() &&
- b.nr() == c.nr() &&
- b.nc() == c.nc() &&
- c.nr() == d.nr() &&
- c.nc() == d.nc(),
- "\tconst matrix_exp pointwise_multiply(a,b,c,d)"
- << "\n\tYou can only make a do a pointwise multiply between equally sized matrices"
- << "\n\ta.nr(): " << a.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nr(): " << b.nr()
- << "\n\tb.nc(): " << b.nc()
- << "\n\tc.nr(): " << c.nr()
- << "\n\tc.nc(): " << c.nc()
- << "\n\td.nr(): " << d.nr()
- << "\n\td.nc(): " << d.nc()
- );
-
- typedef op_pointwise_multiply4<EXP1,EXP2,EXP3,EXP4> op;
- return matrix_op<op>(op(a.ref(),b.ref(),c.ref(),d.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename P,
- int type = static_switch<
- pixel_traits<P>::grayscale,
- pixel_traits<P>::rgb,
- pixel_traits<P>::hsi,
- pixel_traits<P>::rgb_alpha,
- pixel_traits<P>::lab
- >::value
- >
- struct pixel_to_vector_helper;
-
- template <typename P>
- struct pixel_to_vector_helper<P,1>
- {
- template <typename M>
- static void assign (
- M& m,
- const P& pixel
- )
- {
- m(0) = static_cast<typename M::type>(pixel);
- }
- };
-
- template <typename P>
- struct pixel_to_vector_helper<P,2>
- {
- template <typename M>
- static void assign (
- M& m,
- const P& pixel
- )
- {
- m(0) = static_cast<typename M::type>(pixel.red);
- m(1) = static_cast<typename M::type>(pixel.green);
- m(2) = static_cast<typename M::type>(pixel.blue);
- }
- };
-
- template <typename P>
- struct pixel_to_vector_helper<P,3>
- {
- template <typename M>
- static void assign (
- M& m,
- const P& pixel
- )
- {
- m(0) = static_cast<typename M::type>(pixel.h);
- m(1) = static_cast<typename M::type>(pixel.s);
- m(2) = static_cast<typename M::type>(pixel.i);
- }
- };
-
- template <typename P>
- struct pixel_to_vector_helper<P,4>
- {
- template <typename M>
- static void assign (
- M& m,
- const P& pixel
- )
- {
- m(0) = static_cast<typename M::type>(pixel.red);
- m(1) = static_cast<typename M::type>(pixel.green);
- m(2) = static_cast<typename M::type>(pixel.blue);
- m(3) = static_cast<typename M::type>(pixel.alpha);
- }
- };
-
- template <typename P>
- struct pixel_to_vector_helper<P,5>
- {
- template <typename M>
- static void assign (
- M& m,
- const P& pixel
- )
- {
- m(0) = static_cast<typename M::type>(pixel.l);
- m(1) = static_cast<typename M::type>(pixel.a);
- m(2) = static_cast<typename M::type>(pixel.b);
- }
- };
-
-
- template <
- typename T,
- typename P
- >
- inline const matrix<T,pixel_traits<P>::num,1> pixel_to_vector (
- const P& pixel
- )
- {
- COMPILE_TIME_ASSERT(pixel_traits<P>::num > 0);
- matrix<T,pixel_traits<P>::num,1> m;
- pixel_to_vector_helper<P>::assign(m,pixel);
- return m;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename P,
- int type = static_switch<
- pixel_traits<P>::grayscale,
- pixel_traits<P>::rgb,
- pixel_traits<P>::hsi,
- pixel_traits<P>::rgb_alpha,
- pixel_traits<P>::lab
- >::value
- >
- struct vector_to_pixel_helper;
-
- template <typename P>
- struct vector_to_pixel_helper<P,1>
- {
- template <typename M>
- static void assign (
- P& pixel,
- const M& m
- )
- {
- pixel = static_cast<unsigned char>(m(0));
- }
- };
-
- template <typename P>
- struct vector_to_pixel_helper<P,2>
- {
- template <typename M>
- static void assign (
- P& pixel,
- const M& m
- )
- {
- pixel.red = static_cast<unsigned char>(m(0));
- pixel.green = static_cast<unsigned char>(m(1));
- pixel.blue = static_cast<unsigned char>(m(2));
- }
- };
-
- template <typename P>
- struct vector_to_pixel_helper<P,3>
- {
- template <typename M>
- static void assign (
- P& pixel,
- const M& m
- )
- {
- pixel.h = static_cast<unsigned char>(m(0));
- pixel.s = static_cast<unsigned char>(m(1));
- pixel.i = static_cast<unsigned char>(m(2));
- }
- };
-
- template <typename P>
- struct vector_to_pixel_helper<P,4>
- {
- template <typename M>
- static void assign (
- P& pixel,
- const M& m
- )
- {
- pixel.red = static_cast<unsigned char>(m(0));
- pixel.green = static_cast<unsigned char>(m(1));
- pixel.blue = static_cast<unsigned char>(m(2));
- pixel.alpha = static_cast<unsigned char>(m(3));
- }
- };
-
- template <typename P>
- struct vector_to_pixel_helper<P,5>
- {
- template <typename M>
- static void assign (
- P& pixel,
- const M& m
- )
- {
- pixel.l = static_cast<unsigned char>(m(0));
- pixel.a = static_cast<unsigned char>(m(1));
- pixel.b = static_cast<unsigned char>(m(2));
- }
- };
-
- template <
- typename P,
- typename EXP
- >
- inline void vector_to_pixel (
- P& pixel,
- const matrix_exp<EXP>& vector
- )
- {
- COMPILE_TIME_ASSERT(pixel_traits<P>::num == matrix_exp<EXP>::NR);
- COMPILE_TIME_ASSERT(matrix_exp<EXP>::NC == 1);
- vector_to_pixel_helper<P>::assign(pixel,vector);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, long lower, long upper>
- struct op_clamp : basic_op_m<M>
- {
- op_clamp( const M& m_) : basic_op_m<M>(m_){}
-
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- const static long cost = M::cost + 2;
-
- const_ret_type apply ( long r, long c) const
- {
- const type temp = this->m(r,c);
- if (temp > static_cast<type>(upper))
- return static_cast<type>(upper);
- else if (temp < static_cast<type>(lower))
- return static_cast<type>(lower);
- else
- return temp;
- }
- };
-
- template <
- long l,
- long u,
- typename EXP
- >
- const matrix_op<op_clamp<EXP,l,u> > clamp (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_clamp<EXP,l,u> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_clamp2 : basic_op_m<M>
- {
- typedef typename M::type type;
-
- op_clamp2( const M& m_, const type& l, const type& u) :
- basic_op_m<M>(m_), lower(l), upper(u){}
-
- const type& lower;
- const type& upper;
-
- typedef const typename M::type const_ret_type;
- const static long cost = M::cost + 2;
-
- const_ret_type apply ( long r, long c) const
- {
- const type temp = this->m(r,c);
- if (temp > upper)
- return upper;
- else if (temp < lower)
- return lower;
- else
- return temp;
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_clamp2<EXP> > clamp (
- const matrix_exp<EXP>& m,
- const typename EXP::type& lower,
- const typename EXP::type& upper
- )
- {
- typedef op_clamp2<EXP> op;
- return matrix_op<op>(op(m.ref(),lower, upper));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2, typename M3>
- struct op_clamp_m : basic_op_mmm<M1,M2,M3>
- {
- op_clamp_m( const M1& m1_, const M2& m2_, const M3& m3_) :
- basic_op_mmm<M1,M2,M3>(m1_,m2_,m3_){}
-
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- const static long cost = M1::cost + M2::cost + M3::cost + 2;
-
- const_ret_type apply (long r, long c) const
- {
- const type val = this->m1(r,c);
- const type lower = this->m2(r,c);
- const type upper = this->m3(r,c);
- if (val <= upper)
- {
- if (lower <= val)
- return val;
- else
- return lower;
- }
- else
- {
- return upper;
- }
- }
- };
-
- template <
- typename EXP1,
- typename EXP2,
- typename EXP3
- >
- const matrix_op<op_clamp_m<EXP1,EXP2,EXP3> >
- clamp (
- const matrix_exp<EXP1>& m,
- const matrix_exp<EXP2>& lower,
- const matrix_exp<EXP3>& upper
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- COMPILE_TIME_ASSERT((is_same_type<typename EXP2::type,typename EXP3::type>::value == true));
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || EXP1::NR == 0 || EXP2::NR == 0);
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || EXP1::NR == 0 || EXP2::NC == 0);
- COMPILE_TIME_ASSERT(EXP2::NR == EXP3::NR || EXP2::NR == 0 || EXP3::NR == 0);
- COMPILE_TIME_ASSERT(EXP2::NC == EXP3::NC || EXP2::NC == 0 || EXP3::NC == 0);
- DLIB_ASSERT(m.nr() == lower.nr() &&
- m.nc() == lower.nc() &&
- m.nr() == upper.nr() &&
- m.nc() == upper.nc(),
- "\tconst matrix_exp clamp(m,lower,upper)"
- << "\n\t Invalid inputs were given to this function."
- << "\n\t m.nr(): " << m.nr()
- << "\n\t m.nc(): " << m.nc()
- << "\n\t lower.nr(): " << lower.nr()
- << "\n\t lower.nc(): " << lower.nc()
- << "\n\t upper.nr(): " << upper.nr()
- << "\n\t upper.nc(): " << upper.nc()
- );
-
- typedef op_clamp_m<EXP1,EXP2,EXP3> op;
- return matrix_op<op>(op(m.ref(),lower.ref(),upper.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_lowerbound : basic_op_m<M>
- {
- typedef typename M::type type;
-
- op_lowerbound( const M& m_, const type& thresh_) :
- basic_op_m<M>(m_), thresh(thresh_){}
-
- const type& thresh;
-
- typedef const typename M::type const_ret_type;
- const static long cost = M::cost + 2;
-
- const_ret_type apply ( long r, long c) const
- {
- const type temp = this->m(r,c);
- if (temp >= thresh)
- return temp;
- else
- return thresh;
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_lowerbound<EXP> > lowerbound (
- const matrix_exp<EXP>& m,
- const typename EXP::type& thresh
- )
- {
- typedef op_lowerbound<EXP> op;
- return matrix_op<op>(op(m.ref(), thresh));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_upperbound : basic_op_m<M>
- {
- typedef typename M::type type;
-
- op_upperbound( const M& m_, const type& thresh_) :
- basic_op_m<M>(m_), thresh(thresh_){}
-
- const type& thresh;
-
- typedef const typename M::type const_ret_type;
- const static long cost = M::cost + 2;
-
- const_ret_type apply ( long r, long c) const
- {
- const type temp = this->m(r,c);
- if (temp <= thresh)
- return temp;
- else
- return thresh;
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_upperbound<EXP> > upperbound (
- const matrix_exp<EXP>& m,
- const typename EXP::type& thresh
- )
- {
- typedef op_upperbound<EXP> op;
- return matrix_op<op>(op(m.ref(), thresh));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_reshape
- {
- op_reshape(const M& m_, const long& rows_, const long& cols_) : m(m_),rows(rows_),cols(cols_) {}
- const M& m;
- const long rows;
- const long cols;
-
- const static long cost = M::cost+2;
- const static long NR = 0;
- const static long NC = 0;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- const_ret_type apply ( long r, long c) const
- {
- const long idx = r*cols + c;
- return m(idx/m.nc(), idx%m.nc());
- }
-
- long nr () const { return rows; }
- long nc () const { return cols; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_reshape<EXP> > reshape (
- const matrix_exp<EXP>& m,
- const long& rows,
- const long& cols
- )
- {
- DLIB_ASSERT(m.size() == rows*cols && rows > 0 && cols > 0,
- "\tconst matrix_exp reshape(m, rows, cols)"
- << "\n\t The size of m must match the dimensions you want to reshape it into."
- << "\n\t m.size(): " << m.size()
- << "\n\t rows*cols: " << rows*cols
- << "\n\t rows: " << rows
- << "\n\t cols: " << cols
- );
-
- typedef op_reshape<EXP> op;
- return matrix_op<op>(op(m.ref(), rows, cols));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP1,
- typename EXP2
- >
- typename disable_if<is_complex<typename EXP1::type>,bool>::type equal (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b,
- const typename EXP1::type eps = 100*std::numeric_limits<typename EXP1::type>::epsilon()
- )
- {
- // check if the dimensions don't match
- if (a.nr() != b.nr() || a.nc() != b.nc())
- return false;
-
- for (long r = 0; r < a.nr(); ++r)
- {
- for (long c = 0; c < a.nc(); ++c)
- {
- if (std::abs(a(r,c)-b(r,c)) > eps)
- return false;
- }
- }
-
- // no non-equal points found so we return true
- return true;
- }
-
- template <
- typename EXP1,
- typename EXP2
- >
- typename enable_if<is_complex<typename EXP1::type>,bool>::type equal (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b,
- const typename EXP1::type::value_type eps = 100*std::numeric_limits<typename EXP1::type::value_type>::epsilon()
- )
- {
- // check if the dimensions don't match
- if (a.nr() != b.nr() || a.nc() != b.nc())
- return false;
-
- for (long r = 0; r < a.nr(); ++r)
- {
- for (long c = 0; c < a.nc(); ++c)
- {
- if (std::abs(real(a(r,c)-b(r,c))) > eps ||
- std::abs(imag(a(r,c)-b(r,c))) > eps)
- return false;
- }
- }
-
- // no non-equal points found so we return true
- return true;
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_scale_columns
- {
- op_scale_columns(const M1& m1_, const M2& m2_) : m1(m1_), m2(m2_) {}
- const M1& m1;
- const M2& m2;
-
- const static long cost = M1::cost + M2::cost + 1;
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
- const static long NR = M1::NR;
- const static long NC = M1::NC;
-
- const_ret_type apply ( long r, long c) const { return m1(r,c)*m2(c); }
-
- long nr () const { return m1.nr(); }
- long nc () const { return m1.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item) ; }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.destructively_aliases(item) || m2.aliases(item); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- const matrix_op<op_scale_columns<EXP1,EXP2> > scale_columns (
- const matrix_exp<EXP1>& m,
- const matrix_exp<EXP2>& v
- )
- {
- // Both arguments to this function must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- // The v argument must be a row or column vector.
- COMPILE_TIME_ASSERT((EXP2::NC == 1 || EXP2::NC == 0) || (EXP2::NR == 1 || EXP2::NR == 0));
-
- // figure out the compile time known length of v
- const long v_len = ((EXP2::NR)*(EXP2::NC) == 0)? 0 : (tmax<EXP2::NR,EXP2::NC>::value);
-
- // the length of v must match the number of columns in m
- COMPILE_TIME_ASSERT(EXP1::NC == v_len || EXP1::NC == 0 || v_len == 0);
-
- DLIB_ASSERT(is_vector(v) == true && v.size() == m.nc(),
- "\tconst matrix_exp scale_columns(m, v)"
- << "\n\tv must be a row or column vector and its length must match the number of columns in m"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tv.nr(): " << v.nr()
- << "\n\tv.nc(): " << v.nc()
- );
- typedef op_scale_columns<EXP1,EXP2> op;
- return matrix_op<op>(op(m.ref(),v.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_scale_columns_diag
- {
- op_scale_columns_diag(const M1& m1_, const M2& m2_) : m1(m1_), m2(m2_) {}
- const M1& m1;
- const M2& m2;
-
- const static long cost = M1::cost + M2::cost + 1;
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
- const static long NR = M1::NR;
- const static long NC = M1::NC;
-
- const_ret_type apply ( long r, long c) const { return m1(r,c)*m2(c,c); }
-
- long nr () const { return m1.nr(); }
- long nc () const { return m1.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item) ; }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.destructively_aliases(item) || m2.aliases(item); }
- };
-
-// turn expressions of the form mat*diagonal_matrix into scale_columns(mat, d)
- template <
- typename EXP1,
- typename EXP2
- >
- const matrix_op<op_scale_columns_diag<EXP1,EXP2> > operator* (
- const matrix_exp<EXP1>& m,
- const matrix_diag_exp<EXP2>& d
- )
- {
- // Both arguments to this function must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
-
- // figure out the compile time known length of d
- const long v_len = ((EXP2::NR)*(EXP2::NC) == 0)? 0 : (tmax<EXP2::NR,EXP2::NC>::value);
-
- // the length of d must match the number of columns in m
- COMPILE_TIME_ASSERT(EXP1::NC == v_len || EXP1::NC == 0 || v_len == 0);
-
- DLIB_ASSERT(m.nc() == d.nr(),
- "\tconst matrix_exp operator*(m, d)"
- << "\n\tmatrix dimensions don't match"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\td.nr(): " << d.nr()
- << "\n\td.nc(): " << d.nc()
- );
- typedef op_scale_columns_diag<EXP1,EXP2> op;
- return matrix_op<op>(op(m.ref(),d.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_scale_rows
- {
- op_scale_rows(const M1& m1_, const M2& m2_) : m1(m1_), m2(m2_) {}
- const M1& m1;
- const M2& m2;
-
- const static long cost = M1::cost + M2::cost + 1;
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
- const static long NR = M1::NR;
- const static long NC = M1::NC;
-
- const_ret_type apply ( long r, long c) const { return m1(r,c)*m2(r); }
-
- long nr () const { return m1.nr(); }
- long nc () const { return m1.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item) ; }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.destructively_aliases(item) || m2.aliases(item); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- const matrix_op<op_scale_rows<EXP1,EXP2> > scale_rows (
- const matrix_exp<EXP1>& m,
- const matrix_exp<EXP2>& v
- )
- {
- // Both arguments to this function must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- // The v argument must be a row or column vector.
- COMPILE_TIME_ASSERT((EXP2::NC == 1 || EXP2::NC == 0) || (EXP2::NR == 1 || EXP2::NR == 0));
-
- // figure out the compile time known length of v
- const long v_len = ((EXP2::NR)*(EXP2::NC) == 0)? 0 : (tmax<EXP2::NR,EXP2::NC>::value);
-
- // the length of v must match the number of rows in m
- COMPILE_TIME_ASSERT(EXP1::NR == v_len || EXP1::NR == 0 || v_len == 0);
-
- DLIB_ASSERT(is_vector(v) == true && v.size() == m.nr(),
- "\tconst matrix_exp scale_rows(m, v)"
- << "\n\tv must be a row or column vector and its length must match the number of rows in m"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tv.nr(): " << v.nr()
- << "\n\tv.nc(): " << v.nc()
- );
- typedef op_scale_rows<EXP1,EXP2> op;
- return matrix_op<op>(op(m.ref(),v.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_scale_rows_diag
- {
- op_scale_rows_diag(const M1& m1_, const M2& m2_) : m1(m1_), m2(m2_) {}
- const M1& m1;
- const M2& m2;
-
- const static long cost = M1::cost + M2::cost + 1;
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
- const static long NR = M1::NR;
- const static long NC = M1::NC;
-
- const_ret_type apply ( long r, long c) const { return m1(r,c)*m2(r,r); }
-
- long nr () const { return m1.nr(); }
- long nc () const { return m1.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item) ; }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.destructively_aliases(item) || m2.aliases(item); }
- };
-
-// turn expressions of the form diagonal_matrix*mat into scale_rows(mat, d)
- template <
- typename EXP1,
- typename EXP2
- >
- const matrix_op<op_scale_rows_diag<EXP1,EXP2> > operator* (
- const matrix_diag_exp<EXP2>& d,
- const matrix_exp<EXP1>& m
- )
- {
- // Both arguments to this function must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
-
- // figure out the compile time known length of d
- const long v_len = ((EXP2::NR)*(EXP2::NC) == 0)? 0 : (tmax<EXP2::NR,EXP2::NC>::value);
-
- // the length of d must match the number of rows in m
- COMPILE_TIME_ASSERT(EXP1::NR == v_len || EXP1::NR == 0 || v_len == 0);
-
- DLIB_ASSERT(d.nc() == m.nr(),
- "\tconst matrix_exp operator*(d, m)"
- << "\n\tThe dimensions of the d and m matrices don't match."
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\td.nr(): " << d.nr()
- << "\n\td.nc(): " << d.nc()
- );
- typedef op_scale_rows_diag<EXP1,EXP2> op;
- return matrix_op<op>(op(m.ref(),d.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- /*
- The idea here is to catch expressions of the form d*M*d where d is diagonal and M
- is some square matrix and turn them into something equivalent to
- pointwise_multiply(diag(d)*trans(diag(d)), M).
-
- The reason for this is that doing it this way is more numerically stable. In particular,
- doing 2 matrix multiplies as suggested by d*M*d could result in an asymmetric matrix even
- if M is symmetric to begin with.
- */
-
- template <typename M1, typename M2, typename M3>
- struct op_diag_m_diag
- {
- // This operator represents M1*M2*M3 where M1 and M3 are diagonal
-
- op_diag_m_diag(const M1& m1_, const M2& m2_, const M3& m3_) : m1(m1_), m2(m2_), m3(m3_) {}
- const M1& m1;
- const M2& m2;
- const M3& m3;
-
- const static long cost = M1::cost + M2::cost + M3::cost + 1;
- typedef typename M2::type type;
- typedef const typename M2::type const_ret_type;
- typedef typename M2::mem_manager_type mem_manager_type;
- typedef typename M2::layout_type layout_type;
- const static long NR = M2::NR;
- const static long NC = M2::NC;
-
- const_ret_type apply ( long r, long c) const { return (m1(r,r)*m3(c,c))*m2(r,c); }
-
- long nr () const { return m2.nr(); }
- long nc () const { return m2.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) ; }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m2.destructively_aliases(item) || m1.aliases(item) || m3.aliases(item) ; }
- };
-
- // catch d*(M*d) = EXP1*EXP2*EXP3
- template <
- typename EXP1,
- typename EXP2,
- typename EXP3
- >
- const matrix_op<op_diag_m_diag<EXP1,EXP2,EXP3> > operator* (
- const matrix_diag_exp<EXP1>& d,
- const matrix_exp<matrix_op<op_scale_columns_diag<EXP2,EXP3> > >& m
- )
- {
- // Both arguments to this function must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
-
- // figure out the compile time known length of d
- const long v_len = ((EXP1::NR)*(EXP1::NC) == 0)? 0 : (tmax<EXP1::NR,EXP1::NC>::value);
-
- // the length of d must match the number of rows in m
- COMPILE_TIME_ASSERT(EXP2::NR == v_len || EXP2::NR == 0 || v_len == 0);
-
- DLIB_ASSERT(d.nc() == m.nr(),
- "\tconst matrix_exp operator*(d, m)"
- << "\n\tmatrix dimensions don't match"
- << "\n\td.nr(): " << d.nr()
- << "\n\td.nc(): " << d.nc()
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- );
- typedef op_diag_m_diag<EXP1,EXP2,EXP3> op;
- return matrix_op<op>(op(d.ref(), m.ref().op.m1, m.ref().op.m2));
- }
-
- // catch (d*M)*d = EXP1*EXP2*EXP3
- template <
- typename EXP1,
- typename EXP2,
- typename EXP3
- >
- const matrix_op<op_diag_m_diag<EXP1,EXP2,EXP3> > operator* (
- const matrix_exp<matrix_op<op_scale_rows_diag<EXP2,EXP1> > >& m,
- const matrix_diag_exp<EXP3>& d
- )
- {
- // Both arguments to this function must contain the same type of element
- COMPILE_TIME_ASSERT((is_same_type<typename EXP3::type,typename EXP2::type>::value == true));
-
- // figure out the compile time known length of d
- const long v_len = ((EXP3::NR)*(EXP3::NC) == 0)? 0 : (tmax<EXP3::NR,EXP3::NC>::value);
-
- // the length of d must match the number of columns in m
- COMPILE_TIME_ASSERT(EXP2::NC == v_len || EXP2::NC == 0 || v_len == 0);
-
- DLIB_ASSERT(m.nc() == d.nr(),
- "\tconst matrix_exp operator*(m, d)"
- << "\n\tmatrix dimensions don't match"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\td.nr(): " << d.nr()
- << "\n\td.nc(): " << d.nc()
- );
- typedef op_diag_m_diag<EXP1,EXP2,EXP3> op;
- return matrix_op<op>(op(m.ref().op.m2, m.ref().op.m1, d.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- struct sort_columns_sort_helper
- {
- template <typename T>
- bool operator() (
- const T& item1,
- const T& item2
- ) const
- {
- return item1.first < item2.first;
- }
- };
-
- template <
- typename T, long NR, long NC, typename mm, typename l1,
- long NR2, long NC2, typename mm2, typename l2
- >
- void sort_columns (
- matrix<T,NR,NC,mm,l1>& m,
- matrix<T,NR2,NC2,mm2,l2>& v
- )
- {
- COMPILE_TIME_ASSERT(NC2 == 1 || NC2 == 0);
- COMPILE_TIME_ASSERT(NC == NR2 || NC == 0 || NR2 == 0);
-
- DLIB_ASSERT(is_col_vector(v) == true && v.size() == m.nc(),
- "\tconst matrix_exp sort_columns(m, v)"
- << "\n\tv must be a column vector and its length must match the number of columns in m"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tv.nr(): " << v.nr()
- << "\n\tv.nc(): " << v.nc()
- );
-
-
-
- // Now we have to sort the given vectors in the m matrix according
- // to how big their corresponding v(column index) values are.
- typedef std::pair<T, matrix<T,0,1,mm> > col_pair;
- typedef std_allocator<col_pair, mm> alloc;
- std::vector<col_pair,alloc> colvalues;
- col_pair p;
- for (long r = 0; r < v.nr(); ++r)
- {
- p.first = v(r);
- p.second = colm(m,r);
- colvalues.push_back(p);
- }
- std::sort(colvalues.begin(), colvalues.end(), sort_columns_sort_helper());
-
- for (long i = 0; i < v.nr(); ++i)
- {
- v(i) = colvalues[i].first;
- set_colm(m,i) = colvalues[i].second;
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T, long NR, long NC, typename mm, typename l1,
- long NR2, long NC2, typename mm2, typename l2
- >
- void rsort_columns (
- matrix<T,NR,NC,mm,l1>& m,
- matrix<T,NR2,NC2,mm2,l2>& v
- )
- {
- COMPILE_TIME_ASSERT(NC2 == 1 || NC2 == 0);
- COMPILE_TIME_ASSERT(NC == NR2 || NC == 0 || NR2 == 0);
-
- DLIB_ASSERT(is_col_vector(v) == true && v.size() == m.nc(),
- "\tconst matrix_exp rsort_columns(m, v)"
- << "\n\tv must be a column vector and its length must match the number of columns in m"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tv.nr(): " << v.nr()
- << "\n\tv.nc(): " << v.nc()
- );
-
-
-
- // Now we have to sort the given vectors in the m matrix according
- // to how big their corresponding v(column index) values are.
- typedef std::pair<T, matrix<T,0,1,mm> > col_pair;
- typedef std_allocator<col_pair, mm> alloc;
- std::vector<col_pair,alloc> colvalues;
- col_pair p;
- for (long r = 0; r < v.nr(); ++r)
- {
- p.first = v(r);
- p.second = colm(m,r);
- colvalues.push_back(p);
- }
- std::sort(colvalues.rbegin(), colvalues.rend(), sort_columns_sort_helper());
-
- for (long i = 0; i < v.nr(); ++i)
- {
- v(i) = colvalues[i].first;
- set_colm(m,i) = colvalues[i].second;
- }
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_tensor_product
- {
- op_tensor_product(const M1& m1_, const M2& m2_) : m1(m1_),m2(m2_) {}
- const M1& m1;
- const M2& m2;
-
- const static long cost = M1::cost + M2::cost + 1;
- const static long NR = M1::NR*M2::NR;
- const static long NC = M1::NC*M2::NC;
- typedef typename M1::type type;
- typedef const typename M1::type const_ret_type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- const_ret_type apply ( long r, long c) const
- {
- return m1(r/m2.nr(),c/m2.nc())*m2(r%m2.nr(),c%m2.nc());
- }
-
- long nr () const { return m1.nr()*m2.nr(); }
- long nc () const { return m1.nc()*m2.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_op<op_tensor_product<EXP1,EXP2> > tensor_product (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- typedef op_tensor_product<EXP1,EXP2> op;
- return matrix_op<op>(op(a.ref(),b.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_make_symmetric : basic_op_m<M>
- {
- op_make_symmetric ( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost+1;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r >= c)
- return this->m(r,c);
- else
- return this->m(c,r);
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_make_symmetric<EXP> > make_symmetric (
- const matrix_exp<EXP>& m
- )
- {
- DLIB_ASSERT(m.nr() == m.nc(),
- "\tconst matrix make_symmetric(m)"
- << "\n\t m must be a square matrix"
- << "\n\t m.nr(): " << m.nr()
- << "\n\t m.nc(): " << m.nc()
- );
-
- typedef op_make_symmetric<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_lowerm : basic_op_m<M>
- {
- op_lowerm( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost+2;
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r >= c)
- return this->m(r,c);
- else
- return 0;
- }
- };
-
- template <typename M>
- struct op_lowerm_s : basic_op_m<M>
- {
- typedef typename M::type type;
- op_lowerm_s( const M& m_, const type& s_) : basic_op_m<M>(m_), s(s_){}
-
- const type s;
-
- const static long cost = M::cost+2;
- typedef const typename M::type const_ret_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r > c)
- return this->m(r,c);
- else if (r==c)
- return s;
- else
- return 0;
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_lowerm<EXP> > lowerm (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_lowerm<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
- template <
- typename EXP
- >
- const matrix_op<op_lowerm_s<EXP> > lowerm (
- const matrix_exp<EXP>& m,
- typename EXP::type s
- )
- {
- typedef op_lowerm_s<EXP> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_upperm : basic_op_m<M>
- {
- op_upperm( const M& m_) : basic_op_m<M>(m_){}
-
- const static long cost = M::cost+2;
- typedef typename M::type type;
- typedef const typename M::type const_ret_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r <= c)
- return this->m(r,c);
- else
- return 0;
- }
- };
-
- template <typename M>
- struct op_upperm_s : basic_op_m<M>
- {
- typedef typename M::type type;
- op_upperm_s( const M& m_, const type& s_) : basic_op_m<M>(m_), s(s_){}
-
- const type s;
-
- const static long cost = M::cost+2;
- typedef const typename M::type const_ret_type;
- const_ret_type apply ( long r, long c) const
- {
- if (r < c)
- return this->m(r,c);
- else if (r==c)
- return s;
- else
- return 0;
- }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_upperm<EXP> > upperm (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_upperm<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
- template <
- typename EXP
- >
- const matrix_op<op_upperm_s<EXP> > upperm (
- const matrix_exp<EXP>& m,
- typename EXP::type s
- )
- {
- typedef op_upperm_s<EXP> op;
- return matrix_op<op>(op(m.ref(),s));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename rand_gen>
- inline const matrix<double> randm(
- long nr,
- long nc,
- rand_gen& rnd
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0,
- "\tconst matrix randm(nr, nc, rnd)"
- << "\n\tInvalid inputs to this function"
- << "\n\tnr: " << nr
- << "\n\tnc: " << nc
- );
-
- matrix<double> m(nr,nc);
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- m(r,c) = rnd.get_random_double();
- }
- }
-
- return m;
- }
-
-// ----------------------------------------------------------------------------------------
-
- inline const matrix<double> randm(
- long nr,
- long nc
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0,
- "\tconst matrix randm(nr, nc)"
- << "\n\tInvalid inputs to this function"
- << "\n\tnr: " << nr
- << "\n\tnc: " << nc
- );
-
- matrix<double> m(nr,nc);
- // make a double that contains RAND_MAX + the smallest number that still
- // makes the resulting double slightly bigger than static_cast<double>(RAND_MAX)
- double max_val = RAND_MAX;
- max_val += std::numeric_limits<double>::epsilon()*RAND_MAX;
-
- for (long r = 0; r < m.nr(); ++r)
- {
- for (long c = 0; c < m.nc(); ++c)
- {
- m(r,c) = std::rand()/max_val;
- }
- }
-
- return m;
- }
-
-// ----------------------------------------------------------------------------------------
-
- inline const matrix_range_exp<double> linspace (
- double start,
- double end,
- long num
- )
- {
- DLIB_ASSERT(num >= 0,
- "\tconst matrix_exp linspace(start, end, num)"
- << "\n\tInvalid inputs to this function"
- << "\n\tstart: " << start
- << "\n\tend: " << end
- << "\n\tnum: " << num
- );
-
- return matrix_range_exp<double>(start,end,num,false);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_linpiece
- {
- op_linpiece(const double val_, const M& joints_) : joints(joints_), val(val_){}
-
- const M& joints;
- const double val;
-
- const static long cost = 10;
-
- const static long NR = (M::NR*M::NC==0) ? (0) : (M::NR*M::NC-1);
- const static long NC = 1;
- typedef typename M::type type;
- typedef default_memory_manager mem_manager_type;
- typedef row_major_layout layout_type;
-
- typedef type const_ret_type;
- const_ret_type apply (long i, long ) const
- {
- if (joints(i) < val)
- return std::min<type>(val,joints(i+1)) - joints(i);
- else
- return 0;
- }
-
- long nr () const { return joints.size()-1; }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return joints.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return joints.aliases(item); }
- };
-
- template < typename EXP >
- const matrix_op<op_linpiece<EXP> > linpiece (
- const double val,
- const matrix_exp<EXP>& joints
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(is_vector(joints) && joints.size() >= 2,
- "\t matrix_exp linpiece()"
- << "\n\t Invalid inputs were given to this function "
- << "\n\t is_vector(joints): " << is_vector(joints)
- << "\n\t joints.size(): " << joints.size()
- );
-#ifdef ENABLE_ASSERTS
- for (long i = 1; i < joints.size(); ++i)
- {
- DLIB_ASSERT(joints(i-1) < joints(i),
- "\t matrix_exp linpiece()"
- << "\n\t Invalid inputs were given to this function "
- << "\n\t joints("<<i-1<<"): " << joints(i-1)
- << "\n\t joints("<<i<<"): " << joints(i)
- );
- }
-#endif
-
- typedef op_linpiece<EXP> op;
- return matrix_op<op>(op(val,joints.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- inline const matrix_log_range_exp<double> logspace (
- double start,
- double end,
- long num
- )
- {
- DLIB_ASSERT(num >= 0,
- "\tconst matrix_exp logspace(start, end, num)"
- << "\n\tInvalid inputs to this function"
- << "\n\tstart: " << start
- << "\n\tend: " << end
- << "\n\tnum: " << num
- );
-
- return matrix_log_range_exp<double>(start,end,num);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_cart_prod
- {
- op_cart_prod(const M1& m1_, const M2& m2_) : m1(m1_),m2(m2_) {}
- const M1& m1;
- const M2& m2;
-
- const static long cost = M1::cost+M2::cost+1;
- typedef typename M1::type type;
- typedef const typename M1::const_ret_type const_ret_type;
-
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
- const static long NR = M1::NR+M2::NR;
- const static long NC = M1::NC*M2::NC;
-
- const_ret_type apply ( long r, long c) const
- {
- if (r < m1.nr())
- return m1(r, c/m2.nc());
- else
- return m2(r-m1.nr(), c%m2.nc());
- }
-
- long nr () const { return m1.nr() + m2.nr(); }
- long nc () const { return m1.nc() * m2.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- const matrix_op<op_cart_prod<EXP1,EXP2> > cartesian_product (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
-
- typedef op_cart_prod<EXP1,EXP2> op;
- return matrix_op<op>(op(a.ref(),b.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_mat_to_vect
- {
- op_mat_to_vect(const M& m_) : m(m_) {}
- const M& m;
-
- const static long cost = M::cost+2;
- const static long NR = M::NC*M::NR;
- const static long NC = 1;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- const_ret_type apply ( long r, long ) const { return m(r/m.nc(), r%m.nc()); }
-
- long nr () const { return m.size(); }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP
- >
- const matrix_op<op_mat_to_vect<EXP> > reshape_to_column_vector (
- const matrix_exp<EXP>& m
- )
- {
- typedef op_mat_to_vect<EXP> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR_,
- long NC_,
- typename MM
- >
- struct op_mat_to_vect2
- {
- typedef matrix<T,NR_,NC_,MM,row_major_layout> M;
- op_mat_to_vect2(const M& m_) : m(m_) {}
- const M& m;
-
- const static long cost = M::cost+2;
- const static long NR = M::NC*M::NR;
- const static long NC = 1;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- const_ret_type apply ( long r, long ) const { return (&m(0,0))[r]; }
-
- long nr () const { return m.size(); }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM
- >
- const matrix_op<op_mat_to_vect2<T,NR,NC,MM> > reshape_to_column_vector (
- const matrix<T,NR,NC,MM,row_major_layout>& m
- )
- {
- typedef op_mat_to_vect2<T,NR,NC,MM> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_join_rows
- {
- op_join_rows(const M1& m1_, const M2& m2_) : m1(m1_),m2(m2_),_nr(std::max(m1.nr(),m2.nr())) {}
- const M1& m1;
- const M2& m2;
- const long _nr;
-
- template <typename T, typename U, bool selection>
- struct type_selector;
- template <typename T, typename U>
- struct type_selector<T,U,true> { typedef T type; };
- template <typename T, typename U>
- struct type_selector<T,U,false> { typedef U type; };
-
- // If both const_ret_types are references then we should use them as the const_ret_type type
- // but otherwise we should use the normal type.
- typedef typename M1::const_ret_type T1;
- typedef typename M1::type T2;
- typedef typename M2::const_ret_type T3;
- typedef typename type_selector<T1, T2, is_reference_type<T1>::value && is_reference_type<T3>::value>::type const_ret_type;
-
- const static long cost = M1::cost + M2::cost + 1;
- const static long NR = tmax<M1::NR, M2::NR>::value;
- const static long NC = (M1::NC*M2::NC != 0)? (M1::NC+M2::NC) : (0);
- typedef typename M1::type type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- const_ret_type apply (long r, long c) const
- {
- if (c < m1.nc())
- return m1(r,c);
- else
- return m2(r,c-m1.nc());
- }
-
- long nr () const { return _nr; }
- long nc () const { return m1.nc()+m2.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_op<op_join_rows<EXP1,EXP2> > join_rows (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- // You are getting an error on this line because you are trying to join two matrices that
- // don't have the same number of rows
- COMPILE_TIME_ASSERT(EXP1::NR == EXP2::NR || (EXP1::NR*EXP2::NR == 0));
-
- DLIB_ASSERT(a.nr() == b.nr() || a.size() == 0 || b.size() == 0,
- "\tconst matrix_exp join_rows(const matrix_exp& a, const matrix_exp& b)"
- << "\n\tYou can only use join_rows() if both matrices have the same number of rows"
- << "\n\ta.nr(): " << a.nr()
- << "\n\tb.nr(): " << b.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nc(): " << b.nc()
- );
-
- typedef op_join_rows<EXP1,EXP2> op;
- return matrix_op<op>(op(a.ref(),b.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M1, typename M2>
- struct op_join_cols
- {
- op_join_cols(const M1& m1_, const M2& m2_) : m1(m1_),m2(m2_),_nc(std::max(m1.nc(),m2.nc())) {}
- const M1& m1;
- const M2& m2;
- const long _nc;
-
- template <typename T, typename U, bool selection>
- struct type_selector;
- template <typename T, typename U>
- struct type_selector<T,U,true> { typedef T type; };
- template <typename T, typename U>
- struct type_selector<T,U,false> { typedef U type; };
-
- // If both const_ret_types are references then we should use them as the const_ret_type type
- // but otherwise we should use the normal type.
- typedef typename M1::const_ret_type T1;
- typedef typename M1::type T2;
- typedef typename M2::const_ret_type T3;
- typedef typename type_selector<T1, T2, is_reference_type<T1>::value && is_reference_type<T3>::value>::type const_ret_type;
-
-
-
- const static long cost = M1::cost + M2::cost + 1;
- const static long NC = tmax<M1::NC, M2::NC>::value;
- const static long NR = (M1::NR*M2::NR != 0)? (M1::NR+M2::NR) : (0);
- typedef typename M1::type type;
- typedef typename M1::mem_manager_type mem_manager_type;
- typedef typename M1::layout_type layout_type;
-
- const_ret_type apply ( long r, long c) const
- {
- if (r < m1.nr())
- return m1(r,c);
- else
- return m2(r-m1.nr(),c);
- }
-
- long nr () const { return m1.nr()+m2.nr(); }
- long nc () const { return _nc; }
-
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const
- { return m1.aliases(item) || m2.aliases(item); }
- };
-
- template <
- typename EXP1,
- typename EXP2
- >
- inline const matrix_op<op_join_cols<EXP1,EXP2> > join_cols (
- const matrix_exp<EXP1>& a,
- const matrix_exp<EXP2>& b
- )
- {
- COMPILE_TIME_ASSERT((is_same_type<typename EXP1::type,typename EXP2::type>::value == true));
- // You are getting an error on this line because you are trying to join two matrices that
- // don't have the same number of columns
- COMPILE_TIME_ASSERT(EXP1::NC == EXP2::NC || (EXP1::NC*EXP2::NC == 0));
-
- DLIB_ASSERT(a.nc() == b.nc() || a.size() == 0 || b.size() == 0,
- "\tconst matrix_exp join_cols(const matrix_exp& a, const matrix_exp& b)"
- << "\n\tYou can only use join_cols() if both matrices have the same number of columns"
- << "\n\ta.nr(): " << a.nr()
- << "\n\tb.nr(): " << b.nr()
- << "\n\ta.nc(): " << a.nc()
- << "\n\tb.nc(): " << b.nc()
- );
-
- typedef op_join_cols<EXP1,EXP2> op;
- return matrix_op<op>(op(a.ref(),b.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_fliplr
- {
- op_fliplr( const M& m_) : m(m_){}
-
- const M& m;
-
- const static long cost = M::cost;
- const static long NR = M::NR;
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- const_ret_type apply (long r, long c) const { return m(r,m.nc()-c-1); }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
-
- };
-
- template <
- typename M
- >
- const matrix_op<op_fliplr<M> > fliplr (
- const matrix_exp<M>& m
- )
- {
- typedef op_fliplr<M> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_flipud
- {
- op_flipud( const M& m_) : m(m_){}
-
- const M& m;
-
- const static long cost = M::cost;
- const static long NR = M::NR;
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- const_ret_type apply (long r, long c) const { return m(m.nr()-r-1,c); }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
-
- };
-
- template <
- typename M
- >
- const matrix_op<op_flipud<M> > flipud (
- const matrix_exp<M>& m
- )
- {
- typedef op_flipud<M> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M>
- struct op_flip
- {
- op_flip( const M& m_) : m(m_){}
-
- const M& m;
-
- const static long cost = M::cost;
- const static long NR = M::NR;
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef typename M::const_ret_type const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- const_ret_type apply (long r, long c) const { return m(m.nr()-r-1, m.nc()-c-1); }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
-
- };
-
- template <
- typename M
- >
- const matrix_op<op_flip<M> > flip (
- const matrix_exp<M>& m
- )
- {
- typedef op_flip<M> op;
- return matrix_op<op>(op(m.ref()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T, long NR, long NC, typename MM, typename L>
- uint32 hash (
- const matrix<T,NR,NC,MM,L>& item,
- uint32 seed = 0
- )
- {
- DLIB_ASSERT_HAS_STANDARD_LAYOUT(T);
-
- if (item.size() == 0)
- return 0;
- else
- return murmur_hash3(&item(0,0), sizeof(T)*item.size(), seed);
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_UTILITIES_
-
diff --git a/ml/dlib/dlib/matrix/matrix_utilities_abstract.h b/ml/dlib/dlib/matrix/matrix_utilities_abstract.h
deleted file mode 100644
index ad4c91167..000000000
--- a/ml/dlib/dlib/matrix/matrix_utilities_abstract.h
+++ /dev/null
@@ -1,1874 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MATRIx_UTILITIES_ABSTRACT_
-#ifdef DLIB_MATRIx_UTILITIES_ABSTRACT_
-
-#include "matrix_abstract.h"
-#include <complex>
-#include "../pixel.h"
-#include "../geometry/rectangle.h"
-#inclue <vector>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Simple matrix utilities
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP>
- constexpr bool is_row_major (
- const matrix_exp<EXP>&
- );
- /*!
- ensures
- - returns true if and only if the given matrix expression uses the row_major_layout.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp diag (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a column vector R that contains the elements from the diagonal
- of m in the order R(0)==m(0,0), R(1)==m(1,1), R(2)==m(2,2) and so on.
- !*/
-
- template <typename EXP>
- struct diag_exp
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This struct allows you to determine the type of matrix expression
- object returned from the diag() function. An example makes its
- use clear:
-
- template <typename EXP>
- void do_something( const matrix_exp<EXP>& mat)
- {
- // d is a matrix expression that aliases mat.
- typename diag_exp<EXP>::type d = diag(mat);
-
- // Print the diagonal of mat. So we see that by using
- // diag_exp we can save the object returned by diag() in
- // a local variable.
- cout << d << endl;
-
- // Note that you can only save the return value of diag() to
- // a local variable if the argument to diag() has a lifetime
- // beyond the diag() expression. The example shown above is
- // OK but the following would result in undefined behavior:
- typename diag_exp<EXP>::type bad = diag(mat + mat);
- }
- !*/
- typedef type_of_expression_returned_by_diag type;
- };
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp diagm (
- const matrix_exp& m
- );
- /*!
- requires
- - is_vector(m) == true
- (i.e. m is a row or column matrix)
- ensures
- - returns a square matrix M such that:
- - diag(M) == m
- - non diagonal elements of M are 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp trans (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns the transpose of the matrix m
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_type::type dot (
- const matrix_exp& m1,
- const matrix_exp& m2
- );
- /*!
- requires
- - is_vector(m1) == true
- - is_vector(m2) == true
- - m1.size() == m2.size()
- - m1.size() > 0
- ensures
- - returns the dot product between m1 and m2. That is, this function
- computes and returns the sum, for all i, of m1(i)*m2(i).
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp lowerm (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix M such that:
- - M::type == the same type that was in m
- - M has the same dimensions as m
- - M is the lower triangular part of m. That is:
- - if (r >= c) then
- - M(r,c) == m(r,c)
- - else
- - M(r,c) == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp lowerm (
- const matrix_exp& m,
- const matrix_exp::type scalar_value
- );
- /*!
- ensures
- - returns a matrix M such that:
- - M::type == the same type that was in m
- - M has the same dimensions as m
- - M is the lower triangular part of m except that the diagonal has
- been set to scalar_value. That is:
- - if (r > c) then
- - M(r,c) == m(r,c)
- - else if (r == c) then
- - M(r,c) == scalar_value
- - else
- - M(r,c) == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp upperm (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix M such that:
- - M::type == the same type that was in m
- - M has the same dimensions as m
- - M is the upper triangular part of m. That is:
- - if (r <= c) then
- - M(r,c) == m(r,c)
- - else
- - M(r,c) == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp upperm (
- const matrix_exp& m,
- const matrix_exp::type scalar_value
- );
- /*!
- ensures
- - returns a matrix M such that:
- - M::type == the same type that was in m
- - M has the same dimensions as m
- - M is the upper triangular part of m except that the diagonal has
- been set to scalar_value. That is:
- - if (r < c) then
- - M(r,c) == m(r,c)
- - else if (r == c) then
- - M(r,c) == scalar_value
- - else
- - M(r,c) == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp make_symmetric (
- const matrix_exp& m
- );
- /*!
- requires
- - m.nr() == m.nc()
- (i.e. m must be a square matrix)
- ensures
- - returns a matrix M such that:
- - M::type == the same type that was in m
- - M has the same dimensions as m
- - M is a symmetric matrix, that is, M == trans(M) and
- it is constructed from the lower triangular part of m. Specifically,
- we have:
- - lowerm(M) == lowerm(m)
- - upperm(M) == trans(lowerm(m))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- T val
- >
- const matrix_exp uniform_matrix (
- );
- /*!
- requires
- - NR > 0 && NC > 0
- ensures
- - returns an NR by NC matrix with elements of type T and all set to val.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC
- >
- const matrix_exp uniform_matrix (
- const T& val
- );
- /*!
- requires
- - NR > 0 && NC > 0
- ensures
- - returns an NR by NC matrix with elements of type T and all set to val.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_exp uniform_matrix (
- long nr,
- long nc,
- const T& val
- );
- /*!
- requires
- - nr >= 0 && nc >= 0
- ensures
- - returns an nr by nc matrix with elements of type T and all set to val.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp ones_matrix (
- const matrix_exp& mat
- );
- /*!
- requires
- - mat.nr() >= 0 && mat.nc() >= 0
- ensures
- - Let T denote the type of element in mat. Then this function
- returns uniform_matrix<T>(mat.nr(), mat.nc(), 1)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_exp ones_matrix (
- long nr,
- long nc
- );
- /*!
- requires
- - nr >= 0 && nc >= 0
- ensures
- - returns uniform_matrix<T>(nr, nc, 1)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp zeros_matrix (
- const matrix_exp& mat
- );
- /*!
- requires
- - mat.nr() >= 0 && mat.nc() >= 0
- ensures
- - Let T denote the type of element in mat. Then this function
- returns uniform_matrix<T>(mat.nr(), mat.nc(), 0)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_exp zeros_matrix (
- long nr,
- long nc
- );
- /*!
- requires
- - nr >= 0 && nc >= 0
- ensures
- - returns uniform_matrix<T>(nr, nc, 0)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp identity_matrix (
- const matrix_exp& mat
- );
- /*!
- requires
- - mat.nr() == mat.nc()
- ensures
- - returns an identity matrix with the same dimensions as mat and
- containing the same type of elements as mat.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- const matrix_exp identity_matrix (
- long N
- );
- /*!
- requires
- - N > 0
- ensures
- - returns an N by N identity matrix with elements of type T.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long N
- >
- const matrix_exp identity_matrix (
- );
- /*!
- requires
- - N > 0
- ensures
- - returns an N by N identity matrix with elements of type T.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp linspace (
- double start,
- double end,
- long num
- );
- /*!
- requires
- - num >= 0
- ensures
- - returns a matrix M such that:
- - M::type == double
- - is_row_vector(M) == true
- - M.size() == num
- - M == a row vector with num linearly spaced values beginning with start
- and stopping with end.
- - M(num-1) == end
- - if (num > 1) then
- - M(0) == start
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp logspace (
- double start,
- double end,
- long num
- );
- /*!
- requires
- - num >= 0
- ensures
- - returns a matrix M such that:
- - M::type == double
- - is_row_vector(M) == true
- - M.size() == num
- - M == a row vector with num logarithmically spaced values beginning with
- 10^start and stopping with 10^end.
- (i.e. M == pow(10, linspace(start, end, num)))
- - M(num-1) == 10^end
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp linpiece (
- const double val,
- const matrix_exp& joints
- );
- /*!
- requires
- - is_vector(joints) == true
- - joints.size() >= 2
- - for all valid i < j:
- - joints(i) < joints(j)
- ensures
- - linpiece() is useful for creating piecewise linear functions of val. For
- example, if w is a parameter vector then you can represent a piecewise linear
- function of val as: f(val) = dot(w, linpiece(val, linspace(0,100,5))). In
- this case, f(val) is piecewise linear on the intervals [0,25], [25,50],
- [50,75], [75,100]. Moreover, w(i) defines the derivative of f(val) in the
- i-th interval. Finally, outside the interval [0,100] f(val) has a derivative
- of zero and f(0) == 0.
- - To be precise, this function returns a column vector L such that:
- - L.size() == joints.size()-1
- - is_col_vector(L) == true
- - L contains the same type of elements as joints.
- - for all valid i:
- - if (joints(i) < val)
- - L(i) == min(val,joints(i+1)) - joints(i)
- - else
- - L(i) == 0
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- long R,
- long C
- >
- const matrix_exp rotate (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- R( (r+R)%m.nr() , (c+C)%m.nc() ) == m(r,c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp fliplr (
- const matrix_exp& m
- );
- /*!
- ensures
- - flips the matrix m from left to right and returns the result.
- I.e. reverses the order of the columns.
- - returns a matrix M such that:
- - M::type == the same type that was in m
- - M has the same dimensions as m
- - for all valid r and c:
- M(r,c) == m(r, m.nc()-c-1)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp flipud (
- const matrix_exp& m
- );
- /*!
- ensures
- - flips the matrix m from up to down and returns the result.
- I.e. reverses the order of the rows.
- - returns a matrix M such that:
- - M::type == the same type that was in m
- - M has the same dimensions as m
- - for all valid r and c:
- M(r,c) == m(m.nr()-r-1, c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp flip (
- const matrix_exp& m
- );
- /*!
- ensures
- - flips the matrix m from up to down and left to right and returns the
- result. I.e. returns flipud(fliplr(m)).
- - returns a matrix M such that:
- - M::type == the same type that was in m
- - M has the same dimensions as m
- - for all valid r and c:
- M(r,c) == m(m.nr()-r-1, m.nc()-c-1)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp reshape (
- const matrix_exp& m,
- long rows,
- long cols
- );
- /*!
- requires
- - m.size() == rows*cols
- - rows > 0
- - cols > 0
- ensures
- - returns a matrix M such that:
- - M.nr() == rows
- - M.nc() == cols
- - M.size() == m.size()
- - for all valid r and c:
- - let IDX = r*cols + c
- - M(r,c) == m(IDX/m.nc(), IDX%m.nc())
-
- - i.e. The matrix m is reshaped into a new matrix of rows by cols
- dimension. Additionally, the elements of m are laid into M in row major
- order.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp reshape_to_column_vector (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix M such that:
- - is_col_vector(M) == true
- - M.size() == m.size()
- - for all valid r and c:
- - m(r,c) == M(r*m.nc() + c)
-
- - i.e. The matrix m is reshaped into a column vector. Note that
- the elements are pulled out in row major order.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- long R,
- long C
- >
- const matrix_exp removerc (
- const matrix_exp& m
- );
- /*!
- requires
- - m.nr() > R >= 0
- - m.nc() > C >= 0
- ensures
- - returns a matrix M such that:
- - M.nr() == m.nr() - 1
- - M.nc() == m.nc() - 1
- - M == m with its R row and C column removed
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp removerc (
- const matrix_exp& m,
- long R,
- long C
- );
- /*!
- requires
- - m.nr() > R >= 0
- - m.nc() > C >= 0
- ensures
- - returns a matrix M such that:
- - M.nr() == m.nr() - 1
- - M.nc() == m.nc() - 1
- - M == m with its R row and C column removed
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- long R
- >
- const matrix_exp remove_row (
- const matrix_exp& m
- );
- /*!
- requires
- - m.nr() > R >= 0
- ensures
- - returns a matrix M such that:
- - M.nr() == m.nr() - 1
- - M.nc() == m.nc()
- - M == m with its R row removed
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp remove_row (
- const matrix_exp& m,
- long R
- );
- /*!
- requires
- - m.nr() > R >= 0
- ensures
- - returns a matrix M such that:
- - M.nr() == m.nr() - 1
- - M.nc() == m.nc()
- - M == m with its R row removed
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- long C
- >
- const matrix_exp remove_col (
- const matrix_exp& m
- );
- /*!
- requires
- - m.nc() > C >= 0
- ensures
- - returns a matrix M such that:
- - M.nr() == m.nr()
- - M.nc() == m.nc() - 1
- - M == m with its C column removed
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp remove_col (
- const matrix_exp& m,
- long C
- );
- /*!
- requires
- - m.nc() > C >= 0
- ensures
- - returns a matrix M such that:
- - M.nr() == m.nr()
- - M.nc() == m.nc() - 1
- - M == m with its C column removed
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename target_type
- >
- const matrix_exp matrix_cast (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R where for all valid r and c:
- R(r,c) == static_cast<target_type>(m(r,c))
- also, R has the same dimensions as m.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename U,
- typename L
- >
- void set_all_elements (
- matrix<T,NR,NC,MM,L>& m,
- U value
- );
- /*!
- ensures
- - for all valid r and c:
- m(r,c) == value
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::matrix_type tmp (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a temporary matrix object that is a copy of m.
- (This allows you to easily force a matrix_exp to fully evaluate)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- long NR,
- long NC,
- typename MM,
- typename L
- >
- uint32 hash (
- const matrix<T,NR,NC,MM,L>& item,
- uint32 seed = 0
- );
- /*!
- requires
- - T is a standard layout type (e.g. a POD type like int, float,
- or a simple struct).
- ensures
- - returns a 32bit hash of the data stored in item.
- - Each value of seed results in a different hash function being used.
- (e.g. hash(item,0) should generally not be equal to hash(item,1))
- - uses the murmur_hash3() routine to compute the actual hash.
- - Note that if the memory layout of the elements in item change between
- hardware platforms then hash() will give different outputs. If you want
- hash() to always give the same output for the same input then you must
- ensure that elements of item always have the same layout in memory.
- Typically this means using fixed width types and performing byte swapping
- to account for endianness before passing item to hash().
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- // if matrix_exp contains non-complex types (e.g. float, double)
- bool equal (
- const matrix_exp& a,
- const matrix_exp& b,
- const matrix_exp::type epsilon = 100*std::numeric_limits<matrix_exp::type>::epsilon()
- );
- /*!
- ensures
- - if (a and b don't have the same dimensions) then
- - returns false
- - else if (there exists an r and c such that abs(a(r,c)-b(r,c)) > epsilon) then
- - returns false
- - else
- - returns true
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- // if matrix_exp contains std::complex types
- bool equal (
- const matrix_exp& a,
- const matrix_exp& b,
- const matrix_exp::type::value_type epsilon = 100*std::numeric_limits<matrix_exp::type::value_type>::epsilon()
- );
- /*!
- ensures
- - if (a and b don't have the same dimensions) then
- - returns false
- - else if (there exists an r and c such that abs(real(a(r,c)-b(r,c))) > epsilon
- or abs(imag(a(r,c)-b(r,c))) > epsilon) then
- - returns false
- - else
- - returns true
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp pointwise_multiply (
- const matrix_exp& a,
- const matrix_exp& b
- );
- /*!
- requires
- - a.nr() == b.nr()
- - a.nc() == b.nc()
- - a and b both contain the same type of element (one or both
- can also be of type std::complex so long as the underlying type
- in them is the same)
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in a and b.
- - R has the same dimensions as a and b.
- - for all valid r and c:
- R(r,c) == a(r,c) * b(r,c)
- !*/
-
- const matrix_exp pointwise_multiply (
- const matrix_exp& a,
- const matrix_exp& b,
- const matrix_exp& c
- );
- /*!
- performs pointwise_multiply(a,pointwise_multiply(b,c));
- !*/
-
- const matrix_exp pointwise_multiply (
- const matrix_exp& a,
- const matrix_exp& b,
- const matrix_exp& c,
- const matrix_exp& d
- );
- /*!
- performs pointwise_multiply(pointwise_multiply(a,b),pointwise_multiply(c,d));
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp join_rows (
- const matrix_exp& a,
- const matrix_exp& b
- );
- /*!
- requires
- - a.nr() == b.nr() || a.size() == 0 || b.size() == 0
- - a and b both contain the same type of element
- ensures
- - This function joins two matrices together by concatenating their rows.
- - returns a matrix R such that:
- - R::type == the same type that was in a and b.
- - R.nr() == a.nr() == b.nr()
- - R.nc() == a.nc() + b.nc()
- - for all valid r and c:
- - if (c < a.nc()) then
- - R(r,c) == a(r,c)
- - else
- - R(r,c) == b(r, c-a.nc())
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp join_cols (
- const matrix_exp& a,
- const matrix_exp& b
- );
- /*!
- requires
- - a.nc() == b.nc() || a.size() == 0 || b.size() == 0
- - a and b both contain the same type of element
- ensures
- - This function joins two matrices together by concatenating their columns.
- - returns a matrix R such that:
- - R::type == the same type that was in a and b.
- - R.nr() == a.nr() + b.nr()
- - R.nc() == a.nc() == b.nc()
- - for all valid r and c:
- - if (r < a.nr()) then
- - R(r,c) == a(r,c)
- - else
- - R(r,c) == b(r-a.nr(), c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp tensor_product (
- const matrix_exp& a,
- const matrix_exp& b
- );
- /*!
- requires
- - a and b both contain the same type of element
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in a and b.
- - R.nr() == a.nr() * b.nr()
- - R.nc() == a.nc() * b.nc()
- - for all valid r and c:
- R(r,c) == a(r/b.nr(), c/b.nc()) * b(r%b.nr(), c%b.nc())
- - I.e. R is the tensor product of matrix a with matrix b
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp cartesian_product (
- const matrix_exp& A,
- const matrix_exp& B
- );
- /*!
- requires
- - A and B both contain the same type of element
- ensures
- - Think of A and B as sets of column vectors. Then this function
- returns a matrix that contains a set of column vectors that is
- the Cartesian product of the sets A and B. That is, the resulting
- matrix contains every possible combination of vectors from both A and
- B.
- - returns a matrix R such that:
- - R::type == the same type that was in A and B.
- - R.nr() == A.nr() + B.nr()
- - R.nc() == A.nc() * B.nc()
- - Each column of R is the concatenation of a column vector
- from A with a column vector from B.
- - for all valid r and c:
- - if (r < A.nr()) then
- - R(r,c) == A(r, c/B.nc())
- - else
- - R(r,c) == B(r-A.nr(), c%B.nc())
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp scale_columns (
- const matrix_exp& m,
- const matrix_exp& v
- );
- /*!
- requires
- - is_vector(v) == true
- - v.size() == m.nc()
- - m and v both contain the same type of element
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m and v.
- - R has the same dimensions as m.
- - for all valid r and c:
- R(r,c) == m(r,c) * v(c)
- - i.e. R is the result of multiplying each of m's columns by
- the corresponding scalar in v.
-
- - Note that this function is identical to the expression m*diagm(v).
- That is, the * operator is overloaded for this case and will invoke
- scale_columns() automatically as appropriate.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp scale_rows (
- const matrix_exp& m,
- const matrix_exp& v
- );
- /*!
- requires
- - is_vector(v) == true
- - v.size() == m.nr()
- - m and v both contain the same type of element
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m and v.
- - R has the same dimensions as m.
- - for all valid r and c:
- R(r,c) == m(r,c) * v(r)
- - i.e. R is the result of multiplying each of m's rows by
- the corresponding scalar in v.
-
- - Note that this function is identical to the expression diagm(v)*m.
- That is, the * operator is overloaded for this case and will invoke
- scale_rows() automatically as appropriate.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void sort_columns (
- matrix<T>& m,
- matrix<T>& v
- );
- /*!
- requires
- - is_col_vector(v) == true
- - v.size() == m.nc()
- - m and v both contain the same type of element
- ensures
- - the dimensions for m and v are not changed
- - sorts the columns of m according to the values in v.
- i.e.
- - #v == the contents of v but in sorted order according to
- operator<. So smaller elements come first.
- - Let #v(new(i)) == v(i) (i.e. new(i) is the index element i moved to)
- - colm(#m,new(i)) == colm(m,i)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void rsort_columns (
- matrix<T>& m,
- matrix<T>& v
- );
- /*!
- requires
- - is_col_vector(v) == true
- - v.size() == m.nc()
- - m and v both contain the same type of element
- ensures
- - the dimensions for m and v are not changed
- - sorts the columns of m according to the values in v.
- i.e.
- - #v == the contents of v but in sorted order according to
- operator>. So larger elements come first.
- - Let #v(new(i)) == v(i) (i.e. new(i) is the index element i moved to)
- - colm(#m,new(i)) == colm(m,i)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type length_squared (
- const matrix_exp& m
- );
- /*!
- requires
- - is_vector(m) == true
- ensures
- - returns sum(squared(m))
- (i.e. returns the square of the length of the vector m)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type length (
- const matrix_exp& m
- );
- /*!
- requires
- - is_vector(m) == true
- ensures
- - returns sqrt(sum(squared(m)))
- (i.e. returns the length of the vector m)
- - if (m contains integer valued elements) then
- - The return type is a double that represents the length. Therefore, the
- return value of length() is always represented using a floating point
- type.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- bool is_row_vector (
- const matrix_exp& m
- );
- /*!
- ensures
- - if (m.nr() == 1) then
- - return true
- - else
- - returns false
- !*/
-
- bool is_col_vector (
- const matrix_exp& m
- );
- /*!
- ensures
- - if (m.nc() == 1) then
- - return true
- - else
- - returns false
- !*/
-
- bool is_vector (
- const matrix_exp& m
- );
- /*!
- ensures
- - if (is_row_vector(m) || is_col_vector(m)) then
- - return true
- - else
- - returns false
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- bool is_finite (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns true if all the values in m are finite values and also not any kind
- of NaN value.
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Thresholding relational operators
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator< (
- const matrix_exp& m,
- const S& s
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (m(r,c) < s) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator< (
- const S& s,
- const matrix_exp& m
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (s < m(r,c)) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator<= (
- const matrix_exp& m,
- const S& s
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (m(r,c) <= s) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator<= (
- const S& s,
- const matrix_exp& m
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (s <= m(r,c)) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator> (
- const matrix_exp& m,
- const S& s
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (m(r,c) > s) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator> (
- const S& s,
- const matrix_exp& m
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (s > m(r,c)) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator>= (
- const matrix_exp& m,
- const S& s
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (m(r,c) >= s) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator>= (
- const S& s,
- const matrix_exp& m
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (s >= m(r,c)) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator== (
- const matrix_exp& m,
- const S& s
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (m(r,c) == s) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator== (
- const S& s,
- const matrix_exp& m
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (s == m(r,c)) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator!= (
- const matrix_exp& m,
- const S& s
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (m(r,c) != s) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename S>
- const matrix_exp operator!= (
- const S& s,
- const matrix_exp& m
- );
- /*!
- requires
- - is_built_in_scalar_type<S>::value == true
- - is_built_in_scalar_type<matrix_exp::type>::value == true
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m.
- - R has the same dimensions as m.
- - for all valid r and c:
- - if (s != m(r,c)) then
- - R(r,c) == 1
- - else
- - R(r,c) == 0
- - i.e. R is a binary matrix of all 1s or 0s.
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Statistics
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type min (
- const matrix_exp& m
- );
- /*!
- requires
- - m.size() > 0
- ensures
- - returns the value of the smallest element of m. If m contains complex
- elements then the element returned is the one with the smallest norm
- according to std::norm().
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp min_pointwise (
- const matrix_exp& a,
- const matrix_exp& b
- );
- /*!
- requires
- - a.nr() == b.nr()
- - a.nc() == b.nc()
- - a and b both contain the same type of element
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in a and b.
- - R has the same dimensions as a and b.
- - for all valid r and c:
- R(r,c) == std::min(a(r,c), b(r,c))
- !*/
-
- const matrix_exp min_pointwise (
- const matrix_exp& a,
- const matrix_exp& b,
- const matrix_exp& c
- );
- /*!
- performs min_pointwise(a,min_pointwise(b,c));
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type max (
- const matrix_exp& m
- );
- /*!
- requires
- - m.size() > 0
- ensures
- - returns the value of the biggest element of m. If m contains complex
- elements then the element returned is the one with the largest norm
- according to std::norm().
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp max_pointwise (
- const matrix_exp& a,
- const matrix_exp& b
- );
- /*!
- requires
- - a.nr() == b.nr()
- - a.nc() == b.nc()
- - a and b both contain the same type of element
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in a and b.
- - R has the same dimensions as a and b.
- - for all valid r and c:
- R(r,c) == std::max(a(r,c), b(r,c))
- !*/
-
- const matrix_exp max_pointwise (
- const matrix_exp& a,
- const matrix_exp& b,
- const matrix_exp& c
- );
- /*!
- performs max_pointwise(a,max_pointwise(b,c));
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- void find_min_and_max (
- const matrix_exp& m,
- matrix_exp::type& min_val,
- matrix_exp::type& max_val
- );
- /*!
- requires
- - m.size() > 0
- ensures
- - #min_val == min(m)
- - #max_val == max(m)
- - This function computes both the min and max in just one pass
- over the elements of the matrix m.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- long index_of_max (
- const matrix_exp& m
- );
- /*!
- requires
- - is_vector(m) == true
- - m.size() > 0
- ensures
- - returns the index of the largest element in m.
- (i.e. m(index_of_max(m)) == max(m))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- long index_of_min (
- const matrix_exp& m
- );
- /*!
- requires
- - is_vector(m) == true
- - m.size() > 0
- ensures
- - returns the index of the smallest element in m.
- (i.e. m(index_of_min(m)) == min(m))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- point max_point (
- const matrix_exp& m
- );
- /*!
- requires
- - m.size() > 0
- ensures
- - returns the location of the maximum element of the array, that is, if the
- returned point is P then it will be the case that: m(P.y(),P.x()) == max(m).
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- dlib::vector<double,2> max_point_interpolated (
- const matrix_exp& m
- );
- /*!
- requires
- - m.size() > 0
- ensures
- - Like max_point(), this function finds the location in m with the largest
- value. However, we additionally use some quadratic interpolation to find the
- location of the maximum point with sub-pixel accuracy. Therefore, the
- returned point is equal to max_point(m) + some small sub-pixel delta.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- point min_point (
- const matrix_exp& m
- );
- /*!
- requires
- - m.size() > 0
- ensures
- - returns the location of the minimum element of the array, that is, if the
- returned point is P then it will be the case that: m(P.y(),P.x()) == min(m).
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type sum (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns the sum of all elements in m
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp sum_rows (
- const matrix_exp& m
- );
- /*!
- requires
- - m.size() > 0
- ensures
- - returns a row matrix that contains the sum of all the rows in m.
- - returns a matrix M such that
- - M::type == the same type that was in m
- - M.nr() == 1
- - M.nc() == m.nc()
- - for all valid i:
- - M(i) == sum(colm(m,i))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp sum_cols (
- const matrix_exp& m
- );
- /*!
- requires
- - m.size() > 0
- ensures
- - returns a column matrix that contains the sum of all the columns in m.
- - returns a matrix M such that
- - M::type == the same type that was in m
- - M.nr() == m.nr()
- - M.nc() == 1
- - for all valid i:
- - M(i) == sum(rowm(m,i))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type prod (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns the results of multiplying all elements of m together.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type mean (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns the mean of all elements in m.
- (i.e. returns sum(m)/(m.nr()*m.nc()))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type variance (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns the unbiased sample variance of all elements in m
- (i.e. 1.0/(m.nr()*m.nc() - 1)*(sum of all pow(m(i,j) - mean(m),2)))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp::type stddev (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns sqrt(variance(m))
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix covariance (
- const matrix_exp& m
- );
- /*!
- requires
- - matrix_exp::type == a dlib::matrix object
- - is_col_vector(m) == true
- - m.size() > 1
- - for all valid i, j:
- - is_col_vector(m(i)) == true
- - m(i).size() > 0
- - m(i).size() == m(j).size()
- - i.e. m contains only column vectors and all the column vectors
- have the same non-zero length
- ensures
- - returns the unbiased sample covariance matrix for the set of samples
- in m.
- (i.e. 1.0/(m.nr()-1)*(sum of all (m(i) - mean(m))*trans(m(i) - mean(m))))
- - the returned matrix will contain elements of type matrix_exp::type::type.
- - the returned matrix will have m(0).nr() rows and columns.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename rand_gen>
- const matrix<double> randm(
- long nr,
- long nc,
- rand_gen& rnd
- );
- /*!
- requires
- - nr >= 0
- - nc >= 0
- - rand_gen == an object that implements the rand/rand_float_abstract.h interface
- ensures
- - generates a random matrix using the given rnd random number generator
- - returns a matrix M such that
- - M::type == double
- - M.nr() == nr
- - M.nc() == nc
- - for all valid i, j:
- - M(i,j) == a random number such that 0 <= M(i,j) < 1
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- inline const matrix<double> randm(
- long nr,
- long nc
- );
- /*!
- requires
- - nr >= 0
- - nc >= 0
- ensures
- - generates a random matrix using std::rand()
- - returns a matrix M such that
- - M::type == double
- - M.nr() == nr
- - M.nc() == nc
- - for all valid i, j:
- - M(i,j) == a random number such that 0 <= M(i,j) < 1
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- inline const matrix_exp gaussian_randm (
- long nr,
- long nc,
- unsigned long seed = 0
- );
- /*!
- requires
- - nr >= 0
- - nc >= 0
- ensures
- - returns a matrix with its values filled with 0 mean unit variance Gaussian
- random numbers.
- - Each setting of the seed results in a different random matrix.
- - The returned matrix is lazily evaluated using the expression templates
- technique. This means that the returned matrix doesn't take up any memory
- and is only an expression template. The values themselves are computed on
- demand using the gaussian_random_hash() routine.
- - returns a matrix M such that
- - M::type == double
- - M.nr() == nr
- - M.nc() == nc
- - for all valid i, j:
- - M(i,j) == gaussian_random_hash(i,j,seed)
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Pixel and Image Utilities
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- typename P
- >
- const matrix<T,pixel_traits<P>::num,1> pixel_to_vector (
- const P& pixel
- );
- /*!
- requires
- - pixel_traits<P> must be defined
- ensures
- - returns a matrix M such that:
- - M::type == T
- - M::NC == 1
- - M::NR == pixel_traits<P>::num
- - if (pixel_traits<P>::grayscale) then
- - M(0) == pixel
- - if (pixel_traits<P>::rgb) then
- - M(0) == pixel.red
- - M(1) == pixel.green
- - M(2) == pixel.blue
- - if (pixel_traits<P>::hsi) then
- - M(0) == pixel.h
- - M(1) == pixel.s
- - M(2) == pixel.i
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename P
- >
- void vector_to_pixel (
- P& pixel,
- const matrix_exp& vector
- );
- /*!
- requires
- - vector::NR == pixel_traits<P>::num
- - vector::NC == 1
- (i.e. you have to use a statically dimensioned vector)
- ensures
- - if (pixel_traits<P>::grayscale) then
- - pixel == M(0)
- - if (pixel_traits<P>::rgb) then
- - pixel.red == M(0)
- - pixel.green == M(1)
- - pixel.blue == M(2)
- - if (pixel_traits<P>::hsi) then
- - pixel.h == M(0)
- - pixel.s == M(1)
- - pixel.i == M(2)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- long lower,
- long upper
- >
- const matrix_exp clamp (
- const matrix_exp& m
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (m(r,c) > upper) then
- - R(r,c) == upper
- - else if (m(r,c) < lower) then
- - R(r,c) == lower
- - else
- - R(r,c) == m(r,c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp clamp (
- const matrix_exp& m,
- const matrix_exp::type& lower,
- const matrix_exp::type& upper
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (m(r,c) > upper) then
- - R(r,c) == upper
- - else if (m(r,c) < lower) then
- - R(r,c) == lower
- - else
- - R(r,c) == m(r,c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp clamp (
- const matrix_exp& m,
- const matrix_exp& lower,
- const matrix_exp& upper
- );
- /*!
- requires
- - m.nr() == lower.nr()
- - m.nc() == lower.nc()
- - m.nr() == upper.nr()
- - m.nc() == upper.nc()
- - m, lower, and upper all contain the same type of elements.
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (m(r,c) > upper(r,c)) then
- - R(r,c) == upper(r,c)
- - else if (m(r,c) < lower(r,c)) then
- - R(r,c) == lower(r,c)
- - else
- - R(r,c) == m(r,c)
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp lowerbound (
- const matrix_exp& m,
- const matrix_exp::type& thresh
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (m(r,c) >= thresh) then
- - R(r,c) == m(r,c)
- - else
- - R(r,c) == thresh
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- const matrix_exp upperbound (
- const matrix_exp& m,
- const matrix_exp::type& thresh
- );
- /*!
- ensures
- - returns a matrix R such that:
- - R::type == the same type that was in m
- - R has the same dimensions as m
- - for all valid r and c:
- - if (m(r,c) <= thresh) then
- - R(r,c) == m(r,c)
- - else
- - R(r,c) == thresh
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MATRIx_UTILITIES_ABSTRACT_
-
diff --git a/ml/dlib/dlib/matrix/symmetric_matrix_cache.h b/ml/dlib/dlib/matrix/symmetric_matrix_cache.h
deleted file mode 100644
index bff268aef..000000000
--- a/ml/dlib/dlib/matrix/symmetric_matrix_cache.h
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_SYMMETRIC_MATRIX_CAcHE_Hh_
-#define DLIB_SYMMETRIC_MATRIX_CAcHE_Hh_
-
-#include "symmetric_matrix_cache_abstract.h"
-#include <vector>
-#include "../matrix.h"
-#include "../algs.h"
-#include "../array.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, typename cache_element_type>
- struct op_symm_cache : basic_op_m<M>
- {
- inline op_symm_cache(
- const M& m_,
- long max_size_megabytes_
- ) :
- basic_op_m<M>(m_),
- max_size_megabytes(max_size_megabytes_),
- is_initialized(false)
- {
- lookup.assign(this->m.nr(), -1);
-
- diag_cache = matrix_cast<cache_element_type>(dlib::diag(m_));
- }
-
- op_symm_cache (
- const op_symm_cache& item
- ) :
- basic_op_m<M>(item.m),
- diag_cache(item.diag_cache),
- max_size_megabytes(item.max_size_megabytes),
- is_initialized(false)
- {
- lookup.assign(this->m.nr(), -1);
- }
-
- typedef cache_element_type type;
- typedef const cache_element_type& const_ret_type;
- const static long cost = M::cost + 3;
-
- inline const_ret_type apply ( long r, long c) const
- {
- if (lookup[c] != -1)
- {
- return cache[lookup[c]](r);
- }
- else if (r == c)
- {
- return diag_cache(r);
- }
- else if (lookup[r] != -1)
- {
- // the matrix is symmetric so this is legit
- return cache[lookup[r]](c);
- }
- else
- {
- add_col_to_cache(c);
- return cache[lookup[c]](r);
- }
- }
-
- inline std::pair<const type*,long*> col(long i) const
- /*!
- requires
- - 0 <= i < nc()
- ensures
- - returns a pair P such that:
- - P.first == a pointer to the first element of the ith column
- - P.second == a pointer to the integer used to count the number of
- outstanding references to the ith column.
- !*/
- {
- if (is_cached(i) == false)
- add_col_to_cache(i);
-
- // find where this column is in the cache
- long idx = lookup[i];
- if (idx == next)
- {
- // if this column was the next to be replaced
- // then make sure that doesn't happen
- next = (next + 1)%cache.size();
- }
-
- return std::make_pair(&cache[idx](0), &references[idx]);
- }
-
- const type* diag() const { init(); return &diag_cache(0); }
-
- long* diag_ref_count() const
- {
- return &diag_reference_count;
- }
-
- private:
- inline bool is_cached (
- long r
- ) const
- {
- return (lookup[r] != -1);
- }
-
- inline void init() const
- {
- if (is_initialized == false)
- {
- // figure out how many columns of the matrix we can have
- // with the given amount of memory.
- long max_size = (max_size_megabytes*1024*1024)/(this->m.nr()*sizeof(type));
- // don't let it be 0 or 1
- if (max_size <= 1)
- max_size = 2;
-
- const long size = std::min(max_size,this->m.nr());
-
- diag_reference_count = 0;
-
- references.set_max_size(this->m.nr());
- references.set_size(size);
- for (unsigned long i = 0; i < references.size(); ++i)
- references[i] = 0;
-
- cache.set_max_size(this->m.nr());
- cache.set_size(size);
-
- rlookup.assign(size,-1);
- next = 0;
-
- is_initialized = true;
- }
- }
-
- void make_sure_next_is_unreferenced (
- ) const
- {
- if (references[next] != 0)
- {
- // find an unreferenced element of the cache
- unsigned long i;
- for (i = 1; i < references.size(); ++i)
- {
- const unsigned long idx = (next+i)%references.size();
- if (references[idx] == 0)
- {
- next = idx;
- break;
- }
- }
-
- // if all elements of the cache are referenced then make the cache bigger
- // and use the new element.
- if (references[next] != 0)
- {
- cache.resize(cache.size()+1);
-
- next = references.size();
- references.resize(references.size()+1);
- references[next] = 0;
-
- rlookup.push_back(-1);
- }
- }
- }
-
- inline void add_col_to_cache(
- long c
- ) const
- {
- init();
- make_sure_next_is_unreferenced();
-
- // if the lookup table is pointing to cache[next] then clear lookup[next]
- if (rlookup[next] != -1)
- lookup[rlookup[next]] = -1;
-
- // make the lookup table so that it says c is now cached at the spot indicated by next
- lookup[c] = next;
- rlookup[next] = c;
-
- // compute this column in the matrix and store it in the cache
- cache[next] = matrix_cast<cache_element_type>(colm(this->m,c));
-
- next = (next + 1)%cache.size();
- }
-
- /*!
- INITIAL VALUE
- - for all valid x:
- - lookup(x) == -1
-
- - diag_cache == the diagonal of the original matrix
- - is_initialized == false
- - max_size_megabytes == the max_size_megabytes from symmetric_matrix_cache()
-
- CONVENTION
- - diag_cache == the diagonal of the original matrix
- - lookup.size() == diag_cache.size()
-
- - if (is_initialized) then
- - if (lookup[c] != -1) then
- - cache[lookup[c]] == the cached column c of the matrix
- - rlookup[lookup[c]] == c
-
- - if (rlookup[x] != -1) then
- - lookup[rlookup[x]] == x
- - cache[x] == the cached column rlookup[x] of the matrix
-
- - next == the next element in the cache table to use to cache something
- - references[i] == the number of outstanding references to cache element cache[i]
-
- - diag_reference_count == the number of outstanding references to diag_cache.
- (this isn't really needed. It's just here so that we can reuse the matrix
- expression from colm() to implement diag())
- !*/
-
-
- mutable array<matrix<type,0,1,typename M::mem_manager_type> > cache;
- mutable array<long> references;
- matrix<type,0,1,typename M::mem_manager_type> diag_cache;
- mutable std::vector<long> lookup;
- mutable std::vector<long> rlookup;
- mutable long next;
-
- const long max_size_megabytes;
- mutable bool is_initialized;
- mutable long diag_reference_count;
-
- };
-
- template <
- typename cache_element_type,
- typename EXP
- >
- const matrix_op<op_symm_cache<EXP,cache_element_type> > symmetric_matrix_cache (
- const matrix_exp<EXP>& m,
- long max_size_megabytes
- )
- {
- // Don't check that m is symmetric since doing so would be extremely onerous for the
- // kinds of matrices intended for use with the symmetric_matrix_cache. Check everything
- // else though.
- DLIB_ASSERT(m.size() > 0 && m.nr() == m.nc() && max_size_megabytes >= 0,
- "\tconst matrix_exp symmetric_matrix_cache(const matrix_exp& m, max_size_megabytes)"
- << "\n\t You have given invalid arguments to this function"
- << "\n\t m.nr(): " << m.nr()
- << "\n\t m.nc(): " << m.nc()
- << "\n\t m.size(): " << m.size()
- << "\n\t max_size_megabytes: " << max_size_megabytes
- );
-
- typedef op_symm_cache<EXP,cache_element_type> op;
- return matrix_op<op>(op(m.ref(), max_size_megabytes));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, typename cache_element_type>
- struct op_colm_symm_cache
- {
- typedef cache_element_type type;
-
- op_colm_symm_cache(
- const M& m_,
- const type* data_,
- long* ref_count_
- ) :
- m(m_),
- data(data_),
- ref_count(ref_count_)
- {
- *ref_count += 1;
- }
-
- op_colm_symm_cache (
- const op_colm_symm_cache& item
- ) :
- m(item.m),
- data(item.data),
- ref_count(item.ref_count)
- {
- *ref_count += 1;
- }
-
- ~op_colm_symm_cache(
- )
- {
- *ref_count -= 1;
- }
-
- const M& m;
-
- const type* const data;
- long* const ref_count;
-
- const static long cost = M::cost;
- const static long NR = M::NR;
- const static long NC = 1;
- typedef const type& const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- inline const_ret_type apply ( long r, long) const { return data[r]; }
-
- long nr () const { return m.nr(); }
- long nc () const { return 1; }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP,
- typename cache_element_type
- >
- inline const matrix_op<op_colm_symm_cache<EXP,cache_element_type> > colm (
- const matrix_exp<matrix_op<op_symm_cache<EXP,cache_element_type> > >& m,
- long col
- )
- {
- DLIB_ASSERT(col >= 0 && col < m.nc(),
- "\tconst matrix_exp colm(const matrix_exp& m, row)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\tcol: " << col
- );
-
- std::pair<const cache_element_type*,long*> p = m.ref().op.col(col);
-
- typedef op_colm_symm_cache<EXP,cache_element_type> op;
- return matrix_op<op>(op(m.ref().op.m,
- p.first,
- p.second));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename EXP,
- typename cache_element_type
- >
- inline const matrix_op<op_colm_symm_cache<EXP,cache_element_type> > diag (
- const matrix_exp<matrix_op<op_symm_cache<EXP,cache_element_type> > >& m
- )
- {
- typedef op_colm_symm_cache<EXP,cache_element_type> op;
- return matrix_op<op>(op(m.ref().op.m,
- m.ref().op.diag(),
- m.ref().op.diag_ref_count()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename M, typename cache_element_type>
- struct op_rowm_symm_cache
- {
- typedef cache_element_type type;
-
- op_rowm_symm_cache(
- const M& m_,
- const type* data_,
- long* ref_count_
- ) :
- m(m_),
- data(data_),
- ref_count(ref_count_)
- {
- *ref_count += 1;
- }
-
- op_rowm_symm_cache (
- const op_rowm_symm_cache& item
- ) :
- m(item.m),
- data(item.data),
- ref_count(item.ref_count)
- {
- *ref_count += 1;
- }
-
- ~op_rowm_symm_cache(
- )
- {
- *ref_count -= 1;
- }
-
- const M& m;
-
- const type* const data;
- long* const ref_count;
-
- const static long cost = M::cost;
- const static long NR = 1;
- const static long NC = M::NC;
- typedef const type& const_ret_type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
- inline const_ret_type apply ( long , long c) const { return data[c]; }
-
- long nr () const { return 1; }
- long nc () const { return m.nc(); }
-
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- };
-
- template <
- typename EXP,
- typename cache_element_type
- >
- inline const matrix_op<op_rowm_symm_cache<EXP,cache_element_type> > rowm (
- const matrix_exp<matrix_op<op_symm_cache<EXP,cache_element_type> > >& m,
- long row
- )
- {
- DLIB_ASSERT(row >= 0 && row < m.nr(),
- "\tconst matrix_exp rowm(const matrix_exp& m, row)"
- << "\n\tYou have specified invalid sub matrix dimensions"
- << "\n\tm.nr(): " << m.nr()
- << "\n\tm.nc(): " << m.nc()
- << "\n\trow: " << row
- );
-
- std::pair<const cache_element_type*,long*> p = m.ref().op.col(row);
-
- typedef op_rowm_symm_cache<EXP,cache_element_type> op;
- return matrix_op<op>(op(m.ref().op.m,
- p.first,
- p.second));
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename EXP, typename cache_element_type>
- struct colm_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > >
- {
- typedef matrix_op<op_colm_symm_cache<EXP, cache_element_type> > type;
- };
-
- template <typename EXP, typename cache_element_type>
- struct rowm_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > >
- {
- typedef matrix_op<op_rowm_symm_cache<EXP, cache_element_type> > type;
- };
-
- template <typename EXP, typename cache_element_type>
- struct diag_exp<matrix_op<op_symm_cache<EXP, cache_element_type> > >
- {
- typedef matrix_op<op_colm_symm_cache<EXP, cache_element_type> > type;
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_SYMMETRIC_MATRIX_CAcHE_Hh_
-
diff --git a/ml/dlib/dlib/matrix/symmetric_matrix_cache_abstract.h b/ml/dlib/dlib/matrix/symmetric_matrix_cache_abstract.h
deleted file mode 100644
index 6a41ad282..000000000
--- a/ml/dlib/dlib/matrix/symmetric_matrix_cache_abstract.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#define DLIB_SYMMETRIC_MATRIX_CAcHE_ABSTRACT_Hh_
-#ifndef DLIB_SYMMETRIC_MATRIX_CAcHE_ABSTRACT_Hh_
-
-#include "matrix_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename cache_element_type
- >
- const matrix_exp symmetric_matrix_cache (
- const matrix_exp& m,
- long max_size_megabytes
- );
- /*!
- requires
- - m.size() > 0
- - m.nr() == m.nc()
- - max_size_megabytes >= 0
- ensures
- - This function assumes that m is symmetric. If m is not symmetric then it won't
- crash but you will get incorrect results.
- - This method creates a matrix expression which internally caches the elements
- of m so that they can be accessed quickly. It is useful if m is some kind of
- complex matrix expression which is both very large and expensive to evaluate.
- An example would be a kernel_matrix() expression with an expensive kernel and
- a large number of samples. Such an expression would result in a huge matrix,
- potentially too big to store in memory. The symmetric_matrix_cache() then makes
- it easy to store just the parts of a matrix expression which are accessed most
- often in memory. The specific details are defined below.
- - returns a matrix M such that
- - M == m
- (i.e. M represents the same matrix as m)
- - M will cache elements of m and hold them internally so they can be quickly
- accessed. In particular, M will attempt to allocate no more than
- max_size_megabytes megabytes of memory for the purposes of caching
- elements of m. When an element of the matrix is accessed it is either
- retrieved from the cache, or if this is not possible, then an entire
- column of m is loaded into a part of the cache which hasn't been used
- recently and the needed element returned.
- - diag(m) is always loaded into the cache and is stored separately from
- the cached columns. That means accesses to the diagonal elements of m
- are always fast.
- - M will store the cached elements of m as cache_element_type objects.
- Typically, cache_element_type will be float or double.
- - To avoid repeated cache lookups, the following operations are optimized for
- use with the symmetric_matrix_cache():
- - diag(M), rowm(M,row_idx), colm(M,col_idx)
- These methods will perform only one cache lookup operation for an
- entire row/column/diagonal worth of data.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_SYMMETRIC_MATRIX_CAcHE_ABSTRACT_Hh_
-