Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file utils.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224(* File: utils.ml
OCaml-GPR - Gaussian Processes for OCaml
Copyright (C) 2009- Markus Mottl
email: markus.mottl@gmail.com
WWW: http://www.ocaml.info
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*)openCoreopenBigarrayopenLacaml.D(* Global definitions *)moduleInt_vec=structtypet=(int,int_elt,fortran_layout)Array1.tletcreaten:t=Array1.createintfortran_layoutnletdim(t:t)=Array1.dimtletsub(t:t)n=Array1.subtnendletdebug=reffalseletcholesky_jitter=ref1e-6typefast_float_ref={mutablex:float}letpi=4.*.Float.atan1.letlog_2pi=log(pi+.pi)letdefault_rng=Gsl.Rng.make(Gsl.Rng.default())(* Testing and I/O functionality *)letprint_intnamen=Format.printf"%s: @[%d@]@.@."namenletprint_floatnamen=Format.printf"%s: @[%.9f@]@.@."namenletprint_vecnamevec=Format.printf"%s: @[%a@]@.@."namepp_vecvecletprint_matnamemat=Format.printf"%s: @[%a@]@.@."namepp_matmatlettimingnamef=lett1=Unix.times()inletres=f()inlett2=Unix.times()inFormat.printf"%s %.2f@."name(t2.Unix.tms_utime-.t1.Unix.tms_utime);res(* General matrix functions *)(* Choose columns of a matrix *)letchoose_colsmatindexes=letm=Mat.dim1matinletn=Mat.dim2matinletk=Int_vec.dimindexesinletres=Mat.createmkinforc=1tokdoletreal_c=indexes.{c}inifreal_c<1||real_c>nthenfailwithf"Gpr.Utils.choose_cols: violating 1 <= index (%d) <= dim (%d)"real_cn()elseforr=1tomdores.{r,c}<-mat.{r,real_c}donedone;res(* Compute the sum of all elements in a matrix *)letsum_matmat=Vec.sum(Mat.as_vecmat)(* Compute the sum of all elements in a symmetric matrix *)letsum_symm_matmat=letdiag_ref=ref0.inletrest_ref=ref0.inletn=Mat.dim1matinforc=1tondoforr=1toc-1dorest_ref:=!rest_ref+.mat.{r,c}done;diag_ref:=!diag_ref+.mat.{c,c}done;letrest=!rest_refinrest+.!diag_ref+.rest(* Computes logarithm of determinant; assumes Cholesky factorized matrix *)letlog_detmat=letn=Mat.dim1matinifMat.dim2mat<>nthenfailwith"log_det: not a square matrix";letrecloopacci=ifi=0thenacc+.accelseloop(acc+.logmat.{i,i})(i-1)inloop0.n(* Solve triangular system *)letsolve_tri?transcholmat=letichol_mat=lacpymatintrtrs?transcholichol_mat;ichol_mat(* Compute the inverse of a matrix using the cholesky factor *)leticholchol=letinv=lacpy~uplo:`Ucholinpotri~factorize:falseinv;inv(* Sparse matrices and vectors *)(* Checks whether a sparse row matrix is sane *)letcheck_sparse_row_mat_sane~real_m~smat~rows=if!debugthenbeginifreal_m<0thenfailwith"Gpr.Utils.check_sparse_row_mat_sane: real_m < 0";letm=Mat.dim1smatinletn_rows=Int_vec.dimrowsinifn_rows<>mthenfailwithf"Gpr.Utils.check_sparse_row_mat_sane: number of rows in \
sparse matrix (%d) disagrees with size of row array (%d)"mn_rows();letrecloop~i~limit=ifi>0thenletrows_i=rows.{i}inifrows_i<=0thenfailwithf"Gpr.Utils.check_sparse_row_mat_sane: sparse row %d contains \
illegal negative real row index %d"irows_i()elseifrows_i>limitthenfailwithf"Gpr.Utils.check_sparse_row_mat_sane: sparse row %d \
associated with real row index %d violates consistency \
(current row limit: %d)"irows_ilimit()elseloop~i:(i-1)~limit:rows_iinloop~i:n_rows~limit:real_mend(* Checks whether a sparse column matrix is sane *)letcheck_sparse_col_mat_sane~real_n~smat~cols=if!debugthenbeginifreal_n<0thenfailwith"Gpr.Utils.check_sparse_col_mat_sane: real_n < 0";letn=Mat.dim2smatinletn_cols=Int_vec.dimcolsinifn_cols<>nthenfailwithf"Gpr.Utils.check_sparse_col_mat_sane: number of cols in \
sparse matrix (%d) disagrees with size of col array (%d)"nn_cols();letrecloop~i~limit=ifi>0thenletcols_i=cols.{i}inifcols_i<=0thenfailwithf"Gpr.Utils.check_sparse_col_mat_sane: sparse col %d contains \
illegal negative real col index %d"icols_i()elseifcols_i>limitthenfailwithf"Gpr.Utils.check_sparse_col_mat_sane: sparse col %d \
associated with real col index %d violates consistency \
(current col limit: %d)"icols_ilimit()elseloop~i:(i-1)~limit:cols_iinloop~i:n_cols~limit:real_nend(* Checks whether a parse vector is sane *)letcheck_sparse_vec_sane~real_n~svec~rows=if!debugthenletk=Vec.dimsvecinifInt_vec.dimrows<>kthenfailwith"Gpr.Utils.check_sparse_vec_sane: \
size of sparse vector disagrees with indexes";letrecloop~lasti=ifi>0thenletind=rows.{i}inifind>=last||ind<=0thenfailwith"Gpr.Utils.check_sparse_vec_sane: rows inconsistent"elseloop~last:ind(i-1)inloop~last:real_n(Int_vec.dimrows)(* Computes the trace of the product of a symmetric and sparse
symmetric matrix *)letsymm2_sparse_trace~mat~smat~rows=letm=Int_vec.dimrowsinletn=Mat.dim2smatinletfull_ref=ref0.inlethalf_ref=ref0.inletrows_ix_ref=ref1inforsparse_r=1tomdoletc=rows.{sparse_r}inforr=1tondoletmat_el=ifr>cthenmat.{c,r}elsemat.{r,c}inletrows_ix=!rows_ix_refinifrows_ix>m||letrows_el=rows.{rows_ix}inr<rows_el||c<rows_elthenfull_ref:=!full_ref+.mat_el*.smat.{sparse_r,r}elsebeginhalf_ref:=!half_ref+.mat_el*.smat.{rows_ix,c};incrrows_ix_refenddone;rows_ix_ref:=1done;letfull=!full_refinfull+.!half_ref+.full