[PYTHON MATRIX-SIG] Let's get going

Jim Fulton, U.S. Geological Survey jfulton@usgs.gov
Wed, 13 Sep 1995 17:40:42 -0400


On Wed, 13 Sep 95 17:01:31 -0400 
James Hugunin said:
> 
> I've got to run to a meeting, but I wanted to reply to your points.
> 
> I'm not at all sure that we disagree on the implementation of slices.  Let  
> me ask two simple questions.  Let's say A is a slice taken from a matrix,  
> and B is a contiguous matrix.
> 
> 1) Should I be able to say C = A+B, and have the obvious thing happen  
> (assuming that dimensions line up, etc.)?

Yes.
 
> I'd say yes, and I have a few performance optimizations to make this fast  
> in certain cases and nobody needs to worry about those.

Cool.

> 
> 2) Should I be able to say fft(A) where fft is an in-place FFT routine?   
> Should it be expected to modify the memory referred to by A, or only to  
> return a brand-new matrix which corresponds to the fft of A?
> 
> I'm not sure what the right answer to this one is.

My opinion, in general is that functions should return new objects,
however, reasonable performance arguments can be made for at least
some cases of having functions modify large matrices rather than
creating new ones. 

In the case above, even if I had fft modify it's argument, I would
still have it return the argument as a return value.

The problem is that you want to be able to call routines that expect
contigous data. Slice data, even for the cases you mentioned aren't
like that.  Slices could be implemented with their own contiguous
data area that they keep in sync with the original matrices data, but
I think this would complicate the implementation of slices beyound
their benefit.  Of course, this is only a problem when calling Fortran
or C.  Python functions (or C functions written for Python, which are
much faster than python functions, but have many of the benefits)
should nor present a problem.

I suppose when calling a library function that wants to modify it's
data, one could (within the glue code) do something equivalent to:

  def spam_glue(m):
	if type(m) is MatrixType:
		return spam(m)
	else:
		t=Matrix(m)
		r=spam(t)
		m[:]=t
		return r

That is the (automagically generated) glue code could create a
temporrary matrix as copy of the original data, call the function with
the copy, and then slice-assign the modified copy back to the
argument.  Note this should work work with any sequence, such as a
slice, that allows assignment from any arbitrary sequence. (Grrrrrr.
Unfortunately, this won't work with list arguments, as the following
code fails:

   a=[1,2,3]
   a[:]=(7,8,9) # This fails, but shouldn't, IMHO

This should work!)

I think I could work this behavior into FIDL, without much trouble.

Hm.  So perhaps allowing slices to be used as modifyable arguments
might not be too bad, as long as the implementor is willing to do a
little extra work. (In my case, the implementor is a program, so I
don't mind if it works hard. ;) You still pay the performance penalty
of making a copy, but at least functions that provide performance wins
when used with matrices can still function correctly with slices.

> 
> > > > Hm. Does this operate in-place or return a value?
> > >
> > > In-place.  In fact, I am tempted to try and make all of the methods on  
> > > matrices operate "in-place" in order to be in line with list objects.
> >
> > I'm not sure what you mean by this.  Surely, you aren't trying to
> > make:
> >
> >    m=[[1,2,3],[4,5,6],[7,8,9]]
> >    b=[11,22,33]
> >    m=[1]=b
> >    b[1]=99
> >
> > cause m[1][1] to equal 99? Are you?
> 
> Not at all!  All I meant by this is that methods on list objects (like  
> insert or append) actually change the list object that they are operating  
> on, whereas operations like concatenation return a new object.  In that  
> vein, I feel that m.byteswap() should operate in-place on m and cause the  
> memory associated with m to be byte-swapped.  This is as opposed to having  
> it return a new matrix in with the same dimensions as m, but with all values  
> byte-swapped.

Cool.  Actually, I would use a naming convention to make this clear,
so I might have both "byteswap" which modifies in place, and
"byteswapped" which returns a new objects.

(BTW Guido, I wish lists has a "sorted" operation that returned a new
sorted list.)

Jim

=================
MATRIX-SIG  - SIG on Matrix Math for Python

send messages to: matrix-sig@python.org
administrivia to: matrix-sig-request@python.org
=================