Расчет следующего значения функции на базе квадратичной интерполяции
Материал из Модулярная арифметики
(Различия между версиями)
Turbo (обсуждение | вклад) (Новая страница: «Положим нам задана функция, которая принимает определенные значения через равные проме…») |
Turbo (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
Положим нам задана функция, которая принимает определенные значения через равные промежутки времени. То есть заданы точки вида: | Положим нам задана функция, которая принимает определенные значения через равные промежутки времени. То есть заданы точки вида: | ||
− | <math>(X_1, Y_1), (X_2, Y_2), (X_3, Y_3)</math>. Для простоты зададим равный промежуток равный единице. То есть точки будут иметь вид: <math>(0, Y_1), (1, Y_2), (2, Y_3)</math>. Нам требуется определить значение функции в точке <math>X= | + | <math>(X_1, Y_1), (X_2, Y_2), (X_3, Y_3)</math>. Для простоты зададим равный промежуток равный единице. То есть точки будут иметь вид: <math>(0, Y_1), (1, Y_2), (2, Y_3)</math>. Нам требуется определить значение функции в точке <math>X=3</math>. Воспользуемся формулой квадратичной интерполяции: |
− | <math></math> | + | <math>Y = \frac{(X-X_2)\cdot(X-X_3)}{(X_1-X_2)\cdot(X_1-X_3)}\cdot Y_1 + \frac{(X-X_1)\cdot(X-X_3)}{(X_2-X_1)\cdot(X_2-X_3)}\cdot Y_2 + \frac{(X-X_1)\cdot(X-X_2)}{(X_3-X_1)\cdot(X_3-X_2)}\cdot Y_3</math> |
+ | |||
+ | <math>Y = \frac{(X-1)\cdot(X-2)}{(0-1)\cdot(0-2)}\cdot Y_1 + \frac{(X-0)\cdot(X-2)}{(1-0)\cdot(1-2)}\cdot Y_2 + \frac{(X-0)\cdot(X-1)}{(2-0)\cdot(2-1)}\cdot Y_3</math> | ||
+ | |||
+ | <math>Y(X=3) = \frac{(3-1)\cdot(3-2)}{2}\cdot Y_1 + \frac{(3)\cdot(3-2)}{(-1)}\cdot Y_2 + \frac{(3-0)\cdot(3-1)}{2}\cdot Y_3 = Y_1 - 3\cdot Y_2 + 3\cdot Y_3</math> | ||
+ | |||
+ | == Реализация на Verilog == | ||
+ | * Синхронная схема, которая выдает интерполированное значение функции по трем предыдущим. | ||
+ | |||
+ | |||
+ | <source lang="verilog" line> | ||
+ | module interpolation(out, in, clk); | ||
+ | input clk; | ||
+ | input [7:0] in; | ||
+ | reg [7:0] storage[0:2]; | ||
+ | wire signed [10:0] data; | ||
+ | output reg [7:0] out; | ||
+ | |||
+ | initial storage[0] = 0; | ||
+ | initial storage[1] = 0; | ||
+ | initial storage[2] = 0; | ||
+ | |||
+ | assign data = storage[2] - 3*storage[1] + 3*storage[0]; | ||
+ | |||
+ | always @ (posedge clk) | ||
+ | begin | ||
+ | if (data < 0) | ||
+ | out = 0; | ||
+ | else if (data > 255) | ||
+ | out = 255; | ||
+ | else | ||
+ | out = $unsigned(data[7:0]); | ||
+ | |||
+ | storage[2] = storage[1]; | ||
+ | storage[1] = storage[0]; | ||
+ | storage[0] = in; | ||
+ | end | ||
+ | endmodule | ||
+ | |||
+ | module atest_bench(); | ||
+ | reg clk; | ||
+ | reg [7:0] in; | ||
+ | wire [7:0] out; | ||
+ | |||
+ | integer l, z, val1, val2, val3; | ||
+ | reg dummy; | ||
+ | integer i0, prev; | ||
+ | |||
+ | interpolation r1 (out, in, clk); | ||
+ | |||
+ | // One test. Ticks: 3 | ||
+ | initial | ||
+ | begin | ||
+ | val1 = 0; | ||
+ | val2 = 0; | ||
+ | val3 = 0; | ||
+ | for (z = 0; z < 100; z = z+1) | ||
+ | begin | ||
+ | prev = val3 - 3*val2 + 3*val1; | ||
+ | val3 = val2; | ||
+ | val2 = val1; | ||
+ | if (prev < 0) | ||
+ | begin | ||
+ | prev = 0; | ||
+ | end | ||
+ | else if (prev > 255) | ||
+ | begin | ||
+ | prev = 255; | ||
+ | end | ||
+ | |||
+ | val1 = $unsigned($random) % 256; | ||
+ | |||
+ | #1 dummy = 1; | ||
+ | clk = 0; | ||
+ | #1 dummy = 1; | ||
+ | in = val1; | ||
+ | #1 dummy = 1; | ||
+ | clk = 1; | ||
+ | #1 dummy = 1; | ||
+ | |||
+ | $display ("!!! Res=(%d) Expect=(%d) Data = [val1 = %d, val2 = %d, val3 = %d]", out, prev, val1, val2, val3); | ||
+ | l = out; | ||
+ | if (l != prev) | ||
+ | begin | ||
+ | $display ("!!! Error (%d, %d)!!!", prev, l); | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | endmodule | ||
+ | </source> |
Текущая версия на 15:24, 28 августа 2013
Положим нам задана функция, которая принимает определенные значения через равные промежутки времени. То есть заданы точки вида: . Для простоты зададим равный промежуток равный единице. То есть точки будут иметь вид: . Нам требуется определить значение функции в точке . Воспользуемся формулой квадратичной интерполяции:
[править] Реализация на Verilog
- Синхронная схема, которая выдает интерполированное значение функции по трем предыдущим.
module interpolation(out, in, clk);
input clk;
input [7:0] in;
reg [7:0] storage[0:2];
wire signed [10:0] data;
output reg [7:0] out;
initial storage[0] = 0;
initial storage[1] = 0;
initial storage[2] = 0;
assign data = storage[2] - 3*storage[1] + 3*storage[0];
always @ (posedge clk)
begin
if (data < 0)
out = 0;
else if (data > 255)
out = 255;
else
out = $unsigned(data[7:0]);
storage[2] = storage[1];
storage[1] = storage[0];
storage[0] = in;
end
endmodule
module atest_bench();
reg clk;
reg [7:0] in;
wire [7:0] out;
integer l, z, val1, val2, val3;
reg dummy;
integer i0, prev;
interpolation r1 (out, in, clk);
// One test. Ticks: 3
initial
begin
val1 = 0;
val2 = 0;
val3 = 0;
for (z = 0; z < 100; z = z+1)
begin
prev = val3 - 3*val2 + 3*val1;
val3 = val2;
val2 = val1;
if (prev < 0)
begin
prev = 0;
end
else if (prev > 255)
begin
prev = 255;
end
val1 = $unsigned($random) % 256;
#1 dummy = 1;
clk = 0;
#1 dummy = 1;
in = val1;
#1 dummy = 1;
clk = 1;
#1 dummy = 1;
$display ("!!! Res=(%d) Expect=(%d) Data = [val1 = %d, val2 = %d, val3 = %d]", out, prev, val1, val2, val3);
l = out;
if (l != prev)
begin
$display ("!!! Error (%d, %d)!!!", prev, l);
end
end
end
endmodule