Расчет следующего значения функции на базе квадратичной интерполяции

Материал из Модулярная арифметики
Перейти к: навигация, поиск

Положим нам задана функция, которая принимает определенные значения через равные промежутки времени. То есть заданы точки вида: (X_1, Y_1), (X_2, Y_2), (X_3, Y_3). Для простоты зададим равный промежуток равный единице. То есть точки будут иметь вид: (0, Y_1), (1, Y_2), (2, Y_3). Нам требуется определить значение функции в точке X=3. Воспользуемся формулой квадратичной интерполяции:

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

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

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

Реализация на Verilog

  • Синхронная схема, которая выдает интерполированное значение функции по трем предыдущим.


  1. module interpolation(out, in, clk);
  2. 	input clk;
  3. 	input [7:0] in;
  4. 	reg [7:0] storage[0:2];
  5. 	wire signed [10:0] data;
  6. 	output reg [7:0] out;
  7.  
  8. 	initial storage[0] = 0;
  9. 	initial storage[1] = 0;
  10. 	initial storage[2] = 0;
  11.  
  12. 	assign data = storage[2] - 3*storage[1] + 3*storage[0];
  13.  
  14. 	always @ (posedge clk) 
  15. 	begin 
  16. 		if (data < 0)
  17. 			out = 0;
  18. 		else if (data > 255)
  19. 			out = 255;
  20. 		else
  21. 			out = $unsigned(data[7:0]);
  22.  
  23. 		storage[2] = storage[1];
  24. 		storage[1] = storage[0];
  25. 		storage[0] = in;
  26. 	end
  27. endmodule
  28.  
  29. module atest_bench();
  30. 	reg clk;
  31. 	reg [7:0] in;
  32. 	wire [7:0] out;
  33.  
  34. 	integer l, z, val1, val2, val3;
  35. 	reg dummy;
  36. 	integer i0, prev;
  37.  
  38. 	interpolation r1 (out, in, clk);
  39.  
  40. 	// One test. Ticks: 3
  41. 	initial
  42. 	begin
  43. 		val1 = 0;
  44. 		val2 = 0;
  45. 		val3 = 0;
  46. 		for (z = 0; z < 100; z = z+1)
  47. 		begin
  48. 			prev = val3 - 3*val2 + 3*val1;
  49. 			val3 = val2;
  50. 			val2 = val1;
  51. 			if (prev < 0)
  52. 			begin
  53. 				prev = 0;
  54. 			end
  55. 			else if (prev > 255)
  56. 			begin
  57. 				prev = 255;
  58. 			end
  59.  
  60. 			val1 = $unsigned($random) % 256;
  61.  
  62. 			#1 dummy = 1;
  63. 			clk = 0;
  64. 			#1 dummy = 1;
  65. 			in = val1;
  66. 			#1 dummy = 1;
  67. 			clk = 1;
  68. 			#1 dummy = 1;
  69.  
  70. 			$display ("!!! Res=(%d) Expect=(%d) Data = [val1 = %d, val2 = %d, val3 = %d]", out, prev, val1, val2, val3);
  71. 			l = out;
  72. 			if (l != prev)
  73. 			begin
  74. 				$display ("!!! Error (%d, %d)!!!", prev, l);
  75. 			end
  76. 		end
  77. 	end
  78. endmodule