Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file owl_base_linalg_generic.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195# 1 "src/base/linalg/owl_base_linalg_generic.ml"(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2019 Liang Wang <liang.wang@cl.cam.ac.uk>
*)type('a,'b)t=('a,'b)Owl_base_dense_ndarray_generic.tmoduleM=Owl_base_dense_ndarray_generic(* Check matrix properties *)letis_triux=letshp=M.shapexinletm,n=shp.(0),shp.(1)inletk=Stdlib.minmninlet_a0=Owl_const.zero(M.kindx)intryfori=0tok-1doforj=0toi-1doassert(M.getx[|i;j|]=_a0)donedone;truewith_exn->falseletis_trilx=letshp=M.shapexinletm,n=shp.(0),shp.(1)inletk=Stdlib.minmninlet_a0=Owl_const.zero(M.kindx)intryfori=0tok-1doforj=i+1tok-1doassert(M.getx[|i;j|]=_a0)donedone;truewith_exn->falseletis_symmetricx=letshp=M.shapexinletm,n=shp.(0),shp.(1)inifm<>nthenfalseelse(tryfori=0ton-1doforj=i+1ton-1doleta=M.getx[|j;i|]inletb=M.getx[|i;j|]inassert(a=b)donedone;truewith_exn->false)letis_hermitianx=letshp=M.shapexinletm,n=shp.(0),shp.(1)inifm<>nthenfalseelse(tryfori=0ton-1doforj=iton-1doleta=M.getx[|j;i|]inletb=Complex.conj(M.getx[|i;j|])inassert(a=b)donedone;truewith_exn->false)letis_diagx=is_triux&&is_trilxlet_check_is_matrixdims=if(Array.lengthdims)!=2thenraise(Invalid_argument"The given NDarray is not a matrix!")else()(* Linear equation solution by Gauss-Jordan elimination.
* Input matrix: a[n][n], b[n][m];
* Output: ``ainv``, inversed matrix of a; ``x``, so that ax = b.
* TODO: Extend to multiple types: double, complex; unify with existing owl
* structures e.g. naming.
* Test: https://github.com/scipy/scipy/blob/master/scipy/linalg/tests/test_basic.py#L496 *)letlinsolve_gaussab=let(dims_a,dims_b)=(M.shapea,M.shapeb)inlet(_,_)=(_check_is_matrixdims_a,_check_is_matrixdims_b)inleta=M.copyainletb=M.copybinletn=dims_a.(0)inletm=dims_b.(1)inleticol=ref0inletirow=ref0inletdum=ref0.0inletpivinv=ref0.0inletindxc=Array.maken0inletindxr=Array.maken0inletipiv=Array.maken0in(* Main loop over the columns to be reduced. *)fori=0ton-1doletbig=ref0.0in(* Outer loop of the search for at pivot element *)forj=0ton-1doifipiv.(j)!=1then(fork=0ton-1doifipiv.(k)==0then(letv=M.geta[|j;k|]|>abs_floatinif(v>=!big)then(big:=v;irow:=j;icol:=k;))done)done;ipiv.(!icol)<-ipiv.(!icol)+1;if(!irow<>!icol)then(forl=0ton-1doletu=M.geta[|!irow;l|]inletv=M.geta[|!icol;l|]inM.seta[|!icol;l|]u;M.seta[|!irow;l|]vdone;forl=0tom-1doletu=M.getb[|!irow;l|]inletv=M.getb[|!icol;l|]inM.setb[|!icol;l|]u;M.setb[|!irow;l|]vdone);indxr.(i)<-!irow;indxc.(i)<-!icol;letp=M.geta[|!icol;!icol|]inif(p=0.0)thenraiseOwl_exception.SINGULAR;pivinv:=1.0/.p;M.seta[|!icol;!icol|]1.0;forl=0ton-1doletprev=M.geta[|!icol;l|]inM.seta[|!icol;l|](prev*.!pivinv)done;forl=0tom-1doletprev=M.getb[|!icol;l|]inM.setb[|!icol;l|](prev*.!pivinv)done;forll=0ton-1doif(ll!=!icol)then(dum:=M.geta[|ll;!icol|];M.seta[|ll;!icol|]0.0;forl=0ton-1doletp=M.geta[|!icol;l|]inletprev=M.geta[|ll;l|]inM.seta[|ll;l|](prev-.p*.!dum)done;forl=0tom-1doletp=M.getb[|!icol;l|]inletprev=M.getb[|ll;l|]inM.setb[|ll;l|](prev-.p*.!dum)done)donedone;forl=n-1downto0doif(indxr.(l)!=indxc.(l))then(fork=0ton-1doletu=M.geta[|k;indxr.(l)|]inletv=M.geta[|k;indxc.(l)|]inM.seta[|k;indxc.(l)|]u;M.seta[|k;indxr.(l)|]vdone)done;a,b(* ends here *)