HELP CONVOLVE_INDEX David Young November 1992 Carries out an indexed convolution on an array of any number of dimensions, using single precision floats. The main procedure convolve_index(ARRIN, WEIGHTS, OFFSETS, ARROUT, REGION) -> ARROUT convolves ARRIN with the convolution mask effectively specified by WEIGHTS and OFFSETS. For efficiency, the input and output arrays should be constructed using *NEWSFLOATARRAY, or any other procedure that gives a packed arrayvector of single floats. The last two arguments may be given as for straightforward use. The formula is: ARROUT (x1, ... xk, ... xz) = SUM ARRIN(x1-OFFi(1), ... xk-OFFi(k), ... xz-OFFi(z)) * WEIGHTS(i) i=1,N where N is the number of weights and the number of offsets, and OFFi is shorthand for the i'th element of OFFSET. The array may have any number of dimensions greater than 0. For example, suppose the arrays are 2-D, WEIGHTS is [ 4 -1 -1 -1 -1 ] and OFFSETS is [{ 0 0} {-1 1} {-1 -1} { 1 -1} { 1 1}] then the convolution is with a centre-surround operator, which would look like this if laid out as a 2-D array: -1 -1 4 -1 -1 That is, you can imagine constructing a mask array, storing the number in WEIGHTS(I) at the position specified by the elements of OFFSETS(I), and zeroes everywhere else. Then the result is equivalent to convolving this mask array with the input array. (No such array is in fact constructed.) Note that the subtraction used to get the indices into the input array is correct for such a convolution. Another way to think of the process is to imagine multiplying every element of ARRIN by WEIGHTS(1), and storing each result in a new array, in a position shifted by the vector OFFSETS(1). Repeat this for all the other weights and offsets, and add up all these new arrays element by element to get ARROUT. (No such intermediate arrays are actually created in practice, of course.) The simplest way to call the procedure is: convolve_index(ARRIN, WEIGHTS, OFFSETS, false, false) -> ARROUT A new array will be created and returned. The convolution will be run over the whole of ARRIN, and ARROUT will be smaller than ARRIN by an amount depending on the maximum offsets, to allow for the fact that the mask has to be wholly within ARRIN all the time. E.g. if OFFSETS is boundslist [{-2 -2} {2 2}] and ARRIN has bounds [1 100 1 100], then ARROUT will have bounds [3 98 3 98]. See the code for the general case, or figure it out from the formula above. WEIGHTS may be an array, vector or list containing the weight values (it must only contain numbers). There will be a slight efficiency advantage if it is an array created with *NEWSFLOATARRAY. OFFSETS must be a list, with as many elements as there are weights. Each element of the list may be a vector or list containing integers, specifying an offset into the mask. If the more general form convolve_index(ARRIN, WEIGHTS, OFFSETS, ARROUT, REGION) -> ARROUT then the ARROUT argument may be used to pass in an array which is to be filled with results, in order to avoid creating a new array. This array should be created with *NEWSFLOATARRAY (or a similar constructor), otherwise it will get copied. One easy way to get a suitable output array is to use an array produced as a result of a previous call to -convolve_index-. If ARROUT is supplied, and REGION is , then as much of ARROUT as possible will be filled. Parts of ARROUT which cannot be filled, because to do so would take the mask off the edge of the input array, are left untouched. Equally, parts of the input array not needed to fill ARROUT are left unreferenced. If ARROUT is a list, it must specify a boundslist with which to create a new array, together with a value with which to initialise the array. The intialising value is given as the head of the list, the boundslist as the tail. The behaviour will then be as if this array had been passed in - i.e. as much as possible of it is filled. Any parts that cannot be filled will be left as the initial value. So the call convolve_2d(ARRIN, MASK, 0 :: boundslist(ARRIN), false) -> ARROUT; will return an array the same size as ARRIN but with a border of zeroes corresponding to the region where the mask would have gone off the edge. The last argument, REGION, can be used to specify a part of the output array to fill. If it is not , REGION should have the structure of a boundslist. Only the part of ARROUT specified by REGION is then filled: the rest of the output array is left unchanged. REGION must be wholly contained within the output array's bounds, and must not require the mask to cross the input array's boundaries. If REGION is specified and ARROUT is on entry, then the array returned has REGION as its boundslist. --- $popvision/help/convolve_index --- Copyright University of Sussex 1992. All rights reserved. ----------