code 34502;
procedure BOUNDS(N,A,RE,IM,RELE,ABSE,RECENTRE,IMCENTRE,BOUND);
value N, RELE, ABSE; integer N; real RELE, ABSE;
array RE, IM, A, RECENTRE, IMCENTRE, BOUND;
begin integer I, J, K, L, INDEX1, INDEX2; boolean GOON;
real H, MIN, RECENT, IMCENT, GIA, XK, YK, ZK, CORR;
array RC, C, RCE[0:N], CLUST[1:N];
real procedure G(RAD, RECENT, IMCENT, K, M);
value RAD, RECENT, IMCENT, K, M; real RAD, RECENT, IMCENT;
integer K, M;
begin real S, H1, H2; integer I;
S:= SQRT(RECENT * RECENT + IMCENT * IMCENT) + RAD;
H1:= RC[1]; H2:= RC[0];
for I:= 2 step 1 until N do H1:= H1*S + RC[I];
for I:= 1 step 1 until M-1, M+K step 1 until N do
H2:= H2 * ABS(SQRT((RE[I]-RECENT)**2 + (IM[I]-IMCENT)**2) - RAD);
G:= if H1=0 then 0 else if H2=0 then -10 else H1 / H2
end;
procedure KCLUSTER(K, M);
value K, M; integer K, M;
begin integer I, J, STOP, L; boolean NONZERO;
real RECENT, IMCENT, D, PROD, RAD, GR, R;
array DIST[M: M+K-1];
RECENT:= RE[M]; IMCENT:= IM[M]; STOP:= M+K-1;
L:= SIGN(IMCENT); NONZERO:= L ^= 0;
for I:= M+1 step 1 until STOP do
begin RECENT:= RECENT+RE[I];
if NONZERO then
begin NONZERO:= L = SIGN(IM[I]); IMCENT:= IMCENT+IM[I] end
end;
RECENT:= RECENT/K; IMCENT:= if NONZERO then IMCENT/K else 0;
D:= 0; RAD:= 0;
for I:= M step 1 until STOP do
begin RECENTRE[I]:= RECENT; IMCENTRE[I]:= IMCENT;
DIST[I]:= SQRT((RE[I] -RECENT)**2 + (IM[I]-IMCENT)**2);
if D < DIST[I] then D:= DIST[I]
end;
GR:= ABS(G(0, RECENT, IMCENT, K, M));
if GR > 0 then
begin for J:= 1, 1 while PROD <= GR do
begin R:= RAD; RAD:= D + EXP(LN(1.1*GR)/K);
if RAD = R then RAD:= EXP(LN(1.1)/K) * RAD;
GR:= G(RAD, RECENT, IMCENT, K, M);
PROD:= 1;
for I:= M step 1 until STOP do
PROD:= PROD*(RAD-DIST[I])
end
end;
for I:= M step 1 until STOP do
begin BOUND[I]:= RAD; CLUST[I]:= K end;
procedure SHIFT(INDEX, NEW);
value INDEX, NEW; integer INDEX, NEW;
begin integer J, PLACE, CLUSTIN;
real BOUNDIN, IMCENT, RECENT;
real array WA1, WA2[1:CLUST[INDEX]];
CLUSTIN:= CLUST[INDEX]; BOUNDIN:= BOUND[INDEX];
IMCENT:= IMCENTRE[INDEX]; RECENT:= RECENTRE[INDEX];
for J:= 1 step 1 until CLUSTIN do
begin PLACE:=INDEX+J-1; WA1[J]:= RE[PLACE]; WA2[J]:= IM[PLACE];
end;
for J:= INDEX-1 step -1 until NEW do
begin PLACE:= J+CLUSTIN;
RE[PLACE]:= RE[J]; IM[PLACE]:= IM[J]; CLUST[PLACE]:= CLUST[J];
BOUND[PLACE]:= BOUND[J]; RECENTRE[PLACE]:= RECENTRE[J];
IMCENTRE[PLACE]:= IMCENTRE[J]
end;
for J:= NEW+CLUSTIN-1 step -1 until NEW do
begin PLACE:= J+1-NEW;
RE[J]:= WA1[PLACE]; IM[J]:= WA2[PLACE];
BOUND[J]:= BOUNDIN; CLUST[J]:= CLUSTIN;
RECENTRE[J]:= RECENT; IMCENTRE[J]:= IMCENT
end
end;
GIA:= GIANT;
RC[0]:= C[0]:= A[N]; RCE[0]:= ABS(C[0]); K:= 0;
for I:= 1 step 1 until N do
begin RC[I]:= RCE[I]:= 0 ; C[I]:= A[N-I] end;
for I:= 0 while K < N do
begin K:= K+1; XK:= RE[K]; YK:= IM[K]; ZK:= XK*XK+YK*YK;
for J:= K step -1 until 1 do
RCE[J]:= RCE[J]+RCE[J-1]*SQRT(ZK);
if YK = 0 then
begin for J:= K step -1 until 1 do
RC[J]:= RC[J]-XK*RC[J-1]
end else
begin K:= K+1;
if K <= N & XK = RE[K] & YK = -IM[K] then
begin XK:= -2*XK;
for J:= K step -1 until 1 do
RCE[J]:= RCE[J]+RCE[J-1]*SQRT(ZK);
for J:= K step -1 until 2 do
RC[J]:= RC[J]+XK*RC[J-1]+ZK*RC[J-2];
RC[1]:= RC[1]+XK*RC[0]
end
end
end;
RC[0]:= RCE[0]; CORR:= 1.06*ARREB;
for I:= 1 step 1 until N-1 do
RC[I]:= ABS(RC[I]-C[I])+RCE[I]*CORR*(N+I-2)+RELE*ABS(C[I])+ABSE;
RC[N]:= ABS(RC[N]-C[N])+RCE[N]*CORR*(N-1)+RELE*ABS(C[N])+ABSE;
for I:= 1 step 1 until N do KCLUSTER(1, I);
GOON:= true;
for L:= 1 while GOON do
begin INDEX1:= INDEX2:= 0; MIN:= GIANT; I:= N-CLUST[N]+1;
for I:= I while I >= 2 do
begin J:= I; RECENT:= RECENTRE[I]; IMCENT:= IMCENTRE[I];
for J:= J while J >= 2 do
begin J:= J-CLUST[J-1];
H:= SQRT((RECENT-RECENTRE[J])**2 + (IMCENT-IMCENTRE[J])**2);
if H < BOUND[I] + BOUND[J] & H <= MIN then
begin INDEX1:= J; INDEX2:= I; MIN:= H end
end; I:= I-CLUST[I-1]
end;
if INDEX1 = 0 then GOON:= false else
begin if IMCENTRE[INDEX1] = 0 then
begin if IMCENTRE[INDEX2] ^= 0 then
CLUST[INDEX2]:= 2*CLUST[INDEX2]
end else if IMCENTRE[INDEX2] = 0 then
CLUST[INDEX1]:= 2*CLUST[INDEX1];
K:= INDEX1+CLUST[INDEX1];
if K ^= INDEX2 then SHIFT(INDEX2, K);
K:= CLUST[INDEX1]+CLUST[K];
KCLUSTER(K, INDEX1)
end
end
end;
eop