#ifndef ICL_DYN_MATRIX_UTILS_H #define ICL_DYN_MATRIX_UTILS_H #include #include namespace icl{ /** @} @{ @name unary functions */ /// Matrix initialization template /** This function can e.g. be used to initialize a matrix with random values \code #include #include int main(){ DynMatrix M(10,10); // initialize all entries with a uniform random number matrix_init(M,URand(0,1)); } \endcode @param m matrix to initialize @param init initializer function value or functor @return m */ template inline DynMatrix &matrix_init(DynMatrix &m, Init init){ std::fill(m.begin(),m.end(),init); return m; } /// element-wise absolute value (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_abs(DynMatrix &m); /// element-wise absolute value [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_abs(const DynMatrix &m, DynMatrix &dst); /// element-wise logarith (basis E) (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_log(DynMatrix &m); /// element-wise logarith (basis E) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_log(const DynMatrix &m, DynMatrix &dst); /// element-wise exp-function (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_exp(DynMatrix &m); /// element-wise exp-function [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_exp(const DynMatrix &m, DynMatrix &dst); /// element-wise square-root-function (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_sqrt(DynMatrix &m); /// element-wise square-root-function [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_sqrt(const DynMatrix &m, DynMatrix &dst); /// element-wise square-function (x*x) (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_sqr(DynMatrix &m); /// element-wise square-function (x*x) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_sqr(const DynMatrix &m, DynMatrix &dst); /// element-wise sinus-function (x*x) (inplace) /** For float and double only */ template DynMatrix &matrix_sin(DynMatrix &m); /// element-wise sinus-function (x*x) /** For float and double only */ template DynMatrix &matrix_sin(const DynMatrix &m, DynMatrix &dst); /// element-wise cosinus-function (inplace) /** For float and double only */ template DynMatrix &matrix_cos(DynMatrix &m); /// element-wise cosinus-function /** For float and double only */ template DynMatrix &matrix_cos(const DynMatrix &m, DynMatrix &dst); /// element-wise tangent-function (inplace) /** For float and double only */ template DynMatrix &matrix_tan(DynMatrix &m); /// element-wise tangent-function /** For float and double only */ template DynMatrix &matrix_tan(const DynMatrix &m, DynMatrix &dst); /// element-wise arcus sinus-function (inplace) /** For float and double only */ template DynMatrix &matrix_arcsin(DynMatrix &m); /// element-wise arcus sinus-function /** For float and double only */ template DynMatrix &matrix_arcsin(const DynMatrix &m, DynMatrix &dst); /// element-wise arcus cosinus-function (inplace) /** For float and double only */ template DynMatrix &matrix_arccos(DynMatrix &m); /// element-wise arcus cosinus-function /** For float and double only */ template DynMatrix &matrix_arccos(const DynMatrix &m, DynMatrix &dst); /// element-wise arcus tangent-function (inplace) /** For float and double only */ template DynMatrix &matrix_arctan(DynMatrix &m); /// element-wise arcus tangent-function /** For float and double only */ template DynMatrix &matrix_arctan(const DynMatrix &m, DynMatrix &dst); /// element-wise reciprocal-function (1/x) (inplace) /** For float and double only */ template DynMatrix &matrix_reciprocal(DynMatrix &m); /// element-wise reciprocal-function (1/x) /** For float and double only */ template DynMatrix &matrix_reciprocal(const DynMatrix &m, DynMatrix &dst); /** @} @{ @name unary functions with scalar argument */ /// element-wise power-function (x^exponent) (inplace) /** For float and double only */ template DynMatrix &matrix_powc(DynMatrix &m, T exponent); /// element-wise power-function (x^exponent) /** For float and double only */ template DynMatrix &matrix_powc(const DynMatrix &m, T exponent, DynMatrix &dst); /// element-wise addition of constant value (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_addc(DynMatrix &m, T val); /// element-wise addition of constant value [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_addc(const DynMatrix &m, T val, DynMatrix &dst); /// element-wise substraction of constant value (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_subc(DynMatrix &m, T val); /// element-wise substraction of constant value [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_subc(const DynMatrix &m, T val, DynMatrix &dst); /// element-wise division by constant value (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_divc(DynMatrix &m, T val); /// element-wise division by constant value [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_divc(const DynMatrix &m, T val, DynMatrix &dst); /// element-wise multiplication with constant value (inplace) [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_mulc(DynMatrix &m, T val); /// element-wise multiplication with constant value [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_mulc(const DynMatrix &m, T val, DynMatrix &dst); /** @} @{ @name binary functions */ /// element-wise atan2 function atan2(y,x) /** For float and double only */ template DynMatrix &matrix_arctan2(const DynMatrix &my, const DynMatrix &mx, DynMatrix &dst) throw (IncompatibleMatrixDimensionException); /// element-wise addition [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_add(const DynMatrix &m1, const DynMatrix &m2, DynMatrix &dst) throw (IncompatibleMatrixDimensionException); /// element-wise substraction [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_sub(const DynMatrix &m1, const DynMatrix &m2, DynMatrix &dst) throw (IncompatibleMatrixDimensionException); /// element-wise multiplication [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_mul(const DynMatrix &m1, const DynMatrix &m2, DynMatrix &dst) throw (IncompatibleMatrixDimensionException); /// element-wise division [IPP-optimized] /** For float and double only */ template DynMatrix &matrix_div(const DynMatrix &m1, const DynMatrix &m2, DynMatrix &dst) throw (IncompatibleMatrixDimensionException); /// element-wise power /** For float and double only */ template DynMatrix &matrix_pow(const DynMatrix &m1, const DynMatrix &m2, DynMatrix &dst) throw (IncompatibleMatrixDimensionException); /** @} */ /** @{ @name matrix distance measurement */ /// computes norm between matrix vectors /** For float and double only \f[ D = \left(\sum\limits_{i,j} (A_{ij}-B_{ij})^n\right)^{\frac{1}{n}} \f] */ template T matrix_distance(const DynMatrix &m1, const DynMatrix &m2, T norm=2) throw (IncompatibleMatrixDimensionException); /// computes generalized Kullback-Leibler-divergence between matrix vectors /** For float and double only \f[ \mbox{div} = \sum\limits_{i,j} A_{ij} \cdot \log{\frac{A_{ij}}{B_{ij}}} - A_{ij} + B_{ij} \f] */ template T matrix_divergence(const DynMatrix &m1, const DynMatrix &m2) throw (IncompatibleMatrixDimensionException); /** @} */ /** @{ @name statistical functions */ /// find minimum element of matrix (optionally find location too) [IPP-optimized] /** For float and double only @param m source matrix @param x if no NULL, minimum x-location (column-index) is written to *x @param y if no NULL, minimum y-location (row-index) is written to *y */ template T matrix_min(const DynMatrix &m, int *x=0, int *y=0); /// find maximum element of matrix (optionally find location too) [IPP-optimized] /** For float and double only @param m source matrix @param x if no NULL, maximum x-location (column-index) is written to *x @param y if no NULL, maximum y-location (row-index) is written to *y */ template T matrix_max(const DynMatrix &m, int *x=0, int *y=0); /// find min- and maxinim element at once (optionally with locations) [IPP-optimized] /** For float and double only @param m source matrix @param dst found min and max value are written to dst\n (dst[0]<-min, dst[1]<-max) @param minx if no NULL, minimum x-location (column-index) is written to *minx @param miny if no NULL, minimum y-location (row-index) is written to *miny @param maxx if no NULL, maximum x-location (column-index) is written to *maxx @param maxy if no NULL, maximum y-location (row-index) is written to *maxy */ template void matrix_minmax(const DynMatrix &m, T dst[2], int *minx=0, int *miny=0, int *maxx=0, int *maxy=0); /// calculate matrix mean value [IPP-optimized] /** For float and double only */ template T matrix_mean(const DynMatrix &m); /// calculate matrix variance [IPP-optimized] /** For float and double only */ template T matrix_var(const DynMatrix &m); /// calculate matrix variance with given mean /** For float and double only @param m source matrix @param mean given sample mean @param empiricalMean if true, then the given mean was computed from the data, too, and therefore, the intermediate result 'sum of square distances' has to be normalized with m.dim()-1. The reason is that, the the empirical mean minimizes the variance 'per-definition', so we substract that degree of freedom here. If empiricalMean is false, intermediate sum-of-squares is normalized by m.dim() only. */ template T matrix_var(const DynMatrix &m, T mean, bool empiricalMean=true); /// computes matrix mean and variance at once [IPP-optimized] /** For float and double only note thatn mean and var must not be null */ template void matrix_meanvar(const DynMatrix &m, T *mean, T*var); /// computes matrix standard deviation (sqrt(var)) [IPP-optimized] /** For float and double only */ template T matrix_stddev(const DynMatrix &m); /// calculate matrix standard deviation with given mean /** For float and double only @param m source matrix @param mean given sample mean @param empiricalMean if true, then the given mean was computed from the data, too, and therefore, the intermediate result 'sum of square distances' has to be normalized with m.dim()-1. The reason is that, the the empirical mean minimizes the variance 'per-definition', so we substract that degree of freedom here. If empiricalMean is false, intermediate sum-of-squares is normalized by m.dim() only. */ template T matrix_stddev(const DynMatrix &m, T mean, bool empiricalMean=true); /** @} */ /** @{ @name other functions ...*/ /// computes alpha*a + beta*b + gamma /** For float and double only */ template DynMatrix &matrix_muladd(const DynMatrix &a,T alpha, const DynMatrix &b, T beta, T gamma, DynMatrix &dst) throw (IncompatibleMatrixDimensionException); /// computes alpha*a + gamma /** For float and double only */ template DynMatrix &matrix_muladd(const DynMatrix &a,T alpha, T gamma, DynMatrix &dst); /// applies masking operation (m(i,j) is set to 0 if mask(i,j) is 0) (inplace) /** For float and double only */ template DynMatrix &matrix_mask(const DynMatrix &mask, DynMatrix &m) throw (IncompatibleMatrixDimensionException); /// applies masking operation (m(i,j) is set to 0 if mask(i,j) is 0) /** For float and double only */ template DynMatrix &matrix_mask(const DynMatrix &mask, const DynMatrix &m, DynMatrix &dst) throw (IncompatibleMatrixDimensionException); /** @} */ /** @{ @name special functions for transposed matrices ...*/ /// special utility type for definition of transposed states for matrices enum transposedDef{ NONE_T=0, SRC1_T=1<<0, SRC2_T=1<<1, BOTH_T=SRC1_T | SRC2_T, }; /// applies matrix mutliplication on optionally transposed matrices /** sometimes, it might be more efficient to call matrix multiplication on imaginary transposed source matrices, to avoid having to apply an additional transposing step. This function is IPP accelerated. In case of having no IPP support, a trivial fallback implementation is provided (something like \code src1.transp().mult( src2.transp(),dst) ) \endcode in case of having transpDef == BOTH_T @param src1 left operand @param src2 right operand @param dst1 destination matrix (adapted on demand) @param transpDef or-ed list of transposedDef values e.g. (SRC1_T | SRC2_T) mean both matrices are transposed. */ template DynMatrix &matrix_mult_t(const DynMatrix &src1, const DynMatrix &src2, DynMatrix &dst, int transpDef) throw (IncompatibleMatrixDimensionException); /// applies matrix mutliplication on optionally transposed matrices (specialized for big matrices) /** sometimes, it might be more efficient to call matrix multiplication on imaginary transposed source matrices, to avoid having to apply an additional transposing step. This function is accelerated using Intel MKL. If Intel MKL is not available, function matrix_mult_t is used as fallback. @param src1 left operand @param src2 right operand @param dst1 destination matrix (adapted on demand) @param transpDef or-ed list of transposedDef values e.g. (SRC1_T | SRC2_T) mean both matrices are transposed. */ template DynMatrix &big_matrix_mult_t(const DynMatrix &src1, const DynMatrix &src2, DynMatrix &dst, int transpDef) throw (IncompatibleMatrixDimensionException); template DynMatrix &matrix_add_t(const DynMatrix &src1, const DynMatrix &src2, DynMatrix &dst, int transpDef) throw (IncompatibleMatrixDimensionException); template DynMatrix &matrix_sub_t(const DynMatrix &src1, const DynMatrix &src2, DynMatrix &dst, int transpDef) throw (IncompatibleMatrixDimensionException); /** @} */ } #endif