Deconvolution/2D+: Difference between revisions

Content added Content deleted
m (→‎{{header|Tcl}}: formatting (oops!))
m (→‎{{header|Tcl}}: Add comments)
Line 110: Line 110:


# Utility to get the size of a matrix, as a list of lengths
# Utility to get the size of a matrix, as a list of lengths
proc size f {
proc size m {
set r [rank $f]
set r [rank $m]
set index {}
set index {}
set size {}
set size {}
for {set i 0} {$i<$r} {incr i} {
for {set i 0} {$i<$r} {incr i} {
lappend size [llength [lindex $f $index]]
lappend size [llength [lindex $m $index]]
lappend index 0
lappend index 0
}
}
Line 121: Line 121:
}
}


# Utility that iterates over the space of coordinates within a matrix
# Utility that iterates over the space of coordinates within a matrix.
#
# Arguments:
# var The name of the variable (in the caller's context) to set to each
# coordinate.
# size The size of matrix whose coordinates are to be iterated over.
# body The script to evaluate (in the caller's context) for each coordinate,
# with the variable named by 'var' set to the coordinate for the particular
# iteration.
proc loopcoords {var size body} {
proc loopcoords {var size body} {
upvar 1 $var v
upvar 1 $var v
Line 138: Line 146:
}
}


# Assembles a row, which is one of the simultaneous equations that needs
# to be solved by reducing the whole set to reduced row echelon form. Note
# that each row describes the equation for a single cell of the 'g' function.
#
# Arguments:
# g The "result" matrix of the convolution being undone.
# h The known "input" matrix of the convolution being undone.
# gs The size descriptor of 'g', passed as argument for efficiency.
# gc The coordinate in 'g' that we are generating the equation for.
# fs The size descriptor of 'f', passed as argument for efficiency.
# hs The size descriptor of 'h' (the unknown "input" matrix), passed
# as argument for efficiency.
proc row {g f gs gc fs hs} {
proc row {g f gs gc fs hs} {
loopcoords hc $hs {
loopcoords hc $hs {
Line 206: Line 226:
}
}


# Deconvolve a pair of matrixes. Solves for 'h' such that 'g = f convolve h'.
#
# Arguments:
# g The matrix of data to be deconvolved.
# f The matrix describing the convolution to be removed.
# type Optional description of the type of data expected. Defaults to 32-bit
# integer data; use 'double' for floating-point data.
proc deconvolve {g f {type int}} {
proc deconvolve {g f {type int}} {
# Compute the sizes of the various matrixes involved.
set gsize [size $g]
set gsize [size $g]
set fsize [size $f]
set fsize [size $f]
Line 213: Line 241:
}
}


# Prepare the set of simultaneous equations to solve
set toSolve {}
set toSolve {}
loopcoords coords $gsize {
loopcoords coords $gsize {
Line 218: Line 247:
}
}


# Solve the equations
set solved [toRREF $toSolve]
set solved [toRREF $toSolve]


# Make a dummy result matrix of the right size
set h 0
set h 0
foreach hs [lreverse $hsize] {set h [lrepeat $hs $h]}
foreach hs [lreverse $hsize] {set h [lrepeat $hs $h]}

# Fill the results from the equations into the result matrix
set idx 0
set idx 0
loopcoords coords $hsize {
loopcoords coords $hsize {