123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502(* File: impl_CZ.ml
Copyright (C) 2005-
Egbert Ammicht
email: eammicht@lucent.com
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
Oleg Trott
email: ot14@columbia.edu
WWW: http://www.columbia.edu/~ot14
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.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
*)openPrintfopenBigarrayopenComplexopenComplex64openCommonopenUtilsopenImpl4_ZmoduleVec=Vec4_ZmoduleMat=Mat4_ZmoduleRVec=Vec4_D(* BLAS-1 interface *)externaldirect_dotu:n:(int[@untagged])->ofsx:(int[@untagged])->incx:(int[@untagged])->x:vec->ofsy:(int[@untagged])->incy:(int[@untagged])->y:vec->Complex.t="lacaml_Zdotu_stub_bc""lacaml_Zdotu_stub"externaldirect_dotc:n:(int[@untagged])->ofsx:(int[@untagged])->incx:(int[@untagged])->x:vec->ofsy:(int[@untagged])->incy:(int[@untagged])->y:vec->Complex.t="lacaml_Zdotc_stub_bc""lacaml_Zdotc_stub"letgen_dotlocdot_fun=();fun?n?ofsx?incxx?ofsy?incyy->letofsx,incx=get_vec_geomlocx_strofsxincxinletofsy,incy=get_vec_geomlocy_strofsyincyinletn=get_dim_veclocx_strofsxincxxn_strnincheck_veclocy_stry(ofsy+(n-1)*absincy);dot_fun~n~ofsx~incx~x~ofsy~incy~yletdotu=gen_dot"Lacaml.Z.dotu"direct_dotuletdotc=gen_dot"Lacaml.Z.dotc"direct_dotc(* Auxiliary routines *)externaldirect_lansy:norm:char->uplo:char->n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->work:rvec->(float[@unboxed])="lacaml_Zlansy_stub_bc""lacaml_Zlansy_stub"letlansy_min_lworkn=function`I->n|_->0letlansy?n?(up=true)?(norm=`O)?work?(ar=1)?(ac=1)a=letloc="Lacaml.Z.lansy"inletn=get_n_of_alocaracaninletuplo=get_uplo_charupinletmin_work=lansy_min_lworknnorminletwork,_lwork=get_worklocRVec.createworkmin_workmin_work"lwork"inletnorm=get_norm_charnormindirect_lansy~norm~uplo~n~ar~ac~a~work(* Linear equations (computational routines) *)(* GECON *)externaldirect_gecon:n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->work:vec->rwork:rvec->norm:char->anorm:(float[@unboxed])->int*float="lacaml_Zgecon_stub_bc""lacaml_Zgecon_stub"letgecon_min_lworkn=2*nletgecon_min_lrworkn=2*nletgecon?n?(norm=`O)?anorm?work?rwork?(ar=1)?(ac=1)a=letloc="Lacaml.Z.gecon"inletn=get_n_of_alocaracaninletwork,_lwork=get_worklocVec.creatework(gecon_min_lworkn)(gecon_min_lworkn)"lwork"inletrwork,_lrwork=get_worklocRVec.createrwork(gecon_min_lrworkn)(gecon_min_lrworkn)"lrwork"inletanorm=matchanormwith|None->lange~norm:(norm:>norm4)~m:n~n~work:rworka|Someanorm->anorminletnorm=get_norm_charnorminletinfo,rcond=direct_gecon~n~ar~ac~a~work~rwork~norm~anorminifinfo=0thenrcondelsegecon_errlocnormnainfo(* SYCON *)externaldirect_sycon:uplo:char->n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->ipiv:int32_vec->work:vec->anorm:(float[@unboxed])->int*float="lacaml_Zsycon_stub_bc""lacaml_Zsycon_stub"letsycon_min_lworkn=2*nletsycon?n?(up=true)?ipiv?anorm?work?(ar=1)?(ac=1)a=letloc="Lacaml.Z.sycon"inletn=get_n_of_alocaracaninletuplo=get_uplo_charupinletwork,_lwork=get_worklocVec.creatework(sycon_min_lworkn)(sycon_min_lworkn)"lwork"inletipiv=ifipiv=Nonethensytrf~n~up~work~ar~acaelsesytrf_get_ipivlocipivninletanorm=matchanormwith|None->lange~m:n~n~ar~aca|Someanorm->anorminletinfo,rcond=direct_sycon~uplo~n~ar~ac~a~ipiv~work~anorminifinfo=0thenrcondelsexxcon_errlocnainfo(* POCON *)externaldirect_pocon:uplo:char->n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->work:vec->rwork:rvec->anorm:(float[@unboxed])->int*float="lacaml_Zpocon_stub_bc""lacaml_Zpocon_stub"letpocon_min_lworkn=3*nletpocon_min_lrworkn=nletpocon?n?(up=true)?anorm?work?rwork?(ar=1)?(ac=1)a=letloc="Lacaml.Z.pocon"inletn=get_n_of_alocaracaninletuplo=get_uplo_charupinletmin_lwork,min_lrwork=pocon_min_lworkn,pocon_min_lrworkninletwork,_lwork=get_worklocVec.createworkmin_lworkmin_lwork"lwork"inletrwork,_lrwork=get_worklocRVec.createrworkmin_lrworkmin_lrwork"lrwork"inletanorm=matchanormwith|None->lange~m:n~n~ar~aca|Someanorm->anorminletinfo,rcond=direct_pocon~uplo~n~ar~ac~a~work~rwork~anorminifinfo=0thenrcondelsexxcon_errlocnainfo(* General Schur factorization *)(* GEES *)externaldirect_gees:jobvs:char->sort:char->select:(int[@untagged])->select_fun:(Complex.t->bool)->n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->w:vec->vsr:(int[@untagged])->vsc:(int[@untagged])->vs:mat->work:vec->lwork:(int[@untagged])->rwork:rvec->bwork:int32_vec->int*int="lacaml_Zgees_stub_bc""lacaml_Zgees_stub"(* result : (SDIM, INFO) *)externalinit_gees:unit->unit="lacaml_Zinit_gees"let()=init_gees()letgees_get_opt_lwork~loc~jobvs~sort~select~select_fun~n~ar~ac~a~w~vsr~vsc~vs~rwork~bwork=letlwork=-1inletwork=Vec.create1inlet_,info=direct_gees~jobvs~sort~select~select_fun~n~ar~ac~a~w~vsr~vsc~vs~work~lwork~rwork~bworkinifinfo=0thenint_of_floatwork.{1}.reelsegees_errlocninfojobvssortletgees?n?(jobvs=`Compute_Schur_vectors)?(sort=`No_sort)?w?(vsr=1)?(vsc=1)?vs?work?(ar=1)?(ac=1)a=letloc="Lacaml.Z.gees"inletjobvs,sort_char,select,select_fun,n,vs,w=gees_get_params_complexlocVec.createMat.createMat.emptyjobvssortnaracawvsrvscvsinletbwork=matchsortwith|`No_sort->empty_int32_vec|_->create_int32_vecninletrwork=RVec.createninletwork,lwork=matchworkwith|Somework->work,Array1.dimwork|None->letlwork=gees_get_opt_lwork~loc~jobvs~sort:sort_char~select~select_fun~n~ar~ac~a~w~vsr~vsc~vs~rwork~bworkinVec.createlwork,lworkinletsdim,info=direct_gees~jobvs~sort:sort_char~select~select_fun~n~ar~ac~a~w~vsr~vsc~vs~work~lwork~rwork~bworkinifinfo=0thensdim,w,vselsegees_errlocninfojobvssort_char(* General SVD routines *)(* GESVD *)externaldirect_gesvd:jobu:char->jobvt:char->m:(int[@untagged])->n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->s:rvec->ur:(int[@untagged])->uc:(int[@untagged])->u:mat->vtc:(int[@untagged])->vtr:(int[@untagged])->vt:mat->work:vec->lwork:(int[@untagged])->rwork:rvec->(int[@untagged])="lacaml_Zgesvd_stub_bc""lacaml_Zgesvd_stub"letgesvd_min_lwork~m~n=letmin_m_n=minmninmax1(min_m_n+min_m_n+maxmn)letgesvd_lrwork~m~n=5*minmnletgesvd_get_opt_lworklocjobujobvtmnaracasurucuvtrvtcvt=letlwork=-1inletwork=Vec.create1inletinfo=direct_gesvd~jobu~jobvt~m~n~ar~ac~a~s~ur~uc~u~vtr~vtc~vt~work~lwork~rwork:RVec.emptyinifinfo=0thenFloat64.int_of_float64work.{1}.reelsegesvd_errlocjobujobvtmnauvtlworkinfoletgesvd_opt_lwork?m?n?(jobu=`A)?(jobvt=`A)?s?(ur=1)?(uc=1)?u?(vtr=1)?(vtc=1)?vt?(ar=1)?(ac=1)a=letloc="Lacaml.Z.gesvd_opt_lwork"inletjobu,jobvt,m,n,s,u,vt=gesvd_get_paramslocRVec.createMat.createjobujobvtmnaracasurucuvtrvtcvtingesvd_get_opt_lworklocjobujobvtmnaracasurucuvtrvtcvtletgesvd?m?n?(jobu=`A)?(jobvt=`A)?s?(ur=1)?(uc=1)?u?(vtr=1)?(vtc=1)?vt?work?rwork?(ar=1)?(ac=1)a=letloc="Lacaml.Z.gesvd"inletjobu,jobvt,m,n,s,u,vt=gesvd_get_paramslocRVec.createMat.createjobujobvtmnaracasurucuvtrvtcvtinletwork,lwork=matchworkwith|Somework->work,Array1.dimwork|None->letlwork=gesvd_get_opt_lworklocjobujobvtmnaracasurucuvtrvtcvtinVec.createlwork,lworkinletrwork=matchrworkwith|None->RVec.create(gesvd_lrwork~m~n)|Somerwork->letlrwork=Array1.dimrworkinletmin_lrwork=gesvd_lrwork~m~niniflrwork<min_lrworktheninvalid_arg(sprintf"%s: lrwork: valid=[%d..[ got=%d"locmin_lrworklrwork)elserworkinletinfo=direct_gesvd~jobu~jobvt~m~n~ar~ac~a~s~ur~uc~u~vtc~vtr~vt~work~lwork~rworkinifinfo=0thens,u,vtelsegesvd_errlocjobujobvtmnauvtlworkinfo(* General eigenvalue problem (simple drivers) *)(* GEEV error handler *)letgeev_errlocmin_workanvlvrlworkerr=iferr>0thenletmsg=sprintf"\
%s: The QR algorithm failed to compute all the eigenvalues, and\n\
no eigenvectors have been computed; elements %d:%d of WR and WI\n\
contain eigenvalues which have converged"loc(err+1)ninfailwithmsgelseletmsg=matcherrwith|-3->sprintf"n: valid=[0..[ got=%d"n|-5->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|-8->sprintf"dim1(vl): valid=[%d..[ got=%d"(max1n)(Array2.dim1vl)|-10->sprintf"dim1(vr): valid=[%d..[ got=%d"(max1n)(Array2.dim1vr)|-12->sprintf"dim(work): valid=[%d..[ got=%d"(min_workn)lwork|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)(* GEEV *)externaldirect_geev:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->n:(int[@untagged])->ofsw:(int[@untagged])->w:vec->vlr:(int[@untagged])->vlc:(int[@untagged])->vl:mat->jobvl:char->vrr:(int[@untagged])->vrc:(int[@untagged])->vr:mat->jobvr:char->work:vec->lwork:(int[@untagged])->rwork:vec->(int[@untagged])="lacaml_Zgeev_stub_bc""lacaml_Zgeev_stub"letgeev_min_lworkn=max1(n+n)letgeev_min_lrworkn=n+nletgeev_get_opt_lworklocnvlrvlcvljobvlvrrvrcvrjobvrofswwaraca=letwork=Vec.create1inletinfo=direct_geev~ar~ac~a~n~ofsw~w~vlr~vlc~vl~jobvl~vrr~vrc~vr~jobvr~work~lwork:~-1~rwork:Vec.emptyinifinfo=0thenint_of_floatwork.{1}.reelsegeev_errlocgeev_min_lworkanvlvr~-1infoletgeev_get_paramslocaracanvlrvlcvlvrrvrcvrofsww=letn,_,_,_,_,_,_,_,_,_asparams=geev_gen_get_paramslocMat.emptyMat.createaracanvlrvlcvlvrrvrcvrinparams,xxev_get_wxVec.createlocw_strofswwnletgeev_opt_lwork?n?(vlr=1)?(vlc=1)?vl?(vrr=1)?(vrc=1)?vr?(ofsw=1)?w?(ar=1)?(ac=1)a=letloc="Lacaml.Z.geev_opt_lwork"inlet(n,vlr,vlc,vl,jobvl,vrr,vrc,vr,jobvr,_),w=geev_get_paramslocaracanvlrvlcvlvrrvrcvrofswwingeev_get_opt_lworklocnvlrvlcvljobvlvrrvrcvrjobvrofswwaracaletgeev?n?work?rwork?(vlr=1)?(vlc=1)?vl?(vrr=1)?(vrc=1)?vr?(ofsw=1)?w?(ar=1)?(ac=1)a=letloc="Lacaml.Z.geev"inlet(n,vlr,vlc,vl,jobvl,vrr,vrc,vr,jobvr,_),w=geev_get_paramslocaracanvlrvlcvlvrrvrcvrofswwinletwork,lwork=matchworkwith|Somework->letlwork=Array1.dimworkinletmin_lwork=geev_min_lworkniniflwork<min_lworktheninvalid_arg(sprintf"%s: lwork: valid=[%d..[ got=%d"locmin_lworklwork)elsework,lwork|None->letlwork=geev_get_opt_lworklocnvlrvlcvljobvlvrrvrcvrjobvrofswwaracainVec.createlwork,lworkinletrwork=matchrworkwith|None->Vec.create(geev_min_lrworkn)|Somerwork->letlrwork=Array1.dimrworkinletmin_lrwork=geev_min_lrworkniniflrwork<min_lrworktheninvalid_arg(sprintf"%s: lrwork: valid=[%d..[ got=%d"locmin_lrworklrwork)elserworkinletinfo=direct_geev~ar~ac~a~n~ofsw~w~vlr~vlc~vl~jobvl~vrr~vrc~vr~jobvr~work~lwork~rworkinifinfo=0thenvl,w,vrelsegeev_errlocgeev_min_lworkanvlvrlworkinfo