-module(argamak@tensor). -compile(no_auto_import). -export([from_float/1, from_int/1, from_bool/1, from_floats/2, from_ints/2, from_bools/2, from_native/3, format/1, space/1, axes/1, rank/1, shape/1, size/1, reformat/2, reshape/2, broadcast/2, broadcast_over/3, squeeze/2, equal/2, not_equal/2, greater/2, greater_or_equal/2, less/2, less_or_equal/2, logical_and/2, logical_or/2, logical_xor/2, logical_not/1, add/2, subtract/2, multiply/2, divide/2, try_divide/2, remainder/2, try_remainder/2, modulo/2, try_modulo/2, power/2, max/2, min/2, absolute_value/1, negate/1, sign/1, ceiling/1, floor/1, round/1, exp/1, square_root/1, ln/1, all/2, in_situ_all/2, any/2, in_situ_any/2, arg_max/2, in_situ_arg_max/2, arg_min/2, in_situ_arg_min/2, max_over/2, in_situ_max_over/2, min_over/2, in_situ_min_over/2, sum/2, in_situ_sum/2, product/2, in_situ_product/2, mean/2, in_situ_mean/2, to_float/1, to_int/1, to_bool/1, to_floats/1, to_ints/1, to_bools/1, to_native/1, to_string/3, debug/1, print/1, print_data/1]). -export_type([tensor/1, native/0, tensor_error/0, to_string/0, to_string_acc/0, fit_by/0, fit_acc/1, reducible/0, reducible_acc/0]). -opaque tensor(JQN) :: {tensor, native(), argamak@format:format(JQN), argamak@space:space()}. -type native() :: any(). -type tensor_error() :: cannot_broadcast | incompatible_axes | incompatible_shape | invalid_data | {space_errors, list(argamak@space:space_error())} | zero_division. -type to_string() :: data | record. -type to_string_acc() :: {to_string_acc, list(gleam@string_builder:string_builder()), gleam@string_builder:string_builder()}. -type fit_by() :: definition | inference. -type fit_acc(JQW) :: {fit_acc, integer(), fit_by()} | {gleam_phantom, JQW}. -type reducible() :: away | in_situ. -type reducible_acc() :: {reducible_acc, list(argamak@axis:axis()), list(integer())}. -spec from_float(float()) -> tensor(argamak@format:float32()). from_float(X) -> {ok, X@2} = case tensor(X, argamak@space:new(), argamak@format:float32()) of {ok, X@1} -> {ok, X@1}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"argamak/tensor"/utf8>>, function => <<"from_float"/utf8>>, line => 71}) end, X@2. -spec from_int(integer()) -> tensor(argamak@format:int32()). from_int(X) -> {ok, X@2} = case tensor(X, argamak@space:new(), argamak@format:int32()) of {ok, X@1} -> {ok, X@1}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"argamak/tensor"/utf8>>, function => <<"from_int"/utf8>>, line => 86}) end, X@2. -spec from_bool(boolean()) -> tensor(argamak@format:int32()). from_bool(X) -> {ok, X@2} = case begin _pipe = X, _pipe@1 = gleam@bool:to_int(_pipe), tensor(_pipe@1, argamak@space:new(), argamak@format:int32()) end of {ok, X@1} -> {ok, X@1}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"argamak/tensor"/utf8>>, function => <<"from_bool"/utf8>>, line => 107}) end, X@2. -spec from_floats(list(float()), argamak@space:space()) -> {ok, tensor(argamak@format:float32())} | {error, tensor_error()}. from_floats(Xs, Space) -> tensor(Xs, Space, argamak@format:float32()). -spec from_ints(list(integer()), argamak@space:space()) -> {ok, tensor(argamak@format:int32())} | {error, tensor_error()}. from_ints(Xs, Space) -> tensor(Xs, Space, argamak@format:int32()). -spec from_bools(list(boolean()), argamak@space:space()) -> {ok, tensor(argamak@format:int32())} | {error, tensor_error()}. from_bools(Xs, Space) -> _pipe = Xs, _pipe@1 = gleam@list:map(_pipe, fun gleam@bool:to_int/1), tensor(_pipe@1, Space, argamak@format:int32()). -spec from_native(native(), argamak@space:space(), argamak@format:format(JRI)) -> {ok, tensor(JRI)} | {error, tensor_error()}. from_native(X, Space, Format) -> _pipe = X, _pipe@1 = {tensor, _pipe, Format, Space}, _pipe@2 = reformat(_pipe@1, Format), reshape(_pipe@2, Space). -spec format(tensor(JRL)) -> argamak@format:format(JRL). format(X) -> erlang:element(3, X). -spec space(tensor(any())) -> argamak@space:space(). space(X) -> erlang:element(4, X). -spec axes(tensor(any())) -> list(argamak@axis:axis()). axes(X) -> _pipe = X, _pipe@1 = space(_pipe), argamak@space:axes(_pipe@1). -spec rank(tensor(any())) -> integer(). rank(X) -> _pipe = X, _pipe@1 = space(_pipe), argamak@space:degree(_pipe@1). -spec shape(tensor(any())) -> list(integer()). shape(X) -> _pipe = X, _pipe@1 = space(_pipe), argamak@space:shape(_pipe@1). -spec size(tensor(any())) -> integer(). size(X) -> _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:size(_pipe@1). -spec reformat(tensor(any()), argamak@format:format(JSA)) -> tensor(JSA). reformat(X, Format) -> _pipe = X, _pipe@1 = to_native(_pipe), _pipe@2 = argamak_ffi:reformat(_pipe@1, argamak@format:to_native(Format)), {tensor, _pipe@2, Format, space(X)}. -spec reshape(tensor(JSD), argamak@space:space()) -> {ok, tensor(JSD)} | {error, tensor_error()}. reshape(X, New_space) -> case begin _pipe = erlang:setelement(4, X, New_space), fit(_pipe) end of {error, _try} -> {error, _try}; {ok, X@1} -> Shape = shape(X@1), case begin _pipe@1 = X@1, _pipe@2 = to_native(_pipe@1), argamak_ffi:reshape(_pipe@2, Shape) end of {error, _try@1} -> {error, _try@1}; {ok, Native} -> _pipe@3 = erlang:setelement(2, X@1, Native), {ok, _pipe@3} end end. -spec broadcast(tensor(JSG), argamak@space:space()) -> {ok, tensor(JSG)} | {error, tensor_error()}. broadcast(X, New_space) -> case begin _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:broadcast(_pipe@1, argamak@space:shape(New_space)) end of {error, _try} -> {error, _try}; {ok, Native} -> _pipe@2 = erlang:setelement( 4, erlang:setelement(2, X, Native), New_space ), {ok, _pipe@2} end. -spec broadcast_over( tensor(JSJ), argamak@space:space(), fun((argamak@axis:axis()) -> binary()) ) -> {ok, tensor(JSJ)} | {error, tensor_error()}. broadcast_over(X, New_space, Space_map) -> New_axes = argamak@space:axes(New_space), case begin _pipe = X, _pipe@1 = axes(_pipe), _pipe@6 = gleam@list:map( _pipe@1, begin _pipe@2 = Space_map, gleam@function:compose( _pipe@2, fun(Name) -> _pipe@3 = New_axes, _pipe@5 = gleam@list:find_map( _pipe@3, fun(Axis) -> case argamak@axis:name(Axis) =:= Name of true -> _pipe@4 = {Name, argamak@axis:size(Axis)}, {ok, _pipe@4}; false -> {error, nil} end end ), gleam@result:replace_error(_pipe@5, incompatible_axes) end ) end ), gleam@result:all(_pipe@6) end of {error, _try} -> {error, _try}; {ok, Mapped_axes} -> Axis_map = gleam@map:from_list(Mapped_axes), Pre_shape = begin _pipe@7 = New_axes, gleam@list:map( _pipe@7, fun(Axis@1) -> _pipe@8 = Axis_map, _pipe@9 = gleam@map:get( _pipe@8, argamak@axis:name(Axis@1) ), gleam@result:unwrap(_pipe@9, 1) end ) end, Shape = argamak@space:shape(New_space), case begin _pipe@10 = X, _pipe@11 = to_native(_pipe@10), argamak_ffi:reshape(_pipe@11, Pre_shape) end of {error, _try@1} -> {error, _try@1}; {ok, Native} -> case argamak_ffi:broadcast(Native, Shape) of {error, _try@2} -> {error, _try@2}; {ok, Native@1} -> _pipe@12 = erlang:setelement( 4, erlang:setelement(2, X, Native@1), New_space ), {ok, _pipe@12} end end end. -spec squeeze(tensor(JSM), fun((argamak@axis:axis()) -> boolean())) -> tensor(JSM). squeeze(X, Filter) -> Filter@1 = fun(Axis) -> case argamak@axis:size(Axis) of 1 -> Filter(Axis); _@1 -> false end end, reducible_over_axes(fun argamak_ffi:squeeze/2, X, Filter@1, away). -spec equal(tensor(JSP), tensor(JSP)) -> {ok, tensor(JSP)} | {error, tensor_error()}. equal(A, B) -> broadcastable(fun argamak_ffi:equal/2, A, B). -spec not_equal(tensor(JST), tensor(JST)) -> {ok, tensor(JST)} | {error, tensor_error()}. not_equal(A, B) -> broadcastable(fun argamak_ffi:not_equal/2, A, B). -spec greater(tensor(JSX), tensor(JSX)) -> {ok, tensor(JSX)} | {error, tensor_error()}. greater(A, B) -> broadcastable(fun argamak_ffi:greater/2, A, B). -spec greater_or_equal(tensor(JTB), tensor(JTB)) -> {ok, tensor(JTB)} | {error, tensor_error()}. greater_or_equal(A, B) -> broadcastable(fun argamak_ffi:greater_or_equal/2, A, B). -spec less(tensor(JTF), tensor(JTF)) -> {ok, tensor(JTF)} | {error, tensor_error()}. less(A, B) -> broadcastable(fun argamak_ffi:less/2, A, B). -spec less_or_equal(tensor(JTJ), tensor(JTJ)) -> {ok, tensor(JTJ)} | {error, tensor_error()}. less_or_equal(A, B) -> broadcastable(fun argamak_ffi:less_or_equal/2, A, B). -spec logical_and(tensor(JTN), tensor(JTN)) -> {ok, tensor(JTN)} | {error, tensor_error()}. logical_and(A, B) -> broadcastable(fun argamak_ffi:logical_and/2, A, B). -spec logical_or(tensor(JTR), tensor(JTR)) -> {ok, tensor(JTR)} | {error, tensor_error()}. logical_or(A, B) -> broadcastable(fun argamak_ffi:logical_or/2, A, B). -spec logical_xor(tensor(JTV), tensor(JTV)) -> {ok, tensor(JTV)} | {error, tensor_error()}. logical_xor(A, B) -> broadcastable(fun argamak_ffi:logical_xor/2, A, B). -spec logical_not(tensor(JTZ)) -> tensor(JTZ). logical_not(X) -> erlang:setelement(2, X, argamak_ffi:logical_not(to_native(X))). -spec add(tensor(JUC), tensor(JUC)) -> {ok, tensor(JUC)} | {error, tensor_error()}. add(A, B) -> broadcastable(fun argamak_ffi:add/2, A, B). -spec subtract(tensor(JUG), tensor(JUG)) -> {ok, tensor(JUG)} | {error, tensor_error()}. subtract(A, B) -> broadcastable(fun argamak_ffi:subtract/2, A, B). -spec multiply(tensor(JUK), tensor(JUK)) -> {ok, tensor(JUK)} | {error, tensor_error()}. multiply(A, B) -> broadcastable(fun argamak_ffi:multiply/2, A, B). -spec divide(tensor(JUO), tensor(JUO)) -> {ok, tensor(JUO)} | {error, tensor_error()}. divide(A, B) -> _pipe = fun(_capture) -> broadcastable(fun argamak_ffi:divide/2, A, _capture) end, permit_zero(B, _pipe). -spec try_divide(tensor(JUS), tensor(JUS)) -> {ok, tensor(JUS)} | {error, tensor_error()}. try_divide(A, B) -> case all_nonzero(B) of {error, _try} -> {error, _try}; {ok, B@1} -> divide(A, B@1) end. -spec remainder(tensor(JUW), tensor(JUW)) -> {ok, tensor(JUW)} | {error, tensor_error()}. remainder(A, B) -> do_remainder(A, B). -spec do_remainder(tensor(JVA), tensor(JVA)) -> {ok, tensor(JVA)} | {error, tensor_error()}. do_remainder(A, B) -> _pipe = fun(_capture) -> broadcastable(fun argamak_ffi:remainder/2, A, _capture) end, permit_zero(B, _pipe). -spec try_remainder(tensor(JVE), tensor(JVE)) -> {ok, tensor(JVE)} | {error, tensor_error()}. try_remainder(A, B) -> case all_nonzero(B) of {error, _try} -> {error, _try}; {ok, B@1} -> remainder(A, B@1) end. -spec modulo(tensor(JVI), tensor(JVI)) -> {ok, tensor(JVI)} | {error, tensor_error()}. modulo(A, B) -> do_modulo(A, B). -spec do_modulo(tensor(JVM), tensor(JVM)) -> {ok, tensor(JVM)} | {error, tensor_error()}. do_modulo(A, B) -> case sign_not_equal(A, B) of {error, _try} -> {error, _try}; {ok, Adjust} -> case multiply(Adjust, B) of {error, _try@1} -> {error, _try@1}; {ok, Adjust@1} -> case remainder(A, B) of {error, _try@2} -> {error, _try@2}; {ok, X} -> add(X, Adjust@1) end end end. -spec try_modulo(tensor(JVQ), tensor(JVQ)) -> {ok, tensor(JVQ)} | {error, tensor_error()}. try_modulo(A, B) -> case all_nonzero(B) of {error, _try} -> {error, _try}; {ok, B@1} -> modulo(A, B@1) end. -spec power(tensor(JVU), tensor(JVU)) -> {ok, tensor(JVU)} | {error, tensor_error()}. power(A, B) -> broadcastable(fun argamak_ffi:power/2, A, B). -spec max(tensor(JVY), tensor(JVY)) -> {ok, tensor(JVY)} | {error, tensor_error()}. max(A, B) -> broadcastable(fun argamak_ffi:max/2, A, B). -spec min(tensor(JWC), tensor(JWC)) -> {ok, tensor(JWC)} | {error, tensor_error()}. min(A, B) -> broadcastable(fun argamak_ffi:min/2, A, B). -spec absolute_value(tensor(JWG)) -> tensor(JWG). absolute_value(X) -> erlang:setelement(2, X, argamak_ffi:absolute_value(to_native(X))). -spec negate(tensor(JWJ)) -> tensor(JWJ). negate(X) -> erlang:setelement(2, X, argamak_ffi:negate(to_native(X))). -spec sign(tensor(JWM)) -> tensor(JWM). sign(X) -> erlang:setelement(2, X, argamak_ffi:sign(to_native(X))). -spec ceiling(tensor(JWP)) -> tensor(JWP). ceiling(X) -> erlang:setelement(2, X, argamak_ffi:ceiling(to_native(X))). -spec floor(tensor(JWS)) -> tensor(JWS). floor(X) -> erlang:setelement(2, X, argamak_ffi:floor(to_native(X))). -spec round(tensor(JWV)) -> tensor(JWV). round(X) -> erlang:setelement(2, X, argamak_ffi:round(to_native(X))). -spec exp(tensor(JWY)) -> tensor(JWY). exp(X) -> erlang:setelement(2, X, argamak_ffi:exp(to_native(X))). -spec square_root(tensor(JXB)) -> {ok, tensor(JXB)} | {error, tensor_error()}. square_root(X) -> case begin _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:square_root(_pipe@1) end of {error, _try} -> {error, _try}; {ok, Native} -> _pipe@2 = erlang:setelement(2, X, Native), {ok, _pipe@2} end. -spec ln(tensor(JXE)) -> {ok, tensor(JXE)} | {error, tensor_error()}. ln(X) -> case begin _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:ln(_pipe@1) end of {error, _try} -> {error, _try}; {ok, Native} -> _pipe@2 = erlang:setelement(2, X, Native), {ok, _pipe@2} end. -spec all(tensor(JXH), fun((argamak@axis:axis()) -> boolean())) -> tensor(JXH). all(X, Filter) -> reducible_over_axes(fun argamak_ffi:all/2, X, Filter, away). -spec in_situ_all(tensor(JXK), fun((argamak@axis:axis()) -> boolean())) -> tensor(JXK). in_situ_all(X, Filter) -> reducible_over_axes(fun argamak_ffi:all/2, X, Filter, in_situ). -spec any(tensor(JXN), fun((argamak@axis:axis()) -> boolean())) -> tensor(JXN). any(X, Filter) -> reducible_over_axes(fun argamak_ffi:any/2, X, Filter, away). -spec in_situ_any(tensor(JXQ), fun((argamak@axis:axis()) -> boolean())) -> tensor(JXQ). in_situ_any(X, Filter) -> reducible_over_axes(fun argamak_ffi:any/2, X, Filter, in_situ). -spec arg_max(tensor(JXT), fun((argamak@axis:axis()) -> boolean())) -> tensor(JXT). arg_max(X, Find) -> reducible_over_axis(fun argamak_ffi:arg_max/2, X, Find, away). -spec in_situ_arg_max(tensor(JXW), fun((argamak@axis:axis()) -> boolean())) -> tensor(JXW). in_situ_arg_max(X, Find) -> reducible_over_axis(fun argamak_ffi:arg_max/2, X, Find, in_situ). -spec arg_min(tensor(JXZ), fun((argamak@axis:axis()) -> boolean())) -> tensor(JXZ). arg_min(X, Find) -> reducible_over_axis(fun argamak_ffi:arg_min/2, X, Find, away). -spec in_situ_arg_min(tensor(JYC), fun((argamak@axis:axis()) -> boolean())) -> tensor(JYC). in_situ_arg_min(X, Find) -> reducible_over_axis(fun argamak_ffi:arg_min/2, X, Find, in_situ). -spec max_over(tensor(JYF), fun((argamak@axis:axis()) -> boolean())) -> tensor(JYF). max_over(X, Filter) -> reducible_over_axes(fun argamak_ffi:max_over/2, X, Filter, away). -spec in_situ_max_over(tensor(JYI), fun((argamak@axis:axis()) -> boolean())) -> tensor(JYI). in_situ_max_over(X, Filter) -> reducible_over_axes(fun argamak_ffi:max_over/2, X, Filter, in_situ). -spec min_over(tensor(JYL), fun((argamak@axis:axis()) -> boolean())) -> tensor(JYL). min_over(X, Filter) -> reducible_over_axes(fun argamak_ffi:min_over/2, X, Filter, away). -spec in_situ_min_over(tensor(JYO), fun((argamak@axis:axis()) -> boolean())) -> tensor(JYO). in_situ_min_over(X, Filter) -> reducible_over_axes(fun argamak_ffi:min_over/2, X, Filter, in_situ). -spec sum(tensor(JYR), fun((argamak@axis:axis()) -> boolean())) -> tensor(JYR). sum(X, Filter) -> reducible_over_axes(fun argamak_ffi:sum/2, X, Filter, away). -spec in_situ_sum(tensor(JYU), fun((argamak@axis:axis()) -> boolean())) -> tensor(JYU). in_situ_sum(X, Filter) -> reducible_over_axes(fun argamak_ffi:sum/2, X, Filter, in_situ). -spec product(tensor(JYX), fun((argamak@axis:axis()) -> boolean())) -> tensor(JYX). product(X, Filter) -> reducible_over_axes(fun argamak_ffi:product/2, X, Filter, away). -spec in_situ_product(tensor(JZA), fun((argamak@axis:axis()) -> boolean())) -> tensor(JZA). in_situ_product(X, Filter) -> reducible_over_axes(fun argamak_ffi:product/2, X, Filter, in_situ). -spec mean(tensor(JZD), fun((argamak@axis:axis()) -> boolean())) -> tensor(JZD). mean(X, Filter) -> reducible_over_axes(fun argamak_ffi:mean/2, X, Filter, away). -spec in_situ_mean(tensor(JZG), fun((argamak@axis:axis()) -> boolean())) -> tensor(JZG). in_situ_mean(X, Filter) -> reducible_over_axes(fun argamak_ffi:mean/2, X, Filter, in_situ). -spec to_float(tensor(any())) -> {ok, float()} | {error, tensor_error()}. to_float(X) -> _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:to_float(_pipe@1). -spec to_int(tensor(any())) -> {ok, integer()} | {error, tensor_error()}. to_int(X) -> _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:to_int(_pipe@1). -spec to_bool(tensor(any())) -> {ok, boolean()} | {error, tensor_error()}. to_bool(X) -> _pipe = X, _pipe@1 = all(_pipe, fun(_) -> false end), _pipe@2 = to_int(_pipe@1), gleam@result:map(_pipe@2, fun int_to_bool/1). -spec to_floats(tensor(any())) -> list(float()). to_floats(X) -> _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:to_floats(_pipe@1). -spec to_ints(tensor(any())) -> list(integer()). to_ints(X) -> _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:to_ints(_pipe@1). -spec to_bools(tensor(any())) -> list(boolean()). to_bools(X) -> _pipe = X, _pipe@1 = all(_pipe, fun(_) -> false end), _pipe@2 = to_ints(_pipe@1), gleam@list:map(_pipe@2, fun int_to_bool/1). -spec to_native(tensor(any())) -> native(). to_native(X) -> erlang:element(2, X). -spec to_string(tensor(any()), to_string(), integer()) -> binary(). to_string(X, Record_or_data, Column) -> Column@1 = case Column < 0 of true -> argamak_ffi:columns(); false -> Column end, Tab = case Record_or_data of record -> 2; data -> 0 end, Data = begin _pipe = X, do_to_string(_pipe, Column@1, Tab) end, case Record_or_data of record -> Format = begin _pipe@1 = X, _pipe@2 = format(_pipe@1), argamak@format:to_string(_pipe@2) end, Space = begin _pipe@3 = X, _pipe@4 = space(_pipe@3), argamak@space:to_string(_pipe@4) end, Space@1 = case gleam@string:length(Space) > Column@1 of true when Column@1 > 0 -> _pipe@5 = Space, _pipe@6 = gleam@string:replace( _pipe@5, <<"Space("/utf8>>, <<"Space(\n "/utf8>> ), _pipe@7 = gleam@string:replace( _pipe@6, <<"), "/utf8>>, <<"),\n "/utf8>> ), gleam@string:replace( _pipe@7, <<"))"/utf8>>, <<"),\n )"/utf8>> ); _@1 -> Space end, _pipe@8 = [<<"Tensor("/utf8>>, <<<<" "/utf8, Format/binary>>/binary, ","/utf8>>, <<<<" "/utf8, Space@1/binary>>/binary, ","/utf8>>, <>, <<")"/utf8>>], gleam@string:join(_pipe@8, <<"\n"/utf8>>); data -> Data end. -spec do_to_string(tensor(any()), integer(), integer()) -> binary(). do_to_string(X, Column, Tab) -> {Xs, Item_length} = begin _pipe = X, _pipe@1 = to_native(_pipe), argamak_ffi:prepare_to_string(_pipe@1) end, Rank = rank(X), Shape = case Rank of 0 -> [1]; _@1 -> _pipe@2 = X, _pipe@3 = shape(_pipe@2), gleam@list:reverse(_pipe@3) end, Try_wrap = case Column > 0 of true -> Max_length = (Column - Tab) - (Rank * 2), Item_length@1 = Item_length + 2, Wrap_at = gleam@int:max(case Item_length@1 of 0 -> 0; Gleam@denominator -> Max_length div Gleam@denominator end, 1), Inner_size@1 = case Shape of [Inner_size | _@2] -> Inner_size; _@3 -> 0 end, fun(J, F) -> case case Wrap_at of 0 -> 0; Gleam@denominator@1 -> (J + 1) rem Gleam@denominator@1 end of 0 when Wrap_at < Inner_size@1 -> fun() -> {ok, F()} end; _@4 -> fun() -> {error, nil} end end end; false -> fun(_, _) -> fun() -> {error, nil} end end end, {to_string_acc, _@5, Init_builder} = To_string_acc = {to_string_acc, [], gleam@string_builder:new( )}, Xs@1 = begin _pipe@4 = Xs, _pipe@5 = gleam@iterator:from_list(_pipe@4), _pipe@8 = gleam@iterator:map( _pipe@5, fun(X@1) -> _pipe@6 = X@1, _pipe@7 = gleam@string:pad_left( _pipe@6, Item_length, <<" "/utf8>> ), gleam@string_builder:from_string(_pipe@7) end ), gleam@iterator:index(_pipe@8) end, [{_@10, Xs@2}] = begin _pipe@9 = Shape, _pipe@27 = gleam@list:index_fold( _pipe@9, Xs@1, fun(Acc, Size, I) -> Try_build = fun(J@1, F@1) -> case case Size of 0 -> 0; Gleam@denominator@2 -> (J@1 + 1) rem Gleam@denominator@2 end of 0 -> {ok, F@1()}; _@6 -> {error, nil} end end, {to_string_acc, Built, _@9} = case I of 0 -> _pipe@10 = Acc, gleam@iterator:fold( _pipe@10, To_string_acc, fun(Acc@1, Item) -> {J@2, X@2} = Item, Builder = gleam@string_builder:append_builder( erlang:element(3, Acc@1), X@2 ), _pipe@11 = J@2, _pipe@14 = Try_build( _pipe@11, fun() -> case Rank of 0 -> erlang:setelement( 2, Acc@1, gleam@list:append( erlang:element(2, Acc@1), [Builder] ) ); _@7 -> Builder@1 = begin _pipe@12 = Builder, _pipe@13 = gleam@string_builder:prepend( _pipe@12, <<"["/utf8>> ), gleam@string_builder:append( _pipe@13, <<"]"/utf8>> ) end, {to_string_acc, gleam@list:append( erlang:element(2, Acc@1), [Builder@1] ), Init_builder} end end ), _pipe@17 = gleam@result:lazy_or( _pipe@14, Try_wrap( J@2, fun() -> Indent = gleam@string:repeat( <<" "/utf8>>, Tab + Rank ), Builder@2 = begin _pipe@15 = Builder, _pipe@16 = gleam@string_builder:append( _pipe@15, <<",\n"/utf8>> ), gleam@string_builder:append( _pipe@16, Indent ) end, erlang:setelement( 3, Acc@1, Builder@2 ) end ) ), gleam@result:lazy_unwrap( _pipe@17, fun() -> Builder@3 = gleam@string_builder:append( Builder, <<", "/utf8>> ), erlang:setelement(3, Acc@1, Builder@3) end ) end ); _@8 -> _pipe@18 = Acc, gleam@iterator:fold( _pipe@18, To_string_acc, fun(Acc@2, Item@1) -> {J@3, X@3} = Item@1, Builder@4 = gleam@string_builder:append_builder( erlang:element(3, Acc@2), X@3 ), _pipe@19 = J@3, _pipe@22 = Try_build( _pipe@19, fun() -> Builder@5 = begin _pipe@20 = Builder@4, _pipe@21 = gleam@string_builder:prepend( _pipe@20, <<"["/utf8>> ), gleam@string_builder:append( _pipe@21, <<"]"/utf8>> ) end, {to_string_acc, gleam@list:append( erlang:element(2, Acc@2), [Builder@5] ), Init_builder} end ), gleam@result:lazy_unwrap( _pipe@22, fun() -> Indent@1 = gleam@string:repeat( <<" "/utf8>>, (Tab + Rank) - I ), Builder@6 = begin _pipe@23 = Builder@4, _pipe@24 = gleam@string_builder:append( _pipe@23, <<",\n"/utf8>> ), gleam@string_builder:append( _pipe@24, Indent@1 ) end, erlang:setelement(3, Acc@2, Builder@6) end ) end ) end, _pipe@25 = Built, _pipe@26 = gleam@iterator:from_list(_pipe@25), gleam@iterator:index(_pipe@26) end ), gleam@iterator:to_list(_pipe@27) end, Indent@2 = gleam@string:repeat(<<" "/utf8>>, Tab), _pipe@28 = Xs@2, _pipe@29 = gleam@string_builder:prepend(_pipe@28, Indent@2), gleam@string_builder:to_string(_pipe@29). -spec debug(tensor(KAT)) -> tensor(KAT). debug(X) -> print(X), X. -spec print(tensor(any())) -> nil. print(X) -> _pipe = X, _pipe@1 = to_string(_pipe, record, -1), gleam@io:println(_pipe@1). -spec print_data(tensor(any())) -> nil. print_data(X) -> _pipe = X, _pipe@1 = to_string(_pipe, data, -1), gleam@io:println(_pipe@1). -spec tensor(any(), argamak@space:space(), argamak@format:format(KBB)) -> {ok, tensor(KBB)} | {error, tensor_error()}. tensor(Data, Space, New_format) -> case argamak_ffi:tensor(Data, argamak@format:to_native(New_format)) of {error, _try} -> {error, _try}; {ok, Native} -> case begin _pipe = Native, _pipe@1 = {tensor, _pipe, New_format, Space}, reshape(_pipe@1, Space) end of {error, _try@1} -> {error, _try@1}; {ok, X} -> {ok, X} end end. -spec fit(tensor(KBG)) -> {ok, tensor(KBG)} | {error, tensor_error()}. fit(X) -> Dividend = size(X), {fit_acc, Divisor, Fit_by} = begin _pipe = X, _pipe@1 = axes(_pipe), gleam@list:fold( _pipe@1, {fit_acc, 1, definition}, fun(Acc, Axis) -> case Axis of {infer, _@1} -> erlang:setelement(3, Acc, inference); _@2 -> erlang:setelement( 2, Acc, erlang:element(2, Acc) * argamak@axis:size(Axis) ) end end ) end, case case Divisor of 0 -> 0; Gleam@denominator -> Dividend rem Gleam@denominator end of 0 when Fit_by =:= definition -> {ok, X}; 0 when Fit_by =:= inference -> {ok, Space@1} = case begin _pipe@2 = X, _pipe@3 = space(_pipe@2), argamak@space:map(_pipe@3, fun(Axis@1) -> case Axis@1 of {infer, _@3} -> argamak@axis:resize(Axis@1, case Divisor of 0 -> 0; Gleam@denominator@1 -> Dividend div Gleam@denominator@1 end); _@4 -> Axis@1 end end) end of {ok, Space} -> {ok, Space}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"argamak/tensor"/utf8>>, function => <<"fit"/utf8>>, line => 4239}) end, _pipe@4 = erlang:setelement(4, X, Space@1), {ok, _pipe@4}; _@5 -> {error, incompatible_shape} end. -spec broadcastable( fun((native(), native()) -> {ok, native()} | {error, tensor_error()}), tensor(KBJ), tensor(KBJ) ) -> {ok, tensor(KBJ)} | {error, tensor_error()}. broadcastable(F, A, B) -> case begin _pipe = A, _pipe@1 = space(_pipe), _pipe@2 = argamak@space:merge(_pipe@1, space(B)), gleam@result:map_error(_pipe@2, fun(A) -> {space_errors, A} end) end of {error, _try} -> {error, _try}; {ok, Space} -> case F(to_native(A), to_native(B)) of {error, _try@1} -> {error, _try@1}; {ok, Native} -> _pipe@3 = erlang:setelement( 4, erlang:setelement(2, A, Native), Space ), {ok, _pipe@3} end end. -spec sign_not_equal(tensor(KBN), tensor(KBN)) -> {ok, tensor(KBN)} | {error, tensor_error()}. sign_not_equal(A, B) -> Zero = begin _pipe = 0, _pipe@1 = from_int(_pipe), reformat(_pipe@1, format(A)) end, case multiply(sign(A), sign(B)) of {error, _try} -> {error, _try}; {ok, X} -> less(X, Zero) end. -spec permit_zero( tensor(KBR), fun((tensor(KBR)) -> {ok, tensor(KBR)} | {error, tensor_error()}) ) -> {ok, tensor(KBR)} | {error, tensor_error()}. permit_zero(X, F) -> Zero = begin _pipe = 0, _pipe@1 = from_int(_pipe), reformat(_pipe@1, format(X)) end, case not_equal(X, Zero) of {error, _try} -> {error, _try}; {ok, Is_nonzero} -> case equal(X, Zero) of {error, _try@1} -> {error, _try@1}; {ok, Is_zero} -> case add(X, Is_zero) of {error, _try@2} -> {error, _try@2}; {ok, X@1} -> case F(X@1) of {error, _try@3} -> {error, _try@3}; {ok, X@2} -> multiply(X@2, Is_nonzero) end end end end. -spec all_nonzero(tensor(KBW)) -> {ok, tensor(KBW)} | {error, tensor_error()}. all_nonzero(X) -> case begin _pipe = X, _pipe@1 = all(_pipe, fun(_) -> true end), _pipe@2 = reformat(_pipe@1, argamak@format:int32()), to_int(_pipe@2) end of {error, _try} -> {error, _try}; {ok, All} -> case All of 1 -> {ok, X}; _@1 -> {error, zero_division} end end. -spec reducible_over_axes( fun((native(), list(integer())) -> native()), tensor(KBZ), fun((argamak@axis:axis()) -> boolean()), reducible() ) -> tensor(KBZ). reducible_over_axes(F, X, Filter, Reduce) -> Acc@1 = begin _pipe = X, _pipe@1 = axes(_pipe), gleam@list:index_fold( _pipe@1, {reducible_acc, [], []}, fun(Acc, Axis, Index) -> case Filter(Axis) of true when Reduce =:= in_situ -> Axis@1 = argamak@axis:resize(Axis, 1), {reducible_acc, [Axis@1 | erlang:element(2, Acc)], [Index | erlang:element(3, Acc)]}; true -> erlang:setelement( 3, Acc, [Index | erlang:element(3, Acc)] ); false -> erlang:setelement( 2, Acc, [Axis | erlang:element(2, Acc)] ) end end ) end, {ok, New_space@1} = case begin _pipe@2 = erlang:element(2, Acc@1), _pipe@3 = gleam@list:reverse(_pipe@2), argamak@space:from_list(_pipe@3) end of {ok, New_space} -> {ok, New_space}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"argamak/tensor"/utf8>>, function => <<"reducible_over_axes"/utf8>>, line => 4340}) end, Native = to_native(X), Native@5 = case gleam@list:reverse(erlang:element(3, Acc@1)) of [] -> {ok, Native@2} = case begin _pipe@4 = X, _pipe@5 = shape(_pipe@4), _pipe@6 = gleam@list:append(_pipe@5, [1]), argamak_ffi:reshape(Native, _pipe@6) end of {ok, Native@1} -> {ok, Native@1}; _try@1 -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try@1, module => <<"argamak/tensor"/utf8>>, function => <<"reducible_over_axes"/utf8>>, line => 4348}) end, F(Native@2, [rank(X)]); Indices -> {ok, Native@4} = case begin _pipe@7 = Native, _pipe@8 = F(_pipe@7, Indices), argamak_ffi:reshape(_pipe@8, argamak@space:shape(New_space@1)) end of {ok, Native@3} -> {ok, Native@3}; _try@2 -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try@2, module => <<"argamak/tensor"/utf8>>, function => <<"reducible_over_axes"/utf8>>, line => 4356}) end, Native@4 end, erlang:setelement(4, erlang:setelement(2, X, Native@5), New_space@1). -spec reducible_over_axis( fun((native(), integer()) -> native()), tensor(KCC), fun((argamak@axis:axis()) -> boolean()), reducible() ) -> tensor(KCC). reducible_over_axis(F, X, Find, Reduce) -> Acc@1 = begin _pipe = X, _pipe@1 = axes(_pipe), gleam@list:index_fold( _pipe@1, {reducible_acc, [], []}, fun(Acc, Axis, Index) -> case (erlang:element(3, Acc) =:= []) andalso Find(Axis) of true when Reduce =:= in_situ -> Axis@1 = argamak@axis:resize(Axis, 1), {reducible_acc, [Axis@1 | erlang:element(2, Acc)], [Index]}; true -> erlang:setelement(3, Acc, [Index]); false -> erlang:setelement( 2, Acc, [Axis | erlang:element(2, Acc)] ) end end ) end, {ok, New_space@1} = case begin _pipe@2 = erlang:element(2, Acc@1), _pipe@3 = gleam@list:reverse(_pipe@2), argamak@space:from_list(_pipe@3) end of {ok, New_space} -> {ok, New_space}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"argamak/tensor"/utf8>>, function => <<"reducible_over_axis"/utf8>>, line => 4388}) end, case erlang:element(3, Acc@1) of [] -> {ok, New_space@3} = case begin _pipe@4 = <<"Nil"/utf8>>, _pipe@5 = {infer, _pipe@4}, argamak@space:d1(_pipe@5) end of {ok, New_space@2} -> {ok, New_space@2}; _try@1 -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try@1, module => <<"argamak/tensor"/utf8>>, function => <<"reducible_over_axis"/utf8>>, line => 4395}) end, {ok, X@2} = case reshape(X, New_space@3) of {ok, X@1} -> {ok, X@1}; _try@2 -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try@2, module => <<"argamak/tensor"/utf8>>, function => <<"reducible_over_axis"/utf8>>, line => 4399}) end, erlang:setelement( 4, erlang:setelement(2, X@2, F(to_native(X@2), 0)), argamak@space:new() ); [Index@1 | _@1] -> {ok, Native@1} = case begin _pipe@6 = X, _pipe@7 = to_native(_pipe@6), _pipe@8 = F(_pipe@7, Index@1), argamak_ffi:reshape(_pipe@8, argamak@space:shape(New_space@1)) end of {ok, Native} -> {ok, Native}; _try@3 -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try@3, module => <<"argamak/tensor"/utf8>>, function => <<"reducible_over_axis"/utf8>>, line => 4403}) end, erlang:setelement(4, erlang:setelement(2, X, Native@1), New_space@1) end. -spec int_to_bool(integer()) -> boolean(). int_to_bool(X) -> case X of 0 -> false; _@1 -> true end.