R8Q^55.5.0+dev0-2025-04-28/%Float$zero%float@@@@6../../stdlib/float.mlii<<i<L@@%Float@@@#one @@@@mzzmz@@A@@)minus_one @@@@qq@@B@@#neg@/ @@@4 @@@@@)%negfloatAA @@@8u9u &@@7C@@#add@I @@@@P@@@U@@@@@@@)%addfloatBA!@@@@Yx ? ?Zx ? s@@XD@@#sub@j@@@@q@@@v@@@@@@@)%subfloatBAB@@@@z{  {{  @@yE@@#mul@@@@@@@@@@@@@@@)%mulfloatBAc@@@@~  ~  "@@F@@#div@@@@@@@@@@@@@@@)%divfloatBA@@@@A J JA J ~@@G@@#fma@@@@@@@@@@@@@@@@@@@@@.caml_fma_floatC@(caml_fmaAAA@AD  E  @'unboxedE  E  @@E  E  @'noallocE  E  @@E  @@H@@#rem@ @@@@@@@@@@@@@@Đ/caml_fmod_floatB@$fmodAA@AR  S Q h@'unboxed$S Q T%S Q [@@(S Q Q)S Q \@'noalloc/S Q `0S Q g@@3S Q ]@@1I@@$succ@C @@@H!@@@@@@GX""HX";@@FJ@@$pred@X"@@@]#@@@@@@\^]^@@[K@@#abs@m$@@@r%@@@@@͐)%absfloatAA>@@@udvd@@tL@@(infinity&@@@@gg"@@M@@,neg_infinity '@@@@j>>j>V@@N@@#nan!(@@@@mrrmr@@O@@-signaling_nan")@@@@xxxxx@@P@@)quiet_nan#*@@@@~88~8M@@Q@@"pi$+@@@@qqq@@R@@)max_float%,@@@@@@S@@)min_float&-@@@@@@T@@'epsilon'.@@@@QQQd@@U@@)is_finite(@/@@@$bool0@@@@@@  @@V@@+is_infinite)@1@@@2@@@@@@ppp@@W@@&is_nan*@/3@@@+4@@@@@@34@@2X@@*is_integer+@D5@@@@6@@@@@@HuuIu@@GY@@&of_int,@#int7@@@_8@@@@@+%floatofintAA+@@@bc@@aZ@@&to_int-@s9@@@:@@@@@+%intoffloatAAD@@@{DD|Dr@@z[@@)of_string.@&string;@@@<@@@@@4caml_float_of_stringAA^@@@$$$a@@\@@-of_string_opt/@=@@@&optionL>@@@@@@@@@@@]@@)to_string0@?@@@;@@@@@@@555T@@^@@'fpclass1A;@@)FP_normal2@@@@`@,FP_subnormal3@@@@a@'FP_zero4@@@@b@+FP_infinite5@@GIGV@@c@&FP_nan6@@@@d@@@A&StdlibA'fpclass@@@@@@@cc @@A@_@A@.classify_float7@B@@@%FloatC'fpclass@@@@@3caml_classify_floatA@;caml_classify_float_unboxedA@@"EE#@'noalloc)*@@- @@+e@@#pow8@=D@@@ @DE@@@ IF@@@ @@@@0caml_power_floatB@#powAA@AN 6 6O x @'unboxedU x {V x @@Y x xZ x @'noalloc` x a x @@d x @@bf@@$sqrt9@tG@@@yH@@@@@/caml_sqrt_floatA@$sqrtA@A}  ~  @'unboxed    @@    @'noalloc    @@  @@g@@$cbrt:@I@@@J@@@@@/caml_cbrt_floatA@)caml_cbrtA@A!!!N!g@'unboxed!N!S!N!Z@@!N!P!N![@'noalloc!N!_!N!f@@!N!\@@h@@#exp;@K@@@L@@@@@.caml_exp_floatA@#expA@A!!!!@'unboxed!!!!@@!!!!@'noalloc!!!!@@!!@@i@@$exp2<@M@@@N@@@@@/caml_exp2_floatA@)caml_exp2A@A !! "/"H@'unboxed"/"4"/";@@"/"1"/"<@'noalloc"/"@"/"G@@ "/"=@@j@@#log=@0O@@@5P@@@@@.caml_log_floatA@#logA@A9"":""@'unboxed@""A""@@D""E""@'noallocK""L""@@O""@@Mk@@%log10>@_Q@@@dR@@@ @@!0caml_log10_floatA@%log10A@Ah""i#&#=@'unboxedo#&#)p#&#0@@s#&#&t#&#1@'noallocz#&#5{#&#<@@~#&#2@@|l@@$log2?@S@@@"T@@@#@@$/caml_log2_floatA@)caml_log2A@A#Y#Y##@'unboxed####@@####@'noalloc####@@##@@m@@%expm1@@U@@@%V@@@&@@'0caml_expm1_floatA@*caml_expm1A@A##$$6@'unboxed$$"$$)@@$$$$*@'noalloc$$.$$5@@$$+@@n@@%log1pA@W@@@(X@@@)@@*0caml_log1p_floatA@*caml_log1pA@A$$$%@'unboxed$$$$@@$$$$@'noalloc$$$%@@ $$@@ o@@#cosB@Y@@@+ Z@@@,@@-.caml_cos_floatA@#cosA@A$ %%% %%@'unboxed+ %%, %%@@/ %%0 %%@'noalloc6 %%7 %%@@: %%@@8p@@#sinC@J[@@@.O\@@@/@@0.caml_sin_floatA@#sinA@AS &&T &&P@'unboxedZ &&<[ &&C@@^ &&9_ &&D@'noalloce &&Hf &&O@@i &&E@@gq@@#tanD@y]@@@1~^@@@2@@3.caml_tan_floatA@#tanA@A&x&x&x&@'unboxed&x&&x&@@&x&&x&@'noalloc&x&&x&@@&x&@@r@@$acosE@_@@@4`@@@5@@6/caml_acos_floatA@$acosA@A&&'+'B@'unboxed'+'.'+'5@@'+'+'+'6@'noalloc'+':'+'A@@'+'7@@s@@$asinF@a@@@7b@@@8@@9/caml_asin_floatA@$asinA@A''((@'unboxed(((( @@(((( @'noalloc((((@@(( @@t@@$atanG@c@@@: d@@@;@@Ag@@@?@@@@@A0caml_atan2_floatB@%atan2AA@AF!)B)BG"))@'unboxedM"))N"))@@Q"))R"))@'noallocX"))Y"))@@\"))@@Zv@@%hypotI@lh@@@B@si@@@Cxj@@@D@@E@@F0caml_hypot_floatB@*caml_hypotAA@A}'*a*a~(**@'unboxed(**(**@@(**(**@'noalloc(**(**@@(**@@w@@$coshJ@k@@@Gl@@@H@@I/caml_cosh_floatA@$coshA@A/++0,8,O@'unboxed0,8,;0,8,B@@0,8,80,8,C@'noalloc0,8,G0,8,N@@0,8,D@@x@@$sinhK@m@@@Jn@@@K@@L/caml_sinh_floatA@$sinhA@A3,,4,,@'unboxed4,,4,,@@4,,4,,@'noalloc4,,4,,@@4,,@@y@@$tanhL@o@@@Mp@@@N@@O/caml_tanh_floatA@$tanhA@A 7-- 8-B-Y@'unboxed8-B-E8-B-L@@8-B-B8-B-M@'noalloc8-B-Q8-B-X@@ 8-B-N@@z@@%acoshM@0q@@@P5r@@@Q@@R0caml_acosh_floatA@*caml_acoshA@A9;--:<--@'unboxed@<--A<--@@D<--E<--@'noallocK<--L<--@@O<--@@M{@@%asinhN@_s@@@Sdt@@@T@@U0caml_asinh_floatA@*caml_asinhA@AhD..iE..@'unboxedoE..pE..@@sE..tE..@'noalloczE..{E..@@~E..@@||@@%atanhO@u@@@Vv@@@W@@X0caml_atanh_floatA@*caml_atanhA@AM/q/qN//@'unboxedN//N//@@N//N//@'noallocN//N//@@N//@@}@@#erfP@w@@@Yx@@@Z@@[.caml_erf_floatA@(caml_erfA@AV0y0yW00@'unboxedW00W00@@W00W00@'noallocW00W00@@W00@@~@@$erfcQ@y@@@\z@@@]@@^/caml_erfc_floatA@)caml_erfcA@A^1W1W_11@'unboxed_11_11@@_11_11@'noalloc_11_11@@ _11@@ @@%truncR@{@@@_ |@@@`@@a0caml_trunc_floatA@*caml_truncA@A$g2_2_%h22@'unboxed+h22,h22@@/h220h22@'noalloc6h227h22@@:h22@@8@@@%roundS@J}@@@bO~@@@c@@d0caml_round_floatA@*caml_roundA@ASn3W3WTo33@'unboxedZo33[o33@@^o33_o33@'noalloceo33fo33@@io33@@gA@@$ceilT@y@@@e~@@@f@@g/caml_ceil_floatA@$ceilA@Az5X5X{55@'unboxed{55{55@@{55{55@'noalloc{55{55@@{55@@B@@%floorU@@@@h@@@i@@j0caml_floor_floatA@%floorA@A6E6E66@'unboxed6666@@6666@'noalloc6666@@66@@C@@*next_afterV@@@@k@@@@l@@@m@@n@@o4caml_nextafter_floatB@.caml_nextafterAA@A7:7:7h7@'unboxed7h77h7@@7h77h7@'noalloc7h77h7@@7h7@@D@@)copy_signW@ @@@p@ @@@q @@@r@@s@@t3caml_copysign_floatB@-caml_copysignAA@A : :  :d:{@'unboxed &:d:g ':d:n@@ *:d:d +:d:o@'noalloc 1:d:s 2:d:z@@ 5:d:p@@ 3E@@(sign_bitX@ E@@@uA@@@v@@w2caml_signbit_floatA@,caml_signbitA@@ N;b;b O;;@'noalloc U;; V;;@@ Y;; @@ WF@@%frexpY@ i@@@x@ r@@@y@ @@@z@@{@@|0caml_frexp_floatAA E@@@ |<< }<<@@ {G@@%ldexpZ@ @@@}@;@@@~ @@@@@@@0caml_ldexp_floatB@8caml_ldexp_float_unboxedAB@A == >+>f@'noalloc >+>^ >+>e@@ >+>[ @@ H@@$modf[@ @@@@ @@@@ @@@@@@@/caml_modf_floatAA @@@ >> >>@@ I@@!t\B;@@@A @@@@@@@ ?? ??-@@@@ J@A@'compare]@%Float!t@@@@%Float!t@@@@@@@@@@@ ?g?g ?g?@@ K@@%equal^@%Float!t@@@@%Float!t@@@@@@@@@@@ @@ !@@@@ L@@#min_@%Float!t@@@@%Float!t@@@%Float!t@@@@@@@@ EA:A: FA:AO@@ DM@@#max`@ V@@@@ ]@@@ b@@@@@@@@ aAA bAB@@ `N@@'min_maxa@ r@@@@ y@@@@ @@@@ @@@@@@@@@@ BB BB@@ O@@'min_numb@%Float!t@@@@%Float!t@@@%Float!t@@@@@@@@ C"C" C"C;@@ P@@'max_numc@%Float!t@@@@%Float!t@@@%Float!t@@@@@@@@ DD DD@@ Q@@+min_max_numd@ @@@@ @@@@ @@@@ @@@@@@@@@@ DD DE@@ R@@+seeded_hashe@@@@@%Float!t@@@@@@@@@@@ EE EE@@ S@@$hashf@%Float!t@@@@@@@@@ 0FF 1FF@@ /T@@ӱ%ArrayC@!tgD;@@jA*floatarray@@@@@@@ FGG GGG@@@@ EU@A@&lengthh@%Float%Array!t@@@ @@@@@@ `H#H% aH#H:@@ _V@@#geti@%Float%Array!t@@@@ $@@@ @@@@@@@@ HH HH@@ W@@#setj@%Float%Array!t@@@@ E@@@@ @@@$unit@@@@@@@@@@ I@IB I@Ie@@ X@@$makek@ b@@@@ @@@%Float%Array!t@@@@@@@@ J"J$ J"J@@@ Y@@&createl@ @@@%Float%Array!t@@@@@@  JJ  JJ@@ Z@@$initm@ @@@@@ @@@ @@@@@%Float%Array!t@@@@@@@@ KK KK@@ [@@+make_matrixn@ @@@@ @@@@ ,@@@%arrayˠ%Float%Array!t@@@@@@@@@@@@@ <MM =MM8@@ ;\@@+init_matrixo@ @@@@ @@@@@ @@@@ @@@ i@@@@@@@=Ҡ%Float%Array!t@@@@@@@@@@@@@ x"NN y"NN@@ w]@@&appendp@%Float%Array!t@@@@%Float%Array!t@@@%Float%Array!t@@@@@@@@ -P5P7 -P5PO@@ ^@@&concatq@$listנ%Float%Array!t@@@@@@%Float%Array!t@@@@@@ 3Q%Q' 3Q%Q?@@ _@@#subr@%Float%Array!t@@@ @ @@@ @ @@@ %Float%Array!t@@@ @@ @@@@@ 6QQ 6QQ@@ `@@$copys@%Float%Array!t@@@%Float%Array!t@@@@@@ >RR >RR@@ a@@$fillt@%Float%Array!t@@@@ @@@@ @@@@ @@@@@@@@@@@@@@@@ DBSoSq EBSoS@@ Cb@@$blitu@%Float%Array!t@@@@ @@@@%Float%Array!t@@@@ @@@@ "@@@ @@@!@@"@@#@@$@@%@@&@ HTT HTT@@ ~c@@'to_listv@%Float%Array!t@@@' @@@(@@@*@@+@ SVV SVV@@ d@@'of_listw@ @@@,@@@.%Float%Array!t@@@/@@0@ VWW VWW2@@ e@@%equalx@@ @@@1@ @@@2 @@@3@@4@@5@%Float%Array!t@@@6@%Float%Array!t@@@7 @@@8@@9@@:@@;@ ^XX ^XXK@@ f@@'comparey@@ @@@<@@@@= @@@>@@?@@@@%Float%Array!t@@@A@%Float%Array!t@@@B @@@C@@D@@E@@F@5eXY6eXY7@@4g@@$iterz@@H@@@G@@@H@@I@%Float%Array!t@@@J@@@K@@L@@M@]nZ@ZB^nZ@Zi@@\h@@%iteri{@@ @@@N@w@@@O@@@P@@Q@@R@%Float%Array!t@@@S@@@T@@U@@V@s[ [ s[ [;@@i@@#map|@@@@@W@@@X@@Y@%Float%Array!t@@@Z%Float%Array!t@@@[@@\@@]@x[[x[\@@j@@+map_inplace}@@ @@@^ @@@_@@`@%Float %Array!t@@@a8 @@@b@@c@@d@|\\|\\@@k@@$mapi~@@  @@@e@@@@f@@@g@@h@@i@%Float%Array!t@@@j%Float%Array!t@@@k@@l@@m@]<]>]<]j@@l@@,mapi_inplace@@ @@@n@/@@@o4@@@p@@q@@r@%Float%Array!t@@@s@@@t@@u@@v@D^^ E^^@@@Cm@@)fold_left@@#acc@E@w@_@@@x @@y@@z@@%Float%Array!t@@@{@@|@@}@@~@l^^m^_.@@kn@@*fold_right@@@@@@#acc@E@@@@@@%Float%Array!t@@@@@@@@@@@___` @@o@@%iter2@@@@@@@@@ @@@@@@@@%Float%Array!t@@@@%Float%Array!t@@@& @@@@@@@@@@````@@p@@$map2@@!@@@@"@@@#@@@@@@@@%Float$%Array!t@@@@%Float%%Array!t@@@%Float&%Array!t@@@@@@@@@@aaaa@@q@@'for_all@@"'@@@(@@@@@@%Float)%Array!t@@@/*@@@@@@@@7cc8ccA@@6r@@&exists@@J+@@@F,@@@@@@%Float-%Array!t@@@W.@@@@@@@@_cc`cd@@^s@@#mem@p/@@@@%Float0%Array!t@@@x1@@@@@@@@dddd@@t@@(mem_ieee@2@@@@%Float3%Array!t@@@4@@@@@@@@eeee@@u@@(find_opt@@5@@@6@@@@@@%Float7%Array!t@@@8@@@@@@@@@@@f;f=f;fp@@v@@*find_index@@9@@@:@@@@@@%Float;%Array!t@@@L<@@@@@@@@@@@g9g;g9gm@@w@@(find_map@@=@@@h!a@E@@@@@@@%Float>%Array!t@@@@@@@@@@@)h^h`*h^h@@(x@@)find_mapi@@?@@@@C@@@@!a@E@@@@@@@@@%FloatA%Array!t@@@@@@@@@@@^i<i>_i<i{@@]y@@$sort@@qB@@@@xC@@@$D@@@@@@@@%FloatE%Array!t@@@F@@@@@@@@jxjzjxj@@z@@+stable_sort@@G@@@@H@@@SI@@@@@@@@%FloatJ%Array!t@@@K@@@@@@@@o#o%o#o[@@{@@)fast_sort@@L@@@@M@@@N@@@@@@@@%FloatO%Array!t@@@BP@@@@@@@@pppq3@@|@@'shuffle$rand@Q@@@R@@@@@@%FloatS%Array!t@@@lT@@@@@@@@qqqq@@}@@&to_seq@%FloatU%Array!t@@@&StdlibW#Seq!t:V@@@ +@@@ -@@ .@:ss;ss@@9~@@'to_seqi@%FloatX%Array!t@@@ /&Stdlib[#Seq!t@ Y@@@ 0@jZ@@@ 1@@ 2@@@ 4@@ 5@j tTtVk tTt|@@i@@&of_seq@&Stdlib]#Seq!t\@@@ 6@@@ 8%Float^%Array!t@@@ 9@@ :@u8u:u8uW@@@@,map_to_array@@_@@@ ;!a@ DE@ <@@ =@%Float`%Array!t@@@ >a@@@ @@@ A@@ B@uuuu@@@@.map_from_array@@!a@ NE@ Eb@@@ F@@ G@c@@@ I%Floatd%Array!t@@@ J@@ K@@ L@v~vv~v@@@@*unsafe_get@%Floate%Array!t@@@ O@f@@@ Pg@@@ Q@@ R@@ S6%floatarray_unsafe_getBAѠ@@@@ m m@@@@*unsafe_set@%Floath%Array!t@@@ V@i@@@ W@-j@@@ Xk@@@ Y@@ Z@@ [@@ \6%floatarray_unsafe_setCA@@@@@7n8n@@6@@@@;GG<p@:@@@ӱ+ArrayLabelsE@!tF;@@ uA l@@@ `@@@@PtfhQtf{@@@@O@A@&length@%Floatm+ArrayLabels!t@@@ gn@@@ h@@ i@jyky@@i@@#get@%Floato+ArrayLabels!t@@@ j@.p@@@ kq@@@ l@@ m@@ n@|35|3P@@@@#set@%Floatr+ArrayLabels!t@@@ o@Os@@@ p@t@@@ q u@@@ r@@ s@@ t@@ u@@@@@$make@kv@@@ v@w@@@ w%Floatx+ArrayLabels!t@@@ x@@ y@@ z@@@@@&create@y@@@ {%Floatz+ArrayLabels!t@@@ |@@ }@@@@@$init@{@@@ ~!f@|@@@ }@@@ @@ %Float~+ArrayLabels!t@@@ @@ @@ @TVT}@@@@+make_matrix$dimx@@@ $dimy@@@ @;@@@ %Float+ArrayLabels!t@@@ @@@ @@ @@ @@ @JK@@I@@+init_matrix$dimx@@@ $dimy @@@ !f@@@@ @@@@ }@@@ @@ @@ Q%Float+ArrayLabels!t@@@ @@@ @@ @@ @@ @GIG@@@@&append@%Float+ArrayLabels!t@@@ @%Float+ArrayLabels!t@@@ %Float+ArrayLabels!t@@@ @@ @@ @@@@@&concat@%Float+ArrayLabels!t@@@ @@@ %Float+ArrayLabels!t@@@ @@ @ @@@@#sub@%Float+ArrayLabels!t@@@ #pos@@@ #len@@@ %Float+ArrayLabels!t@@@ @@ @@ @@ @ RTRz@@ @@$copy@%Float+ArrayLabels!t@@@ %Float+ArrayLabels!t@@@ @@ @,-@@+@@$fill@%Float+ArrayLabels!t@@@ #pos@@@ #len@@@ @[@@@  @@@ @@ @@ @@ @@ @_FH`F{@@^@@$blit#src%Float+ArrayLabels!t@@@ 'src_pos'@@@ #dst%Float+ArrayLabels!t@@@ 'dst_pos>@@@ #lenG@@@  @@@ @@ @@ @@ @@ @@ @aca@@@@'to_list@%Float+ArrayLabels!t@@@  @@@ @@@ @@ @@@@@'of_list@ !@@@ @@@ %Float+ArrayLabels!t@@@ @@ @4@@@@%equal"eq@@@@ @@@@ @@@ @@ @@ @%Float+ArrayLabels!t@@@ @%Float+ArrayLabels!t@@@ @@@ @@ @@ @@ @!"P@@ @@'compare#cmp@6@@@ @=@@@ @@@ @@ @@ @%Float+ArrayLabels!t@@@ @%Float+ArrayLabels!t@@@ @@@ @@ @@ @@ @^_@@@]@@$iter!f@s@@@  @@@ @@ @%Float+ArrayLabels!t@@@  @@@ @@ @@ @IKIt@@@@%iteri!f@D@@@ @@@@  @@@ @@ @@ @%Float+ArrayLabels!t@@@  @@@ @@ @@ @I@@@@#map!f@@@@ @@@ @@ @%Float+ArrayLabels!t@@@ %Float+ArrayLabels!t@@@ @@ @@ @@@@@+map_inplace!f@@@@ @@@ @@ @%Float+ArrayLabels!t@@@  i@@@ @@ @@ @@@@@$mapi!f@@@@ @.@@@ 3@@@ @@ @@ @%Float+ArrayLabels!t@@@ %Float+ArrayLabels!t@@@ @@ @@ @HOQIO@@G@@,mapi_inplace!f@@@@ @d@@@ i@@@ @@ @@ @%Float+ArrayLabels!t@@@  @@@ @@ @@ @yzW@@x@@)fold_left!f@#acc@ G@ @@@@  @@ @@ $init@%Float+ArrayLabels!t@@@ @@ @@ @@ @   L@@@@*fold_right!f@@@@ @#acc@ &G@ @@ @@ @%Float+ArrayLabels!t@@@ !$init@@ "@@ #@@ $@1@@@@%iter2!f@@@@ '@@@@ ( H@@@ )@@ *@@ +@%Float+ArrayLabels!t@@@ ,@%Float+ArrayLabels!t@@@ - e@@@ .@@ /@@ 0@@ 1@'@@ @@$map2!f@#@@@ 2@*@@@ 3/@@@ 4@@ 5@@ 6@%Float+ArrayLabels!t@@@ 7@%Float+ArrayLabels!t@@@ 8%Float+ArrayLabels!t@@@ 9@@ :@@ ;@@ <@PQ@@O@@'for_all!f@e@@@ =a@@@ >@@ ?@%Float+ArrayLabels!t@@@ @r@@@ A@@ B@@ C@z#BD{#Bp@@y@@&exists!f@@@@ D@@@ E@@ F@%Float+ArrayLabels!t@@@ G@@@ H@@ I@@ J@(!#(!N@@@@#mem@@@@ K#set%Float+ArrayLabels!t@@@ L@@@ M@@ N@@ O@- -)@@@@(mem_ieee@@@@ P#set%Float+ArrayLabels!t@@@ Q@@@ R@@ S@@ T@22@@@@(find_opt!f@@@@ U@@@ V@@ W@%Float+ArrayLabels!t@@@ Xj@@@ Y@@@ [@@ \@@ ]@7vx7v@@@@*find_index!f@.@@@ ^*@@@ _@@ `@%Float+ArrayLabels!t@@@ a@@@ b@@@ d@@ e@@ f@H=wyI=w@@G@@(find_map!f@]@@@ g!a@ rG@ h@@@ j@@ k@%Float+ArrayLabels!t@@@ lΠ@@@ n@@ o@@ p@xEyE@@w@@)find_mapi!f@4@@@ s@@@@ t!a@ G@ u@@@ w@@ x@@ y@%Float+ArrayLabels!t@@@ z@@@ |@@ }@@ ~@JJ@@@@$sort#cmp@@@@ @@@@ w@@@ @@ @@ @%Float+ArrayLabels!t@@@ 7@@@ @@ @@ @SS@@@@+stable_sort#cmp@@@@ @@@@ @@@ @@ @@ @%Float+ArrayLabels!t@@@ h@@@ @@ @@ @lmolm@@@@)fast_sort#cmp@&@@@ @-@@@ @@@ @@ @@ @%Float+ArrayLabels!t@@@ @@@ @@ @@ @BuKMCuK@@A@@'shuffle$rand@ @@@  @@@ @@ @%Float +ArrayLabels!t@@@  @@@ @@ @@ @lymz6@@k@@&to_seq@%Float +ArrayLabels!t@@@ &Stdlib#Seq!t@@@ @@@ @@ @@@@@'to_seqi@%Float+ArrayLabels!t@@@ &Stdlib#Seq!t@a@@@ @@@@ @@ @@@ @@ @@@@@&of_seq@&Stdlib#Seq!t@@@ @@@ %Float+ArrayLabels!t@@@ @@ @@@@@,map_to_array!f@@@@ !a@ G@ @@ @%Float+ArrayLabels!t@@@ @@@ @@ @@ @@@@@.map_from_array!f@!a@ G@ -@@@ @@ @@@@ %Float+ArrayLabels!t@@@ @@ @@ @>? @@=@@*unsafe_get@%Float+ArrayLabels!t@@@ @@@@ `@@@ @@ @@ ̐6%floatarray_unsafe_getBA,@@@@de1@@c@@*unsafe_set@%Float +ArrayLabels!t@@@ @(!@@@ @"@@@ #@@@ @@ @@ @@ Ր6%floatarray_unsafe_setCAY@@@@@242~@@@@@@sMMÀÃ@@@@@3:Floating-point arithmetic.@ " OCaml's floating-point numbers follow the IEEE 754 standard, using double precision (64 bits) numbers. Floating-point operations never raise an exception on overflow, underflow, division by zero, etc. Instead, special IEEE numbers are returned as appropriate, such as (infinity% for *1.0 /. 0.0&, ,neg_infinity% for +-1.0 /. 0.0&, and #nan: ('not a number') for *0.0 /. 0.0 o. These special numbers then propagate through floating-point computations as expected: for instance, /1.0 /. infinity$ is #0.0 #, basic arithmetic operations ("+.", "-.", "*.", "/.') with #nan7 as an argument return #nan%, ...@@@@$4.07@@@@@@@A6../../stdlib/float.mli*Float.zero35The floating point 0.@@@@$4.08@@@@@@@@@@@ )Float.one35The floating-point 1.@@@@$4.08@@@@@@@ @@@@/Float.minus_one36The floating-point -1.@@@@$4.08@@@@@@@ @@@@)Float.neg3/Unary negation.@@@@@@@@@@@@ @  @@@@)Float.add38Floating-point addition.@@@@@@@@@@@@@@@@@@)Float.sub3;Floating-point subtraction.@@@@@@@@@@@@@"@%@@@@ࠕ)Float.mul3>Floating-point multiplication.@@@@@@@@@@@@@4@7@@@@Ѡ)Float.div38Floating-point division.@@@@@@@@@@@@@F@I@@@@ )Float.fma3)fma x y z) returns )x * y + z , with a best effort for computing this expression with a single rounding, using either hardware instructions (providing full IEEE compliance) or a software emulation.@  On 64-bit Cygwin, 64-bit mingw-w64 and MSVC 2017 and earlier, this function may be emulated owing to known bugs on limitations on these platforms. Note: since software emulation of the fma is costly, make sure that you are using hardware fma support if performance matters.@@@@$4.08@@@@@@@@g@j@m@@@@)Float.rem3'rem a b: returns the remainder of !a1 with respect to !b=. The returned value is +a -. n *. b(, where !n1 is the quotient &a /. b ( rounded towards zero to an integer.@@@@@@@@@@@@@@@@@@*Float.succ3&succ x / returns the floating point number right after !x : i.e., the smallest floating-point number greater than !x/. See also 0Float.next_afterD@!.@@@@$4.08@@@@@@@@@@@@*Float.pred3&pred x 0 returns the floating-point number right before !x : i.e., the greatest floating-point number smaller than !x/. See also 'D@!.@@@@$4.08@@@@@@@@@@@@Ơ)Float.abs3%abs f? returns the absolute value of !f!.@@@@@@@@@@@@@@@@@Š.Float.infinity32Positive infinity.@@@@@@@@@@@@@@@@à2Float.neg_infinity32Negative infinity.@@@@@@@@@@@@@@@@)Float.nan3 YA special floating-point value denoting the result of an undefined operation such as *0.0 /. 0.0 E. Stands for 'not a number'. Any floating-point operation with #nan9 as argument returns #nan i as result, unless otherwise specified in IEEE 754 standard. As for floating-point comparisons, !=", !<", "<=", !>% and ">=( return %false% and "<>) returns $true * if one or both of their arguments is #nan!.@% #nan$ is )quiet_nan * since 5.1; it was a signaling NaN before.@@@@@@@@@@@@@@@@3Float.signaling_nan3 Signaling NaN. The corresponding signals do not raise OCaml exception, but the value can be useful for interoperability with C libraries.@@@@#5.1@@@@@@@@@@@/Float.quiet_nan3*Quiet NaN.@@@@#5.1@@@@@@@@@@@(Float.pi30The constant pi.@@@@@@@@@@@@@@@@/Float.max_float3 *The largest positive finite value of type %float!.@@@@@@@@@@@@@@@@/Float.min_float3 @The smallest positive, non-zero, non-denormalized value of type %float!.@@@@@@@@@@@@ @@@@-Float.epsilon37The difference between #1.0 O and the smallest exactly representable floating-point number greater than #1.0!.@@@@@@@@@@@@*@@@@'/Float.is_finite3+is_finite x$ is $true0 if and only if !x ) is finite i.e., not infinite and not D@!.@@@@$4.08@@@@@@@?@ @@@@@71Float.is_infinite3-is_infinite x$ is $true0 if and only if !x$ is D@( or D@!.@@@@$4.08@@@@@@@U@7V@@@@N,Float.is_nan3(is_nan x$ is $true0 if and only if !x6 is not a number (see 2D@").@@@@$4.08@@@@@@@f@]g@@@@_0Float.is_integer3,is_integer x$ is $true0 if and only if !x/ is an integer.@@@@$4.08@@@@@@@q@}r@@@@j,Float.of_int3 %Convert an integer to floating-point.@@@@@@@@@@@@k@l@@@@_,Float.to_int3 iTruncate the given floating-point number to an integer. The result is unspecified if the argument is #nan : or falls outside the range of representable integers.@@@@@@@@@@@@f@g@@@@[/Float.of_string3 rConvert the given string to a float. The string is read in decimal (by default) or in hexadecimal (marked by "0x$ or "0X ;). The format of decimal floating-point numbers is ; [-] dd.ddd (e|E) [+|-] dd (, where !d Y stands for a decimal digit. The format of hexadecimal floating-point numbers is " [-] 0(x|X) hh.hhh (p|P) [+|-] dd (, where !h ) stands for an hexadecimal digit and !d for a decimal digit. In both cases, at least one of the integer and fractional parts must be given; the exponent part is optional. The !_ (underscore) character can appear anywhere in the string and is ignored. Depending on the execution platforms, other representations of floating-point numbers can be accepted, but should not be relied upon.@@@@@@@@'Failure Aif the given string is not a valid representation of a float.@@@@@@@@@@3Float.of_string_opt3(Same as )of_string., but returns $None4 instead of raising.@@@@@@@@@@@@@@@@@/Float.to_string3 :Return a string representation of a floating-point number.@ This conversion can involve a loss of precision. For greater control over the manner in which the number is printed, see &Printf@@!.@ # This function is an alias for 6Stdlib.string_of_float@@!.@@@@@@@@@@@@@$@@@@#-Float.fpclass3 EThe five classes of floating-point numbers, as determined by the 4Float.classify_floatD@* function.@@@@@@@@@@@@@@@3 Normal number, none of the below@@@@@@@@@@@@@@3 /Number very close to 0.0, has reduced precision@@@@@@@@@@@@@@35Number is 0.0 or -0.0@@@@@@@@@@@@@@3 'Number is positive or negative infinity@@@@@@@@@@@@@@3 .Not a number: result of an undefined operation@@@@@@@@@@@@@A@@@;3 lReturn the class of the given floating-point number: normal, subnormal, zero, infinite, or not a number.@@@@@@@@@@@@@v@@@@)Float.pow3/Exponentiation.@@@@@@@@@@@@@@}@@@@o*Float.sqrt3,Square root.@@@@@@@@@@@@[@\@@@@O*Float.cbrt3*Cube root.@@@@$4.13@@@@@@@=@>@@@@1)Float.exp3,Exponential.@@@@@@@@@@@@@@@@@*Float.exp23Sine. Argument is in radians.@@@@@@@@@@@@K@]L@@@@?)Float.tan3 !Tangent. Argument is in radians.@@@@@@@@@@@@+@l,@@@@*Float.acos3 5Arc cosine. The argument must fall within the range +[-1.0, 1.0] *. Result is in radians and is between #0.0% and "pi!.@@@@@@@@@@@@@@@@@*Float.asin3 3Arc sine. The argument must fall within the range +[-1.0, 1.0] *. Result is in radians and is between %-pi/2% and $pi/2!.@@@@@@@@@@@@@@@@@*Float.atan3 5Arc tangent. Result is in radians and is between %-pi/2% and $pi/2!.@@@@@@@@@@@@@@@@@+Float.atan23)atan2 y x< returns the arc tangent of &y /. x0. The signs of !x) and !y [ are used to determine the quadrant of the result. Result is in radians and is between #-pi% and "pi!.@@@@@@@@@@@@@@@@@@렕+Float.hypot3)hypot x y) returns 6sqrt(x *. x +. y *. y) `, that is, the length of the hypotenuse of a right-angled triangle with sides of length !x% and !y ., or, equivalently, the distance of the point %(x,y); to origin. If one of !x$ or !y6 is infinite, returns (infinity: even if the other is #nan!.@@@@@@@@@@@@ @> @A@@@@*Float.cosh3 +Hyperbolic cosine. Argument is in radians.@@@@@@@@@@@@@P@@@@٠*Float.sinh3 )Hyperbolic sine. Argument is in radians.@@@@@@@@@@@@@_@@@@*Float.tanh3 ,Hyperbolic tangent. Argument is in radians.@@@@@@@@@@@@@n@@@@+Float.acosh3 DHyperbolic arc cosine. The argument must fall within the range *[1.0, inf] *. Result is in radians and is between #0.0% and #inf!.@@@@$4.13@@@@@@@@@@@@+Float.asinh3 lHyperbolic arc sine. The argument and result range over the entire real line. Result is in radians.@@@@$4.13@@@@@@@{@|@@@@o+Float.atanh3 EHyperbolic arc tangent. The argument must fall within the range +[-1.0, 1.0] @. Result is in radians and ranges over the entire real line.@@@@$4.13@@@@@@@c@d@@@@W)Float.erf3 `Error function. The argument ranges over the entire real line. The result is always within +[-1.0, 1.0]!.@@@@$4.13@@@@@@@K@L@@@@?*Float.erfc3>Complementary error function (2erfc x = 1 - erf x V). The argument ranges over the entire real line. The result is always within *[0.0, 2.0]!.@@@@$4.13@@@@@@@9@:@@@@-+Float.trunc3'trunc x( rounds !x I to the nearest integer whose absolute value is less than or equal to !x!.@@@@$4.08@@@@@@@*@ +@@@@+Float.round3'round x( rounds !x to the nearest integer with ties (fractional values of 0.5) rounded away from zero, regardless of the current rounding direction. If !x0 is an integer, #+0.", #-0.", #nan2, or infinite, !x4 itself is returned.@ y On 64-bit mingw-w64, this function may be emulated owing to a bug in the C runtime library (CRT) on this platform.@@@@$4.08@@@@@@@7@I8@@@@+*Float.ceil3 %Round above to an integer value. &ceil f : returns the least integer value greater than or equal to !f (. The result is returned as a float.@@@@@@@@@@@@#@d$@@@@+Float.floor3 %Round below to an integer value. 'floor f > returns the greatest integer value less than or equal to !f (. The result is returned as a float.@@@@@@@@@@@@@@@@@ǐ3.next_after x y B returns the next representable floating-point value following !x5 in the direction of !y9. More precisely, if !y> is greater (resp. less) than !x \, it returns the smallest (resp. largest) representable number greater (resp. less) than !x(. If !x( equals !y7, the function returns !y&. If !x$ or !y' is #nan$, a #nan; is returned. Note that (next_after max_float infinity = infinity- and that 6next_after 0. infinity 5 is the smallest denormalized positive number. If !x 2 is the smallest denormalized positive number, 4next_after x 0. = 0.@@@@$4.08@@@@@@@P@Q@M@@@@?/Float.copy_sign3-copy_sign x y 1 returns a float whose absolute value is that of !x? and whose sign is that of !y&. If !x$ is #nan*, returns #nan). If !y$ is #nan1, returns either !x$ or $-. x $, but it is not specified which.@@@@@@@@@@@@d@:e@=a@@@@S.Float.sign_bit3*sign_bit x$ is $true if and only if the sign bit of !x9 is set. For example +sign_bit 1.% and *signbit 0.% are %false+ while .sign_bit (-1.)% and .sign_bit (-0.)% are $true!.@@@@$4.08@@@@@@@t@u@@@@h+Float.frexp3'frexp f = returns the pair of the significant and the exponent of !f(. When !f> is zero, the significant !x2 and the exponent !n$ of !f> are equal to zero. When !f & is non-zero, they are defined by /f = x *. 2 ** n% and .0.5 <= x < 1.0!.@@@@@@@@@@@@@@@@@|+Float.ldexp3)ldexp x n) returns +x *. 2 ** n!.@@@@@@@@@@@@@@@@@@u*Float.modf3&modf f = returns the pair of the fractional and integral part of !f!.@@@@@@@@@@@@u@v@@@@_#'Float.t3 0An alias for the type of floating-point numbers.@@@@@@@@@@@@@@A`@]\@@-Float.compare3+compare x y) returns !0$ if !x- is equal to !y8, a negative integer if !x2 is less than !y<, and a positive integer if !x5 is greater than !y". 'compare( treats #nan P as equal to itself and less than any other float value. This treatment of #nan. ensures that 'compare ' defines a total ordering relation.@@@@@@@@@@@@@Y@\@@@@+Float.equal3 >The equal function for floating-point numbers, compared using `D@!.@@@@@@@@@@@@@q@t@@@@)Float.min3'min x y8 returns the minimum of !x% and !y.. It returns #nan) when !x$ or !y$ is #nan,. Moreover 5min (-0.) (+0.) = -0.@@@@$4.08@@@@@@@@@@@@@)Float.max3'max x y8 returns the maximum of !x% and !y.. It returns #nan) when !x$ or !y$ is #nan,. Moreover 5max (-0.) (+0.) = +0.@@@@$4.08@@@@@@@@@@@@@Ġ-Float.min_max3+min_max x y$ is 2(min x y, max x y)6, just more efficient.@@@@$4.08@@@@@@@@ @ @@@@-Float.min_num3+min_num x y8 returns the minimum of !x% and !y* treating #nan as missing values. If both !x% and !y% are #nan", #nan: is returned. Moreover 9min_num (-0.) (+0.) = -0.@@@@$4.08@@@@@@@@ N@ Q@@@@٠-Float.max_num3+max_num x y8 returns the maximum of !x% and !y* treating #nan as missing values. If both !x% and !y% are #nan! #nan: is returned. Moreover 9max_num (-0.) (+0.) = +0.@@@@$4.08@@@@@@@ @  @ @@@@1Float.min_max_num3/min_max_num x y$ is :(min_num x y, max_num x y) 3, just more efficient. Note that in particular :min_max_num x nan = (x, x)( and :min_max_num nan y = (y, y)!.@@@@$4.08@@@@@@@@ @  @@@@1Float.seeded_hash3 EA seeded hash function for floats, with the same output value as 3Hashtbl.seeded_hash@@ O. This function allows this module to be passed as argument to the functor 2Hashtbl.MakeSeeded@@!.@@@@#5.1@@@@@@@ @  @ @@@@*Float.hash3 HAn unseeded hash function for floats, with the same output value as ,Hashtbl.hash@@ O. This function allows this module to be passed as argument to the functor ,Hashtbl.Make@@!.@@@@@@@@@@@@@  @@@@/+Float.Array3 (Float arrays with packed representation.@@@@@@@@@@@@A >#-Float.Array.t3 4The type of float arrays with packed representation.@@@@$4.08@@@@@@@@@A@@@2Float.Array.length3 ?Return the length (number of elements) of the given floatarray.@@@@@@@@@@@@@ $@@@@/Float.Array.get3'get a n< returns the element number !n/ of floatarray !a!.@@@@@@@@0Invalid_argument#if !n ! is outside the range 0 to .(length a - 1)!.@@@@@@ T@ W@@@@ /Float.Array.set3)set a n x5 modifies floatarray !a * in place, replacing element number !n& with !x!.@@@@@@@@0Invalid_argument#if !n ! is outside the range 0 to .(length a - 1)!.@@@@@3@ 4@ +@ '@@@@0Float.Array.make3(make n x & returns a fresh floatarray of length !n3, initialized with !x!.@@@@@@@@0Invalid_argument#if %n < 0$ or =n > Sys.max_floatarray_length!.@@@@@@@ A@ =@@@@02Float.Array.create3(create n & returns a fresh floatarray of length !n , with uninitialized data.@@@@@@@@0Invalid_argument#if %n < 0$ or =n > Sys.max_floatarray_length!.@@@@@L@ M@@@@@0Float.Array.init3(init n f & returns a fresh floatarray of length !n<, with element number !i> initialized to the result of #f i8. In other terms, (init n f: tabulates the results of !f? applied to the integers !0$ to #n-1!.@@@@@@@@0Invalid_argument#if %n < 0$ or =n > Sys.max_floatarray_length!.@@@@@@ >@ A}@@@@i7Float.Array.make_matrix37make_matrix dimx dimy e Q returns a two-dimensional array (an array of arrays) with first dimension $dimx< and second dimension $dimy *, where all elements are initialized with !e!.@@@@#5.2@@@0Invalid_argument#if $dimx$ or $dimy # is negative or greater than 9Sys.max_floatarray_length@@!.@@@@@@ @ @ @@@@~7Float.Array.init_matrix37init_matrix dimx dimy f W returns a two-dimensional array (an array of arrays) with first dimension $dimx6 and second dimension $dimy $, where the element at index (#x,y6) is initialized with %f x y!.@@@@#5.2@@@0Invalid_argument#if $dimx$ or $dimy # is negative or greater than 9Sys.max_floatarray_length@@!.@@@@@@ @ @ @@@@2Float.Array.append3,append v1 v2 R returns a fresh floatarray containing the concatenation of the floatarrays "v1% and "v2!.@@@@@@@@0Invalid_argument)if 1length v1 + length v2 > Sys.max_floatarray_length!.@@@@@@ @ @@@@2Float.Array.concat3(Same as 6D@ ), but concatenates a list of floatarrays.@@@@@@@@@@@@@ @@@@}/Float.Array.sub3-sub a pos len & returns a fresh floatarray of length #len ', containing the elements number #pos$ to -pos + len - 15 of floatarray !a!.@@@@@@@@0Invalid_argument#if #pos% and #len , do not designate a valid subarray of !a4; that is, if 'pos < 0%, or 'len < 0%, or 4pos + len > length a!.@@@@@@ e@ h@ k@@@@0Float.Array.copy3© a3 returns a copy of !a D, that is, a fresh floatarray containing the same elements as !a!.@@@@@@@@@@@@@ @@@@0Float.Array.fill30fill a pos len x9 modifies the floatarray !a9 in place, storing !x4 in elements number #pos$ to -pos + len - 1!.@@@@@@@@0Invalid_argument#if #pos% and #len , do not designate a valid subarray of !a!.@@@@@@ @ @ @ @@@@Š0Float.Array.blit3 blit src src_pos dst dst_pos len( copies #len elements from floatarray #src=, starting at element number 'src_pos6, to floatarray #dst=, starting at element number 'dst_pos ). It works correctly even if #src% and #dst N are the same floatarray, and the source and destination chunks overlap.@@@@@@@@0Invalid_argument#if 'src_pos% and #len , do not designate a valid subarray of #src(, or if 'dst_pos% and #len , do not designate a valid subarray of #dst!.@@@@@@ :@ =@ @@ C@ F@@@@3Float.Array.to_list3)to_list a ) returns the list of all the elements of !a!.@@@@@@@@@@@@@ ^@@@@3Float.Array.of_list3)of_list l = returns a fresh floatarray containing the elements of !l!.@@@@@@@@0Invalid_argument1if the length of !l7 is greater than 9Sys.max_floatarray_length!.@@@@@@ @@@@A*comparison*Comparison@@1Float.Array.equal3,equal eq a b$ is $true0 if and only if !a% and !b< have the same length !n- and for all !i% in [!0!;#n-1#], .eq a.(i) b.(i)* is $true!.@@@@#5.4@@@@@@@C@ D@ 2@ )@@@@3Float.Array.compare3/compare cmp a b* compares !a% and !b according to the shortlex order, that is, shorter arrays are smaller and equal-sized arrays are compared in lexicographic order using #cmp5 to compare elements.@@@@#5.4@@@@@@@4@5@ #@ @@@@ A@)Iterators@@0Float.Array.iter3(iter f a2 applies function !f & in turn to all the elements of !a=. It is equivalent to -f a.(0); f a.(1); ...; f a.(length a - 1); ()!.@@@@@@@@@@@@*@8+@; @@@@1Float.Array.iteri3(Same as 0D@ , but the function is applied with the index of the element as first argument, and the element itself as second argument.@@@@@@@@@@@@@P@S @@@@/Float.Array.map3'map f a2 applies function !f8 to all the elements of !a =, and builds a floatarray with the results returned by !f!.@@@@@@@@@@@@@w@z@@@@7Float.Array.map_inplace3/map_inplace f a2 applies function !f4 to all elements of !a *, and updates their values in place.@@@@#5.1@@@@@@@@ @@@@@0Float.Array.mapi3(Same as SD@ , but the function is applied to the index of the element as first argument, and the element itself as second argument.@@@@@@@@@@@@@@@@@@ՠ8Float.Array.mapi_inplace3(Same as DD@ }, but the function is applied to the index of the element as first argument, and the element itself as second argument.@@@@#5.1@@@@@@@@@@@@@5Float.Array.fold_left32fold_left f x init0 computes 2f (... (f (f x init.(0)) init.(1)) ...) init.(n-1)., where !n ! is the length of the floatarray $init!.@@@@@@@@@@@@@@@@@@@ 6Float.Array.fold_right33fold_right f a init0 computes -f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...))., where !n ! is the length of the floatarray !a!.@@@@@@@@@@@@@@ @#@@@@ĠA@7Iterators on two arrays@@1Float.Array.iter231Array.iter2 f a b2 applies function !f8 to all the elements of !a+ and !b!.@@@@@@@@0Invalid_argument )if the floatarrays are not the same size.@@@@@@T@W@Z@@@@0Float.Array.map23*map2 f a b2 applies function !f8 to all the elements of !a+ and !b 7, and builds a floatarray with the results returned by !f(: <[| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|]!.@@@@@@@@0Invalid_argument )if the floatarrays are not the same size.@@@@@@@@@@@@A@.Array scanning@@3Float.Array.for_all39for_all f [|a1; ...; an|] F checks if all elements of the floatarray satisfy the predicate !f<. That is, it returns !(f a1) && (f a2) && ... && (f an)!.@@@@@@@@@@@@@@@@@@2Float.Array.exists38exists f [|a1; ...; an|] P checks if at least one element of the floatarray satisfies the predicate !f<. That is, it returns !(f a1) || (f a2) || ... || (f an)!.@@@@@@@@@@@@@@@@@@/Float.Array.mem3)mem a set / is true if and only if there is an element of #set % that is structurally equal to !a3, i.e. there is an !x$ in #set1 such that /compare a x = 0!.@@@@@@@@@@@@@@@@@@Ǡ4Float.Array.mem_ieee3(Same as  0 if and only if 'cmp y x$ < 0@( if 'cmp x y* >= 0 and 'cmp y z+ >= 0 then 'cmp x z% >= 0@@, When $sort* returns, !a k contains the same elements as before, reordered in such a way that for all i and j valid indices of !a" :% /cmp a.(i) a.(j)/ >= 0 if i >= j@@@@@@@@@@@@@@@;@>@@@@栕7Float.Array.stable_sort3(Same as D@ , but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.@ d The current implementation uses Merge Sort. It uses a temporary floatarray of length #n/2(, where !n a is the length of the floatarray. It is usually faster than the current implementation of D@!.@@@@@@@@@@@@@i@l@@@@堕5Float.Array.fast_sort3(Same as АD@$ or =D@ -, whichever is faster on typical input.@@@@@@@@@@@@@@@@@@Ԡ3Float.Array.shuffle3.shuffle rand a3 randomly permutes !a2's elements using $rand C for randomness. The distribution of permutations is uniform.@' $rand= must be such that a call to &rand n C returns a uniformly distributed random number in the range [!0!;#n-1)]. *Random.int@@ . can be used for this (do not forget to 0Random.self_init@*initialize@0 the generator).@@@@#5.2@@@@@@@@@@@@@A@:Float arrays and Sequences@@2Float.Array.to_seq3 Iterate on the floatarray, in increasing order. Modifications of the floatarray during iteration will be reflected in the sequence.@@@@@@@@@@@@@@@@@ꠕ3Float.Array.to_seqi3 Iterate on the floatarray, in increasing order, yielding indices along elements. Modifications of the floatarray during iteration will be reflected in the sequence.@@@@@@@@@@@@@@@@@ɠ2Float.Array.of_seq3 #Create an array from the generator.@@@@@@@@@@@@@ @@@@8Float.Array.map_to_array30map_to_array f a2 applies function !f8 to all the elements of !a 9, and builds an array with the results returned by !f(: /[| f a.(0); f a.(1); ...; f a.(length a - 1) |]!.@@@@@@@@@@@@@7@:@@@@:Float.Array.map_from_array32map_from_array f a2 applies function !f8 to all the elements of !a =, and builds a floatarray with the results returned by !f!.@@@@@@@@@@@@@^@a@@@@A6floatarray_concurrency=Arrays and concurrency safety@@ Care must be taken when concurrently accessing float arrays from multiple domains: accessing an array will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.@' B4floatarray_atomicity)Atomicity@@ Every float array operation that accesses more than one array element is not atomic. This includes iteration, scanning, sorting, splitting and combining arrays.@ 6 For example, consider the following program: /let size = 100_000_000 let a = Float.Array.make size 1. let update a f () = Float.Array.iteri (fun i x -> Float.Array.set a i (f x)) a let d1 = Domain.spawn (update a (fun x -> x +. 1.)) let d2 = Domain.spawn (update a (fun x -> 2. *. x +. 1.)) let () = Domain.join d1; Domain.join d2 @ @ After executing this code, each field of the float array !a1 is either "2.", "3.", "4.$ or "5. m. If atomicity is required, then the user must implement their own synchronization (for example, using 'Mutex.t@@").@' B4floatarray_data_race*Data races@@ If two domains only access disjoint parts of the array, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.@ 6 A data race is said to occur when two domains access the same array element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.@ Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the array elements.@ h Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location with a few exceptions.@' B;floatarray_datarace_tearing(Tearing @@ Q Float arrays have two supplementary caveats in the presence of data races.@ D First, the blit operation might copy an array byte-by-byte. Data races between such a blit operation and another operation might produce surprising values due to tearing: partial writes interleaved with other operations can create float values that would not exist with a sequential execution.@ % For instance, at the end of Blet zeros = Float.Array.make size 0. let max_floats = Float.Array.make size Float.max_float let res = Float.Array.copy zeros let d1 = Domain.spawn (fun () -> Float.Array.blit zeros 0 res 0 size) let d2 = Domain.spawn (fun () -> Float.Array.blit max_floats 0 res 0 size) let () = Domain.join d1; Domain.join d2 @+ the #res 3 float array might contain values that are neither "0.+ nor )max_float!.@ Second, on 32-bit architectures, getting or setting a field involves two separate memory accesses. In the presence of data races, the user may observe tearing on any operation.@@@@@@@@/1Float.ArrayLabels3 Sys.max_floatarray_length!.@@@@@<@=@9@@@@,8Float.ArrayLabels.create3(create n & returns a fresh floatarray of length !n , with uninitialized data.@@@@@@@@0Invalid_argument#if %n < 0$ or =n > Sys.max_floatarray_length!.@@@@@H@I@@@@<6Float.ArrayLabels.init3)init n ~f & returns a fresh floatarray of length !n<, with element number !i> initialized to the result of #f i8. In other terms, )init n ~f: tabulates the results of !f? applied to the integers !0$ to #n-1!.@@@@@@@@0Invalid_argument#if %n < 0$ or =n > Sys.max_floatarray_length!.@@@@@|@C}@xw@@@@c=Float.ArrayLabels.make_matrix39make_matrix ~dimx ~dimy e Q returns a two-dimensional array (an array of arrays) with first dimension $dimx< and second dimension $dimy *, where all elements are initialized with !e!.@@@@#5.2@@@0Invalid_argument#if $dimx$ or $dimy # is negative or greater than 9Sys.max_floatarray_length@@!.@@@@@@@@@@@@u=Float.ArrayLabels.init_matrix3:init_matrix ~dimx ~dimy ~f W returns a two-dimensional array (an array of arrays) with first dimension $dimx6 and second dimension $dimy $, where the element at index (#x,y6) is initialized with %f x y!.@@@@#5.2@@@0Invalid_argument#if $dimx$ or $dimy # is negative or greater than 9Sys.max_floatarray_length@@!.@@@@@@@@@@@@}8Float.ArrayLabels.append3,append v1 v2 R returns a fresh floatarray containing the concatenation of the floatarrays "v1% and "v2!.@@@@@@@@0Invalid_argument)if 1length v1 + length v2 > Sys.max_floatarray_length!.@@@@@@@@@@@8Float.ArrayLabels.concat3(Same as 6D@ ), but concatenates a list of floatarrays.@@@@@@@@@@@@@@@@@o5Float.ArrayLabels.sub3/sub a ~pos ~len & returns a fresh floatarray of length #len ', containing the elements number #pos$ to -pos + len - 15 of floatarray !a!.@@@@@@@@0Invalid_argument#if #pos% and #len , do not designate a valid subarray of !a4; that is, if 'pos < 0%, or 'len < 0%, or 4pos + len > length a!.@@@@@@j@@@@@@6Float.ArrayLabels.copy3© a3 returns a copy of !a D, that is, a fresh floatarray containing the same elements as !a!.@@@@@@@@@@@@@@@@@6Float.ArrayLabels.fill32fill a ~pos ~len x9 modifies the floatarray !a9 in place, storing !x4 in elements number #pos$ to -pos + len - 1!.@@@@@@@@0Invalid_argument#if #pos% and #len , do not designate a valid subarray of !a!.@@@@@@@@@@@@@6Float.ArrayLabels.blit3 %blit ~src ~src_pos ~dst ~dst_pos ~len( copies #len elements from floatarray #src=, starting at element number 'src_pos6, to floatarray #dst=, starting at element number 'dst_pos ). It works correctly even if #src% and #dst N are the same floatarray, and the source and destination chunks overlap.@@@@@@@@0Invalid_argument#if 'src_pos% and #len , do not designate a valid subarray of #src(, or if 'dst_pos% and #len , do not designate a valid subarray of #dst!.@@@@@@@@@@@@@@ܠ9Float.ArrayLabels.to_list3)to_list a ) returns the list of all the elements of !a!.@@@@@@@@@@@@@c@@@@Ԡ9Float.ArrayLabels.of_list3)of_list l = returns a fresh floatarray containing the elements of !l!.@@@@@@@@0Invalid_argument1if the length of !l7 is greater than 9Sys.max_floatarray_length!.@@@@@@@@@@ޠA*comparison*Comparison@@7Float.ArrayLabels.equal3,equal eq a b$ is $true0 if and only if !a% and !b< have the same length !n- and for all !i% in [!0!;#n-1#], .eq a.(i) b.(i)* is $true!.@@@@#5.4@@@@@@@#@#"@@@@@@9Float.ArrayLabels.compare3/compare cmp a b* compares !a% and !b according to the shortlex order, that is, shorter arrays are smaller and equal-sized arrays are compared in lexicographic order using #cmp5 to compare elements.@@@@#5.4@@@@@@@@@@@@@@頙A@)Iterators@@6Float.ArrayLabels.iter3)iter ~f a2 applies function !f & in turn to all the elements of !a=. It is equivalent to -f a.(0); f a.(1); ...; f a.(length a - 1); ()!.@@@@@@@@@@@@@@@@@@@7Float.ArrayLabels.iteri3(Same as 0D@ , but the function is applied with the index of the element as first argument, and the element itself as second argument.@@@@@@@@@@@@@@X@@@@Ԡ5Float.ArrayLabels.map3(map ~f a2 applies function !f8 to all the elements of !a =, and builds a floatarray with the results returned by !f!.@@@@@@@@@@@@@@@@@@̠=Float.ArrayLabels.map_inplace3/map_inplace f a2 applies function !f4 to all elements of !a *, and updates their values in place.@@@@#5.1@@@@@@@@@@@@@Š6Float.ArrayLabels.mapi3(Same as SD@ , but the function is applied to the index of the element as first argument, and the element itself as second argument.@@@@@@@@@@@@@@@@@@>Float.ArrayLabels.mapi_inplace3(Same as DD@ }, but the function is applied to the index of the element as first argument, and the element itself as second argument.@@@@#5.1@@@@@@@@@@@@@;Float.ArrayLabels.fold_left34fold_left ~f x ~init0 computes 2f (... (f (f x init.(0)) init.(1)) ...) init.(n-1)., where !n ! is the length of the floatarray $init!.@@@@@@@@@@@@@@@@@@@ 0 if and only if 'cmp y x$ < 0@( if 'cmp x y* >= 0 and 'cmp y z+ >= 0 then 'cmp x z% >= 0@@, When $sort* returns, !a k contains the same elements as before, reordered in such a way that for all i and j valid indices of !a" :% /cmp a.(i) a.(j)/ >= 0 if i >= j@@@@@@@@@@@@@@@@C@@@@=Float.ArrayLabels.stable_sort3(Same as D@ , but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.@ d The current implementation uses Merge Sort. It uses a temporary floatarray of length #n/2(, where !n a is the length of the floatarray. It is usually faster than the current implementation of D@!.@@@@@@@@@@@@@@q@@@@;Float.ArrayLabels.fast_sort3(Same as АD@$ or =D@ -, whichever is faster on typical input.@@@@@@@@@@@@@@@@@@9Float.ArrayLabels.shuffle3/shuffle ~rand a3 randomly permutes !a2's elements using $rand C for randomness. The distribution of permutations is uniform.@' $rand= must be such that a call to &rand n C returns a uniformly distributed random number in the range [!0!;#n-1)]. *Random.int@@ . can be used for this (do not forget to 0Random.self_init@*initialize@0 the generator).@@@@#5.2@@@@@@@@@@@@@A@:Float arrays and Sequences@@8Float.ArrayLabels.to_seq3 Iterate on the floatarray, in increasing order. Modifications of the floatarray during iteration will be reflected in the sequence.@@@@@@@@@@@@@@@@@9Float.ArrayLabels.to_seqi3 Iterate on the floatarray, in increasing order, yielding indices along elements. Modifications of the floatarray during iteration will be reflected in the sequence.@@@@@@@@@@@@@@@@@w8Float.ArrayLabels.of_seq3 #Create an array from the generator.@@@@@@@@@@@@x@y@@@@a>Float.ArrayLabels.map_to_array31map_to_array ~f a2 applies function !f8 to all the elements of !a 9, and builds an array with the results returned by !f(: /[| f a.(0); f a.(1); ...; f a.(length a - 1) |]!.@@@@@@@@@@@@}@}|@?p@@@@b Float.ArrayLabels.map_from_array33map_from_array ~f a2 applies function !f8 to all the elements of !a =, and builds a floatarray with the results returned by !f!.@@@@@@@@@@@@x@xw@fk@@@@]A6floatarray_concurrency=Arrays and concurrency safety@@ Care must be taken when concurrently accessing float arrays from multiple domains: accessing an array will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.@' B4floatarray_atomicity)Atomicity@@ Every float array operation that accesses more than one array element is not atomic. This includes iteration, scanning, sorting, splitting and combining arrays.@ 6 For example, consider the following program: >let size = 100_000_000 let a = Float.ArrayLabels.make size 1. let update a f () = Float.ArrayLabels.iteri ~f:(fun i x -> Float.Array.set a i (f x)) a let d1 = Domain.spawn (update a (fun x -> x +. 1.)) let d2 = Domain.spawn (update a (fun x -> 2. *. x +. 1.)) let () = Domain.join d1; Domain.join d2 @ @ After executing this code, each field of the float array !a1 is either "2.", "3.", "4.$ or "5. m. If atomicity is required, then the user must implement their own synchronization (for example, using 'Mutex.t@@").@' B4floatarray_data_race*Data races@@ If two domains only access disjoint parts of the array, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.@ 6 A data race is said to occur when two domains access the same array element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.@ Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the array elements.@ h Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location with a few exceptions.@' B;floatarray_datarace_tearing(Tearing @@ Q Float arrays have two supplementary caveats in the presence of data races.@ D First, the blit operation might copy an array byte-by-byte. Data races between such a blit operation and another operation might produce surprising values due to tearing: partial writes interleaved with other operations can create float values that would not exist with a sequential execution.@ % For instance, at the end of Blet zeros = Float.Array.make size 0. let max_floats = Float.Array.make size Float.max_float let res = Float.Array.copy zeros let d1 = Domain.spawn (fun () -> Float.Array.blit zeros 0 res 0 size) let d2 = Domain.spawn (fun () -> Float.Array.blit max_floats 0 res 0 size) let () = Domain.join d1; Domain.join d2 @+ the #res 3 float array might contain values that are neither "0.+ nor )max_float!.@ Second, on 32-bit architectures, getting or setting a field involves two separate memory accesses. In the presence of data races, the user may observe tearing on any operation.@@@@@@@@@@B@@A&Stdlib#Seq@@@@@