123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146openPrintfopenBigarrayincludeSexplib0.Sexp_convopenSexptypebigstring=(char,int8_unsigned_elt,c_layout)Array1.ttypefloat32_vec=(float,float32_elt,fortran_layout)Array1.ttypefloat64_vec=(float,float64_elt,fortran_layout)Array1.ttypevec=float64_vectypefloat32_mat=(float,float32_elt,fortran_layout)Array2.ttypefloat64_mat=(float,float64_elt,fortran_layout)Array2.ttypemat=float64_matletsexp_of_float_vecvec=letlst_ref=ref[]infori=Array1.dimvecdownto1dolst_ref:=sexp_of_floatvec.{i}::!lst_refdone;List!lst_ref;;letsexp_of_bigstring(bstr:bigstring)=letn=Array1.dimbstrinletstr=Bytes.createninfori=0ton-1doBytes.setstribstr.{i}done;Atom(Bytes.unsafe_to_stringstr);;letsexp_of_float32_vec(vec:float32_vec)=sexp_of_float_vecvecletsexp_of_float64_vec(vec:float64_vec)=sexp_of_float_vecvecletsexp_of_vec(vec:vec)=sexp_of_float_vecvecletsexp_of_float_matmat=letm=Array2.dim1matinletn=Array2.dim2matinletlst_ref=ref[]in(* It's surprising that we serialize [Fortran_layout] matrices in row-major order. I can
only speculate that it was chosen for readability. The cache performance is
irrelevant because people who care won't serialize to sexp. *)forrow=ndownto1doforcol=mdownto1dolst_ref:=sexp_of_floatmat.{col,row}::!lst_refdonedone;List(sexp_of_intm::sexp_of_intn::!lst_ref);;letsexp_of_float32_mat(mat:float32_mat)=sexp_of_float_matmatletsexp_of_float64_mat(mat:float64_mat)=sexp_of_float_matmatletsexp_of_mat(mat:mat)=sexp_of_float_matmatletbigstring_sexp_grammar:bigstringSexplib0.Sexp_grammar.t={untyped=String}letbigstring_of_sexpsexp=matchsexpwith|Atomstr->letlen=String.lengthstrinletbstr=Array1.createcharc_layoutleninfori=0tolen-1dobstr.{i}<-str.[i]done;bstr|List_->of_sexp_error"bigstring_of_sexp: atom needed"sexp;;letfloat_vec_of_sexpempty_float_veccreate_float_vecsexp=matchsexpwith|List[]->empty_float_vec|Listlst->letlen=List.lengthlstinletres=create_float_vecleninletrecloopi=function|[]->res|h::t->res.{i}<-float_of_sexph;loop(i+1)tinloop1lst|Atom_->of_sexp_error"float_vec_of_sexp: list needed"sexp;;letcreate_float32_vec=Array1.createfloat32fortran_layoutletcreate_float64_vec=Array1.createfloat64fortran_layoutletempty_float32_vec=create_float32_vec0letempty_float64_vec=create_float64_vec0letfloat32_vec_of_sexp=float_vec_of_sexpempty_float32_veccreate_float32_vecletfloat64_vec_of_sexp=float_vec_of_sexpempty_float64_veccreate_float64_vecletvec_of_sexp=float_vec_of_sexpempty_float64_veccreate_float64_vecletvec_sexp_grammar:_Sexplib0.Sexp_grammar.t={untyped=List(ManyFloat)}letfloat32_vec_sexp_grammar=vec_sexp_grammarletfloat64_vec_sexp_grammar=vec_sexp_grammarletcheck_too_much_datasexpdatares=ifdata=[]thenreselseof_sexp_error"float_mat_of_sexp: too much data"sexp;;letfloat_mat_of_sexpcreate_float_matsexp=matchsexpwith|List(sm::sn::data)->letm=int_of_sexpsminletn=int_of_sexpsninletres=create_float_matmninifm=0||n=0thencheck_too_much_datasexpdatareselse(letrecloop_colscoldata=letvec=Array2.slice_rightrescolinletrecloop_rowsrow=function|[]->of_sexp_error"float_mat_of_sexp: not enough data"sexp|h::t->vec.{row}<-float_of_sexph;ifrow=mthenifcol=nthencheck_too_much_datasexptreselseloop_cols(col+1)telseloop_rows(row+1)tinloop_rows1datainloop_cols1data)|List_->of_sexp_error"float_mat_of_sexp: list too short"sexp|Atom_->of_sexp_error"float_mat_of_sexp: list needed"sexp;;letcreate_float32_mat=Array2.createfloat32fortran_layoutletcreate_float64_mat=Array2.createfloat64fortran_layoutletfloat32_mat_of_sexp=float_mat_of_sexpcreate_float32_matletfloat64_mat_of_sexp=float_mat_of_sexpcreate_float64_matletmat_of_sexp=float_mat_of_sexpcreate_float64_matletmat_sexp_grammar:_Sexplib0.Sexp_grammar.t={untyped=List(Cons(Integer,Cons(Integer,ManyFloat)))};;letfloat32_mat_sexp_grammar=mat_sexp_grammarletfloat64_mat_sexp_grammar=mat_sexp_grammarletstring_of__of__sexp_ofto_sexpx=Sexp.to_string(to_sexpx)letof_string__of__of_sexpof_sexps=tryletsexp=Sexp.of_stringsinof_sexpsexpwith|e->failwith(sprintf"of_string failed on %s with %s"s(Sexp.to_string_hum(sexp_of_exne)));;