Skip to content

Commit 3f764f9

Browse files
ADD: convolve
1 parent 7627a38 commit 3f764f9

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

data_control/Vectormath/testcase1.pas

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@
6666
Procedure LoadFromSaveToStream;
6767
End;
6868

69+
{ TOtherTests }
70+
71+
TOtherTests = Class(TTestCase)
72+
protected
73+
published
74+
Procedure Convolve1D;
75+
Procedure ConvolveAVG;
76+
End;
77+
6978
Implementation
7079

7180
{ TMatrix4x4Tests }
@@ -421,6 +430,47 @@
421430
m.free;
422431
End;
423432

433+
{ TOtherTests }
434+
435+
Procedure TOtherTests.Convolve1D;
436+
Var
437+
a, b, c: TVectorN;
438+
Begin
439+
(*
440+
* Falten mit "nicht symmetrischem" filter kern
441+
*)
442+
a := VN([1, 2, 3]);
443+
b := VN([4, 5, 6]);
444+
c := Convolve(a, b);
445+
AssertEquals('Invalid len', 5, length(c));
446+
AssertEquals('Invalid result [0]', 4, c[0]);
447+
AssertEquals('Invalid result [1]', 13, c[1]);
448+
AssertEquals('Invalid result [2]', 28, c[2]);
449+
AssertEquals('Invalid result [3]', 27, c[3]);
450+
AssertEquals('Invalid result [4]', 18, c[4]);
451+
End;
452+
453+
Procedure TOtherTests.ConvolveAVG;
454+
Var
455+
a, b, c: TVectorN;
456+
Begin
457+
(*
458+
* Faltung als Mittelwert filter
459+
*)
460+
a := vn([0, 0, 10, 10, 10, 0, 0]);
461+
b := vn([0.5, 0.5]);
462+
c := Convolve(a, b);
463+
AssertEquals('Invalid len', 8, length(c));
464+
AssertEquals('Invalid result [0]', 0, c[0]);
465+
AssertEquals('Invalid result [1]', 0, c[1]);
466+
AssertEquals('Invalid result [2]', 5, c[2]);
467+
AssertEquals('Invalid result [3]', 10, c[3]);
468+
AssertEquals('Invalid result [4]', 10, c[4]);
469+
AssertEquals('Invalid result [5]', 5, c[5]);
470+
AssertEquals('Invalid result [6]', 0, c[6]);
471+
AssertEquals('Invalid result [7]', 0, c[7]);
472+
End;
473+
424474
Initialization
425475
Randomize;
426476
DefaultFormatSettings.DecimalSeparator := '.';
@@ -429,5 +479,7 @@
429479
RegisterTest(TMatrix3x3Tests);
430480
RegisterTest(TMatrix4x4Tests);
431481
RegisterTest(TMatrixNxMTests);
482+
RegisterTest(TOtherTests);
483+
432484
End.
433485

data_control/uvectormath.pas

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(******************************************************************************)
22
(* uvectormat.pas 12.11.2014 *)
33
(* *)
4-
(* Version : 0.18 *)
4+
(* Version : 0.19 *)
55
(* *)
66
(* Author : Uwe Schächterle (Corpsman) *)
77
(* *)
@@ -60,6 +60,7 @@
6060
(* TMatrix3x3.getInverse, TMatrix2x2.getInverse *)
6161
(* InvertMatrix2 for TMatrix4x4, TMatrix2x2 *)
6262
(* 0.18 CalculatePlumbFootPoint *)
63+
(* 0.19 Convolve *)
6364
(* *)
6465
(******************************************************************************)
6566
Unit uvectormath;
@@ -580,6 +581,14 @@
580581
// Die Koeffizienten von a werden als Vector übergben
581582
Function CalculatePolynom(x: TBaseType; Const a: TVectorN): TBaseType;
582583

584+
// Faltet 2 Vectoren mit einander und gibt das Ergebnis zurück, Achtung,
585+
// hier wird die "ineffiziente" Quadratische Faltung verwendet,
586+
// also die Vectoren lieber nicht zu groß machen!
587+
// Es gibt auch noch die Variante, bei der man zuerst die beiden Vektoren
588+
// durch eine FFT jagt, dann komponentenweise multipliziert und dann wieder
589+
// zurück transformiert, das ist bei Großen Vektoren tatsächlich schneller (siehe hier: https://www.youtube.com/watch?v=KuXjwB4LzSA )
590+
Function Convolve(Const a, b: tvectorN): TVectorN;
591+
583592
Implementation
584593

585594
{$IFDEF UseOperandOverloading}
@@ -3302,6 +3311,21 @@
33023311
End;
33033312
End;
33043313

3314+
Function Convolve(Const a, b: tvectorN): TVectorN;
3315+
Var
3316+
i, j: Integer;
3317+
Begin
3318+
result := Nil;
3319+
setlength(result, length(a) + length(b) - 1);
3320+
For i := 0 To High(Result) Do Begin
3321+
Result[i] := 0;
3322+
For j := 0 To High(a) Do Begin
3323+
If (i - j >= 0) And (i - j <= High(b)) Then
3324+
Result[i] := Result[i] + a[j] * b[i - j];
3325+
End;
3326+
End;
3327+
End;
3328+
33053329
Function CalculateOrthoganlProjection(A, B, M: TVector2): TVector2;
33063330
Var
33073331
d_AB, d_M: TVector2;

0 commit comments

Comments
 (0)