123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002(* File: utils.ml
Copyright (C) 2001-
Markus Mottl
email: markus.mottl@gmail.com
WWW: http://www.ocaml.info
Liam Stewart
email: liam@cs.toronto.edu
WWW: http://www.cs.toronto.edu/~liam
Christophe Troestler
email: Christophe.Troestler@umons.ac.be
WWW: http://math.umh.ac.be/an/
Florent Hoareau
email: h.florent@gmail.com
WWW: none
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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)(** General auxiliary functions *)openPrintfopenBigarrayopenLacaml_common(* Zero-sized dummy vector (int) *)letempty_int32_vec=create_int32_vec0(* Char indicating type of norm to retrieve for XlanYY routines *)letget_norm_char=function`M->'M'|`O->'O'|`I->'I'|`F->'F'(* Char indicating whether the "U"pper or "L"ower triangle of a matrix
is stored *)letget_uplo_charup=ifupthen'U'else'L'(* Char indicating whether some operation operates on a "N"ormal,
"T"ransposed or "C"onjugated transposed matrix. *)letget_trans_char=function`N->'N'|`T->'T'|`C->'C'(* Char indicating which side of the matrix B matrix A should be on *)letget_side_char=function`L->'L'|`R->'R'(* Char indicating whether a diagonal is unit or non-unit *)letget_diag_char=function`U->'U'|`N->'N'(* Char indicating whether/how the left/right singular vectors
should be computed *)letget_s_d_job_char=function`A->'A'|`S->'S'|`O->'O'|`N->'N'(* Char indicating whether the eigen"V"ectors are computed or "N"ot *)letget_job_char=functiontrue->'V'|_->'N'letjob_char_true=get_job_chartrueletjob_char_false=get_job_charfalse(* Name information *)leta_str="a"letab_str="ab"letalphas_str="alphas"letap_str="ap"letb_str="b"letbr_str="br"letbc_str="bc"letc_str="c"letd_str="d"letdl_str="dl"letdu_str="du"lete_str="e"letipiv_str="ipiv"letiseed_str="iseed"letk_str="k"letka_str="ka"letkb_str="kb"letwork_str="work"letlwork_str="lwork"letliwork_str="liwork"letkd_str="kd"letkl_str="kl"letku_str="ku"letm_str="m"letn_str="n"letnrhs_str="nrhs"lets_str="s"lettau_str="tau"letu_str="u"letum_str="um"letun_str="un"letvm_str="vm"letvn_str="vn"letvs_str="vs"letvsr_str="vsr"letvsc_str="vsc"letvt_str="vt"letw_str="w"letwi_str="wi"letwr_str="wr"letx_str="x"lety_str="y"letz_str="z"(* Get a work array *)letget_worklocvec_createworkmin_lworkopt_lworklwork_str=matchworkwith|Somework->letlwork=Array1.dimworkiniflwork<min_lworktheninvalid_arg(sprintf"%s: %s: valid=[%d..[ got=%d"loclwork_strmin_lworklwork)elsework,lwork|None->vec_createopt_lwork,opt_lworkletcalc_unpacked_dimlocn_vec=letn=truncate(sqrt(float(8*n_vec+1))/.2.)inif(n*n+n)/2<>n_vecthenfailwith(sprintf"%s: illegal vector length: %d"locn_vec)elsen(* Calculate the dimension of a packed square matrix given the vector length *)letget_unpacked_dimloc?nn_vec=matchnwith|None->calc_unpacked_dimlocn_vec|Somen->letn_unpacked=calc_unpacked_dimlocn_vecinifn<0||n>n_unpackedtheninvalid_arg(sprintf"%s: n: valid=[0..%d] got=%d"locn_unpackedn)elsen(* Fetches problem-dependent parameters for LAPACK-functions *)externalilaenv:int->string->string->int->int->int->int->int="lacaml_ilaenv_stub_bc""lacaml_ilaenv_stub""noalloc"letcheck_var_ltzlocvar_namevar=ifvar<0theninvalid_arg(sprintf"%s: %s < 0: %d"locvar_namevar)letcheck_veclocvec_namevecmin_dim=letdim=Array1.dimvecinifdim<min_dimtheninvalid_arg(sprintf"%s: dim(%s): valid=[%d..[ got=%d"locvec_namemin_dimdim)letget_veclocvec_namevecofsincmin_elemvec_create=letmin_dim=ofs+(min_elem-1)*absincinmatchvecwith|Somevec->check_veclocvec_namevecmin_dim;vec|None->vec_createmin_dimletraise_mat_ofs_neglockindmat_namerc=invalid_arg(sprintf"%s: mat_%c(%s): valid=[1..] got=%d"lockindmat_namerc)letraise_mat_ofslockindmat_namedimrc=invalid_arg(sprintf"%s: mat_%c(%s): valid=[1..%d] got=%d"lockindmat_namedimrc)letcheck_dim1_matlocmat_namematmat_rm_namem=letdim1=Array2.dim1matinletdim1_rest=dim1-mat_r+1inifmat_r<1||dim1_rest<1thenraise_mat_ofsloc'r'mat_namedim1mat_relseifm<0||dim1_rest<mtheninvalid_arg(sprintf"%s: %s(%s): valid=[0..%d] got=%d"locm_namemat_namedim1_restm)letcheck_dim2_matlocmat_namematmat_cn_namen=letdim2=Array2.dim2matinletdim2_rest=dim2-mat_c+1inifmat_c<1||dim2_rest<1thenraise_mat_ofsloc'c'mat_namedim2mat_celseifn<0||dim2_rest<ntheninvalid_arg(sprintf"%s: %s(%s): valid=[0..%d] got=%d"locn_namemat_namedim2_restn)letcheck_dim_matlocmat_namercmatmn=check_dim1_matlocmat_namematrm_strm;check_dim2_matlocmat_namematcn_strnletget_matlocmat_namemat_creatercmatmn=matchmatwith|Somemat->check_dim_matlocmat_namercmatmn;mat|None->mat_create(m+r-1)(n+c-1)(* ??MV auxiliary functions *)(* [get_dim_vec loc vec_name ofsvec incvec vec n_name n] if the
dimension [n] is given, check that the vector [vec] is big enough,
otherwise return the maximal [n] for the given vector [vec]. *)letget_dim_veclocvec_nameofsvecincvecvecn_name=function|Somen->ifn<0theninvalid_arg(sprintf"%s: %s < 0"locn_name);check_veclocvec_namevec(ofsvec+(n-1)*absincvec);n|None->(Array1.dimvec-ofsvec)/absincvec+1letget_dim1_matlocmat_namematmat_rm_namem=letdim1=Array2.dim1matinletdim1_rest=dim1-mat_r+1inifmat_r<1||dim1_rest<1theninvalid_arg(sprintf"%s: mat_r(%s): valid=[1..%d] got=%d"locmat_namedim1mat_r);matchmwith|Somem->ifm<0||dim1_rest<mtheninvalid_arg(sprintf"%s: %s(%s): valid=[0..%d] got=%d"locm_namemat_namedim1_restm)elsem|None->dim1_restletget_dim2_matlocmat_namematmat_cn_namen=letdim2=Array2.dim2matinletdim2_rest=dim2-mat_c+1inifmat_c<1||dim2_rest<1theninvalid_arg(sprintf"%s: mat_c(%s): valid=[1..%d] got=%d"locmat_namedim2mat_c);matchnwith|Somen->ifn<0||dim2_rest<ntheninvalid_arg(sprintf"%s: %s(%s): valid=[0..%d] got=%d"locn_namemat_namedim2_restn)elsen|None->dim2_rest(* A symmetric band (SB) or triangular band (TB) matrix has physical size
[k+1]*[n] for a logical matrix of size [n]*[n]. Check and return the [k]
(possibly also given by the optional argument [k]). *)letget_k_mat_sblocmat_namematmat_rk_namek=letdim1=Array2.dim1matinletmax_k=dim1-mat_rinifmat_r<1||max_k<0theninvalid_arg(sprintf"%s: mat_r(%s): valid=[1..%d] got=%d"locmat_namedim1mat_r);matchkwith|None->max_k|Somek->ifk<0||max_k<ktheninvalid_arg(sprintf"%s: %s(%s): valid=[0..%d] got=%d"lock_namemat_namemax_kk)elsekletget_dim_mat_packedlocmat_nameofsmatmatn_namen=letdim=Array1.dimmatinmatchnwith|Somen->letn1=ofsmat+(n-1)*(n+2)/2(* ?overflow? *)inifn<0||dim<n1theninvalid_arg(sprintf"%s: %s(%s): valid=[0..%d] got=%d"locn_namemat_namedimn1)elsen|None->(* the greater n s.t. ofsmat - 1 + n(n+1)/2 <= dim mat *)max0(truncate((sqrt(9.+.8.*.float(dim-ofsmat))-.1.)/.2.))letget_inclocvar=function|Someinc->ifinc=0theninvalid_arg(sprintf"%s: inc%s = 0"locvar);inc|None->1letget_ofslocvar=function|Someofs->ifofs<1theninvalid_arg(sprintf"%s: ofs%s < 1"locvar);ofs|None->1letget_vec_geomlocvarofsinc=get_ofslocvarofs,get_inclocvarinc(* Makes sure that [mat] is a square matrix and [n] is within range *)letget_n_of_squarelocmat_namercmatn=letn=get_dim2_matlocmat_namematcn_strnincheck_dim1_matlocmat_namematrn_strn;nletget_n_of_alocaracan=get_n_of_squareloca_straracanletget_nrhs_of_blocnbrbcbnrhs=letnrhs=get_dim2_matlocb_strbbcnrhs_strnrhsincheck_dim1_matlocb_strbbrn_strn;nrhs(* ORGQR - Auxiliary Functions *)letorgqr_err~loc~m~n~k~work~a~err=letmsg=matcherrwith|-1->sprintf"m: valid=[0..[ got=%d"m|-2->sprintf"n: valid=[0..%d] got=%d"mn|-3->sprintf"k: valid=[0..%d] got=%d"nk|-5->sprintf"dim2(a): valid=[%d..[ got=%d"n(Array2.dim2a)|-8->sprintf"dim1(work): valid=[%d..[ got=%d"(max1n)(Array1.dimwork)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letorgqr_get_paramsloc?m?n?k~tau~ar~aca=letm=get_dim1_matloca_straarm_strminletn=get_dim2_matloca_straacn_strninletk=get_dim_vecloctau_str11tauk_strkinm,n,k(* ORMQR - Auxiliary Functions *)letormqr_err~loc~side~m~n~k~lwork~a~c~err=letnq,nw=matchsidewith|`L->m,n|`R->n,minletmsg=matcherrwith|-3->sprintf"m: valid=[0..[ got=%d"m|-4->sprintf"n: valid=[0..[ got=%d"n|-5->sprintf"k: valid=[0..%d] got=%d"knq|-7->sprintf"dim1(a): valid=[%d..[ got=%d"(max1nq)(Array2.dim1a)|-10->sprintf"dim1(c): valid=[%d..[ got=%d"(max1m)(Array2.dim1c)|-12->letmin_lwork=max1nwinsprintf"lwork: valid=[%d..[ got=%d"min_lworklwork|_->raise(InternalError(sprintf"%s: error code %d"locerr))ininvalid_arg(sprintf"%s: %s"locmsg)letormqr_get_paramsloc~side?m?n?k~tau~ar~aca~cr~ccc=letm=get_dim1_matlocc_strccrm_strminletn=get_dim2_matlocc_strcccn_strninletk=get_dim2_matloca_straack_strkinbeginmatchsidewith|`L->ifm<kthenfailwith(sprintf"%s: m(%d) < k(%d)"locmk);check_dim1_matloca_straarm_str(max1m)|`R->ifn<kthenfailwith(sprintf"%s: n(%d) < k(%d)"locnk);check_dim1_matloca_straarn_str(max1n)end;check_vecloctau_strtauk;m,n,k(* GELS? - Auxiliary Functions *)letgelsX_errlocgelsX_min_workaramnlworknrhsbrberr=iferr>0thenfailwith(sprintf"%s: failed to converge on off-diagonal element %d"locerr)elseletmsg=matcherrwith|-1->sprintf"m: valid=[0..[ got=%d"m|-2->sprintf"n: valid=[0..[ got=%d"n|-3->sprintf"nrhs: valid=[0..[ got=%d"nrhs|-5->sprintf"dim1(a): valid=[%d..[ got=%d"(max1m+ar-1)(Array2.dim1a)|-7->letmin_dim=max1(maxmn)+br-1insprintf"dim1(b): valid=[%d..[ got=%d"min_dim(Array2.dim1b)|-12->letmin_lwork=gelsX_min_work~m~n~nrhsinsprintf"lwork: valid=[%d..[ got=%d"min_lworklwork|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letgelsX_get_svec_createlocmin_dimofss=function|Somes->letdim_s=Array1.dimsinletmin_dim_ofs=ofss-1+min_diminifdim_s<min_dim_ofstheninvalid_arg(sprintf"%s: s: valid=[%d..[ got=%d"locmin_dim_ofsdim_s)elses|None->vec_createmin_dimletgelsX_get_paramslocaracamnnrhsbrbcb=letm=get_dim1_matloca_straarm_strminletn=get_dim2_matloca_straacn_strninletnrhs=get_dim2_matlocb_strbbcnrhs_strnrhsincheck_dim1_matlocb_strbbrm_str(maxmn);m,n,nrhs(* ??ev -- auxiliary functions *)letxxev_get_paramslocaracanvectorsup=letn=get_n_of_alocaracaninletjobz=get_job_charvectorsinletuplo=get_uplo_charupinn,jobz,uploletxxev_get_wxvec_createlocwnameofswwn=matchwwith|None->1,vec_createn|Somew->check_veclocwnamew(ofsw-1+n);ofsw,w(* geev -- auxiliary functions *)letgeev_get_job_sidelocmat_emptymat_createmat_namenrcmat_opt=matchmat_optwith|None->ifr<1thenfailwith(sprintf"%s: %sr < 1"locmat_name)elseifc<1thenfailwith(sprintf"%s: %sc < 1"locmat_name)elser,c,mat_create(n+r-1)(n+c-1),job_char_true,true|SomeNone->1,1,mat_empty,job_char_false,false|Some(Somemat)->check_dim1_matlocmat_namematrn_strn;check_dim2_matlocmat_namematcn_strn;r,c,mat,job_char_true,trueletgeev_gen_get_paramslocmat_emptymat_createaracanleftrleftcleftrightrrightcright=letn=get_n_of_alocaracaninletleftr,leftc,vl,jobvl,lvs=geev_get_job_sidelocmat_emptymat_create"vl"nleftrleftcleftinletrightr,rightc,vr,jobvr,rvs=geev_get_job_sidelocmat_emptymat_create"vr"nrightrrightcrightinn,leftr,leftc,vl,jobvl,rightr,rightc,vr,jobvr,lvs||rvs(* g?mv -- auxiliary functions *)letgXmv_get_paramslocvec_createmnofsxincxxofsyincyytrans=letofsx,incx=get_vec_geomlocx_strofsxincxinletofsy,incy=get_vec_geomlocy_strofsyincyinletlx,ly,trans_char=lettrans_char=get_trans_chartransiniftrans=`Nthenn,m,trans_charelsem,n,trans_charincheck_veclocx_strx(ofsx+(lx-1)*absincx);lety=get_veclocy_stryofsyincylyvec_createinofsx,incx,ofsy,incy,y,trans_char(* symv -- auxiliary functions *)letsymv_get_paramslocvec_createaracanofsxincxxofsyincyyup=letn=get_dim1_matloca_straarn_strnincheck_dim2_matloca_straacn_strn;letofsx,incx=get_vec_geomlocx_strofsxincxinletofsy,incy=get_vec_geomlocy_strofsyincyincheck_veclocx_strx(ofsx+(n-1)*absincx);lety=get_veclocy_stryofsyincynvec_createincheck_veclocy_stry(ofsy+(n-1)*absincy);n,ofsx,incx,ofsy,incy,y,get_uplo_charup(* tr?v -- auxiliary functions *)lettrXv_get_paramslocaracanofsxincxxuptransunit_triangular=letn=get_dim1_matloca_straarn_strnincheck_dim2_matloca_straacn_strn;lettrans_char=get_trans_chartransinletdiag_char=get_diag_charunit_triangularinletofsx,incx=get_vec_geomlocx_strofsxincxincheck_veclocx_strx(ofsx+(n-1)*absincx);n,ofsx,incx,get_uplo_charup,trans_char,diag_char(* tp?v -- auxiliary functions *)lettpXv_get_paramslocofsapap?nofsxincxxuptransunit_triangular=letofsap=get_ofslocap_strofsapinletn=get_unpacked_dimloc?n(Array1.dimap-ofsap+1)inlettrans_char=get_trans_chartransinletdiag_char=get_diag_charunit_triangularinletofsx,incx=get_vec_geomlocx_strofsxincxincheck_veclocx_strx(ofsx+(n-1)*absincx);n,ofsap,ofsx,incx,get_uplo_charup,trans_char,diag_char(* gemm -- auxiliary functions *)letget_clocmat_createcrcccmn=get_matlocc_strmat_createcrcccmnletget_rows_mat_trlocmat_strmatmat_rmat_ctranspdim_strdim=matchtranspwith|`N->get_dim1_matlocmat_strmatmat_rdim_strdim|_->get_dim2_matlocmat_strmatmat_cdim_strdimletget_cols_mat_trlocmat_strmatmat_rmat_ctranspdim_strdim=matchtranspwith|`N->get_dim2_matlocmat_strmatmat_cdim_strdim|_->get_dim1_matlocmat_strmatmat_rdim_strdimletget_inner_dimlocmat1_strmat1mat1_rmat1_ctr1mat2_strmat2mat2_rmat2_ctr2dim_strk=letk1=get_cols_mat_trlocmat1_strmat1mat1_rmat1_ctr1dim_strkinletk2=get_rows_mat_trlocmat2_strmat2mat2_rmat2_ctr2dim_strkinifk=None&&k1<>k2thenfailwith(sprintf"%s: inner dimensions of matrices do not match (%d,%d)"lock1k2)elsek1letgemm_get_paramslocmat_createaracatransabrbcbcrtransbcccmnk=letm=get_rows_mat_trloca_straaractransam_strminletn=get_cols_mat_trlocb_strbbrbctransbn_strninletk=get_inner_dimloca_straaractransab_strbbrbctransbk_strkinlettransa=get_trans_chartransainlettransb=get_trans_chartransbinletc=get_clocmat_createcrcccmninm,n,k,transa,transb,c(* symm -- auxiliary functions *)letcheck_mat_squarelocmat_strmatmat_rmat_cn=check_dim1_matlocmat_strmatmat_rn_strn;check_dim2_matlocmat_strmatmat_cn_strnletsymm_get_paramslocmat_createaracabrbcbcrcccmnsideup=letm=get_dim1_matlocb_strbbrm_strminletn=get_dim2_matlocb_strbbcn_strninifside=`Lthencheck_mat_squareloca_straaracmelsecheck_mat_squareloca_straaracn;letside_char=get_side_charsideinletuplo_char=get_uplo_charupinletc=get_clocmat_createcrcccmninm,n,side_char,uplo_char,c(* trmm -- auxiliary functions *)lettrXm_get_paramslocaracabrbcbmnsideuptransadiag=letm=get_dim1_matlocb_strbbrm_strminletn=get_dim2_matlocb_strbbcn_strninifside=`Lthencheck_mat_squareloca_straaracmelsecheck_mat_squareloca_straaracn;letside_char=get_side_charsideinletuplo_char=get_uplo_charupinlettransa=get_trans_chartransainletdiag_char=get_diag_chardiaginm,n,side_char,uplo_char,transa,diag_char(* syrk -- auxiliary functions *)letsyrk_get_paramslocmat_createaracacrcccnkuptrans=letn=get_rows_mat_trloca_straaractransn_strninletk=get_cols_mat_trloca_straaractransk_strkinlettrans_char=get_trans_chartransinletuplo_char=get_uplo_charupinletc=get_clocmat_createcrcccnninn,k,uplo_char,trans_char,c(* syr2k -- auxiliary functions *)letsyr2k_get_paramslocmat_createaracabrbcbcrcccnkuptrans=letn=get_rows_mat_trloca_straaractransn_strninletk=get_cols_mat_trloca_straaractransk_strkinbeginmatchtranswith|`N->check_dim1_matlocb_strbbrn_strn;check_dim2_matlocb_strbbck_strk;|_->check_dim1_matlocb_strbbrk_strk;check_dim2_matlocb_strbbcn_strn;end;lettrans_char=get_trans_chartransinletuplo_char=get_uplo_charupinletc=get_clocmat_createcrcccnninn,k,uplo_char,trans_char,c(* ?lange -- auxiliary functions *)letxlange_get_paramslocmnaraca=letm=get_dim1_matloca_straarm_strminletn=get_dim2_matloca_straacn_strninm,n(* ??trs -- auxiliary functions *)letxxtrs_get_paramslocaracanbrbcbnrhs=letn=get_n_of_alocaracaninletnrhs=get_nrhs_of_blocnbrbcbnrhsinn,nrhsletxxtrs_errlocnnrhsaberr=letmsg=matcherrwith|-2->sprintf"n: valid=[0..[ got=%d"n|-3->sprintf"nrhs: valid=[0..[ got=%d"nrhs|-5->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|-8->sprintf"dim1(b): valid=[%d..[ got=%d"(max1n)(Array2.dim1b)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* ??tri -- auxiliary functions *)letxxtri_singular_errlocerr=failwith(sprintf"%s: singular on index %i"locerr)letxxtri_errlocnaerr=letmsg=matcherrwith|-2->sprintf"n: valid=[0..[ got=%d"n|-4->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* ??con -- auxiliary functions *)letxxcon_errlocnaerr=letmsg=matcherrwith|-2->sprintf"n: valid=[0..[ got=%d"n|-4->sprintf"dim1(a): valid=%d..[ got=%d"(max1n)(Array2.dim1a)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* geXrf -- auxiliary functions *)letgeXrf_get_paramslocmnaraca=letm=get_dim1_matloca_straarm_strminletn=get_dim2_matloca_straacn_strninm,n(* getrf -- auxiliary functions *)letgetrf_errlocmnaerr=letmsg=matcherrwith|-1->sprintf"n: valid=[0..[ got=%d"n|-2->sprintf"m: valid=[0..[ got=%d"m|-4->sprintf"dim1(a): valid=[%d..[ got=%d"(max1m)(Array2.dim1a)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letgetrf_lu_errlocerr=failwith(sprintf"%s: U(%i,%i)=0 in the LU factorization"locerrerr)letgetrf_get_ipivlocipivmn=matchipivwith|None->create_int32_vec(minmn)|Someipiv->check_veclocipiv_stripiv(minmn);ipiv(* sytrf -- auxiliary functions *)letsytrf_get_ipivlocipivn=matchipivwith|None->create_int32_vecn|Someipiv->check_veclocipiv_stripivn;ipivletsytrf_errlocnaerr=letmsg=matcherrwith|-2->sprintf"n: valid=[0..[ got=%d"n|-4->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letsytrf_fact_errlocerr=failwith(sprintf"%s: D(%i,%i)=0 in the factorization"locerrerr)(* potrf -- auxiliary functions *)letpotrf_chol_errlocerr=failwith(sprintf"%s: leading minor of order %d is not positive definite"locerr)letpotrf_errlocnaerr=letmsg=matcherrwith|-2->sprintf"n: valid=[0..[ got=%d"n|-4->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|_->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* potrs -- auxiliary functions *)letpotrs_errlocnnrhsaberr=letmsg=matcherrwith|-2->sprintf"n: valid=[0..[ got=%d"n|-3->sprintf"nrhs: valid=[0..[ got=%d"nrhs|-5->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|-7->sprintf"dim1(b): valid=[%d..[ got=%d"(max1n)(Array2.dim1b)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* trtrs -- auxiliary functions *)lettrtrs_errlocnnrhsaberr=letmsg=matcherrwith|-4->sprintf"n: valid=[0..[ got=%d"n|-5->sprintf"nrhs: valid=[0..[ got=%d"nrhs|-7->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|-9->sprintf"dim1(b): valid=[%d..[ got=%d"(max1n)(Array2.dim1b)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* tbtrs -- auxiliary functions *)lettbtrs_errlocnnrhskdabberr=letmsg=matcherrwith|-4->sprintf"n: valid=[0..[ got=%d"n|-5->sprintf"kd: valid=[0..[ got=%d"kd|-6->sprintf"nrhs: valid=[0..[ got=%d"nrhs|-8->sprintf"dim1(ab): valid=[%d..[ got=%d"(max1n)(Array2.dim1ab)|-10->sprintf"dim1(b): valid=[%d..[ got=%d"(max1n)(Array2.dim1b)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* getri -- auxiliary functions *)letgetri_errlocgetri_min_lworknalworkerr=letmsg=matcherrwith|-1->sprintf"n: valid=[0..[ got=%d"n|-3->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|-6->letmin_lwork=getri_min_lworkninsprintf"lwork: valid=[%d..[ got=%d"min_lworklwork|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* trtri -- auxiliary functions *)lettrtri_errlocnaerr=letmsg=matcherrwith|-3->sprintf"n: valid=[0..[ got=%d"n|-5->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* gecon -- auxiliary functions *)letgecon_errlocnorm_charnaerr=letmsg=matcherrwith|-1->sprintf"norm: valid=['O', I'] got='%c'"norm_char|-2->sprintf"n: valid=[0..[ got=%d"n|-4->sprintf"dim1(a): valid=%d..[ got=%d"(max1n)(Array2.dim1a)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* gees -- auxiliary functions *)letgees_errlocnerrjobvssort=iferr>0&&err<=nthenfailwith(sprintf"%s: %d eigenvalue elements did not converge"locerr)elseiferr=n+1thenfailwith(sprintf"%s: eigenvalues not reordered, too close to separate"loc)elseiferr=n+2thenfailwith(sprintf"%s: after reordering, roundoff changed values of some \
complex eigenvalues so that leading eigenvalues in \
the Schur form no longer satisfy SELECT"loc)elseletmsg=matcherrwith|-1->sprintf"JOBVS: valid=['N', V'] got='%c'"jobvs|-2->sprintf"SORT: valid=['N', S'] got='%c'"sort|-4->sprintf"n: valid=[0..[ got=%d"n|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letdummy_select_fun_=falseletgees_get_params_genericlocmat_createmat_emptyjobvssortnaracavsrvscvs=letn=get_n_of_alocaracaninletjobvs,min_ldvs=matchjobvswith|`No_Schur_vectors->'N',1|`Compute_Schur_vectors->'V',ninletvs=matchvswith|Somevs->check_dim1_matlocvs_strvsvsrvsr_strmin_ldvs;check_dim2_matlocvs_strvsvscvsc_strn;vs|Nonewhenjobvs='N'->mat_empty|None->mat_createmin_ldvsninletsort,select,select_fun=matchsortwith|`No_sort->'N',0,dummy_select_fun|`Select_left_plane->'S',0,dummy_select_fun|`Select_right_plane->'S',1,dummy_select_fun|`Select_interior_disk->'S',2,dummy_select_fun|`Select_exterior_disk->'S',3,dummy_select_fun|`Select_customselect_fun->'S',4,select_funinjobvs,sort,select,select_fun,n,vsletgees_get_params_reallocvec_createmat_createmat_emptyjobvssortnaracawrwivsrvscvs=letjobvs,sort,select,select_fun,n,vs=gees_get_params_genericlocmat_createmat_emptyjobvssortnaracavsrvscvsinletwr=matchwrwith|None->vec_createn|Somewr->check_veclocwr_strwrn;wrinletwi=matchwiwith|None->vec_createn|Somewi->check_veclocwi_strwin;wiinjobvs,sort,select,select_fun,n,vs,wr,wiletgees_get_params_complexlocvec_createmat_createmat_emptyjobvssortnaracawvsrvscvs=letjobvs,sort,select,select_fun,n,vs=gees_get_params_genericlocmat_createmat_emptyjobvssortnaracavsrvscvsinletw=matchwwith|None->vec_createn|Somew->check_veclocw_strwn;winjobvs,sort,select,select_fun,n,vs,w(* gesvd -- auxiliary functions *)letgesvd_errlocjobujobvtmnauvtlworkerr=iferr>0thenfailwith(sprintf"%s: %d off-diagonal elements did not converge"locerr)elseletmsg=matcherrwith|-3->sprintf"m: valid=[0..[ got=%d"m|-4->sprintf"n: valid=[0..[ got=%d"n|-6->sprintf"dim1(a): valid=[%d..[ got=%d"(max1m)(Array2.dim1a)|-9->sprintf"dim1(u): valid=[%d..[ got=%d"(matchjobuwith'A'|'S'->max1m|_->1)(Array2.dim1u)|-11->sprintf"dim1(vt): valid=[%d..[ got=%d"(matchjobvtwith|'A'->max1n|'S'->max1(minmn)|_->1)(Array2.dim1vt)|-13->sprintf"lwork: valid=[%d..[ got=%d"1lwork|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letgesvd_get_paramslocvec_createmat_createjobujobvtmnaracasurucuvtrvtcvt=letm=get_dim1_matloca_straarm_strminletn=get_dim2_matloca_straacn_strninlets=get_veclocs_strs11(minmn)vec_createinletum,un=matchjobuwith|`A->m,m|`S->m,minmn|`O|`N->1,1in(* LDU >= 1 even when U not referenced *)letu=matchuwith|Someu->check_dim1_matlocu_struurum_strum;check_dim2_matlocu_struucun_strun;u|None->mat_createumuninletvm,vn=matchjobvtwith|`A->n,n|`S->minmn,n|`O|`N->1,1in(* LDVT >= 1 even when VT not referenced *)letvt=matchvtwith|Somevt->check_dim1_matlocvt_strvtvtrvm_strvm;check_dim2_matlocvt_strvtvtcvn_strvn;vt|None->mat_createvmvninletjobu_c=get_s_d_job_charjobuinletjobvt_c=get_s_d_job_charjobvtinjobu_c,jobvt_c,m,n,s,u,vt(* gesdd -- auxiliary functions *)letgesdd_errlocjobzmnauvtlworkerr=iferr>0thenfailwith(sprintf"%s: %d DBDSDC did not converge, updating process failed"locerr)elseletmsg=matcherrwith|-2->sprintf"m: valid=[0..[ got=%d"m|-3->sprintf"n: valid=[0..[ got=%d"n|-5->sprintf"dim1(a): valid=[%d..[ got=%d"(max1m)(Array2.dim1a)|-8->sprintf"dim1(u): valid=[%d..[ got=%d"(ifjobz='A'||jobz='S'||(jobz='O'&&m<n)thenmax1melse1)(Array2.dim1u)|-10->sprintf"dim1(vt): valid=[%d..[ got=%d"(ifjobz='A'||(jobz='O'&&m>=n)thenmax1nelseifjobz='S'thenmax1(minmn)else1)(Array2.dim1vt)|-12->sprintf"lwork: valid=[%d..[ got=%d"1lwork|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letgesdd_get_paramslocvec_createmat_createjobzmnaracasurucuvtrvtcvt=letm=get_dim1_matloca_straarm_strminletn=get_dim2_matloca_straacn_strninletmin_m_n=minmninlets=get_veclocs_strs11min_m_nvec_createinletum,un,vm,vn=matchjobzwith|`A->m,m,n,n|`S->m,min_m_n,min_m_n,n|`O->ifm>=nthen1,1,n,nelsem,m,m,n|`N->1,1,1,1in(* LDU >= 1 even when U not referenced *)letu=matchuwith|Someu->check_dim1_matlocu_struurum_strum;check_dim2_matlocu_struucun_strun;u|None->mat_createumuninletvt=matchvtwith|Somevt->check_dim1_matlocvt_strvtvtrvm_strvm;check_dim2_matlocvt_strvtvtcvn_strvn;vt|None->mat_createvmvninletjobz_c=get_s_d_job_charjobzinjobz_c,m,n,s,u,vt(* ??sv -- auxiliary functions *)letxxsv_errlocnnrhsberr=letmsg=matcherrwith|-1->sprintf"n: valid=[0..[ got=%d"n|-2->sprintf"nrhs: valid=[0..[ got=%d"nrhs|-7->sprintf"dim1(b): valid=[%d..[ got=%d"(max1n)(Array2.dim1b)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letxxsv_lu_errlocerr=failwith(sprintf"%s: U(%i,%i)=0 in the LU factorization"locerrerr)letxxsv_pos_errlocerr=letmsg=sprintf"%s: the leading minor of order %i is not positive definite"locerrinfailwithmsgletxxsv_ind_errlocerr=letmsg=sprintf"%s: D(%i,%i)=0 in the diagonal pivoting factorization"locerrerrinfailwithmsgletxxsv_a_errlocan=letmsg=sprintf"%s: dim1(a): valid=[%d..[ got=%d"loc(max1n)(Array2.dim1a)ininvalid_argmsgletxxsv_work_errloclwork=invalid_arg(sprintf"%s: dim(work): valid=[1..[ got=%d"loclwork)letxxsv_get_ipivlocipivn=matchipivwith|None->create_int32_vecn|Someipiv->check_veclocipiv_stripivn;ipivletxxsv_get_paramslocaracanbrbcbnrhs=letn=get_n_of_alocaracaninletnrhs=get_nrhs_of_blocnbrbcbnrhsinn,nrhs