Please help me to convert this PL/SQL into PostgreSQL. Thank you very much.
Prime Numbers
CREATE TABLE n (n NUMBER);<br/>
CREATE OR REPLACE PROCEDURE prime_number (n NUMBER)<br/>
IS <br/>
prime_count NUMBER := 0;<br/>
y VARCHAR2 (1) := 'N';<br/>
BEGIN<br/>
IF n >= 1
THEN
prime_count := 1;
INSERT INTO n
VALUES (2);
END IF;
IF n >= 2
THEN
prime_count := 2;
INSERT INTO n
VALUES (2);
END IF;
IF n >= 3
THEN
FOR i IN 4 .. n * n * n
LOOP
y := 'N';
FOR j IN 2 .. CEIL (SQRT (i))
LOOP
IF (MOD (i, j) = 0)
THEN
y := 'Y';
EXIT;
END IF;
END LOOP;
IF (y = 'N')
THEN
INSERT INTO n
VALUES (i);
COMMIT;
prime_count := prime_count + 1;
EXIT WHEN prime_count = n;
END IF;
END LOOP;
END IF;<br/>
END;
BEGIN<br/>
prime_number (1000000);<br/>
END;
Related
I'M TRYIN TO CREATE A PROGRAM USING MAPLE FOR GAUSSING ELIMINATION BUT I KEEP GETTING THIS ERROR
Gauss := proc (n::posint, A::matrix, c::Vector)
local a, i, k, j, p;
with(MTM):
n := linalg[rowdim](A);
if det(A) = 0 then print('matrice*doit*etre*caree')
else if det(A) <> 0
then a := `<|>`(A, c);
for k to n-1 do
for i from k+1 to n do
if a[i, i] = 0 then swaprow(a, k, i)
else p = a[i, k]/a[k, k];
for j from k+1 to n+1 do a[i, j] = a[i, j]-p*a[k, j]
end do;
end if;
end do;
end do;
else print('rien')
end if; end if; end proc;
Error, (in Gauss) illegal use of a formal parameter
restart;
Gauss := proc(A::Matrix, c::Vector)
local a, i, k, j, m, n, p;
n := linalg[rowdim](A);
m := linalg[coldim](A);
if m <> n then
print("matrice doit etre caree");
else
a := `<|>`(A, c);
for k to n-1 do
for i from k+1 to n do
if a[i, i] = 0 then
a := linalg[swaprow](a, k, i);
else
p := a[i, k]/a[k, k];
for j from k to n+1 do
a[i, j] := a[i, j]-p*a[k, j];
end do;
end if;
end do;
end do;
end if;
return a;
end proc:
c := Vector([2, 3, 4]);
A := Matrix(3, 3, [4, 1, 2, 3, 6, 5, 2, 1, 9]);
Gauss(A, c);
LinearAlgebra:-LUDecomposition(<A|c>, output=U);
There were quite a few mistakes, so let's hope I get most of them.
I didn't bother doing 7. You should do it.
You cannot use with inside a procedure.
Your code uses commands from thelinalg
package, not the MTM package.
Ideally you'd use Matrix&Vector&LinearAlgebra
(instead of your mix of matrix&Vector&linalg(.
Your procedure has n as one of its
parameters, but inside it you also try to
assign a value to n, the argument for which
you passed in as the number 3. That's where
your error message is coming from. You can't
do that.
Several of you lines have just = instead of
:= for assignments. The = does nothing.
The test against det(A)=0 is wrong is wrong
in several ways. I'll just say that it doesn't
actually test whether the A is square.
Compare the row & column dimensions if you
want to test that A is square.
You should be using LinearAlgebra
equivalents instead of the linalg commands
commands swaprow, coldim.
You forgot to have your procedure actually
return the Matrix a.
When your code calls swaprow is was not
actually updating a. It was just throwing
way the result.
It's a sin to not indent your code. It will
lead you to overlook mistakes.
I'm developing a simulation of a swarm of drones. I made a function for checking area in front of drones, but when i'm trying to use it it displays this error:
"The tearing heuristic was not able to avoid discrete iteration variables because otherwise the system could not have been torn".
This is the function:
function seeNearObject "Restituisce una lista contenente tutti gli oggetti rilevati dal sistema video del drone"
InputReal x;
InputReal y;
InputReal z;
InputReal x2[K.N];
InputReal y2[K.N];
InputReal z2[K.N];
InputReal destX;
InputReal destY;
InputReal destZ;
InputReal intrX[K.nIntr];
InputReal intrY[K.nIntr];
InputReal intrZ[K.nIntr];
InputReal missX[K.nRocket];
InputReal missY[K.nRocket];
InputReal missZ[K.nRocket];
InputReal statX[K.nStatObs];
InputReal statY[K.nStatObs];
InputReal statZ[K.nStatObs];
OutputBool outneighbours[K.N];
OutputBool outnearIntr[K.nIntr];
OutputBool outnearMissile[K.nRocket];
OutputBool outnearStatObs[K.nStatObs];
protected
Real viewField[3];
algorithm
//Imposto i limiti del campo visivo. Data la direzione del drone, ogni asse avrà il suo limite.
// viewField := findViewField(x,y,z, destX,destY,destZ);
viewField := zeros(3);
for j in 1:K.N loop
outneighbours[j] := false;
if((x2[j] >= x and x2[j] <= viewField[1]) or (x2[j] <= x and x2[j] >= viewField[1])) then
if((y2[j] >= y and y2[j] <= viewField[2]) or (y2[j] <= y and y2[j] >= viewField[2])) then
if((z2[j] >= z and z2[j] <= viewField[3]) or (z2[j] <= z and z2[j] >= viewField[3])) then
outneighbours[j] := true;
end if;
end if;
end if;
end for;
for j in 1:K.nIntr loop
outnearIntr[j] := false;
if((intrX[j] >= x and intrX[j] <= viewField[1]) or (intrX[j] <= x and intrX[j] >= viewField[1])) then
if((intrY[j] >= y and intrY[j] <= viewField[2]) or (intrY[j] <= y and intrY[j] >= viewField[2])) then
if((intrZ[j] >= z and intrZ[j] <= viewField[3]) or (intrZ[j] <= z and intrZ[j] >= viewField[3])) then
outnearIntr[j] := true;
end if;
end if;
end if;
end for;
for j in 1:K.nRocket loop
outnearMissile[j] := false;
if((missX[j] >= x and missX[j] <= viewField[1]) or (missX[j] <= x and missX[j] >= viewField[1])) then
if((missY[j] >= y and missY[j] <= viewField[2]) or (missY[j] <= y and missY[j] >= viewField[2])) then
if((missZ[j] >= z and missZ[j] <= viewField[3]) or (missZ[j] <= z and missZ[j] >= viewField[3])) then
outnearMissile[j] := true;
end if;
end if;
end if;
end for;
for j in 1:K.nStatObs loop
outnearStatObs[j] := false;
if((statX[j] >= x and statX[j] <= viewField[1]) or (statX[j] <= x and statX[j] >= viewField[1])) then
if((statY[j] >= y and statY[j] <= viewField[2]) or (statY[j] <= y and statY[j] >= viewField[2])) then
if((statZ[j] >= z and statZ[j] <= viewField[3]) or (statZ[j] <= z and statZ[j] >= viewField[3])) then
outnearStatObs[j] := true;
end if;
end if;
end if;
end for;
end seeNearObject;
All the inputs are point in a 3D space, and I have a similar function (written better than this) but it works clearly. Is there any error?
you probably solved this, but as far as I can see there are two issues with the code that may be causing the error.
(1) I don't see any initial condition in the algorithm. In OpenModelica you should always have a
when initial() then [...] end when;
in which you specify the starting values of each parameter (except for the ones in Input).
(2) When reading a status related variable var you should always use the pre(var) call, to read the last value of var, not the current. That is because OpenModelica uses algebraic formulas to solve the system and if your model has loops (all big models do) it may lead to this very issue in which the algebraic formula is inconsistent.
Like so
x := x + 2
It should always be something like
x := pre(x) + 2
Hope this helps. :)
How is it going guys ?
I've written a program that "draws" diamond in the command line (it's a part of my homework). For spaces inside the diamond I was given a formula "1 + 2(k-2) or 2k -3 , where k is line number", but I don't understand how this formula was created. Could anyone explain it ?
program diamond;
var
n, k, h, i: integer;
begin
repeat
write('Enter the diamond''s height (positive odd): ');
readln(h);
until (h > 0) and (h mod 2 = 1);
n := h div 2;
for k := 1 to n + 1 do
begin
for i := 1 to n + 1 - k do
write(' ');
write('*');
if k > 1 then
begin
for i := 1 to 2*k - 3 do
write(' ');
write('*')
end;
writeln
end;
for k := n downto 1 do
begin
for i := 1 to n + 1 - k do
write(' ');
write('*');
if k > 1 then
begin
for i := 1 to 2*k - 3 do
write(' ');
write('*')
end;
writeln
end
end.
I've already figured it out. It's a simple, but modified arithmetic progression An=A1-d(n-2). Usually we would use (n-1), but because we need to substract 2 stars from each line (starting from the second one, as this formula works for k>1), we use (n-2)
I have created a custom aggregate in postgres 11.3 and it works when parallel if off. When I mark it as parallel = safe, it returns null.
Could someone point me in the direction of where to start looking or how do I debug a parallel aggregation in postgres? In non parallel aggregation I can insert the state at each record into a temporary table, but inserts are not allowed in parallel queries...
Here's the aggregate:
CREATE OR REPLACE FUNCTION array_sort(ANYARRAY)
RETURNS ANYARRAY LANGUAGE SQL
AS $$
SELECT ARRAY(SELECT unnest($1) ORDER BY 1)
$$;
create type _stats_agg_accum_type AS (
cnt bigint,
q double precision[],
n double precision[],
np double precision[],
dn double precision[]
);
create type _stats_agg_result_type AS (
count bigint,
q25 double precision,
q50 double precision,
q75 double precision
);
create or replace function _stats_agg_p2_parabolic(_stats_agg_accum_type, double precision, double precision)
returns double precision AS '
DECLARE
a alias for $1;
i alias for $2;
d alias for $3;
BEGIN
RETURN a.q[i] + d / (a.n[i + 1] - a.n[i - 1]) * ((a.n[i] - a.n[i - 1] + d) * (a.q[i + 1] - a.q[i]) / (a.n[i + 1] - a.n[i]) + (a.n[i + 1] - a.n[i] - d) * (a.q[i] - a.q[i - 1]) / (a.n[i] - a.n[i - 1]));
END;
'
language plpgsql;
create or replace function _stats_agg_p2_linear(_stats_agg_accum_type, double precision, double precision)
returns double precision AS '
DECLARE
a alias for $1;
i alias for $2;
d alias for $3;
BEGIN
return a.q[i] + d * (a.q[i + d] - a.q[i]) / (a.n[i + d] - a.n[i]);
END;
'
language plpgsql;
create or replace function _stats_agg_accumulator(_stats_agg_accum_type, double precision)
returns _stats_agg_accum_type AS '
DECLARE
a ALIAS FOR $1;
x alias for $2;
k int;
d double precision;
qp double precision;
BEGIN
a.cnt = a.cnt + 1;
if a.cnt <= 5 then
a.q = array_append(a.q, x);
if a.cnt = 5 then
a.q = array_sort(a.q);
end if;
return a;
end if;
case
when x < a.q[1] then
a.q[1] = x;
k = 1;
when x >= a.q[1] and x < a.q[2] then
k = 1;
when x >= a.q[2] and x < a.q[3] then
k = 2;
when x >= a.q[3] and x < a.q[4] then
k = 3;
when x >= a.q[4] and x <= a.q[5] then
k = 4;
when x > a.q[5] then
a.q[5] = x;
k = 4;
end case;
for ii in 1..5 loop
if ii > k then
a.n[ii] = a.n[ii] + 1;
end if;
a.np[ii] = a.np[ii] + a.dn[ii];
end loop;
for ii in 2..4 loop
d = a.np[ii] - a.n[ii];
if (d >= 1 and a.n[ii+1] - a.n[ii] > 1) or (d <= -1 and a.n[ii-1] - a.n[ii] < -1) then
d = sign(d);
qp = _stats_agg_p2_parabolic(a, ii, d);
if qp > a.q[ii-1] and qp < a.q[ii+1] then
a.q[ii] = qp;
else
a.q[ii] = _stats_agg_p2_linear(a, ii, d);
end if;
a.n[ii] = a.n[ii] + d;
end if;
end loop;
return a;
END;
'
language plpgsql;
create or replace function _stats_agg_combiner(_stats_agg_accum_type, _stats_agg_accum_type)
returns _stats_agg_accum_type AS '
DECLARE
a alias for $1;
b alias for $2;
c _stats_agg_accum_type;
BEGIN
c.cnt = a.cnt + b.cnt;
c.q[2] = (a.q[2] + b.q[2]) / 2;
c.q[3] = (a.q[3] + b.q[3]) / 2;
c.q[4] = (a.q[4] + b.q[4]) / 2;
RETURN c;
END;
'
strict language plpgsql;
create or replace function _stats_agg_finalizer(_stats_agg_accum_type)
returns _stats_agg_result_type AS '
BEGIN
RETURN row(
$1.cnt,
$1.q[2],
$1.q[3],
$1.q[4]
);
END;
'
language plpgsql;
create aggregate stats_agg(double precision) (
sfunc = _stats_agg_accumulator,
stype = _stats_agg_accum_type,
finalfunc = _stats_agg_finalizer,
combinefunc = _stats_agg_combiner,
--parallel = safe,
initcond = '(0, {}, "{1,2,3,4,5}", "{1,2,3,4,5}", "{0,0.25,0.5,0.75,1}")'
);
Here's the setup and run code:
--CREATE TABLE temp (val double precision);
--insert into temp (val) select i from generate_series(0, 150000) as t(i);
select (stats_agg(val)).* from temp;
The expected result as follows and it works when run in parallel = unsafe
150001, 37500, 75000, 112500
In parallel = safe I get nulls:
150001, null, null, null
The problem is in the _stats_agg_combiner function. The function definition includes the strict keyword so there is no need to check for null input values.
In this specific aggregate, the _stats_agg_accum_type includes multiple arrays and the _stats_agg_combiner function requires that these arrays be filled with a minimum of 5 entries. This assumes that each new _stats_agg_accum_type instance processes at a minimum 5 records before being passed to the _stats_agg_combiner function.
Tests were being done on a table with 150k records and an assumption that each instance would therefore receive at a minimum 5 records. For whatever reason, this is an incorrect assumption. Regardless of the number of workers used (tested with 1-4) there is always at least one instance which processed exactly 0 records.
The solution was to add support for a _stats_agg_accum_type instance that had processed zero records and this had an array length of 0. See code below.
create or replace function _stats_agg_combiner(_stats_agg_accum_type, _stats_agg_accum_type)
returns _stats_agg_accum_type AS '
DECLARE
a alias for $1;
b alias for $2;
c _stats_agg_accum_type;
addA boolean;
addB boolean;
BEGIN
addA = a.cnt <= 5;
addB = b.cnt <= 5;
if addA and not addB then
c = b;
elsif addB and not addA then
c = a;
else
c.cnt = a.cnt + b.cnt;
for ii in 2..4 loop
c.q[ii] = (a.q[ii] + b.q[ii]) / 2;
end loop;
end if;
for ii in 1..5 loop
if addA and ii <= a.cnt then
c = _stats_agg_accumulator(c, a.q[ii]);
end if;
if addB and ii <= b.cnt then
c = _stats_agg_accumulator(c, b.q[ii]);
end if;
end loop;
RETURN c;
END;
'
language plpgsql strict;
I'm implementing RSA encryption and need to generate random 1024-bit primes.
I can't use INTEGER signals because of the limit, and so I'm using STD_LOGIC_VECTOR and convert it to UNSIGNED when I need to perform arithmetic operations.
I began by using UNIFORM to generate 32 random 32-bit numbers which I then copy over into a 1024-bit STD_LOGIC_VECTOR.
I then set the most significant and least significant bits to '1' to ensure it is 1024-bits and odd.
I then check for primality using an implementation of the Miller Rabin algorithm, which is where my problem lies.
This is where I generate the random primes:
function GEN_1024_PRIME return STD_LOGIC_VECTOR is
VARIABLE s1, s2 : POSITIVE;
VARIABLE random : REAL;
VARIABLE small_random : STD_LOGIC_VECTOR (31 downto 0);
VARIABLE large_random : STD_LOGIC_VECTOR (1023 downto 0);
VARIABLE prime : STD_LOGIC := '0';
begin
while prime /= '1' loop
for I in 0 to 31 loop
UNIFORM(s1, s2, random);
small_random := STD_LOGIC_VECTOR(to_unsigned(INTEGER(TRUNC(random * REAL(2147483647))), 32));
large_random (I*32 + 31 downto I*32) := small_random;
end loop;
large_random(0) := '1';
large_random(1023) := '1';
prime := MILLER_RABIN (large_random);
end loop;
return large_random;
end function;
And my implementation of Miller Rabin:
function MILLER_RABIN (prime : STD_LOGIC_VECTOR (1023 downto 0)) return STD_LOGIC is
VARIABLE t : INTEGER := 4;
VARIABLE temp, r, a, x, j, n: UNSIGNED (1023 downto 0);
VARIABLE small_random : UNSIGNED (31 downto 0);
VARIABLE large_random : UNSIGNED (1023 downto 0);
VARIABLE s1, s2 : POSITIVE;
VARIABLE random : REAL;
begin
n := UNSIGNED(prime);
if n MOD 2 = 0 OR n MOD 3 = 0 then
return '0';
else
-- calculate n - 1 = 2^s * r such that r is odd
r := n - 1;
while r MOD 2 = 0 loop
r := r / 2;
end loop;
for I in 1 to t loop
-- choose random a, 2 <= a <= n-2
for I in 0 to 31 loop
UNIFORM(s1, s2, random);
small_random := to_unsigned(INTEGER(TRUNC(random * REAL(2147483647))), 32);
large_random (I*32 + 31 downto I*32) := small_random;
end loop;
a := large_random;
temp := r;
x := MOD_3(a, temp, n);
while (temp /= (n - 1) AND x /= 1 AND x /= (n - 1)) loop
x := (x * x) MOD n;
temp := temp * 2;
end loop;
if x /= (n - 1) AND temp MOD 2 = 0 then
return '0';
end if;
end loop;
return '1';
end if;
end function;
function MOD_3 (a, b, c : UNSIGNED (1023 downto 0)) return UNSIGNED is
VARIABLE x : UNSIGNED (1023 downto 0) := TO_UNSIGNED(1, 1024);
VARIABLE y : UNSIGNED (1023 downto 0) := a;
VARIABLE b_temp : UNSIGNED (1023 downto 0) := b;
begin
while b_temp > 0 loop
if b_temp MOD 2 = 1 then
x := (x * y) MOD c;
end if;
y := (y * y) MOD c;
b_temp := b_temp / 2;
end loop;
return x MOD c;
end function;
I convert the input to UNSIGNED in order to perform arithmetic operations, which seemed like it would work until I realized there will be instances in which the product of 2 values will be larger than 1024 bits. For example, in this while loop:
while (temp /= (n - 1) AND x /= 1 AND x /= (n - 1)) loop
x := (x * x) MOD n;
temp := temp * 2;
end loop;
The resultant of temp := temp * 2; is 2048 bits.
I feel like I could get this to work by messing around with the sizes of my UNSIGNED variables, but I think it is getting messier than it needs to be, so I'm wondering if I am approaching this the wrong way? Is there a simpler way to generate 1024-bit primes? Is there another primality test that would be better suited for my problem?