CREATE OR REPLACE FUNCTION public._matmul(
m1 anyarray,
m2 anyarray,
r anyarray)
RETURNS anyarray AS
$BODY$
DECLARE
ubm1 integer;
ubm2 integer;
BEGIN
ubm1 := array_upper(m1,1);
ubm2 := array_upper(m2,1);
FOR i IN 1..ubm1 LOOP
FOR j in 1..ubm1 loop
r[i][j] := m1[i:i][1:ubm2] +* m2[1:ubm2][j:j];
END LOOP;
END LOOP;
return r;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE STRICT;
select _matmul('{{1.0,2.0,3.0},{4.0,5.0,6.0}}'::double precision[], '{{7.0,8.0},{9.0,10.0},{11.0,12.0}}'::double precision[], '{{null,null},{null,null}}');
{{58,64},{139,154}}
11 ms
This is only a proof of concept. It likely has problems but works good enough to run the example. I especially don't like the two nested loops and the result element access by index, maybe there is a better solution...
you should to use OUT modifier for parameter r
ReplyDeleteCREATE OR REPLACE FUNCTION foo(a anyarray, OUT r anyarray) AS $$ ... $$
If I declare r as OUT or INOUT, the function does not compile: ERROR: RETURN cannot have a parameter in function with OUT parameters
DeleteSo I could do this in a procedure but not in a function.
OK, but shouldn't that be:
ReplyDeleteCREATE OR REPLACE FUNCTION foo(a anyarray, INOUT r anyarray) AS $$ ... $$
then because it is passed in, modified and out again? And is this more than syntax? Because it works with the IN default without obvious problems and the documentation does not say wheter argmode triggers some special handling inside the backend...