Want convolution idioms
Author Message
Want convolution idioms

I'm looking for a couple of 'standard' APL ways of expression common
operations.

1) Convolution

In one dimension this is straightforward.  With an origin of 0, if I
want to convolve a smoothing kernel k {is} 0.1 0.2 0.4 0.2 0.1 with a
data vector x (treating the ends in a periodic manner) I can write

+/[0] {minus}2 {minus}1 0 1 2 {rotate}[1] k {jot}.{times} x

The combination of inner product, rotation and reduction does exactly what I
want.

Is there a general idiom for 2 or 3 dimensions?  Secondly, is there a
way to avoid the intermediate value swell effect here.  In the example
above each element in x is replicated by the number of elements in the
kernel.  If x has 1024 elements and the k has 5 there are 5120
elements before the reduction is done.  That's not much of a burden in
this case, but for a typical three dimensional case, say 256 x 256 x 256
data and a 5 x 5 x 5 kernel there are 2097152000 intermediate
values, which would start to tax typical machines.  I suppose that a
smart interpreter would be able to figure out the reduction of an
inner product and so not create all these.  In this case it would
cease to be an issue.

2) Passing a function as a function argument

Is there a better way than passing the name of the function as a
string and using eval to find the result?  For instance, if F is the
name of a monadic functions and X is a variable {eval} F, ' X'
produces the desired result.  This would seem to have the disadvantage
of not allowing the interpreter to use its more global knowledge to
evaluate this in the best way.

3) Does APL have the equivalent of the matlab 'image' function which
produces an image from a matrix?

I'm using APL2 but would be interested in SAX or other APL dialect
solutions.

David Nichols

Mon, 19 Sep 2005 03:43:39 GMT
Want convolution idioms
David,
You asked "3) Does APL have the equivalent of the matlab 'image'
function which
produces an image from a matrix?"

I'm afraid I don't know anything about MATLAB's 'image' function.  AP
207 in APL2 has a command, IMAGE, that puts a pixel into the graphics
window for each character in an array.  The color is determined by the
{quadAF} of the character and the color map.

If the matrix is a series of coordinates through which a virtual pen
should move, the AP-207 DRAW command would be what you're looking for.
Or the GRAPHPAK DRAW function.  Curtis

Mon, 19 Sep 2005 05:42:55 GMT
Want convolution idioms

Quote:

> I'm looking for a couple of 'standard' APL ways of expression common
> operations.

> 2) Passing a function as a function argument

> Is there a better way than passing the name of the function as a
> string and using eval to find the result?  For instance, if F is the
> name of a monadic functions and X is a variable {eval} F, ' X'
> produces the desired result.  This would seem to have the disadvantage
> of not allowing the interpreter to use its more global knowledge to
> evaluate this in the best way.

In APL2 a defined operator can pass one or two functions (including
defined functions).

Mon, 19 Sep 2005 06:00:24 GMT
Want convolution idioms
David,

If you want to pass a function as an argument, I would use a defined
operator.  Pass the function as an operand to the operator.  Look in the
EXAMPLES workspace in library 1 for examples of defined operators.

The AP 207 IMAGE command can produce a picture from a matrix.  The matrix
must be a character matrix.  Each character represents one pixel and is used
as an index into the current color table.

David Liebtag
IBM APL Products and Services

Mon, 19 Sep 2005 11:50:07 GMT
Want convolution idioms

The cut operator in SAX may be used for convolution and it works for
arrays of higher dimension:

(1{table}{transpose}{table}{rho}k){neg}3{on}(+.{times}{on},{with}k)x

The function (+.{times}{on},{with}k) is applied to arrays of size
({rho}k) in x, starting at the top left and "shifting" 1 element
along each of the dimensions.

This is not quite good enough for your example.  Cut does not wrap
around and the order is wrong.  Here is a simplified version of the
above in your order and with enough of the front of the array tacked
on to its end to wrap:

{neg}2{rotate}({table}1 5) {neg}3{on}(+.{times}{with}k) x,4{take}x

There _are_ some intermediate values here too.  Cut will produce a
boxed array containing the results before opening it to produce the
result.  This array will be large for 256 256 256 data ( about 600MB ).

Also, SAX has neither defined operators nor any built-in capability
to produce an image based on RGB values in a matrix ( this is what
image does??? ).

/Jim

Tue, 20 Sep 2005 02:32:10 GMT
Want convolution idioms

Quote:

> I'm looking for a couple of 'standard' APL ways of expression common
> operations.

For longer sequences the best idiom for convolution would be expressed with the
intrinsic FFT operator.  Oops, there isn't one.  :-)

Bob
--

"Things should be described as simply as possible, but no simpler."

A. Einstein

Tue, 20 Sep 2005 06:22:13 GMT
Want convolution idioms

Quote:
> I'm looking for a couple of 'standard' APL ways of expression common
> operations.
<snip>
> 2) Passing a function as a function argument

<snip>

As others have already stated "User defined operators" is the normal way to
go,
and that is my preferred solution. After all that what "operators" (as
against functions) are for.
Operators can take "functions" and "data" as arguments. Functions can only
take "data" as arguments.

However if the functions being passed are members of a known set (e.g. "+"
"*" and ","), a case statement
Such as:-
:Select fn
:Case 'fn1'
2 + 3
:Case 'fn2'
2 * 3
:Case 'fn3'
2 , 3
:End
might be effective in APL version that support it (APL2000, DyalogAPL, APL-X
etc)

Dyalog...
Foo <- { a Fn w }
Fn <- +  <> 2 Foo 3
5
Fn <- -*  <> 2 Foo 3
8
Fn <- ,  <> 2 Foo 3
2 3

Alternately under Dyalog, namespaces can be used.
(Namespaces are first class object and can be passed to functions. One can
also
have vectors of namespaces.)
E.g.
Define in NS1 function Fn
NS1.Fn <- {a + w}
Define in NS2 a different function also called Fn
NS2.Fn <- {a * w}
Etc for NS3....
NS3.Fn <- {a , w}
Then pass the namespace's reference (NS1, NS2 or NS3) as required. This is
an EXTREMELY powerful technique.

In these examples, the functions "+" "*"  and "," could be almost ANY
function including user defined fns.
it. APL cannot tell the difference between assignment and execution.)

The use of direct definition "{...}" is irreverent as far as the above
example are concerned.

Another technique might be to create a "local function" either thru  []FX or
direct definitions
With direct definitions this is very similar to the function assignment
(I know the example looks a bit silly here but its just an example)

Foo <- { a lFn w }
lFn <- {a + w}  <> 2 Foo 3
5
lFn <- (a -* w} <> 2 Foo 3
8
lFn <- {a , w}  <> 2 Foo 3
2 3

But with []FX, its more like string execution

Foo <- { a lFn w }
[]FX 'r <-L lFn R <> r <- L + R' <> 2 Foo 3
5
[]FX 'r <-L lFn R <> r <- L * R' <> 2 Foo 3
8
[]FX 'r <-L lFn R <> r <- L , R'<> 2 Foo 3
2 3

Or even

Foo <- { sink <- []FX 'r <-L lFn R <> r <- L ', w ,' R' <> 2 lFn 3}
Foo '+'
5
Foo '*'
8
Foo ','
2 3

I am sure there are many other methods, but I expect the decision will
depend on how the "selection of the function to be passed", is to be made.

Ray

Thu, 22 Sep 2005 11:20:14 GMT

 Page 1 of 1 [ 7 post ]

Relevant Pages