Apply a digital filter (direct form II transposed): Difference between revisions

m
m (syntax highlighting fixup automation)
m (→‎{{header|Wren}}: Minor tidy)
 
(7 intermediate revisions by 6 users not shown)
Line 8:
 
The signal that needs filtering is the following vector: [-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973, -1.00700480494, -0.404707073677 ,0.800482325044, 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589]
 
;See also:
[[https://en.wikipedia.org/wiki/Butterworth_filter Wikipedia on Butterworth filters]]
 
 
=={{header|11l}}==
{{trans|Nim}}
 
<syntaxhighlight lang="11l">F apply_filter(a, b, signal)
V result = [0.0] * signal.len
L(i) 0 .< signal.len
Line 47 ⟶ 51:
 
=={{header|Ada}}==
<syntaxhighlight lang=Ada"ada">with Ada.Text_IO;
 
procedure Apply_Filter is
Line 110 ⟶ 114:
=={{header|ALGOL 68}}==
{{Trans|C++}} ... via Yabasic<br>
... with the "j" loops transformed to not needlessly iterate beyond i.<br>
The default lower bound in Algol 68 arrays is 1, so the loops/subscripts have been adjusted accordingly.
<syntaxhighlight lang="algol68">BEGIN # apply a digital filter #
BEGIN # apply a digital filter #
# the lower bounds of a, b, signal and result must all be equal #
PROC filter = ( []REAL a, b, signal, REF[]REAL result )VOID:
IF LWB a /= LWB b OR LWB a /= LWB signal OR LWB a /= LWB result THEN
BEGIN
print( ( "Array lower bounds must be equal for filter", newline ) );
stop
BEGINELSE
FOR i FROM LWB result TO UPB result DO result[ i ] := 0 OD;
FOR i FROM LWB signal TO UPB signal DO
REAL tmp := 0;
FOR j FROM LWB b TO IF i > UPB b THEN UPB b ELSE i FI DO
IF i >= j THEN tmp +:= b[ j ] * signal[ LWB signal + ( i - j ) ] FI
OD;
FOR j FROM LWB a + 1 TO IF i > UPB a THEN UPB a ELSE i FI DO
IF i >= j THEN tmp -:= a[ j ] * result[ LWB result + ( i - j ) ] FI
OD;
result[ i ] := tmp / a[ LWB a ]
OD
ENDFI # filter # ;
[ 4 ]REAL a := []REAL( 1, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17 );
[ 4 ]REAL b := []REAL( 0.16666667, 0.5, 0.5, 0.16666667 );
Line 141 ⟶ 151:
IF i MOD 5 /= 0 THEN print( ( ", " ) ) ELSE print( ( newline ) ) FI
OD
END
END</syntaxhighlight>
{{out}}
<pre>
Line 149 ⟶ 160:
-0.211722, -0.174746, 0.069258, 0.385446, 0.651771
</pre>
 
=={{header|AppleScript}}==
{{trans|Julia}} — except that j starts from 2 in the second inner repeat, there being no point in fetching and performing math with the zero about to be overwritten. This change in turn allows the result list to be populated on the fly instead of being pre-populated with zeros.
<syntaxhighlight lang="applescript">on min(a, b)
if (b < a) then return b
return a
Line 188 ⟶ 200:
 
{{output}}
<syntaxhighlight lang="applescript">{-0.1529739895, -0.43525782905, -0.136043396988, 0.697503326548, 0.656444692469, -0.435482453256, -1.089239461153, -0.537676549563, 0.517049992313, 1.052249747155, 0.961854300374, 0.69569009401, 0.424356295096, 0.196262231822, -0.027835124463, -0.21172191545, -0.174745562223, 0.069258408901, 0.385445874308, 0.651770838819}</syntaxhighlight>
 
=={{header|C}}==
Given the number of values a coefficient or signal vector can have and the number of digits, this implementation reads data from a file and prints it to the console if no output file is specified or writes to the specified output file. Usage printed on incorrect invocation.
<syntaxhighlight lang=C"c">
#include<stdlib.h>
#include<string.h>
Line 325 ⟶ 337:
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">using System;
 
namespace ApplyDigitalFilter {
Line 377 ⟶ 389:
This uses the C++11 method of initializing vectors. In g++, use the -std=c++0x compiler switch.
 
<syntaxhighlight lang="cpp">#include <vector>
#include <iostream>
using namespace std;
Line 435 ⟶ 447:
=={{header|Common Lisp}}==
{{trans|zkl}}
<syntaxhighlight lang="lisp">(defparameter a #(1.00000000L0 -2.77555756L-16 3.33333333L-01 -1.85037171L-17))
(defparameter b #(0.16666667L0 0.50000000L0 0.50000000L0 0.16666667L0))
(defparameter s #(-0.917843918645 0.141984778794 1.20536903482 0.190286794412 -0.662370894973
Line 476 ⟶ 488:
=={{header|D}}==
{{trans|Kotlin}}
<syntaxhighlight lang=D"d">import std.stdio;
 
alias T = real;
Line 532 ⟶ 544:
=={{header|FreeBASIC}}==
{{trans|Yabasic}}
<syntaxhighlight lang="freebasic">Sub Filtro(a() As Double, b() As Double, senal() As Double, resultado() As Double)
Dim As Integer j, k
Dim As Double tmp
Line 589 ⟶ 601:
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import "fmt"
Line 666 ⟶ 678:
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">class DigitalFilter {
private static double[] filter(double[] a, double[] b, double[] signal) {
double[] result = new double[signal.length]
Line 711 ⟶ 723:
=={{header|Haskell}}==
The solution is based not on the explicit loops, as in strict imperative languages, but on lazy recursive trick known as "tying a knot".
<syntaxhighlight lang=Haskell"haskell">import Data.List (tails)
 
-- lazy convolution of a list by given kernel
Line 753 ⟶ 765:
There's probably a nicer way to do this:
 
<syntaxhighlight lang=J"j">Butter=: {{
t=. (#n) +/ .*&(|.n)\(}.n*0),y
A=.|.}.m
Line 784 ⟶ 796:
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang=Java"java">public class DigitalFilter {
private static double[] filter(double[] a, double[] b, double[] signal) {
double[] result = new double[signal.length];
Line 830 ⟶ 842:
=={{header|Julia}}==
{{trans|zkl}}
<syntaxhighlight lang="julia">function DF2TFilter(a::Vector, b::Vector, sig::Vector)
rst = zeros(sig)
for i in eachindex(sig)
Line 852 ⟶ 864:
=={{header|Kotlin}}==
{{trans|C++}}
<syntaxhighlight lang="scala">// version 1.1.3
 
fun filter(a: DoubleArray, b: DoubleArray, signal: DoubleArray): DoubleArray {
Line 901 ⟶ 913:
=={{header|Lua}}==
{{trans|C++}}
<syntaxhighlight lang="lua">function filter(b,a,input)
local out = {}
for i=1,table.getn(input) do
Line 956 ⟶ 968:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica"mathematica">b = {0.16666667, 0.5, 0.5, 0.16666667};
a = {1.00000000, -2.77555756*^-16, 3.33333333*^-01, -1.85037171*^-17};
signal = {-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973, -1.00700480494, -0.404707073677, 0.800482325044, 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589};
Line 965 ⟶ 977:
=={{header|MATLAB}}==
MATLAB is commonly used for filter design and implementation. To implement this filter, and display the original signal and the filtered result:
<syntaxhighlight lang=MATLAB"matlab">
signal = [-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973, -1.00700480494, -0.404707073677 ,0.800482325044, 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589];
a = [1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17];
Line 999 ⟶ 1,011:
=={{header|Nim}}==
{{trans|Kotlin}}
<syntaxhighlight lang=Nim"nim">
import strformat
 
Line 1,039 ⟶ 1,051:
=={{header|Objeck}}==
{{trans|Java}}
<syntaxhighlight lang="objeck">class DigitalFilter {
function : Main(args : String[]) ~ Nil {
a := [1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17];
Line 1,090 ⟶ 1,102:
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">/* REXX */
a=.array~of(1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17)
b=.array~of(0.16666667, 0.5, 0.5, 0.16666667)
Line 1,151 ⟶ 1,163:
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl">use strict;
use List::AllUtils 'natatime';
 
Line 1,193 ⟶ 1,205:
Note however that the a[j]* starts from index 2, unlike Julia/C/Raku/Rust/Sidef/zkl,
but the same as C++/C#/D/Java/Kotlin - and it does not seem to make any difference...
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">direct_form_II_transposed_filter</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">signal</span><span style="color: #0000FF;">)</span>
Line 1,223 ⟶ 1,235:
=={{header|Phixmonti}}==
{{trans|Phix}}
<syntaxhighlight lang=Phixmonti"phixmonti">include ..\Utilitys.pmt
 
( 1.00000000 -2.77555756e-16 3.33333333e-01 -1.85037171e-17 ) var a
Line 1,254 ⟶ 1,266:
=={{header|Python}}==
 
<syntaxhighlight lang="python">#!/bin/python
from __future__ import print_function
from scipy import signal
Line 1,287 ⟶ 1,299:
{{trans|C}} Strangely, C was more informative than Common Lisp in helping figure out what was going on here.
 
<syntaxhighlight lang="racket">#lang racket
 
(define a (vector 1.00000000E0 -2.77555756E-16 3.33333333E-01 -1.85037171E-17))
Line 1,338 ⟶ 1,350:
{{trans|zkl}}
 
<syntaxhighlight lang=perl6"raku" line>sub TDF-II-filter ( @signal, @a, @b ) {
my @out = 0 xx @signal;
for ^@signal -> $i {
Line 1,371 ⟶ 1,383:
===version 1===
{{trans|Julia}}
<syntaxhighlight lang=REXX"rexx">/*REXX pgm filters a signal with a order3 lowpass Butterworth, direct form II transposed*/
@a= '1 -2.77555756e-16 3.33333333e-1 -1.85037171e-17' /*filter coefficients*/
@b= 0.16666667 0.5 0.5 0.16666667 /* " " */
Line 1,413 ⟶ 1,425:
===version 2===
{{trans|Julia}}
<syntaxhighlight lang=REXX"rexx">/* REXX */
Numeric Digits 24
acoef = '1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17'
Line 1,467 ⟶ 1,479:
20 0.651770838819
</pre>
 
=={{header|RPL}}==
We use here useful list handling functions that are available from HP48G or newer models.
{| class="wikitable"
! RPL code
! Comment
|-
|
ROT REVLIST ROT REVLIST → signal a b
≪ { } 1 signal SIZE '''FOR''' j
signal j b SIZE - 1 + j SUB
'''WHILE''' DUP SIZE b SIZE < '''REPEAT''' 0 SWAP + '''END'''
b * ∑LIST
OVER j a SIZE - 1 + j 1 - SUB 0 +
'''WHILE''' DUP SIZE a SIZE < '''REPEAT''' 0 SWAP + '''END'''
a * ∑LIST -
a DUP SIZE GET / +
'''NEXT'''
≫ ≫ '<span style="color:blue">'''FILTR'''</span>' STO
|
<span style="color:blue">'''FILTR'''</span> ''( {a} {b} {signal} → {filtered} ) ''
Reverse a and b
For j = 1 to last signal item
extract what to multiply to b
prepend 0's if necessary
multiply by b and sum
extract what to multiply by a except a[0]
prepend 0's if necessary
multiply by a, sum and substract
divide by a[0] which is the last item once a reversed
|}
Figures have been rounded to 3 digits after the decimal point to ease the 100% manual data transfer.
{ 1 -2.778E-16 0.3333 -1.851E-17 }
{ 0.1667 0.5 0.5 0.1667}
{ -0.9178 0.1420 1.2054 0.1903 -0.6624
-1.007 -0.4047 0.8005 0.7435 1.0109
0.7415 0.2778 0.4008 -0.2086 -0.17281 -
-0.1343 0.02593 0.4901 0.5494 0.90472 }
<span style="color:blue">'''FILTR'''</span> 3 RND
'''Output:'''
<span style="color:grey"> 1:</span> { -.153 -.435 -.136 .697 .656
-.436 -1.089 -.538 .517 1.052
.962 .696 .425 .196 .028
-.212 -.175 .069 .386 .652 }
 
=={{header|Ruby}}==
{{trans|C#}}
<syntaxhighlight lang="ruby">def filter(a,b,signal)
result = Array.new(signal.length(), 0.0)
for i in 0..signal.length()-1 do
Line 1,519 ⟶ 1,578:
=={{header|Rust}}==
{{trans|Java}}
<syntaxhighlight lang=Rust"rust">use std::cmp::Ordering;
 
struct IIRFilter<'f>(&'f [f32], &'f [f32]);
Line 1,636 ⟶ 1,695:
{{libheader|Scastie qualified}}
{{works with|Scala|2.13}}
<syntaxhighlight lang=Scala"scala">object ButterworthFilter extends App {
private def filter(a: Vector[Double],
b: Vector[Double],
Line 1,675 ⟶ 1,734:
=={{header|Sidef}}==
{{trans|Raku}}
<syntaxhighlight lang="ruby">func TDF_II_filter(signal, a, b) {
var out = [0]*signal.len
for i in ^signal {
Line 1,712 ⟶ 1,771:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Module Module1
 
Function Filter(a As Double(), b As Double(), signal As Double()) As Double()
Line 1,762 ⟶ 1,821:
-0.21172192, -0.17474556, 0.06925841, 0.38544587, 0.65177084</pre>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">struct Filter {
b []f64
a []f64
Line 1,840 ⟶ 1,899:
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang=ecmascript"wren">import "./fmt" for Fmt
 
var filter = Fn.new { |a, b, signal|
Line 1,877 ⟶ 1,936:
}</syntaxhighlight>
 
{{out}}
<pre>
-0.15297399, -0.43525783, -0.13604340, 0.69750333, 0.65644469
-0.43548245, -1.08923946, -0.53767655, 0.51704999, 1.05224975
0.96185430, 0.69569009, 0.42435630, 0.19626223, -0.02783512
-0.21172192, -0.17474556, 0.06925841, 0.38544587, 0.65177084
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">real A, B, Signal, Temp, Result(20);
int I, J;
[A:= [1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17];
B:= [0.16666667, 0.5, 0.5, 0.16666667];
Signal:= [
-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412,
-0.662370894973, -1.00700480494, -0.404707073677, 0.800482325044,
0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195,
0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293,
0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589 ];
Format(2, 8);
for I:= 0 to 20-1 do
[Temp:= 0.;
for J:= 0 to 4-1 do
if I-J >= 0 then
Temp:= Temp + B(J)*Signal(I-J);
for J:= 1 to 4-1 do
if I-J >= 0 then
Temp:= Temp - A(J)*Result(I-J);
Result(I):= Temp / A(0);
RlOut(0, Result(I));
Text(0, if rem(I/5) = 4 then "^m^j" else ", ");
];
]</syntaxhighlight>
{{out}}
<pre>
Line 1,887 ⟶ 1,979:
=={{header|Yabasic}}==
{{trans|D}}
<syntaxhighlight lang=Yabasic"yabasic">sub filter(a(), b(), signal(), result())
local i, j, tmp
Line 1,935 ⟶ 2,027:
=={{header|zkl}}==
{{trans|C++}}
<syntaxhighlight lang="zkl">fcn direct_form_II_transposed_filter(b,a,signal){
out:=List.createLong(signal.len(),0.0); // vector of zeros
foreach i in (signal.len()){
Line 1,945 ⟶ 2,037:
out
}</syntaxhighlight>
<syntaxhighlight lang="zkl">signal:=T(-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412,
-0.662370894973,-1.00700480494, -0.404707073677, 0.800482325044,
0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195,
9,485

edits