сово зерно) з середньоквадратичним відхиленням = radius.
// Для поточного додатка ми встановлюємо змінні MaxData = 255,
// DataGranularity = 1. Тепер у процедурі встановимо значення
// K.Size так, що при використанні K ми будемо ігнорувати Weights (вага)
// з найменш можливими значеннями. (Малий розмір нам на користь,
// оскільки час виконання напряму залежить від
// значення K.Size.)
const
nmax = 3;
var
j: integer;
temp, delta: double;
KernelSize: TKernelSize;
xmm_n, xmm_r, xmm_a: TXMMSingle;
_low, _high, na: smallint;
begin
_low: = Low (K.Weights);
_high: = High (K.Weights);
j: = _low;
for na: = 0 to nmax do xmm_a [na]: = 2 ;//константа 2
for na: = 0 to nmax do xmm_r [na]: = radius ;//радіус
asm
push eax
push ebx
push ecx
push edx
movups xmm0, xmm_a// 2 в SSE
movups xmm1, xmm_r// радіус в SSE
end;
while (j <= _high) do begin
for na: = 0 to nmax do
if ((j + na) <= _high) then
xmm_n [na]: = j + na
else break;
// копіювання просте і передача не дає оптимізації в SSE
asm
movups xmm2, xmm_n// j
divps xmm2, xmm1// j/radius
movups xmm_n, xmm2
mulps xmm2, xmm2// temp ^ 2
movups xmm_n, xmm2
divps xmm2, xmm0// temp * temp/2
movups xmm_n, xmm2
end ;//asm
for na: = 0 to nmax do begin
if (j <= _high) then
K.Weights [j]: = exp (-xmm_n [na])
else break;
inc (j);
end ;//for
end ;//while
// отримали рядок ваг (зерна)
// робимо так, щоб sum (Weights) = 1:
temp: = 0;
for j: = Low (K.Weights) to High (K.Weights) do
temp: = temp + K.Weights [j] ;//все суміровалі
for j: = Low (K.Weights) to High (K.Weights) do
K.Weights [j]: = K.Weights [j]/temp ;//ділимо кожне на суму (Нормування)
for na: = 0 to nmax do xmm_n [na]: = temp;
asm
movups xmm0, xmm_n;
end;
j: = _low;
while (j <= _high) do begin
for na: = 0 to nmax do begin
if ((j + na) <= _high) then
xmm_n [na]: = K.Weights [j + na]
else break;
end ;//for
asm
movups xmm1, xmm_n
divps xmm1, xmm0// K.Weights [j]/temp
movups xmm_n, xmm1
end;
for na: = 0 to nmax do begin
if (j <= _high) then
K.Weights [j]: = xmm_n [na]
else break;
inc (j);
end;
end ;//while
// відкидаємо (або робимо відмітку "Ігнорувати"
// для змінної Size) дані, що мають відносно невелике значення -
// це важливо, в іншому випадку смазаваніе походимо з малим радіусом і
// тій області, яка "Захоплюється" великим радіусом ...
KernelSize: = MaxKernelSize;
delta: = DataGranularity/(2 * MaxData);
temp: = 0;
while (temp 1) do
begin
temp: = temp + 2 * K.Weights [KernelSize];
dec (KernelSize);
end ;//вирівнювання
K.Size: = KernelSize;
// для коректності повертається результату проводимо ту ж
// операцію з K.Size, так, щоб сума всіх даних була дорівнює одиниці:
temp: = 0;
for j: =-K.Size to K.Size do
temp: = temp + K.Weights [j];
for na: = 0 to nmax do xmm_n [na]: = temp;
asm
movups xmm0, xmm_n;
end;
j: = _low;
while (j <= _high) do begin
for na: = 0 to nmax do begin
if ((j + na) <= _high) then
xmm_n [na]: = K.Weights [j + na]
else break;
end ;//for
asm
movups xmm1, xmm_n
divps xmm1, xmm0// K.Weights [j]/temp
movups xmm_n, xmm1
end;
for na: = 0 to nmax do begin
if (j <= _high) then
K.Weights [j]: = xmm_n [na]
else break;
inc (j);
end;
end ;//while
asm
pop edx
pop ecx
pop ebx
pop eax
end;
end;
// TrimInt - округлення по вказаним кордонів Integer
function TrimInt (Lower, Upper, theInteger: integer): integer;
begin
if (theInteger <= Upper) and (theInteger> = Lower) then
result: = theInteger
else if theInteger> Upper then
result: = Upper
else
result: = Lower;
end;
// TrimReal - округлення за вказаними рамкам Real
function TrimReal (Lower, Upper: integer; x: double): integer;
begin
if (x = Lower) then
result: = trunc (x)
else if x> Upper then
result: = Upper
else
result: = Lower;
end;
// Blu...