Deconvolution/1D: Difference between revisions
Content added Content deleted
SqrtNegInf (talk | contribs) m (→{{header|Raku}}: better sigil, consistent matrix notation, bells, whistles) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 82: | Line 82: | ||
=={{header|11l}}== |
=={{header|11l}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="11l">F deconv(g, f) |
||
V result = [0]*(g.len - f.len + 1) |
V result = [0]*(g.len - f.len + 1) |
||
L(&e) result |
L(&e) result |
||
Line 97: | Line 97: | ||
V g = [24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7] |
V g = [24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7] |
||
print(deconv(g, f)) |
print(deconv(g, f)) |
||
print(deconv(g, h))</ |
print(deconv(g, h))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 106: | Line 106: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
This is a translation of the '''D''' solution. |
This is a translation of the '''D''' solution. |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO; |
||
procedure Main is |
procedure Main is |
||
Line 159: | Line 159: | ||
print (deconv (g, h)); |
print (deconv (g, h)); |
||
end Main; |
end Main; |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{output}} |
{{output}} |
||
<pre> |
<pre> |
||
Line 171: | Line 171: | ||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
As several others, this is a translation of the '''D''' solution. |
As several others, this is a translation of the '''D''' solution. |
||
< |
<syntaxhighlight lang="bbcbasic"> *FLOAT 64 |
||
DIM h(5), f(15), g(20) |
DIM h(5), f(15), g(20) |
||
h() = -8,-9,-3,-1,-6,7 |
h() = -8,-9,-3,-1,-6,7 |
||
Line 208: | Line 208: | ||
a$ += STR$(a(i%)) + ", " |
a$ += STR$(a(i%)) + ", " |
||
NEXT |
NEXT |
||
= LEFT$(LEFT$(a$))</ |
= LEFT$(LEFT$(a$))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 217: | Line 217: | ||
=={{header|C}}== |
=={{header|C}}== |
||
Using [[FFT]]: |
Using [[FFT]]: |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <math.h> |
#include <math.h> |
||
Line 308: | Line 308: | ||
for (int i = 0; i < lh; i++) printf(" %g", h2[i]); |
for (int i = 0; i < lh; i++) printf(" %g", h2[i]); |
||
printf("\n"); |
printf("\n"); |
||
}</ |
}</syntaxhighlight> |
||
{{out}}<pre>f[] data is : -3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1 |
{{out}}<pre>f[] data is : -3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1 |
||
deconv(g, h): -3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1 |
deconv(g, h): -3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1 |
||
Line 317: | Line 317: | ||
Uses the routine (lsqr A b) from [[Multiple regression]] and (mtp A) from [[Matrix transposition]]. |
Uses the routine (lsqr A b) from [[Multiple regression]] and (mtp A) from [[Matrix transposition]]. |
||
< |
<syntaxhighlight lang="lisp">;; Assemble the mxn matrix A from the 2D row vector x. |
||
(defun make-conv-matrix (x m n) |
(defun make-conv-matrix (x m n) |
||
(let ((lx (cadr (array-dimensions x))) |
(let ((lx (cadr (array-dimensions x))) |
||
Line 338: | Line 338: | ||
(A (make-conv-matrix f lg lh))) |
(A (make-conv-matrix f lg lh))) |
||
(lsqr A (mtp g))))</ |
(lsqr A (mtp g))))</syntaxhighlight> |
||
Example: |
Example: |
||
< |
<syntaxhighlight lang="lisp">(setf f #2A((-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1))) |
||
(setf h #2A((-8 -9 -3 -1 -6 7))) |
(setf h #2A((-8 -9 -3 -1 -6 7))) |
||
(setf g #2A((24 75 71 -34 3 22 -45 23 245 25 52 25 -67 -96 96 31 55 36 29 -43 -7))) |
(setf g #2A((24 75 71 -34 3 22 -45 23 245 25 52 25 -67 -96 96 31 55 36 29 -43 -7))) |
||
Line 370: | Line 370: | ||
(-2.0000000000000004) |
(-2.0000000000000004) |
||
(-7.000000000000001) |
(-7.000000000000001) |
||
(-0.9999999999999994))</ |
(-0.9999999999999994))</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">T[] deconv(T)(in T[] g, in T[] f) pure nothrow { |
||
int flen = f.length; |
int flen = f.length; |
||
int glen = g.length; |
int glen = g.length; |
||
Line 395: | Line 395: | ||
writeln(deconv(g, f) == h, " ", deconv(g, f)); |
writeln(deconv(g, f) == h, " ", deconv(g, f)); |
||
writeln(deconv(g, h) == f, " ", deconv(g, h)); |
writeln(deconv(g, h) == f, " ", deconv(g, h)); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>true [-8, -9, -3, -1, -6, 7] |
<pre>true [-8, -9, -3, -1, -6, 7] |
||
Line 402: | Line 402: | ||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
This solution uses the LAPACK95 library. |
This solution uses the LAPACK95 library. |
||
< |
<syntaxhighlight lang="fortran"> |
||
! Build |
! Build |
||
! Windows: ifort /I "%IFORT_COMPILER11%\mkl\include\ia32" deconv1d.f90 "%IFORT_COMPILER11%\mkl\ia32\lib\*.lib" |
! Windows: ifort /I "%IFORT_COMPILER11%\mkl\include\ia32" deconv1d.f90 "%IFORT_COMPILER11%\mkl\ia32\lib\*.lib" |
||
Line 476: | Line 476: | ||
end program deconv |
end program deconv |
||
</syntaxhighlight> |
|||
</lang> |
|||
Results: |
Results: |
||
< |
<syntaxhighlight lang="fortran"> |
||
deconv(f, g) = -8, -9, -3, -1, -6, 7 |
deconv(f, g) = -8, -9, -3, -1, -6, 7 |
||
deconv(h, g) = -3, -6, -1, 8, -6, 3, -1, -9, -9, 3, -2, 5, 2, -2, -7, -1 |
deconv(h, g) = -3, -6, -1, 8, -6, 3, -1, -9, -9, 3, -2, 5, 2, -2, -7, -1 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 514: | Line 514: | ||
} |
} |
||
return h |
return h |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 524: | Line 524: | ||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 588: | Line 588: | ||
y[k], y[k+n/2] = y[k]+tf, y[k]-tf |
y[k], y[k+n/2] = y[k]+tf, y[k]-tf |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Some results have errors out in the last decimal place or so. Only one decimal place shown here to let results fit in 80 columns. |
Some results have errors out in the last decimal place or so. Only one decimal place shown here to let results fit in 80 columns. |
||
Line 598: | Line 598: | ||
</pre> |
</pre> |
||
'''Library gonum/mat:''' |
'''Library gonum/mat:''' |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 633: | Line 633: | ||
fmt.Printf("deconv(g, f) =\n%.1f\n\n", mat.Formatted(deconv(g, f))) |
fmt.Printf("deconv(g, f) =\n%.1f\n\n", mat.Formatted(deconv(g, f))) |
||
fmt.Printf("deconv(g, h) =\n%.1f\n", mat.Formatted(deconv(g, h))) |
fmt.Printf("deconv(g, h) =\n%.1f\n", mat.Formatted(deconv(g, h))) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 664: | Line 664: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">deconv1d :: [Double] -> [Double] -> [Double] |
||
deconv1d xs ys = takeWhile (/= 0) $ deconv xs ys |
deconv1d xs ys = takeWhile (/= 0) $ deconv xs ys |
||
where |
where |
||
Line 706: | Line 706: | ||
main :: IO () |
main :: IO () |
||
main = print $ (h == deconv1d g f) && (f == deconv1d g h)</ |
main = print $ (h == deconv1d g f) && (f == deconv1d g h)</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>True</pre> |
<pre>True</pre> |
||
Line 714: | Line 714: | ||
This solution borrowed from [[Formal_power_series#J|Formal power series]]: |
This solution borrowed from [[Formal_power_series#J|Formal power series]]: |
||
< |
<syntaxhighlight lang="j">Ai=: (i.@] =/ i.@[ -/ i.@>:@-)&# |
||
divide=: [ +/ .*~ [:%.&.x: ] +/ .* Ai</ |
divide=: [ +/ .*~ [:%.&.x: ] +/ .* Ai</syntaxhighlight> |
||
Sample data: |
Sample data: |
||
< |
<syntaxhighlight lang="j">h=: _8 _9 _3 _1 _6 7 |
||
f=: _3 _6 _1 8 _6 3 _1 _9 _9 3 _2 5 2 _2 _7 _1 |
f=: _3 _6 _1 8 _6 3 _1 _9 _9 3 _2 5 2 _2 _7 _1 |
||
g=: 24 75 71 _34 3 22 _45 23 245 25 52 25 _67 _96 96 31 55 36 29</ |
g=: 24 75 71 _34 3 22 _45 23 245 25 52 25 _67 _96 96 31 55 36 29</syntaxhighlight> |
||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="j"> g divide f |
||
_8 _9 _3 _1 _6 7 |
_8 _9 _3 _1 _6 7 |
||
g divide h |
g divide h |
||
_3 _6 _1 8 _6 3 _1 _9 _9 3 _2 5 2 _2 _7 _1</ |
_3 _6 _1 8 _6 3 _1 _9 _9 3 _2 5 2 _2 _7 _1</syntaxhighlight> |
||
That said, note that this particular implementation is slow since it uses extended precision intermediate results. It will run quite a bit faster for this example with no notable loss of precision if floating point is used. In other words: |
That said, note that this particular implementation is slow since it uses extended precision intermediate results. It will run quite a bit faster for this example with no notable loss of precision if floating point is used. In other words: |
||
< |
<syntaxhighlight lang="j">divide=: [ +/ .*~ [:%. ] +/ .* Ai</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{trans|Go}} |
{{trans|Go}} |
||
< |
<syntaxhighlight lang="java">import java.util.Arrays; |
||
public class Deconvolution1D { |
public class Deconvolution1D { |
||
Line 763: | Line 763: | ||
System.out.println(sb.toString()); |
System.out.println(sb.toString()); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 776: | Line 776: | ||
Integer inputs may need to be converted and copied to floating point to use deconv(). |
Integer inputs may need to be converted and copied to floating point to use deconv(). |
||
< |
<syntaxhighlight lang="julia">h = [-8, -9, -3, -1, -6, 7] |
||
g = [24, 75, 71, -34, 3, 22, -45, 23, 245, 25, 52, 25, -67, -96, 96, 31, 55, 36, 29, -43, -7] |
g = [24, 75, 71, -34, 3, 22, -45, 23, 245, 25, 52, 25, -67, -96, 96, 31, 55, 36, 29, -43, -7] |
||
f = [-3, -6, -1, 8, -6, 3, -1, -9, -9, 3, -2, 5, 2, -2, -7, -1] |
f = [-3, -6, -1, 8, -6, 3, -1, -9, -9, 3, -2, 5, 2, -2, -7, -1] |
||
Line 784: | Line 784: | ||
fanswer = deconv(float.(g), float.(h)) |
fanswer = deconv(float.(g), float.(h)) |
||
println("The deconvolution deconv(g, h) is $fanswer, which is the same as f = $f\n")</ |
println("The deconvolution deconv(g, h) is $fanswer, which is the same as f = $f\n")</syntaxhighlight> |
||
{{output}} |
{{output}} |
||
Line 795: | Line 795: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|Go}} |
{{trans|Go}} |
||
< |
<syntaxhighlight lang="scala">// version 1.1.3 |
||
fun deconv(g: DoubleArray, f: DoubleArray): DoubleArray { |
fun deconv(g: DoubleArray, f: DoubleArray): DoubleArray { |
||
Line 821: | Line 821: | ||
println("${f.map { it.toInt() }}") |
println("${f.map { it.toInt() }}") |
||
println("${deconv(g, h).map { it.toInt() }}") |
println("${deconv(g, h).map { it.toInt() }}") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 834: | Line 834: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Using metatables: |
Using metatables: |
||
< |
<syntaxhighlight lang="lua">function deconvolve(f, g) |
||
local h = setmetatable({}, {__index = function(self, n) |
local h = setmetatable({}, {__index = function(self, n) |
||
if n == 1 then self[1] = g[1] / f[1] |
if n == 1 then self[1] = g[1] / f[1] |
||
Line 848: | Line 848: | ||
local _ = h[#g - #f + 1] |
local _ = h[#g - #f + 1] |
||
return setmetatable(h, nil) |
return setmetatable(h, nil) |
||
end</ |
end</syntaxhighlight> |
||
Tests: |
Tests: |
||
< |
<syntaxhighlight lang="lua"> |
||
local f = {-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1} |
local f = {-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1} |
||
local g = {24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7} |
local g = {24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7} |
||
local h = {-8,-9,-3,-1,-6,7} |
local h = {-8,-9,-3,-1,-6,7} |
||
print(unpack(deconvolve(f, g))) --> -8 -9 -3 -1 -6 7 |
print(unpack(deconvolve(f, g))) --> -8 -9 -3 -1 -6 7 |
||
print(unpack(deconvolve(h, g))) --> -3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1</ |
print(unpack(deconvolve(h, g))) --> -3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1</syntaxhighlight> |
||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
This function creates a sparse array for the A matrix and then solves it with a built-in function. It may fail for overdetermined systems, though. Fast approximate methods for deconvolution are also built into Mathematica. See [[Deconvolution/2D%2B]] |
This function creates a sparse array for the A matrix and then solves it with a built-in function. It may fail for overdetermined systems, though. Fast approximate methods for deconvolution are also built into Mathematica. See [[Deconvolution/2D%2B]] |
||
<syntaxhighlight lang="mathematica"> |
|||
<lang Mathematica> |
|||
deconv[f_List, g_List] := |
deconv[f_List, g_List] := |
||
Module[{A = |
Module[{A = |
||
Line 866: | Line 866: | ||
Table[Band[{n, 1}] -> f[[n]], {n, 1, Length[f]}], {Length[g], Length[f] - 1}]}, |
Table[Band[{n, 1}] -> f[[n]], {n, 1, Length[f]}], {Length[g], Length[f] - 1}]}, |
||
Take[LinearSolve[A, g], Length[g] - Length[f] + 1]] |
Take[LinearSolve[A, g], Length[g] - Length[f] + 1]] |
||
</syntaxhighlight> |
|||
</lang> |
|||
Usage: |
Usage: |
||
<pre> |
<pre> |
||
Line 879: | Line 879: | ||
The deconvolution function is built-in to MATLAB as the "deconv(a,b)" function, where "a" and "b" are vectors storing the convolved function values and the values of one of the deconvoluted vectors of "a". |
The deconvolution function is built-in to MATLAB as the "deconv(a,b)" function, where "a" and "b" are vectors storing the convolved function values and the values of one of the deconvoluted vectors of "a". |
||
To test that this operates according to the task spec we can test the criteria above: |
To test that this operates according to the task spec we can test the criteria above: |
||
< |
<syntaxhighlight lang="matlab">>> h = [-8,-9,-3,-1,-6,7]; |
||
>> g = [24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7]; |
>> g = [24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7]; |
||
>> f = [-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1]; |
>> f = [-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1]; |
||
Line 892: | Line 892: | ||
ans = |
ans = |
||
-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1</ |
-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1</syntaxhighlight> |
||
Therefore, "deconv(a,b)" behaves as expected. |
Therefore, "deconv(a,b)" behaves as expected. |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">proc deconv(g, f: openArray[float]): seq[float] = |
||
var h: seq[float] = newSeq[float](len(g) - len(f) + 1) |
var h: seq[float] = newSeq[float](len(g) - len(f) + 1) |
||
for n in 0..<len(h): |
for n in 0..<len(h): |
||
Line 916: | Line 916: | ||
echo deconv(g, f) |
echo deconv(g, f) |
||
echo f |
echo f |
||
echo deconv(g, h)</ |
echo deconv(g, h)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 928: | Line 928: | ||
Using <code>rref</code> routine from [[Reduced row echelon form#Perl|Reduced row echelon form]] task. |
Using <code>rref</code> routine from [[Reduced row echelon form#Perl|Reduced row echelon form]] task. |
||
{{trans|Raku}} |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang="perl">use Math::Cartesian::Product; |
||
sub deconvolve { |
sub deconvolve { |
||
Line 993: | Line 993: | ||
print ' conv(f,h) = g = ' . join(' ', my @g = convolve(\@f, \@h)) . "\n"; |
print ' conv(f,h) = g = ' . join(' ', my @g = convolve(\@f, \@h)) . "\n"; |
||
print 'deconv(g,f) = h = ' . join(' ', deconvolve(\@g, \@f)) . "\n"; |
print 'deconv(g,f) = h = ' . join(' ', deconvolve(\@g, \@f)) . "\n"; |
||
print 'deconv(g,h) = f = ' . join(' ', deconvolve(\@g, \@h)) . "\n";</ |
print 'deconv(g,h) = f = ' . join(' ', deconvolve(\@g, \@h)) . "\n";</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> conv(f,h) = g = 24 75 71 -34 3 22 -45 23 245 25 52 25 -67 -96 96 31 55 36 29 -43 -7 |
<pre> conv(f,h) = g = 24 75 71 -34 3 22 -45 23 245 25 52 25 -67 -96 96 31 55 36 29 -43 -7 |
||
Line 1,001: | Line 1,001: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
{{trans|D}} |
{{trans|D}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #008080;">function</span> <span style="color: #000000;">deconv</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">function</span> <span style="color: #000000;">deconv</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">)</span> |
||
Line 1,039: | Line 1,039: | ||
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"deconv(g,f)"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"h"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">deconv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">),</span><span style="color: #000000;">h</span><span style="color: #0000FF;">)</span> |
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"deconv(g,f)"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"h"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">deconv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">),</span><span style="color: #000000;">h</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"deconv(g,h)"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"f"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">deconv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">),</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span> |
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"deconv(g,h)"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"f"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">deconv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">),</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,048: | Line 1,048: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(load "@lib/math.l") |
||
(de deconv (G F) |
(de deconv (G F) |
||
Line 1,057: | Line 1,057: | ||
(dec 'H |
(dec 'H |
||
(*/ M (get F (- N I)) 1.0) ) ) |
(*/ M (get F (- N I)) 1.0) ) ) |
||
(link (*/ H 1.0 A)) ) ) ) )</ |
(link (*/ H 1.0 A)) ) ) ) )</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="picolisp">(setq |
||
F (-3. -6. -1. 8. -6. 3. -1. -9. -9. 3. -2. 5. 2. -2. -7. -1.) |
F (-3. -6. -1. 8. -6. 3. -1. -9. -9. 3. -2. 5. 2. -2. -7. -1.) |
||
G (24. 75. 71. -34. 3. 22. -45. 23. 245. 25. 52. 25. -67. -96. 96. 31. 55. 36. 29. -43. -7.) |
G (24. 75. 71. -34. 3. 22. -45. 23. 245. 25. 52. 25. -67. -96. 96. 31. 55. 36. 29. -43. -7.) |
||
Line 1,065: | Line 1,065: | ||
(test H (deconv G F)) |
(test H (deconv G F)) |
||
(test F (deconv G H))</ |
(test F (deconv G H))</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 1,071: | Line 1,071: | ||
Inspired by the TCL solution, and using the <code>ToReducedRowEchelonForm</code> function to reduce to row echelon form from [[Reduced row echelon form#Python|here]] |
Inspired by the TCL solution, and using the <code>ToReducedRowEchelonForm</code> function to reduce to row echelon form from [[Reduced row echelon form#Python|here]] |
||
< |
<syntaxhighlight lang="python">def ToReducedRowEchelonForm( M ): |
||
if not M: return |
if not M: return |
||
lead = 0 |
lead = 0 |
||
Line 1,124: | Line 1,124: | ||
g = [24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7] |
g = [24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7] |
||
assert convolve(f,h) == g |
assert convolve(f,h) == g |
||
assert deconvolve(g, f) == h</ |
assert deconvolve(g, f) == h</syntaxhighlight> |
||
Based on the R version. |
Based on the R version. |
||
< |
<syntaxhighlight lang="python"> |
||
import numpy |
import numpy |
||
Line 1,169: | Line 1,169: | ||
print(deconv(g,h)) |
print(deconv(g,h)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output |
Output |
||
Line 1,187: | Line 1,187: | ||
* solution is ifft(fft(a)*fft(b)), truncated. |
* solution is ifft(fft(a)*fft(b)), truncated. |
||
< |
<syntaxhighlight lang="r">conv <- function(a, b) { |
||
p <- length(a) |
p <- length(a) |
||
q <- length(b) |
q <- length(b) |
||
Line 1,204: | Line 1,204: | ||
return(y[1:n]) |
return(y[1:n]) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
To check : |
To check : |
||
<syntaxhighlight lang="r"> |
|||
<lang R> |
|||
h <- c(-8,-9,-3,-1,-6,7) |
h <- c(-8,-9,-3,-1,-6,7) |
||
f <- c(-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1) |
f <- c(-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1) |
||
Line 1,216: | Line 1,216: | ||
max(abs(deconv(g,f) - h)) |
max(abs(deconv(g,f) - h)) |
||
max(abs(deconv(g,h) - f)) |
max(abs(deconv(g,h) - f)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
This solution often introduces complex numbers, with null or tiny imaginary part. If it hurts in applications, type Re(conv(f,h)) and Re(deconv(g,h)) instead, to return only the real part. It's not hard-coded in the functions, since they may be used for complex arguments as well. |
This solution often introduces complex numbers, with null or tiny imaginary part. If it hurts in applications, type Re(conv(f,h)) and Re(deconv(g,h)) instead, to return only the real part. It's not hard-coded in the functions, since they may be used for complex arguments as well. |
||
Line 1,222: | Line 1,222: | ||
R has also a function convolve, |
R has also a function convolve, |
||
<syntaxhighlight lang="r"> |
|||
<lang R> |
|||
conv(a, b) == convolve(a, rev(b), type="open") |
conv(a, b) == convolve(a, rev(b), type="open") |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(require math/matrix) |
(require math/matrix) |
||
Line 1,246: | Line 1,246: | ||
(define lh (+ (- lg lf) 1)) |
(define lh (+ (- lg lf) 1)) |
||
(least-square (convolution-matrix f lg lh) g)) |
(least-square (convolution-matrix f lg lh) g)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Test: |
Test: |
||
< |
<syntaxhighlight lang="racket"> |
||
(define f (col-matrix [-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1])) |
(define f (col-matrix [-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1])) |
||
(define h (col-matrix [-8 -9 -3 -1 -6 7])) |
(define h (col-matrix [-8 -9 -3 -1 -6 7])) |
||
Line 1,255: | Line 1,255: | ||
(deconvolve g f) |
(deconvolve g f) |
||
(deconvolve g h) |
(deconvolve g h) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="racket"> |
||
#<array '#(6 1) #[-8 -9 -3 -1 -6 7]> |
#<array '#(6 1) #[-8 -9 -3 -1 -6 7]> |
||
#<array '#(16 1) #[-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1]> |
#<array '#(16 1) #[-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1]> |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 1,267: | Line 1,267: | ||
Translation of Python, using a modified version of the subroutine <code>rref</code> from [[Reduced row echelon form#Raku| Reduced row echelon form]] task. |
Translation of Python, using a modified version of the subroutine <code>rref</code> from [[Reduced row echelon form#Raku| Reduced row echelon form]] task. |
||
<lang |
<syntaxhighlight lang="raku" line>sub deconvolve (@g, @f) { |
||
my \h = 1 + @g - @f; |
my \h = 1 + @g - @f; |
||
my @m; |
my @m; |
||
Line 1,325: | Line 1,325: | ||
.say for ~@g, ~convolve(@f, @h),''; |
.say for ~@g, ~convolve(@f, @h),''; |
||
.say for ~@h, ~deconvolve(@g, @f),''; |
.say for ~@h, ~deconvolve(@g, @f),''; |
||
.say for ~@f, ~deconvolve(@g, @h),'';</ |
.say for ~@f, ~deconvolve(@g, @h),'';</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,338: | Line 1,338: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
< |
<syntaxhighlight lang="rexx">/*REXX pgm performs deconvolution of two arrays: deconv(g,f)=h and deconv(g,h)=f */ |
||
call make 'H', "-8 -9 -3 -1 -6 7" |
call make 'H', "-8 -9 -3 -1 -6 7" |
||
call make 'F', "-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1" |
call make 'F', "-3 -6 -1 8 -6 3 -1 -9 -9 3 -2 5 2 -2 -7 -1" |
||
Line 1,374: | Line 1,374: | ||
if @.$1.t= @.$2.t then iterate /*create array list. */ |
if @.$1.t= @.$2.t then iterate /*create array list. */ |
||
say "***error*** arrays" $1 ' and ' $2 "aren't equal." |
say "***error*** arrays" $1 ' and ' $2 "aren't equal." |
||
end /*t*/; return /* [↑] build the list. */</ |
end /*t*/; return /* [↑] build the list. */</syntaxhighlight> |
||
{{out|output|text= when using the default internal inputs:}} |
{{out|output|text= when using the default internal inputs:}} |
||
<pre> |
<pre> |
||
Line 1,384: | Line 1,384: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/ENWyl3Z/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/bFag8sS1Qr2Z062LN8dr6A Scastie (remote JVM)]. |
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/ENWyl3Z/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/bFag8sS1Qr2Z062LN8dr6A Scastie (remote JVM)]. |
||
< |
<syntaxhighlight lang="scala">object Deconvolution1D extends App { |
||
val (h, f) = (Array(-8, -9, -3, -1, -6, 7), Array(-3, -6, -1, 8, -6, 3, -1, -9, -9, 3, -2, 5, 2, -2, -7, -1)) |
val (h, f) = (Array(-8, -9, -3, -1, -6, 7), Array(-3, -6, -1, 8, -6, 3, -1, -9, -9, 3, -2, 5, 2, -2, -7, -1)) |
||
val g = Array(24, 75, 71, -34, 3, 22, -45, 23, 245, 25, 52, 25, -67, -96, 96, 31, 55, 36, 29, -43, -7) |
val g = Array(24, 75, 71, -34, 3, 22, -45, 23, 245, 25, 52, 25, -67, -96, 96, 31, 55, 36, 29, -43, -7) |
||
Line 1,406: | Line 1,406: | ||
println(sb.result()) |
println(sb.result()) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
Line 1,412: | Line 1,412: | ||
{{trans|Kotlin}} |
{{trans|Kotlin}} |
||
< |
<syntaxhighlight lang="swift">func deconv(g: [Double], f: [Double]) -> [Double] { |
||
let fs = f.count |
let fs = f.count |
||
var ret = [Double](repeating: 0, count: g.count - fs + 1) |
var ret = [Double](repeating: 0, count: g.count - fs + 1) |
||
Line 1,442: | Line 1,442: | ||
print("\(f.map({ Int($0) }))") |
print("\(f.map({ Int($0) }))") |
||
print("\(deconv(g: g, f: h).map({ Int($0) }))")</ |
print("\(deconv(g: g, f: h).map({ Int($0) }))")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,455: | Line 1,455: | ||
{{works with|Tcl|8.5}} |
{{works with|Tcl|8.5}} |
||
This builds the a command, <code>1D</code>, with two subcommands (<code>convolve</code> and <code>deconvolve</code>) for performing convolution and deconvolution of these kinds of arrays. The deconvolution code is based on a reduction to [[Reduced row echelon form#Tcl|reduced row echelon form]]. |
This builds the a command, <code>1D</code>, with two subcommands (<code>convolve</code> and <code>deconvolve</code>) for performing convolution and deconvolution of these kinds of arrays. The deconvolution code is based on a reduction to [[Reduced row echelon form#Tcl|reduced row echelon form]]. |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.5 |
||
namespace eval 1D { |
namespace eval 1D { |
||
namespace ensemble create; # Will be same name as namespace |
namespace ensemble create; # Will be same name as namespace |
||
Line 1,554: | Line 1,554: | ||
return $result |
return $result |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
To use the above code, a simple demonstration driver (which solves the specific task): |
To use the above code, a simple demonstration driver (which solves the specific task): |
||
< |
<syntaxhighlight lang="tcl"># Simple pretty-printer |
||
proc pp {name nlist} { |
proc pp {name nlist} { |
||
set sep "" |
set sep "" |
||
Line 1,573: | Line 1,573: | ||
pp "deconv(g,f) = h" [1D deconvolve $g $f] |
pp "deconv(g,f) = h" [1D deconvolve $g $f] |
||
pp "deconv(g,h) = f" [1D deconvolve $g $h] |
pp "deconv(g,h) = f" [1D deconvolve $g $h] |
||
pp " conv(f,h) = g" [1D convolve $f $h]</ |
pp " conv(f,h) = g" [1D convolve $f $h]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>deconv(g,f) = h = [-8,-9,-3,-1,-6,7] |
<pre>deconv(g,f) = h = [-8,-9,-3,-1,-6,7] |
||
Line 1,587: | Line 1,587: | ||
the same length by appending zeros to the short ones). |
the same length by appending zeros to the short ones). |
||
< |
<syntaxhighlight lang="ursala">#import std |
||
#import nat |
#import nat |
||
Line 1,593: | Line 1,593: | ||
deconv = lapack..dgelsd^\~&l ~&||0.!**+ band |
deconv = lapack..dgelsd^\~&l ~&||0.!**+ band |
||
</syntaxhighlight> |
|||
</lang> |
|||
test program: |
test program: |
||
< |
<syntaxhighlight lang="ursala">h = <-8.,-9.,-3.,-1.,-6.,7.> |
||
f = <-3.,-6.,-1.,8.,-6.,3.,-1.,-9.,-9.,3.,-2.,5.,2.,-2.,-7.,-1.> |
f = <-3.,-6.,-1.,8.,-6.,3.,-1.,-9.,-9.,3.,-2.,5.,2.,-2.,-7.,-1.> |
||
g = <24.,75.,71.,-34.,3.,22.,-45.,23.,245.,25.,52.,25.,-67.,-96.,96.,31.,55.,36.,29.,-43.,-7.> |
g = <24.,75.,71.,-34.,3.,22.,-45.,23.,245.,25.,52.,25.,-67.,-96.,96.,31.,55.,36.,29.,-43.,-7.> |
||
Line 1,606: | Line 1,606: | ||
'h': deconv(g,f), |
'h': deconv(g,f), |
||
'f': deconv(g,h)> |
'f': deconv(g,h)> |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,638: | Line 1,638: | ||
=={{header|Vlang}}== |
=={{header|Vlang}}== |
||
{{trans|Go}} |
{{trans|Go}} |
||
< |
<syntaxhighlight lang="vlang">fn main() { |
||
h := [f64(-8), -9, -3, -1, -6, 7] |
h := [f64(-8), -9, -3, -1, -6, 7] |
||
f := [f64(-3), -6, -1, 8, -6, 3, -1, -9, -9, 3, -2, 5, 2, -2, -7, -1] |
f := [f64(-3), -6, -1, 8, -6, 3, -1, -9, -9, 3, -2, 5, 2, -2, -7, -1] |
||
Line 1,663: | Line 1,663: | ||
} |
} |
||
return h |
return h |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,675: | Line 1,675: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|Go}} |
{{trans|Go}} |
||
< |
<syntaxhighlight lang="ecmascript">var deconv = Fn.new { |g, f| |
||
var h = List.filled(g.count - f.count + 1, 0) |
var h = List.filled(g.count - f.count + 1, 0) |
||
for (n in 0...h.count) { |
for (n in 0...h.count) { |
||
Line 1,696: | Line 1,696: | ||
System.print(deconv.call(g, f)) |
System.print(deconv.call(g, f)) |
||
System.print(f) |
System.print(f) |
||
System.print(deconv.call(g, h))</ |
System.print(deconv.call(g, h))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,708: | Line 1,708: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
Using GNU Scientific Library: |
Using GNU Scientific Library: |
||
< |
<syntaxhighlight lang="zkl">var [const] GSL=Import("zklGSL"); // libGSL (GNU Scientific Library) |
||
fcn dconv1D(f,g){ |
fcn dconv1D(f,g){ |
||
fsz,hsz:=f.len(), g.len() - fsz +1; |
fsz,hsz:=f.len(), g.len() - fsz +1; |
||
Line 1,715: | Line 1,715: | ||
h:=A.AxEQb(g); |
h:=A.AxEQb(g); |
||
h |
h |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">f:=GSL.VectorFromData(-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1); |
||
g:=GSL.VectorFromData(24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7); |
g:=GSL.VectorFromData(24,75,71,-34,3,22,-45,23,245,25,52,25,-67,-96,96,31,55,36,29,-43,-7); |
||
h:=dconv1D(f,g); |
h:=dconv1D(f,g); |
||
Line 1,722: | Line 1,722: | ||
f:=dconv1D(h,g); |
f:=dconv1D(h,g); |
||
f.format().println();</ |
f.format().println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,730: | Line 1,730: | ||
Or, using lists: |
Or, using lists: |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="zkl">fcn deconv(g,f){ |
||
flen, glen, delta:=f.len(), g.len(), glen - flen + 1; |
flen, glen, delta:=f.len(), g.len(), glen - flen + 1; |
||
result:=List.createLong(delta); // allocate list with space for items |
result:=List.createLong(delta); // allocate list with space for items |
||
Line 1,740: | Line 1,740: | ||
} |
} |
||
result; |
result; |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">h:=T(-8,-9,-3,-1,-6,7); |
||
f:=T(-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1); |
f:=T(-3,-6,-1,8,-6,3,-1,-9,-9,3,-2,5,2,-2,-7,-1); |
||
g:=T(24,75,71,-34,3,22,-45,23,245,25,52,25,-67, |
g:=T(24,75,71,-34,3,22,-45,23,245,25,52,25,-67, |
||
-96,96,31,55,36,29,-43,-7); |
-96,96,31,55,36,29,-43,-7); |
||
println(deconv(g, f) == h, " ", deconv(g, f)); |
println(deconv(g, f) == h, " ", deconv(g, f)); |
||
println(deconv(g, h) == f, " ", deconv(g, h));</ |
println(deconv(g, h) == f, " ", deconv(g, h));</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |