Current section
Files
Jump to
Current section
Files
src/argamak@tensor.erl
-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>>,
<<Data/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.