1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678(* File: impl_SD.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/
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
*)openPrintfopenBigarrayopenFloat32openCommonopenUtilsopenImpl4_SmoduleVec=Vec4_SmoduleMat=Mat4_S(* BLAS-1 *)(* DOT *)externaldirect_dot:n:(int[@untagged])->ofsx:(int[@untagged])->incx:(int[@untagged])->x:vec->ofsy:(int[@untagged])->incy:(int[@untagged])->y:vec->(float[@unboxed])="lacaml_Sdot_stub_bc""lacaml_Sdot_stub"letdot?n?ofsx?incxx?ofsy?incyy=letloc="Lacaml.S.dot"inletofsx,incx=get_vec_geomlocx_strofsxincxinletofsy,incy=get_vec_geomlocy_strofsyincyinletn=get_dim_veclocx_strofsxincxxn_strnincheck_veclocy_stry(ofsy+(n-1)*absincy);direct_dot~n~ofsx~incx~x~ofsy~incy~y(* ASUM *)externaldirect_asum:n:(int[@untagged])->ofsx:(int[@untagged])->incx:(int[@untagged])->x:vec->(float[@unboxed])="lacaml_Sasum_stub_bc""lacaml_Sasum_stub"letasum?n?ofsx?incxx=letloc="Lacaml.S.asum"inletofsx,incx=get_vec_geomlocx_strofsxincxinletn=get_dim_veclocx_strofsxincxxn_strnindirect_asum~n~ofsx~incx~x(* BLAS-2 *)(* SBMV *)externaldirect_sbmv:ofsy:(int[@untagged])->incy:(int[@untagged])->y:vec->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->n:(int[@untagged])->k:(int[@untagged])->uplo:char->alpha:(float[@unboxed])->beta:(float[@unboxed])->ofsx:(int[@untagged])->incx:(int[@untagged])->x:vec->unit="lacaml_Ssbmv_stub_bc""lacaml_Ssbmv_stub"letsbmv?n?k?ofsy?incy?y?(ar=1)?(ac=1)a?(up=true)?(alpha=1.0)?(beta=0.0)?ofsx?incxx=letloc="Lacaml.S.sbmv"in(* [a] is a band matrix of size [k+1]*[n]. *)letn=get_dim2_matloca_straacn_strninletk=get_k_mat_sbloca_straark_strkinletofsx,incx=get_vec_geomlocx_strofsxincxinletofsy,incy=get_vec_geomlocy_strofsyincyinlety=get_veclocy_stryofsyincynVec.createincheck_veclocx_strx(ofsx+(n-1)*absincx);direct_sbmv~ofsy~incy~y~ar~ac~a~n~k~uplo:(get_uplo_charup)~alpha~beta~ofsx~incx~x;y(* GER *)externaldirect_ger:m:(int[@untagged])->n:(int[@untagged])->alpha:(float[@unboxed])->ofsx:(int[@untagged])->incx:(int[@untagged])->x:vec->ofsy:(int[@untagged])->incy:(int[@untagged])->y:vec->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->unit="lacaml_Sger_stub_bc""lacaml_Sger_stub"letger?m?n?(alpha=1.0)?ofsx?incxx?ofsy?incyy?(ar=1)?(ac=1)a=letloc="Lacaml.S.ger"incheck_mat_empty~loc~mat_name:a_str~dim1:(Mat.dim1a)~dim2:(Mat.dim2a);letm=get_dim1_matloca_straarm_strminletn=get_dim2_matloca_straacn_strninletofsx,incx=get_vec_geomlocx_strofsxincxincheck_veclocx_strx(ofsx+(m-1)*absincx);letofsy,incy=get_vec_geomlocy_strofsyincyincheck_veclocy_stry(ofsy+(n-1)*absincy);direct_ger~m~n~alpha~ofsx~incx~x~ofsy~incy~y~ar~ac~a(* SYR *)externaldirect_syr:uplo:char->n:(int[@untagged])->alpha:(float[@unboxed])->ofsx:(int[@untagged])->incx:(int[@untagged])->x:vec->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->unit="lacaml_Ssyr_stub_bc""lacaml_Ssyr_stub"letsyr?n?(alpha=1.0)?(up=true)?ofsx?incxx?(ar=1)?(ac=1)a=letloc="Lacaml.S.syr"incheck_mat_empty~loc~mat_name:a_str~dim1:(Mat.dim1a)~dim2:(Mat.dim2a);letn=get_n_of_alocaracaninletofsx,incx=get_vec_geomlocx_strofsxincxinletuplo=get_uplo_charupincheck_veclocx_strx(ofsx+(n-1)*absincx);direct_syr~uplo~n~alpha~ofsx~incx~x~ar~ac~a(* LAPACK *)(* Auxiliary routines *)externaldirect_lansy:norm:char->uplo:char->n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->work:vec->(float[@unboxed])="lacaml_Slansy_stub_bc""lacaml_Slansy_stub"letlansy_min_lworkn=function|`I|`O->n|_->0letlansy?n?(up=true)?(norm=`O)?work?(ar=1)?(ac=1)a=letloc="Lacaml.S.lansy"inletn=get_n_of_alocaracaninletuplo=get_uplo_charupinletmin_work=lansy_min_lworknnorminletwork,_lwork=get_worklocVec.createworkmin_workmin_worklwork_strinletnorm=get_norm_charnormindirect_lansy~norm~uplo~n~ar~ac~a~workexternaldirect_lamch:char->(float[@unboxed])="lacaml_Slamch_stub_bc""lacaml_Slamch_stub"letlamchcmach=direct_lamch(matchcmachwith|`E->'E'|`S->'S'|`B->'B'|`P->'P'|`N->'N'|`R->'R'|`M->'M'|`U->'U'|`L->'L'|`O->'O')(* Linear equations (computational routines) *)(* ORGQR *)externaldirect_orgqr:m:(int[@untagged])->n:(int[@untagged])->k:(int[@untagged])->work:vec->lwork:(int[@untagged])->tau:vec->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->(int[@untagged])="lacaml_Sorgqr_stub_bc""lacaml_Sorgqr_stub"letorgqr_min_lwork~n=max1nletorgqr_get_opt_lworkloc~m~n~k~tau~ar~ac~a=letwork=Vec.create1inletinfo=direct_orgqr~m~n~k~work~lwork:~-1~tau~ar~ac~ainifinfo=0thenint_of_floatwork.{1}elseorgqr_err~loc~m~n~k~work~a~err:infoletorgqr_opt_lwork?m?n?k~tau?(ar=1)?(ac=1)a=letloc="Lacaml.S.orgqr_opt_lwork"inletm,n,k=orgqr_get_paramsloc?m?n?k~tau~ar~acainorgqr_get_opt_lworkloc~m~n~k~tau~ar~ac~aletorgqr?m?n?k?work~tau?(ar=1)?(ac=1)a=letloc="Lacaml.S.orgqr"inletm,n,k=orgqr_get_paramsloc?m?n?k~tau~ar~acainletwork,lwork=letmin_lwork=orgqr_min_lwork~ninletopt_lwork=orgqr_get_opt_lworkloc~m~n~k~tau~ar~ac~ainget_worklocVec.createworkmin_lworkopt_lworklwork_strinletinfo=direct_orgqr~m~n~k~work~lwork~tau~ar~ac~ainifinfo=0then()elseorgqr_err~loc~m~n~k~work~a~err:info(* ORMQR *)externaldirect_ormqr:side:char->trans:char->m:(int[@untagged])->n:(int[@untagged])->k:(int[@untagged])->work:vec->lwork:(int[@untagged])->tau:vec->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->cr:(int[@untagged])->cc:(int[@untagged])->c:mat->(int[@untagged])="lacaml_Sormqr_stub_bc""lacaml_Sormqr_stub"letormqr_min_lwork~side~m~n=matchsidewith|`L->max1n|`R->max1mletormqr_get_opt_lworkloc~side~trans~m~n~k~tau~ar~ac~a~cr~cc~c=letwork=Vec.create1inletinfo=letside=get_side_charsideinlettrans=get_trans_chartransindirect_ormqr~side~trans~m~n~k~work~lwork:~-1~tau~ar~ac~a~cr~cc~cinifinfo=0thenint_of_floatwork.{1}elseormqr_err~loc~side~m~n~k~lwork:1~a~c~err:infoletormqr_opt_lwork?(side=`L)?(trans=`N)?m?n?k~tau?(ar=1)?(ac=1)a?(cr=1)?(cc=1)c=letloc="Lacaml.S.ormqr_opt_lwork"inletm,n,k=ormqr_get_paramsloc~side?m?n?k~tau~ar~aca~cr~cccinormqr_get_opt_lworkloc~side~trans~m~n~k~tau~ar~ac~a~cr~cc~cletormqr?(side=`L)?(trans=`N)?m?n?k?work~tau?(ar=1)?(ac=1)a?(cr=1)?(cc=1)c=letloc="Lacaml.S.ormqr"inletm,n,k=ormqr_get_paramsloc~side?m?n?k~tau~ar~aca~cr~cccinletwork,lwork=letmin_lwork=ormqr_min_lwork~side~m~ninletopt_lwork=ormqr_get_opt_lworkloc~side~trans~m~n~k~tau~ar~ac~a~cr~cc~cinget_worklocVec.createworkmin_lworkopt_lworklwork_strinletinfo=letside=get_side_charsideinlettrans=get_trans_chartransindirect_ormqr~side~trans~m~n~k~work~lwork~tau~ar~ac~a~cr~cc~cinifinfo=0then()elseormqr_err~loc~side~m~n~k~lwork~a~c~err:info(* GECON *)externaldirect_gecon:n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->work:vec->iwork:int32_vec->norm:char->anorm:(float[@unboxed])->int*float="lacaml_Sgecon_stub_bc""lacaml_Sgecon_stub"letgecon_min_lworkn=4*nletgecon_min_liworkn=nletgecon?n?(norm=`O)?anorm?work?iwork?(ar=1)?(ac=1)a=letloc="Lacaml.S.gecon"inletn=get_n_of_alocaracaninletwork,_lwork=letmin_lwork=gecon_min_lworkninget_worklocVec.createworkmin_lworkmin_lworklwork_strinletiwork,_liwork=get_worklocCommon.create_int32_veciwork(gecon_min_liworkn)(gecon_min_liworkn)liwork_strinletanorm=matchanormwith|None->lange~norm:(norm:>norm4)~m:n~na|Someanorm->anorminletnorm=get_norm_charnorminletinfo,rcond=direct_gecon~n~ar~ac~a~work~iwork~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->iwork:int32_vec->anorm:(float[@unboxed])->int*float="lacaml_Ssycon_stub_bc""lacaml_Ssycon_stub"letsycon_min_lworkn=2*nletsycon_min_liworkn=nletsycon?n?(up=true)?ipiv?anorm?work?iwork?(ar=1)?(ac=1)a=letloc="Lacaml.S.sycon"inletn=get_n_of_alocaracaninletuplo=get_uplo_charupinletwork,_lwork=get_worklocVec.creatework(sycon_min_lworkn)(sycon_min_lworkn)lwork_strinletiwork,_liwork=get_worklocCommon.create_int32_veciwork(sycon_min_liworkn)(sycon_min_liworkn)liwork_strinletipiv=ifipiv=Nonethensytrf~n~up~work~ar~acaelsesytrf_get_ipivlocipivninletanorm=matchanormwith|None->lange~m:n~n~work~ar~aca|Someanorm->anorminletinfo,rcond=direct_sycon~uplo~n~ar~ac~a~ipiv~work~iwork~anorminifinfo=0thenrcondelsexxcon_errlocnainfo(* POCON *)externaldirect_pocon:uplo:char->n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->work:vec->iwork:int32_vec->anorm:(float[@unboxed])->int*float="lacaml_Spocon_stub_bc""lacaml_Spocon_stub"letpocon_min_lworkn=3*nletpocon_min_liworkn=nletpocon?n?(up=true)?anorm?work?iwork?(ar=1)?(ac=1)a=letloc="Lacaml.S.pocon"inletn=get_n_of_alocaracaninletuplo=get_uplo_charupinletwork,_lwork=get_worklocVec.creatework(pocon_min_lworkn)(pocon_min_lworkn)lwork_strinletiwork,_liwork=get_worklocCommon.create_int32_veciwork(pocon_min_liworkn)(pocon_min_liworkn)liwork_strinletanorm=matchanormwith|None->lange~m:n~n~work~ar~aca|Someanorm->anorminletinfo,rcond=direct_pocon~uplo~n~ar~ac~a~work~iwork~anorminifinfo=0thenrcondelsexxcon_errlocnainfo(* Least squares (expert drivers) *)(* GELSY *)externaldirect_gelsy:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->m:(int[@untagged])->n:(int[@untagged])->jpvt:int32_vec->rcond:(float[@unboxed])->work:vec->lwork:(int[@untagged])->nrhs:(int[@untagged])->br:(int[@untagged])->bc:(int[@untagged])->b:mat->int*int="lacaml_Sgelsy_stub_bc""lacaml_Sgelsy_stub"letgelsy_min_lwork~m~n~nrhs=letmn=minmninmax(mn+3*n+1)(2*mn+nrhs)letgelsy_get_opt_lworklocaracamnnrhsbrbcb=letwork=Vec.create1inletinfo,_=direct_gelsy~ar~ac~a~m~n~jpvt:empty_int32_vec~rcond:(-1.0)~work~lwork:~-1~nrhs~br~bc~binifinfo=0thenint_of_floatwork.{1}elsegelsX_errlocgelsy_min_lworkaramn1nrhsbrbinfoletgelsy_opt_lwork?m?n?(ar=1)?(ac=1)a?nrhs?(br=1)?(bc=1)b=letloc="Lacaml.S.gelsy_opt_lwork"inletm,n,nrhs=gelsX_get_paramslocaracamnnrhsbrbcbingelsy_get_opt_lworklocaracamnnrhsbrbcbletgelsy?m?n?(ar=1)?(ac=1)a?(rcond=-1.0)?jpvt?work?nrhs?(br=1)?(bc=1)b=letloc="Lacaml.S.gelsy"inletm,n,nrhs=gelsX_get_paramslocaracamnnrhsbrbcbinletjpvt=matchjpvtwith|Somejpvt->letdim_jpvt=Array1.dimjpvtinifdim_jpvt<ntheninvalid_arg(sprintf"%s: jpvt: valid=[%d..[ got=%d"locndim_jpvt)elsejpvt|None->letjpvt=create_int32_vecninArray1.filljpvt0l;jpvtinletwork,lwork=matchworkwith|Somework->letlwork=Array1.dimworkinletmin_lwork=gelsy_min_lwork~m~n~nrhsiniflwork<min_lworktheninvalid_arg(sprintf"%s: lwork: valid=[%d..[ got=%d"locmin_lworklwork)elsework,lwork|None->letlwork=gelsy_get_opt_lworklocaracamnnrhsbrbcbinVec.createlwork,lworkinletinfo,rank=direct_gelsy~ar~ac~a~m~n~jpvt~rcond~work~lwork~nrhs~br~bc~binifinfo=0thenrankelsegelsX_errlocgelsy_min_lworkaramnlworknrhsbrbinfo(* GELSD *)externaldirect_gelsd:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->m:(int[@untagged])->n:(int[@untagged])->ofss:(int[@untagged])->s:vec->rcond:(float[@unboxed])->work:vec->lwork:(int[@untagged])->iwork:vec->nrhs:(int[@untagged])->br:(int[@untagged])->bc:(int[@untagged])->b:mat->int*int="lacaml_Sgelsd_stub_bc""lacaml_Sgelsd_stub"letlg2_10=log102.0letlog2n=log10n/.lg2_10letgelsd_smlsiz=ilaenv9"SGELSD"" "0000letgelsd_smlsiz1=gelsd_smlsiz+1letfgelsd_smlsiz1=floatgelsd_smlsiz1letgelsd_smlsiz1_2=gelsd_smlsiz1*gelsd_smlsiz1letgelsd_nlvlmn=max0(int_of_float(log2(floatmn/.fgelsd_smlsiz1))+1)letgelsd_min_lwork~m~n~nrhs=letmn=minmninletnlvl=gelsd_nlvlmnin12*mn+2*mn*gelsd_smlsiz+8*mn*nlvl+mn*nrhs+gelsd_smlsiz1_2letgelsd_get_min_iworkmnnlvl=3*mn*nlvl+11*mnletgelsd_min_iworkmn=letmn=minmningelsd_get_min_iworkmn(gelsd_nlvlmn)letgelsd_get_opt_lworklocaracamnnrhsbrbcb=letwork=Vec.create1inletinfo,_=direct_gelsd~ar~ac~a~m~n~ofss:1~s:Vec.empty~rcond:(-1.0)~work~lwork:~-1~iwork:Vec.empty~nrhs~br~bc~binifinfo=0then(* FIXME: LAPACK bug??? *)(* int_of_float32 work.{1} *)max(int_of_float32work.{1})(gelsd_min_lwork~m~n~nrhs)elsegelsX_errlocgelsd_min_lworkaramn1nrhsbrbinfoletgelsd_opt_lwork?m?n?(ar=1)?(ac=1)a?nrhs?(br=1)?(bc=1)b=letloc="Lacaml.S.gelsd_opt_lwork"inletm,n,nrhs=gelsX_get_paramslocaracamnnrhsbrbcbingelsd_get_opt_lworklocaracamnnrhsbrbcbletgelsd?m?n?(rcond=-1.0)?ofss?s?work?iwork?(ar=1)?(ac=1)a?nrhs?(br=1)?(bc=1)b=letloc="Lacaml.S.gelsd"inletm,n,nrhs=gelsX_get_paramslocaracamnnrhsbrbcbinletmn=minmninletofss=get_vec_ofslocs_strofssinlets=gelsX_get_sVec.createlocmnofsssinletiwork=letmin_iwork=gelsd_get_min_iworkmn(gelsd_nlvlmn)inmatchiworkwith|Someiwork->letdim_iwork=Array1.dimiworkinifdim_iwork<min_iworktheninvalid_arg(sprintf"%s: iwork: valid=[%d..[ got=%d"locmin_iworkdim_iwork)elseiwork|None->Vec.createmin_iworkinletwork,lwork=matchworkwith|Somework->letlwork=Array1.dimworkinletmin_lwork=gelsd_min_lwork~m~n~nrhsiniflwork<min_lworktheninvalid_arg(sprintf"%s: lwork: valid=[%d..[ got=%d"locmin_lworklwork)elsework,lwork|None->letlwork=gelsd_get_opt_lworklocaracamnnrhsbrbcbinVec.createlwork,lworkinletinfo,rank=direct_gelsd~ar~ac~a~m~n~ofss~s~rcond~work~lwork~iwork~nrhs~br~bc~binifinfo=0thenrankelsegelsX_errlocgelsd_min_lworkaramnlworknrhsbrbinfo(* GELSS *)externaldirect_gelss:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->m:(int[@untagged])->n:(int[@untagged])->ofss:(int[@untagged])->s:vec->rcond:(float[@unboxed])->work:vec->lwork:(int[@untagged])->nrhs:(int[@untagged])->br:(int[@untagged])->bc:(int[@untagged])->b:mat->int*int="lacaml_Sgelss_stub_bc""lacaml_Sgelss_stub"letgelss_min_lwork~m~n~nrhs=letmin_dim=minmninmax1(3*min_dim+max(max(2*min_dim)(maxmn))nrhs)letgelss_get_opt_lworklocaracamnnrhsbrbcb=letwork=Vec.create1inletinfo,_=direct_gelss~ar~ac~a~m~n~ofss:1~s:Vec.empty~rcond:(-1.0)~work~lwork:~-1~nrhs~br~bc~binifinfo=0thenint_of_float32work.{1}elsegelsX_errlocgelss_min_lworkaramn1nrhsbrbinfoletgelss_opt_lwork?(ar=1)?(ac=1)a?m?n?nrhs?(br=1)?(bc=1)b=letloc="Lacaml.S.gelss_opt_lwork"inletm,n,nrhs=gelsX_get_paramslocaracamnnrhsbrbcbingelss_get_opt_lworklocaracamnnrhsbrbcbletgelss?m?n?(rcond=-1.0)?ofss?s?work?(ar=1)?(ac=1)a?nrhs?(br=1)?(bc=1)b=letloc="Lacaml.S.gelss"inletm,n,nrhs=gelsX_get_paramslocaracamnnrhsbrbcbinletofss=get_vec_ofslocs_strofssinlets=gelsX_get_sVec.createloc(minmn)ofsssinletwork,lwork=matchworkwith|Somework->work,Array1.dimwork|None->letlwork=gelss_get_opt_lworklocaracamnnrhsbrbcbinVec.createlwork,lworkinletinfo,rank=direct_gelss~ar~ac~a~m~n~ofss~s~rcond~work~lwork~nrhs~br~bc~binifinfo=0thenrankelsegelsX_errlocgelss_min_lworkaramnlworknrhsbrbinfo(* 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->wr:vec->wi:vec->vsr:(int[@untagged])->vsc:(int[@untagged])->vs:mat->work:vec->lwork:(int[@untagged])->bwork:int32_vec->int*int="lacaml_Sgees_stub_bc""lacaml_Sgees_stub"(* result : (SDIM, INFO) *)externalinit_gees:unit->unit="lacaml_Sinit_gees"let()=init_gees()letgees_get_opt_lwork~loc~jobvs~sort~select~select_fun~n~ar~ac~a~wr~wi~vsr~vsc~vs~bwork=letlwork=-1inletwork=Vec.create1inlet_,info=direct_gees~jobvs~sort~select~select_fun~n~ar~ac~a~wr~wi~vsr~vsc~vs~work~lwork~bworkinifinfo=0thenint_of_float32work.{1}elsegees_errlocninfojobvssortletgees?n?(jobvs=`Compute_Schur_vectors)?(sort=`No_sort)?wr?wi?(vsr=1)?(vsc=1)?vs?work?(ar=1)?(ac=1)a=letloc="Lacaml.S.gees"inletjobvs,sort_char,select,select_fun,n,vs,wr,wi=gees_get_params_reallocVec.createMat.createMat.emptyjobvssortnaracawrwivsrvscvsinletbwork=matchsortwith|`No_sort->empty_int32_vec|_->create_int32_vecninletwork,lwork=matchworkwith|Somework->work,Array1.dimwork|None->letlwork=gees_get_opt_lwork~loc~jobvs~sort:sort_char~select~select_fun~n~ar~ac~a~wr~wi~vsr~vsc~vs~bworkinVec.createlwork,lworkinletsdim,info=direct_gees~jobvs~sort:sort_char~select~select_fun~n~ar~ac~a~wr~wi~vsr~vsc~vs~work~lwork~bworkinifinfo=0thensdim,wr,wi,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:vec->ur:(int[@untagged])->uc:(int[@untagged])->u:mat->vtc:(int[@untagged])->vtr:(int[@untagged])->vt:mat->work:vec->lwork:(int[@untagged])->(int[@untagged])="lacaml_Sgesvd_stub_bc""lacaml_Sgesvd_stub"letgesvd_min_lwork~m~n=letmin_m_n=minmninmax1(max(3*min_m_n+maxmn)(5*min_m_n))letgesvd_get_opt_lworklocjobujobvtmnaracasurucuvtrvtcvt=letlwork=-1inletwork=Vec.create1inletinfo=direct_gesvd~jobu~jobvt~m~n~ar~ac~a~s~ur~uc~u~vtr~vtc~vt~work~lworkinifinfo=0thenint_of_float32work.{1}elsegesvd_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.S.gesvd_opt_lwork"inletjobu,jobvt,m,n,s,u,vt=gesvd_get_paramslocVec.createMat.createjobujobvtmnaracasurucuvtrvtcvtingesvd_get_opt_lworklocjobujobvtmnaracasurucuvtrvtcvtletget_job_svecsmat=function|`A|`S->mat|`O|`N->Mat.emptyletgesvd?m?n?jobu:(jobu_t=`A)?jobvt:(jobvt_t=`A)?s?(ur=1)?(uc=1)?u?(vtr=1)?(vtc=1)?vt?work?(ar=1)?(ac=1)a=letloc="Lacaml.S.gesvd"inletjobu,jobvt,m,n,s,u,vt=gesvd_get_paramslocVec.createMat.createjobu_tjobvt_tmnaracasurucuvtrvtcvtinletwork,lwork=matchworkwith|Somework->work,Array1.dimwork|None->letlwork=gesvd_get_opt_lworklocjobujobvtmnaracasurucuvtrvtcvtinVec.createlwork,lworkinletinfo=direct_gesvd~jobu~jobvt~m~n~ar~ac~a~s~ur~uc~u~vtr~vtc~vt~work~lworkinifinfo=0thenletu=get_job_svecsujobu_tinletvt=get_job_svecsvtjobvt_tins,u,vtelsegesvd_errlocjobujobvtmnauvtlworkinfo(* GESDD *)externaldirect_gesdd:jobz:char->m:(int[@untagged])->n:(int[@untagged])->ar:(int[@untagged])->ac:(int[@untagged])->a:mat->s:vec->ur:(int[@untagged])->uc:(int[@untagged])->u:mat->vtr:(int[@untagged])->vtc:(int[@untagged])->vt:mat->work:vec->lwork:(int[@untagged])->iwork:int32_vec->(int[@untagged])="lacaml_Sgesdd_stub_bc""lacaml_Sgesdd_stub"letgesdd_min_lwork?(jobz=`A)~m~n()=letmin_lwork=letmin_m_n=minmninletmin_m_n_3=3*min_m_ninletarg=matchjobzwith|`N->7|`O->5*min_m_n+4|`S|`A->4*(min_m_n+1)inmin_m_n_3+max(maxmn)(arg*min_m_n)inmax1min_lworkletgesdd_liwork~m~n=8*minmnletgesdd_get_iworkloc~m~niwork=letmin_liwork=gesdd_liwork~m~ninmatchiworkwith|Someiwork->letliwork=Array1.dimiworkinifliwork<min_liworktheninvalid_arg(sprintf"%s: liwork: valid=[%d..[ got=%d"locmin_liworkliwork);iwork|None->create_int32_vecmin_liworkletgesdd_min_lwork_charjobz~m~n=letjobz=matchjobzwith|'N'->`N|'O'->`O|'S'->`S|_->`Aingesdd_min_lwork~jobz~m~n()letgesdd_get_opt_lworklocjobz?iworkmnaracasurucuvtrvtcvt=letiwork=gesdd_get_iworkloc~m~niworkinletlwork=-1inletwork=Vec.create1inletinfo=direct_gesdd~jobz~m~n~ar~ac~a~s~ur~uc~u~vtr~vtc~vt~work~lwork~iworkinifinfo=0then(* FIXME: LAPACK bug??? *)(* int_of_float32 work.{1} *)max(int_of_float32work.{1})(gesdd_min_lwork_charjobz~m~n)elsegesdd_errlocjobzmnauvtlworkinfoletgesdd_opt_lwork?m?n?(jobz=`A)?s?(ur=1)?(uc=1)?u?(vtr=1)?(vtc=1)?vt?iwork?(ar=1)?(ac=1)a=letloc="Lacaml.S.gesdd_opt_lwork"inletjobz_c,m,n,s,u,vt=gesdd_get_paramslocVec.createMat.createjobzmnaracasurucuvtrvtcvtingesdd_get_opt_lworklocjobz_c?iworkmnaracasurucuvtrvtcvtletgesdd?m?n?jobz:(jobz_t=`A)?s?(ur=1)?(uc=1)?u?(vtr=1)?(vtc=1)?vt?work?iwork?(ar=1)?(ac=1)a=letloc="Lacaml.S.gesdd"inletjobz,m,n,s,u,vt=gesdd_get_paramslocVec.createMat.createjobz_tmnaracasurucuvtrvtcvtinletiwork=gesdd_get_iworkloc~m~niworkinletwork,lwork=matchworkwith|Somework->work,Array1.dimwork|None->letlwork=gesdd_get_opt_lworklocjobz~iworkmnaracasurucuvtrvtcvtinVec.createlwork,lworkinletinfo=direct_gesdd~jobz~m~n~ar~ac~a~s~ur~uc~u~vtr~vtc~vt~work~lwork~iworkinifinfo=0thenmatchjobz_twith|`A|`S->s,u,vt|`O->ifm>=nthens,Mat.empty,vtelses,u,Mat.empty|`N->s,Mat.empty,Mat.emptyelsegesdd_errlocjobzmnauvtlworkinfo(* General eigenvalue problem (simple drivers) *)(* GEEV error handler *)letgeev_errlocmin_workanvlvrlworkerr=iferr>0thenletmsg=sprintf"\
%s: The QR algorithm failed to compute all the eigenvalues,\n\
and no eigenvectors have been computed; elements %d:%d of WR\n\
and WI 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)|-9->sprintf"dim1(vl): valid=[%d..[ got=%d"(max1n)(Array2.dim1vl)|-11->sprintf"dim1(vr): valid=[%d..[ got=%d"(max1n)(Array2.dim1vr)|-13->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])->ofswr:(int[@untagged])->wr:vec->ofswi:(int[@untagged])->wi: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])->(int[@untagged])="lacaml_Sgeev_stub_bc""lacaml_Sgeev_stub"letgeev_min_lwork?(vectors=true)n=ifvectorsthenmax1(4*n)elsemax1(3*n)letgeev_get_opt_lwork~loc~n~vlr~vlc~vl~jobvl~vrr~vrc~vr~jobvr~ofswr~wr~ofswi~wi~ar~ac~a~vectors=letwork=Vec.create1inletinfo=direct_geev~ar~ac~a~n~ofswr~wr~ofswi~wi~vlr~vlc~vl~jobvl~vrr~vrc~vr~jobvr~work~lwork:~-1inifinfo=0thenint_of_floatwork.{1}elsegeev_errloc(geev_min_lwork~vectors)anvlvr~-1infoletgeev_get_params~loc~ar~ac~a~n~vlr~vlc~vl~vrr~vrc~vr~ofswr~wr~ofswi~wi=letn,_,_,_,_,_,_,_,_,_asparams=geev_gen_get_paramslocMat.emptyMat.createaracanvlrvlcvlvrrvrcvrin(params,xxev_get_wxVec.createlocwr_strofswrwrn,xxev_get_wxVec.createlocwi_strofswiwin)letgeev_opt_lwork?n?(vlr=1)?(vlc=1)?vl?(vrr=1)?(vrc=1)?vr?(ofswr=1)?wr?(ofswi=1)?wi?(ar=1)?(ac=1)a=letloc="Lacaml.S.geev_opt_lwork"inlet(n,vlr,vlc,vl,jobvl,vrr,vrc,vr,jobvr,vectors),(ofswr,wr),(ofswi,wi)=geev_get_params~loc~ar~ac~a~n~vlr~vlc~vl~vrr~vrc~vr~ofswr~wr~ofswi~wiingeev_get_opt_lwork~loc~n~vlr~vlc~vl~jobvl~vrr~vrc~vr~jobvr~ofswr~wr~ofswi~wi~ar~ac~a~vectorsletgeev?n?work?(vlr=1)?(vlc=1)?vl?(vrr=1)?(vrc=1)?vr?(ofswr=1)?wr?(ofswi=1)?wi?(ar=1)?(ac=1)a=letloc="Lacaml.S.geev"inlet(n,vlr,vlc,vl,jobvl,vrr,vrc,vr,jobvr,vectors),(ofswr,wr),(ofswi,wi)=geev_get_params~loc~ar~ac~a~n~vlr~vlc~vl~vrr~vrc~vr~ofswr~wr~ofswi~wiinletwork,lwork=matchworkwith|Somework->letlwork=Array1.dimworkinletmin_lwork=geev_min_lwork~vectorsniniflwork<min_lworktheninvalid_arg(sprintf"%s: lwork: valid=[%d..[ got=%d"locmin_lworklwork)elsework,lwork|None->letlwork=geev_get_opt_lwork~loc~n~vlr~vlc~vl~jobvl~vrr~vrc~vr~jobvr~ofswr~wr~ofswi~wi~ar~ac~a~vectorsinVec.createlwork,lworkinletinfo=direct_geev~ar~ac~a~n~ofswr~wr~ofswi~wi~vlr~vlc~vl~jobvl~vrr~vrc~vr~jobvr~work~lworkinifinfo=0thenvl,wr,wi,vrelsegeev_errloc(geev_min_lwork~vectors)anvlvrlworkinfo(* Symmetric-matrix eigenvalue and singular value problems (simple drivers) *)(* SYEV? auxiliary functions *)letsyev_errlocmin_workanlworkerr=iferr>0thenletmsg=sprintf"%s: failed to converge on off-diagonal element %d"locerrinfailwithmsgelseletmsg=matcherrwith|-3->sprintf"n: valid=[0..[ got=%d"n|-5->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|-8->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)letsyevd_errlocmin_workmin_iworkanlworkliworkerr=iferr=-10thenletmsg=sprintf"%s: dim(iwork): valid=[%d..[ got=%d"loc(min_iworkn)liworkininvalid_argmsgelsesyev_errlocmin_workanlworkerr(* SYEV *)externaldirect_syev:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->n:(int[@untagged])->jobz:char->uplo:char->ofsw:(int[@untagged])->w:vec->work:vec->lwork:(int[@untagged])->(int[@untagged])="lacaml_Ssyev_stub_bc""lacaml_Ssyev_stub"letsyev_min_lworkn=max1(3*n-1)letsyev_get_opt_lworklocaracanjobzuplo=letwork=Vec.create1inletinfo=direct_syev~ar~ac~a~n~jobz~uplo~ofsw:1~w:Vec.empty~work~lwork:~-1inifinfo=0thenint_of_floatwork.{1}elsesyev_errlocsyev_min_lworkan~-1infoletsyev_opt_lwork?n?(vectors=false)?(up=true)?(ar=1)?(ac=1)a=letloc="Lacaml.S.syev_opt_lwork"inletn,jobz,uplo=xxev_get_paramslocaracanvectorsupinsyev_get_opt_lworklocaracanjobzuploletsyev?n?(vectors=false)?(up=true)?work?ofsw?w?(ar=1)?(ac=1)a=letloc="Lacaml.S.syev"inletn,jobz,uplo=xxev_get_paramslocaracanvectorsupinletofsw=get_vec_ofslocw_strofswinletofsw,w=xxev_get_wxVec.createlocw_strofswwninletwork,lwork=matchworkwith|Somework->work,Array1.dimwork|None->letlwork=syev_get_opt_lworklocaracanjobzuploinVec.createlwork,lworkinletinfo=direct_syev~ar~ac~a~n~jobz~uplo~ofsw~w~work~lworkinifinfo=0thenwelsesyev_errlocsyev_min_lworkanlworkinfo(* SYEVD *)externaldirect_syevd:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->n:(int[@untagged])->jobz:char->uplo:char->ofsw:(int[@untagged])->w:vec->work:vec->lwork:(int[@untagged])->iwork:int32_vec->liwork:(int[@untagged])->(int[@untagged])="lacaml_Ssyevd_stub_bc""lacaml_Ssyevd_stub"letsyevd_min_lwork~vectorsn=ifn<=1then1elseifvectorsthenletnn=n*nin1+6*n+nn+nnelsen+n+1letsyevd_min_liwork~vectorsn=ifn<=1||notvectorsthen1else3+5*nletsyevd_get_opt_l_li_worklocaracanvectorsjobzuplo=letwork=Vec.create1inletiwork=Common.create_int32_vec1inletinfo=direct_syevd~ar~ac~a~n~jobz~uplo~ofsw:1~w:Vec.empty~work~lwork:~-1~iwork~liwork:~-1inifinfo=0thenint_of_floatwork.{1},Int32.to_intiwork.{1}elsesyevd_errloc(syevd_min_lwork~vectors)(syevd_min_liwork~vectors)an~-1~-1infoletsyevd_get_opt_lworklocaracanvectorsjobzuplo=fst(syevd_get_opt_l_li_worklocaracanvectorsjobzuplo)letsyevd_get_opt_liworklocaracanvectorsjobzuplo=snd(syevd_get_opt_l_li_worklocaracanvectorsjobzuplo)letsyevd_opt_l_li_work?n?(vectors=false)?(up=true)?(ar=1)?(ac=1)a=letloc="Lacaml.S.syevd_opt_l_li_work"inletn,jobz,uplo=xxev_get_paramslocaracanvectorsupinsyevd_get_opt_l_li_worklocaracanvectorsjobzuploletsyevd_opt_lwork?n?vectors?up?ar?aca=fst(syevd_opt_l_li_work?n?vectors?up?ar?aca)letsyevd_opt_liwork?n?vectors?up?ar?aca=snd(syevd_opt_l_li_work?n?vectors?up?ar?aca)letsyevd?n?(vectors=false)?(up=true)?work?iwork?ofsw?w?(ar=1)?(ac=1)a=letloc="Lacaml.S.syevd"inletn,jobz,uplo=xxev_get_paramslocaracanvectorsupinletofsw=get_vec_ofslocw_strofswinletofsw,w=xxev_get_wxVec.createlocw_strofswwninletwork,iwork,lwork,liwork=matchwork,iworkwith|Somework,Someiwork->letlwork=Array1.dimworkinletliwork=Array1.dimiworkinwork,iwork,lwork,liwork|Somework,None->letlwork=Array1.dimworkinletliwork=syevd_get_opt_liworklocaracanvectorsjobzuploinletiwork=Common.create_int32_vecliworkinwork,iwork,lwork,liwork|None,Someiwork->letlwork=syevd_get_opt_lworklocaracanvectorsjobzuploinletwork=Vec.createlworkinletliwork=Array1.dimiworkinwork,iwork,lwork,liwork|None,None->letlwork,liwork=syevd_get_opt_l_li_worklocaracanvectorsjobzuploinletwork=Vec.createlworkinletiwork=Common.create_int32_vecliworkinwork,iwork,lwork,liworkinletinfo=direct_syevd~ar~ac~a~n~jobz~uplo~ofsw~w~work~lwork~iwork~liworkinifinfo=0thenwelsesyevd_errloc(syevd_min_lwork~vectors)(syevd_min_liwork~vectors)anlworkliworkinfo(* SBEV *)externaldirect_sbev:abr:(int[@untagged])->abc:(int[@untagged])->ab:mat->n:(int[@untagged])->kd:(int[@untagged])->jobz:char->uplo:char->ofsw:(int[@untagged])->w:vec->zr:(int[@untagged])->zc:(int[@untagged])->z:mat->ldz:(int[@untagged])->(* require ldz = 1 when z empty (no eigenvectors) *)work:vec->(int[@untagged])="lacaml_Ssbev_stub_bc""lacaml_Ssbev_stub"letsbev_errlocabnkderr=iferr>0thenletmsg=sprintf"%s: failed to converge on %i off-diagonal elements"locerrinfailwithmsgelseletmsg=matcherrwith|-3->sprintf"n: valid=[0..[ got=%d"n|-4->sprintf"kd: valid=[0..[ got=%d"kd|-6->sprintf"dim1(ab): valid=[%d..[ got=%d"(kd+1)(Mat.dim1ab)(* z fully checked *)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letsbev_min_lworkn=max1(3*n-2)letsbev?n?kd?(zr=1)?(zc=1)?z?(up=true)?work?(ofsw=1)?w?(abr=1)?(abc=1)ab=letloc="Lacaml.S.sbev"in(* [a] is a band matrix of physical size [k+1]*[n]. *)letn=get_dim2_matlocab_strababcn_strninletuplo=get_uplo_charupinletkd=get_k_mat_sblocab_strababrkd_strkdinletofsw,w=xxev_get_wxVec.createlocw_strofswwninletlwork=sbev_min_lworkninletwork=matchworkwith|Somework->check_veclocwork_strworklwork;work|None->Vec.createlworkinletjobz,z,ldz=matchzwith|Somez->check_mat_squarelocz_strzzrzcn;job_char_true,z,Mat.dim1z|None->job_char_false,Mat.empty,1inletinfo=direct_sbev~abr~abc~ab~n~kd~jobz~uplo~ofsw~w~zr~zc~z~ldz~workinifinfo=0thenwelsesbev_errlocabnkdinfo(* Symmetric-matrix eigenvalue and singular value problems (expert &
RRR drivers) *)(* SYEVR *)externaldirect_syevr:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->n:(int[@untagged])->jobz:char->range:char->uplo:char->vl:(float[@unboxed])->vu:(float[@unboxed])->il:(int[@untagged])->iu:(int[@untagged])->abstol:(float[@unboxed])->ofsw:(int[@untagged])->w:vec->zr:(int[@untagged])->zc:(int[@untagged])->z:mat->isuppz:int32_vec->work:vec->lwork:(int[@untagged])->iwork:int32_vec->liwork:(int[@untagged])->int*int="lacaml_Ssyevr_stub_bc""lacaml_Ssyevr_stub"letsyevr_errlocanerr=iferr>0thenletmsg=sprintf"%s: internal error: %d"locerrinfailwithmsgelseletmsg=matcherrwith|-4->sprintf"n: valid=[0..[ got=%d"n|-6->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)letsyevr_min_lworkn=max1(26*n)letsyevr_min_liworkn=max1(10*n)letsyevr_get_paramslocn=function|`A->'A',n,0.,0.,0,0|`V(vl,vu)->ifvl>=vutheninvalid_arg(sprintf"%s: vl >= vu (%f >= %f)"locvlvu);'V',n,vl,vu,0,0|`I(il,iu)->ifn=0&&iu<>0theninvalid_arg(sprintf"%s: n = 0 && iu <> 0 (%d)"lociu);ifil<1theninvalid_arg(sprintf"%s: il < 1 (%d)"locil);ifiu>ntheninvalid_arg(sprintf"%s: iu > n (%d > %d)"lociun);ifil>iutheninvalid_arg(sprintf"%s: il > iu (%d > %d)"lociliu);'I',iu-il+1,0.,0.,il,iuletsyevr_get_abstol=functionSomeabstol->abstol|None->lamch`Sletsyevr_get_opt_l_li_worklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppz=letwork=Vec.create1inletiwork=Common.create_int32_vec1inletinfo,_=direct_syevr~ar~ac~a~n~jobz~range~uplo~vl~vu~il~iu~abstol~ofsw~w~zr~zc~z~isuppz~work~lwork:~-1~iwork~liwork:~-1inifinfo=0thenint_of_floatwork.{1},Int32.to_intiwork.{1}elsesyevr_errlocaninfoletsyevr_get_opt_lworklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppz=fst(syevr_get_opt_l_li_worklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppz)letsyevr_get_opt_liworklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppz=snd(syevr_get_opt_l_li_worklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppz)letsyevr_opt_l_li_work?n?(vectors=false)?(range=`A)?(up=true)?(abstol=0.)?(ar=1)?(ac=1)a=letloc="Lacaml.S.syevr_opt_l_li_work"inletn,jobz,uplo=xxev_get_paramslocaracanvectorsupinletrange,_m,vl,vu,il,iu=syevr_get_paramslocnrangeinletzr=1inletzc=1inletz=Mat.createn0inletofsw=1inletw=Vec.emptyinletisuppz=empty_int32_vecinsyevr_get_opt_l_li_worklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppzletsyevr_opt_lwork?n?vectors?range?up?abstol?ar?aca=fst(syevr_opt_l_li_work?n?vectors?range?up?abstol?ar?aca)letsyevr_opt_liwork?n?vectors?range?up?abstol?ar?aca=snd(syevr_opt_l_li_work?n?vectors?range?up?abstol?ar?aca)letsyevr?n?(vectors=false)?(range=`A)?(up=true)?abstol?work?iwork?ofsw?w?(zr=1)?(zc=1)?z?isuppz?(ar=1)?(ac=1)a=letloc="Lacaml.S.syevr"inletn,jobz,uplo=xxev_get_paramslocaracanvectorsupinletrange,m,vl,vu,il,iu=syevr_get_paramslocnrangeinletabstol=syevr_get_abstolabstolinletofsw=get_vec_ofslocw_strofswinletofsw,w=xxev_get_wxVec.createlocw_strofswwninletz=get_matlocz_strMat.createzrzcznm(* order of n, m is ok! *)inletisuppz=letmin_lisuppz_1=max1minletmin_lisuppz=min_lisuppz_1+min_lisuppz_1inmatchisuppzwith|None->create_int32_vecmin_lisuppz|Someisuppz->letlisuppz=Array1.dimisuppziniflisuppz<min_lisuppztheninvalid_arg(sprintf"%s: dim(isuppz): valid=[%d..[ got=%d"locmin_lisuppzlisuppz);isuppzinletwork,iwork,lwork,liwork=matchwork,iworkwith|Somework,Someiwork->letlwork=Array1.dimworkinletliwork=Array1.dimiworkinwork,iwork,lwork,liwork|Somework,None->letlwork=Array1.dimworkinletliwork=syevr_get_opt_liworklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppzinletiwork=Common.create_int32_vecliworkinwork,iwork,lwork,liwork|None,Someiwork->letlwork=syevr_get_opt_lworklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppzinletwork=Vec.createlworkinletliwork=Array1.dimiworkinwork,iwork,lwork,liwork|None,None->letlwork,liwork=syevr_get_opt_l_li_worklocaracanjobzrangeuplovlvuiliuabstolofswwzrzczisuppzinletwork=Vec.createlworkinletiwork=Common.create_int32_vecliworkinwork,iwork,lwork,liworkinletinfo,m=direct_syevr~ar~ac~a~n~jobz~range~uplo~vl~vu~il~iu~abstol~ofsw~w~zr~zc~z~isuppz~work~lwork~iwork~liworkinifinfo=0thenm,w,z,isuppzelsesyevr_errlocaninfo(* SYGV *)letsygv_errlocmin_workabnlworkerr=iferr>nthenletmsg=sprintf"%s: leading minor of order %d of b is not positive definite"loc(err-n)infailwithmsgelseiferr>0thenletmsg=sprintf"%s: failed to converge on off-diagonal element %d"locerrinfailwithmsgelseletmsg=matcherrwith|-4->sprintf"n: valid=[0..[ got=%d"n|-6->sprintf"dim1(a): valid=[%d..[ got=%d"(max1n)(Array2.dim1a)|-8->sprintf"dim1(b): valid=[%d..[ got=%d"(max1n)(Array2.dim1b)|-11->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)letget_itype=function`A_B->1|`AB->2|`BA->3externaldirect_sygv:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->br:(int[@untagged])->bc:(int[@untagged])->b:mat->n:(int[@untagged])->itype:(int[@untagged])->jobz:char->uplo:char->ofsw:(int[@untagged])->w:vec->work:vec->lwork:(int[@untagged])->(int[@untagged])="lacaml_Ssygv_stub_bc""lacaml_Ssygv_stub"letsygv_min_lworkn=max1(3*n-1)letsygv_get_opt_lworklocaracabrbcbnitypejobzuplo=letwork=Vec.create1inletinfo=direct_sygv~ar~ac~a~br~bc~b~n~itype~jobz~uplo~ofsw:1~w:Vec.empty~work~lwork:(-1)inifinfo=0thenint_of_floatwork.{1}elsesygv_errlocsygv_min_lworkabn(-1)infoletsygv_opt_lwork?n?(vectors=false)?(up=true)?(itype=`A_B)?(ar=1)?(ac=1)a?(br=1)?(bc=1)b=letloc="Lacaml.S.sygv_opt_lwork"inletn,jobz,uplo=xxev_get_paramslocaracanvectorsupincheck_dim1_matlocb_strbbrn_strn;check_dim2_matlocb_strbbcn_strn;letitype=get_itypeitypeinsygv_get_opt_lworklocaracabrbcbnitypejobzuploletsygv?n?(vectors=false)?(up=true)?work?ofsw?w?(itype=`A_B)?(ar=1)?(ac=1)a?(br=1)?(bc=1)b=letloc="Lacaml.S.sygv"inletn,jobz,uplo=xxev_get_paramslocaracanvectorsupincheck_dim1_matlocb_strbbrn_strn;check_dim2_matlocb_strbbcn_strn;letofsw=get_vec_ofslocw_strofswinletofsw,w=xxev_get_wxVec.createlocw_strofswwninletitype=get_itypeitypeinletwork,lwork=matchworkwith|Somework->work,Array1.dimwork|None->letlwork=sygv_get_opt_lworklocaracabrbcbnitypejobzuploinVec.createlwork,lworkinletinfo=direct_sygv~ar~ac~a~br~bc~b~n~itype~jobz~uplo~ofsw~w~work~lworkinifinfo=0thenwelsesygv_errlocsygv_min_lworkabnlworkinfo(* SBGV *)externaldirect_sbgv:ar:(int[@untagged])->ac:(int[@untagged])->a:mat->br:(int[@untagged])->bc:(int[@untagged])->b:mat->n:(int[@untagged])->ka:(int[@untagged])->kb:(int[@untagged])->jobz:char->uplo:char->ofsw:(int[@untagged])->w:vec->zr:(int[@untagged])->zc:(int[@untagged])->z:mat->work:vec->(int[@untagged])="lacaml_Ssbgv_stub_bc""lacaml_Ssbgv_stub"letsbgv_min_lworkn=3*nletsbgv_errlocabnkakbzerr=iferr>nthenletmsg=sprintf"%s: leading minor of order %d of b is not positive definite"loc(err-n)infailwithmsgelseiferr>0thenletmsg=sprintf"%s: failed to converge on off-diagonal element %d"locerrinfailwithmsgelseletmsg=matcherrwith|-3->sprintf"n: valid=[0..[ got=%d"n|-4->sprintf"ka: valid=[0..[ got=%d"ka|-5->sprintf"kb: valid=[0..[ got=%d"kb|-7->sprintf"dim1(a): valid=[%d..[ got=%d"(ka+1)(Array2.dim1a)|-9->sprintf"dim1(b): valid=[%d..[ got=%d"(kb+1)(Array2.dim1b)|-12->sprintf"dim1(vectors): valid=[%d..[ got=%d"n(Array2.dim1z)|n->raise(InternalError(sprintf"%s: error code %d"locn))ininvalid_arg(sprintf"%s: %s"locmsg)letdummy_matrix=Mat.create10(* The fact that the number of rows is 1 is important, otherwise SBGV
rejects LDZ as being illegal. *)letsbgv?n?ka?kb?(zr=1)?(zc=1)?z?(up=true)?work?ofsw?w?(ar=1)?(ac=1)a?(br=1)?(bc=1)b=letloc="Lacaml.S.sbgv"in(* [a] is a band matrix of size [ka+1]*[n]. *)letn=get_dim2_matloca_straacn_strninletka=get_k_mat_sbloca_straarka_strkaincheck_dim2_matlocb_strbbcn_strn;letkb=get_k_mat_sblocb_strbbrkb_strkbinletuplo=get_uplo_charupinletjobz,z=matchzwith|None->job_char_false,dummy_matrix|Somez->check_dim_matlocz_strzrzcznn;job_char_true,zinletofsw=get_vec_ofslocw_strofswinletofsw,w=xxev_get_wxVec.createlocw_strofswwninletwork=matchworkwith|Somework->check_veclocwork_strwork(sbgv_min_lworkn);work|None->Vec.create(sbgv_min_lworkn)inletinfo=direct_sbgv~ar~ac~a~br~bc~b~n~ka~kb~jobz~uplo~ofsw~w~zr~zc~z~workinifinfo=0thenwelsesbgv_errlocabnkakbzinfo