87 lines
2.2 KiB
Plaintext
87 lines
2.2 KiB
Plaintext
CREATE TYPE COMPLEX AS STRUCT(r REAL, i REAL);
|
|
|
|
CREATE OR REPLACE FUNCTION isreal(a) AS (
|
|
if (try_cast(a as REAL), true, false)
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION tocomplex(a) AS (
|
|
coalesce( try_cast(a as COMPLEX), {r: a, i:0.0 }::COMPLEX )
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_add_(a, b) AS (
|
|
{r: a.r + b.r, i:a.i + b.i}
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_add(a, b) AS (
|
|
complex_add_(tocomplex(a), tocomplex(b))
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_mul_(a, b) AS (
|
|
{r: a.r * b.r - a.i * b.i, i:a.r * b.i + a.i * b.r}
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_mul(a, b) AS (
|
|
complex_mul_(tocomplex(a), tocomplex(b))
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_mag(a) AS (
|
|
case when isreal(a)
|
|
then abs(a::REAL)
|
|
else sqrt( (a::COMPLEX).r ^ 2 + (a::COMPLEX).i ^2)
|
|
end
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_conj(a) AS (
|
|
case when isreal(a)
|
|
then {r: a::REAL, i: 0.0}
|
|
else {r: (a::COMPLEX).r, i: - (a::COMPLEX).i}
|
|
end
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_mag_squared(x) AS (
|
|
case when isreal(x)
|
|
then x::REAL*x::REAL
|
|
else (x::COMPLEX).r ^ 2 + (x::COMPLEX).i ^ 2
|
|
end
|
|
);
|
|
|
|
# Oddly, the a.r notation cannot currently be used here
|
|
CREATE OR REPLACE FUNCTION complex_div_(a, b) AS (
|
|
WITH denom AS (select complex_mag_squared(b) as denom,
|
|
a['r'] as ar, a['i'] as ai, b['r'] as br, b['i'] as bi
|
|
)
|
|
SELECT {r: (ar * br + ai * bi) / denom,
|
|
i: (ai * br - ar * bi) / denom }
|
|
FROM denom
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_div(a, b) AS (
|
|
complex_div_(tocomplex(a), tocomplex(b))
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_exp_(z) AS (
|
|
complex_mul_( {r: exp(z.r), i: 0.0}, {r: cos(z.i), i:sin(z.i) })
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION complex_exp(z) AS (
|
|
if( isreal(z),
|
|
{r:exp(z::REAL), i:0.0},
|
|
complex_exp_( tocomplex(z) ) )
|
|
);
|
|
|
|
## Examples
|
|
.mode line
|
|
CREATE OR REPLACE FUNCTION test(x,y) as table (
|
|
select x as "x",
|
|
y as "y",
|
|
complex_add(x,y) as "add",
|
|
complex_mul(x,y) as "mul",
|
|
complex_div(1, x) as "1/x",
|
|
complex_conj(x) as "conj(x)",
|
|
complex_div(x,y).complex_mul(y) as "(x/y)*y"
|
|
);
|
|
|
|
from test({r:1,i:1}, {r:0,i:1} );
|
|
|
|
select complex_exp( {r:0, i:pi()} ) as "e^iπ";
|