From acannon@geog.ubc.ca  Thu Aug  1 22:36:05 1996
From: acannon@geog.ubc.ca (Alex Cannon)
Date: Thu, 1 Aug 1996 14:36:05 -0700 (PDT)
Subject: [PYTHON MATRIX-SIG] Gist plots with Tk?
Message-ID: <Pine.SUN.3.91.960801142127.6622B-100000@leghorn>

This may seem off-topic, but I couldn't decide whether this should go in
matrix-sig (because of the gist tie in) or the GUI list (because of 
Tk). 

Anyhow, is it possible to get Tk and the gist module to coexist? As an
example, I've modified the simple 'hello world' tkinter script to plot a line
with gist. Running the script and clicking on the 'Plot' button causes the
gist window to popup, but the plot doesn't finish until after quitting the Tk
mainloop() (when running with -i). 

Is there a way to do this properly? 

Alex

--

from Tkinter import *
from gist import *

class Test(Frame):
    def plot(self):
	plg([0, 1])

    def createWidgets(self):
	self.QUIT = Button(self, {'text': 'Quit', 
				  'fg': 'red', 
				  'command': self.quit})
	
	self.QUIT.pack({'side': 'left', 'fill': 'both'})


	self.gist_test = Button(self, {'text': 'Plot', 
				      'command': self.plot})
	self.gist_test.pack({'side': 'left'})

	
    def __init__(self, master=None):
	Frame.__init__(self, master)
	Pack.config(self)
	self.createWidgets()

test = Test()
test.mainloop()

------------------------------------------------------------
Alex Cannon  (acannon@geog.ubc.ca)       Geography 240C
Atmospheric Science Programme            Tel: (604) 822-2269
University of British Columbia, B.C.     Fax: (604) 822-6150


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

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

From caves@yorvic.york.ac.uk  Fri Aug  2 18:53:51 1996
From: caves@yorvic.york.ac.uk (Leo Caves)
Date: Fri, 2 Aug 1996 18:53:51 +0100
Subject: [PYTHON MATRIX-SIG] "linking" variables to python
Message-ID: <9608021853.ZM1030@pingu>

Hi!

context:
extending python with a legacy FORTRAN app.
and have used the  PyArray_FromDimsAndData() function to
link FORTRAN common block arrays to python array objects.
is working beautifully...

Q: how to do the same with scalar variables ?
eg.
INTEGER N in FORTRAN declaration
to python object (say) n

I am trying to avoid acessing as array of length 1.

Also, I would like to ask what the current opinions on
the perennial array indexing question are.
i.e. indexed from 0 (in python) vs. 1 in FORTRAN.
My point here is that I have a whole load of integer arrays in
FORTRAN which serve as indices into other arrays.  Therefore these
would have to be remapped to point to the correct place in the
python array.

Thanks,
Leo Caves

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

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

From jjh@goldilocks.lcs.mit.edu  Fri Aug  9 23:21:09 1996
From: jjh@goldilocks.lcs.mit.edu (Jim Hugunin)
Date: Fri, 9 Aug 1996 18:21:09 -0400
Subject: [PYTHON MATRIX-SIG] Release 1.0alpha1 now available
Message-ID: <01BB861F.8A1BDA90@ling-ling.lcs.mit.edu>


The first alpha release of the final 1.0 version of the Numeric =
Extensions is now available.  This release contains ZERO patches to the =
python core.  To use it you must have python1.4b2 installed on your =
computer (much thanks to Guido for adding all of the needed =
functionality to this release!).

If you are working under Windows NT (or 95) there is a binary release =
available that includes all needed files.

The 1.0 number here means that I'm finally happy with the basic =
functionality and design of the system and don't intend to make many =
more changes.  This version unfortunately changes many details from the =
previous version and will break most existing code.  I don't want to =
ever do that again (not to you or to myself).  There is an ugly, but =
fairly complete piece of documentation in html for all of the functions =
provided, as well as a very simple example module to help illustrate the =
use of the C API.

The alpha release means that this is not at all well tested.  I'm =
counting on you folks to track down the bugs now, and when that seems =
under control, I'll send it out to the main list as a Beta release =
(ideally coinciding with the first official release of python1.4).  You =
should expect a very rapid release schedule at this point as I =
desperately want this out soon!

Please beat hard on this and let me know where it breaks!

For Unix users:
Untar this wherever you want, and follow the instructions in INSTALL.
Please try and build the dynamically loadable version, and let me know =
about your success on different systems.  I'd really like to include =
binaries in the next alpha release (in preparation for the beta =
release).

ftp://ftp.sls.lcs.mit.edu/pub/jjh/NumPy-1.0a1.tar.gz

There is also an fftmodule in this release.  If you don't have fftpack =
on your system, you can grab

ftp://ftp.sls.lcs.mit.edu/pub/jjh/rfft-1.2.tar.gz=20

which is very easy to compile on almost all unix systems.  This is =
stolen from the rlab source code distribution site.

For Windows 95/NT

Unzip this into wherever you have your binary version of python =
installed.  This should be into a directory that already has a =
py140-b1.dll in it.  That will be replaced by the beta 2 version of that =
library contained in the zip file.

ftp://ftp.sls.lcs.mit.edu/pub/jjh/Win32-NumPy-1.0a1.zip

Enjoy - Jim

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

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

From jjh@goldilocks.lcs.mit.edu  Fri Aug  9 23:33:21 1996
From: jjh@goldilocks.lcs.mit.edu (Jim Hugunin)
Date: Fri, 9 Aug 1996 18:33:21 -0400
Subject: [PYTHON MATRIX-SIG] Standard Numerical Library
Message-ID: <01BB8621.3E6D8BF0@ling-ling.lcs.mit.edu>


I'm getting tired of explaining to people why the Numeric Extensions =
don't contain matrix inversion or fft operators.  I intend to fix this =
by providing a standard library with the 1.0 release of the system.  The =
primitive fftmodule in the current alpha1 release is my start on this.

Here are my plans for this library, please comment:

1) Based on LAPACK and FFTPACK FORTRAN libraries, but only using the =
subset available with the RLab distribution.  This is a very nice =
version of these libraries in C, and on every system I have available =
they've compiled with "./configure; make" without a hitch (like some =
scripting languages I know).  They also seem to compile fairly easily =
under NT.  I'd distribute these packages as well for people without the =
"real" libraries on their machines.

2) Implementing a bare minimum of functionality, in a simple, clean, =
unsophisticated way.

ie. fft( (0,0,1,1) ) will just work.  No need to setup work areas, etc.

3) Implementing the "basic" functions

1D FFT
Matrix Inversion
Matrix Eigenvalues
Matrix Determinant
Any requests?

I'm back - Jim

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

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

From janne@avocado.pc.helsinki.fi  Sat Aug 10 10:42:55 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 10 Aug 1996 12:42:55 +0300
Subject: [PYTHON MATRIX-SIG] Standard Numerical Library
In-Reply-To: Jim Hugunin's message of Fri, 9 Aug 1996 18:33:21 -0400
References: <01BB8621.3E6D8BF0@ling-ling.lcs.mit.edu>
Message-ID: <oahgqb1so0.fsf@avocado.pc.helsinki.fi>

Jim Hugunin <jjh@goldilocks.lcs.mit.edu> writes:

> 3) Implementing the "basic" functions
> 
> 1D FFT
> Matrix Inversion
> Matrix Eigenvalues
> Matrix Determinant
> Any requests?

SVD is a must. Pseudoinverse would be nice and trivial after SVD.

Is there a function returning the index of a minimum or a
maximum? This would be nice in some ANN applications, although I don't
know whether it is generally useful enough to be a standard part of
the language.

-- 
Janne Sinkkonen      <janne@iki.fi>      <URL: http://www.iki.fi/~janne/ >

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

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

From hinsen@physik.rwth-aachen.de  Sat Aug 10 14:46:47 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Sat, 10 Aug 1996 15:46:47 +0200
Subject: [PYTHON MATRIX-SIG] Release 1.0alpha1 now available
In-Reply-To: <01BB861F.8A1BDA90@ling-ling.lcs.mit.edu> (message from Jim Hugunin on Fri, 9 Aug 1996 18:21:09 -0400)
Message-ID: <9608101346.AA03384@acds21>


   The first alpha release of the final 1.0 version of the Numeric =
   Extensions is now available.  This release contains ZERO patches to the =

Great news! That makes me eager to get back to work ;-)
Unfortunately I won't have good enough net access until the end
of next week (right now I have an awfully slow link at 7 cents a minute,
but it works from my laptop...)

   Please beat hard on this and let me know where it breaks!

Sounds like fun!

   I'm getting tired of explaining to people why the Numeric Extensions =
   don't contain matrix inversion or fft operators.  I intend to fix this =
   by providing a standard library with the 1.0 release of the system.  The =
   primitive fftmodule in the current alpha1 release is my start on this.

Good idea. But we should make sure that this standard library is a subset
of some "full" liraries, even if these will not be ready immediately.
I don't want two incompatible matrix inversion functions!

   1) Based on LAPACK and FFTPACK FORTRAN libraries, but only using the =
   subset available with the RLab distribution.  This is a very nice =

I don't know this subset. Is it fully compatible with the current
versions of the full libraries?

   2) Implementing a bare minimum of functionality, in a simple, clean, =
   unsophisticated way.

   ie. fft( (0,0,1,1) ) will just work.  No need to setup work areas, etc.

That should be the default for any numeric library!

   3) Implementing the "basic" functions

   1D FFT
   Matrix Inversion
   Matrix Eigenvalues
   Matrix Determinant

I predict a lot of discussion about what is "basic". My only addition to
your list would be solution of linear equations (inversion is a
terribly inefficient way to do that). I would also like to have different
algorithms where appropriate, a fast one for standard problems and a
foolproof one for people who don't know what they are doing (i.e.
SVD for matrix inversion etc.)

As soon as I am back in business, I will update my LAPACK interface
for the new version. I don't pretend that it is the last word on
linear algebra libraries (some problems, like application to different
types of matrices (symmetric etc.) have been completely ignored
until now), but it has worked quite well for me in the past, and I have
a couple of application algorithms that use it.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From fonseca@gaivota.demon.co.uk  Sat Aug 10 19:15:35 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Sat, 10 Aug 1996 19:15:35 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Standard Numerical Library
In-Reply-To: <oahgqb1so0.fsf@avocado.pc.helsinki.fi>
Message-ID: <Pine.LNX.3.94.960810184659.913C-100000@gaivota.demon.co.uk>

On 10 Aug 1996, Janne Sinkkonen wrote:

> Is there a function returning the index of a minimum or a
> maximum? This would be nice in some ANN applications, although I don't
> know whether it is generally useful enough to be a standard part of
> the language.
> 

I find functions like max(), min(), and sort() (fun() for short)  more
limited than the corresponding argfun(), simply because the former could
always be writen as take(a,argfun(a)).

Unfortunately, the indices argument of take() used to have to be
one-dimensional, so the above would not work for a two dimensional array. 
Has this changed in the new release? A version of take() such that:

take(a,argsort(a,axis),axis) = sort(a,axis)

for arrays of arbitrary shape would be very, very useful. Ideally, it
should also follow the same rules as +, *, etc when "a" or "indices" have
dimensions of length one. Even if implementing this functionality is not a
priority at this stage, making axis in take() default to -1 would allow
for it to be implemented later without breaking any code in the future. 

I guess I should try to write a new version of take() in Python first,
and then see if others could use this functionality.

Carlos Fonseca


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

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

From Carlos Fonseca <fonseca@gaivota.demon.co.uk>  Sat Aug 10 18:46:51 1996
From: Carlos Fonseca <fonseca@gaivota.demon.co.uk> (Carlos Fonseca)
Date: Sat, 10 Aug 1996 18:46:51 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Standard Numerical Library
In-Reply-To: <01BB8621.3E6D8BF0@ling-ling.lcs.mit.edu>
Message-ID: <Pine.LNX.3.94.960810173651.913B-100000@gaivota.demon.co.uk>

On Fri, 9 Aug 1996, Jim Hugunin wrote:

> Here are my plans for this library, please comment: 
> 
> 1) Based on LAPACK and FFTPACK FORTRAN libraries, but only using the
> subset available with the RLab distribution.  This is a very nice
> version of these libraries in C ...
> ... I'd distribute these packages as well for people without the
> "real" libraries on their machines. 

Would it still be possible to use the "real" libraries? It would be nice
to link dynamically with these...

> 2) Implementing a bare minimum of functionality, in a simple, clean,
> unsophisticated way. 
> 
> ie. fft( (0,0,1,1) ) will just work.  No need to setup work areas, etc.

Will 1D functions like the fft (and also 2D functions) work transparently
on arbitrary multidimensional arrays, along user-specified axes? This
should be easier to implement efficiently in C than later in Python. 

In genetic algorithms it is almost always necessary to evaluate cost
functions at a number of points at a time, which adds one dimension to
array containing the decision variables. In control engineering, these
could easily be matrices. Sometimes, the population is structured, which
adds another dimension. Having multidimensional arrays is a great way of
eliminating for-loops in the Python code and/or unnecessary reshaping of
the arrays prior to the computation. 

This also raises the question of which axis/axes these functions should
use by default. I find it counter-intuitive that most functions (but not
all!) default to axis=0 whereas addition, multiplication, etc., match the
last dimensions of arrays of different depths. Personally, I would prefer
axis=-1 by default (but there may be a reason against this), or
axis=(-2,-1) for 2D functions (matrix inversion, etc).

> 3) Implementing the "basic" functions
> 
> 1D FFT
> Matrix Inversion
> Matrix Eigenvalues

... and corresponding eigenvectors. I've seen at least one numerical
package which did not return them :-(

> Matrix Determinant
> Any requests?

* SVD (already mentioned)

* (Generalised) Cholesky decomposition of symmetric matrices would be very
useful to anybody dealing with covariance matrices (and I believe it is in
LINPACK, don't know about LAPACK). 

* Least-squares solution of over/under-determined systems of linear
equations a la A\b in Matlab.

I hope the above comments are useful... I am looking forward to trying out
the new release. Thanks!

Carlos Fonseca



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

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

From janne@avocado.pc.helsinki.fi  Sat Aug 10 22:41:01 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 11 Aug 1996 00:41:01 +0300
Subject: [PYTHON MATRIX-SIG] Standard Numerical Library
In-Reply-To: Carlos Fonseca's message of Sat, 10 Aug 1996 19:15:35 +0100 (BST)
References: <Pine.LNX.3.94.960810184659.913C-100000@gaivota.demon.co.uk>
Message-ID: <oag25u29zm.fsf@avocado.pc.helsinki.fi>

Carlos Fonseca <fonseca@gaivota.demon.co.uk> writes:

> I find functions like max(), min(), and sort() (fun() for short)  more
> limited than the corresponding argfun(), simply because the former could
> always be writen as take(a,argfun(a)).

I agree... it is complex to compute the index from the value, the
other way it's much easier.

argsort() solves my problem, at least less suboptimally than some
other hacks. In 1.0 alpha1 there seems to be some kind of type
conversion missing from argsort(), however:

>>> argsort([5,4,2,3])
2 3 1 0
>>> argsort([5.0,4,2,3])
  6.36598737e-314   4.94065646e-324   0.00000000e+000   0.00000000e+000

-- 
Janne































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

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

From hinsen@physik.rwth-aachen.de  Sun Aug 11 13:54:23 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Sun, 11 Aug 1996 14:54:23 +0200
Subject: [PYTHON MATRIX-SIG] Standard Numerical Library
In-Reply-To: <Pine.LNX.3.94.960810173651.913B-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Sat, 10 Aug 1996 18:46:51 +0100 (BST))
Message-ID: <9608111254.AA03871@acds21>


   Will 1D functions like the fft (and also 2D functions) work transparently
   on arbitrary multidimensional arrays, along user-specified axes? This
   should be easier to implement efficiently in C than later in Python. 

That reminds me of the long discussion about function ranks a few
months ago. Basically, all functions that act on an array of fixed
rank (1 for 1D FFT, 2 for matrix inversion, etc.) should loop
over the remainining indices of higher-rank arrays. This approach
has proven to be very useful in J.

   This also raises the question of which axis/axes these functions should
   use by default. I find it counter-intuitive that most functions (but not
   all!) default to axis=0 whereas addition, multiplication, etc., match the
   last dimensions of arrays of different depths. Personally, I would prefer
   axis=-1 by default (but there may be a reason against this), or
   axis=(-2,-1) for 2D functions (matrix inversion, etc).

Again the J-style rank approach provides a single rule for sorting
out such things in a very nice way...

   * (Generalised) Cholesky decomposition of symmetric matrices would be very
   useful to anybody dealing with covariance matrices (and I believe it is in
   LINPACK, don't know about LAPACK). 

It's also in LAPACK (everything that is in LINPACK is also in LAPACK,
which was designed as a replacement for LINPACK and EISPACK).

   * Least-squares solution of over/under-determined systems of linear
   equations a la A\b in Matlab.

I agree that all teh features you mentiones are essential for serious
linear algebra work, but I am not sure if they are essential for a
*minimal* standard library. I need pseudoinverses almost daily, but
I also know that many people have never heard of them...

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From janne@avocado.pc.helsinki.fi  Sun Aug 11 16:09:23 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 11 Aug 1996 18:09:23 +0300
Subject: [PYTHON MATRIX-SIG] Bugs in 1.0alpha1
In-Reply-To: Jim Hugunin's message of Fri, 9 Aug 1996 18:21:09 -0400
References: <01BB861F.8A1BDA90@ling-ling.lcs.mit.edu>
Message-ID: <oaafw20xgc.fsf@avocado.pc.helsinki.fi>


I think the following may be bugs:

arange(5,3,2) produces a core dump. This seems to come down to (for 
example) zeros((-5,)) producing a core dump. 
 
minimum.reduceAt() produces a core dump.  
 
array() doesn't take a copy. Should it? (doc.html says it should) 
>>> a=array([1,2,3,4,5]) 
>>> b=array(a) 
>>> a[0]=0 
>>> b 
0 2 3 4 5 
 
diagonal() gives odd results: 
>>> d 
1 2 3 4 
5 6 7 8 
1 2 3 4 
5 6 7 8 
>>> diagonal(d) 
1 2 3 4 5 
 
sort() and argsort() do not accept two arguments. 

--
Janne

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

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

From janne@avocado.pc.helsinki.fi  Sun Aug 11 16:10:58 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 11 Aug 1996 18:10:58 +0300
Subject: [PYTHON MATRIX-SIG] Ranf.py for 1.0alpha1
Message-ID: <oa91bm0xdo.fsf@avocado.pc.helsinki.fi>


... after one or two trivial fixes:


import URNG 
import Numeric 
# x=CreateGenerator(seed) creates an random number generator stream 
#   seed < 0  ==>  Use the default initial seed value. 
#   seed = 0  ==>  Set a "random" value for the seed from the system clock. 
#   seed > 0  ==>  Set seed directly (32 bits only). 
#   x.ranf() samples from that stream. 
#   x.sample(n) returns a vector from that stream. 
# 
# ranf() returns a stream of random numbers 
# random_sample(n) returns a vector of length n filled with random numbers 
# random_matrix(n,m,...) returns an arbitrarily shaped matrix filled with 
#                        random numbers. 
 
CreateGenerator = URNG.CreateGenerator 
standard_generator = CreateGenerator(-1) 
 
def ranf(): 
        "ranf() = a random number from the standard generator." 
        return standard_generator.ranf() 
 
def random_sample(*n): 
        """random_sample(n) = array of n random numbers; 
        random_sample(n1, n2, ...)= random array of shape (n1, n2, ..)""" 
 
        if not n: 
                return standard_generator.sample(1) 
        m = 1 
        for i in n: 
                m = m * i 
        return Numeric.reshape(standard_generator.sample(m), n) 


-- 
Janne Sinkkonen      <janne@iki.fi>      <URL: http://www.iki.fi/~janne/ >

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

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

From janne@avocado.pc.helsinki.fi  Sun Aug 11 16:20:28 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 11 Aug 1996 18:20:28 +0300
Subject: [PYTHON MATRIX-SIG] MLab.py for 1.0alpha1
In-Reply-To: Jim Hugunin's message of Fri, 9 Aug 1996 18:21:09 -0400
References: <01BB861F.8A1BDA90@ling-ling.lcs.mit.edu>
Message-ID: <oa7mr60wxv.fsf@avocado.pc.helsinki.fi>


Here is a (hopefully mostly) working MLab.py for 1.0beta1. I have
tried to test it with 1D and 2D arrays, but not with higher
dimensional arrays. max() and min() are changed to mmax() and mmin()
because of name collision with the builtin functions (are mmax() and
mmin() really needed?)

diag(<a 2D matrix>) could be more effective, but I left it as it is
because the diagonal() of Numeric.py does not seem to work right now.



"""Matlab(tm) compatibility functions.

This will hopefully become a complete set of the basic functions available in
matlab.  The syntax is kept as close to the matlab syntax as possible.  One 
fundamental change is that the first index in matlab varies the fastest (as in 
FORTRAN).  That means that it will usually perform reductions over columns, 
whereas with this object the most natural reductions are over rows.  It's perfectly
possible to make this work the way it does in matlab if that's desired.
"""
# ChangeLog:
# Sun Aug 11 18:12:20 EET DST 1996:
#      Hacked for 1.0alpha1 by <janne@iki.fi>

from Numeric import *

# Elementary Matrices

# zeros is from matrixmodule in C
# ones is from Numeric.py

## This should be replaced by Paul Dubois' URNG very soon now. 
import Ranf
def rand(*args):
	"""rand(d1,...,dn, typecode='d') returns a matrix of the given dimensions
	which is initialized to random number in the range [0,1).
	"""
	return Ranf.random_sample(args)


def eye(N, M=None, k=0, typecode=None):
	"""eye(N, M=N, k=0, typecode=None) returns a N-by-M matrix where the 
	k-th diagonal is all ones, and everything else is zeros.
	"""

	if M == None: M = N
	if type(M) == type('d'): 
		typecode = M
		M = N
	m = equal(subtract.outer(arange(N), arange(M)),-k)
	if (typecode == None):
	    return m
	else:
	    return m.asType(typecode)


def tri(N, M=None, k=0, typecode=None):
	if M == None: M = N
	if type(M) == type('d'): 
		typecode = M
		M = N
	m = greaterEqual(subtract.outer(arange(N), arange(M)),-k)
	if (typecode == None):
	    return m
	else:
	    return m.asType(typecode)

# Matrix manipulation

def diag(v, k=0):
	s = v.shape
	if len(s)==1:
		n = s[0]+abs(k)
		if k > 0:
		    v = concatenate((zeros((k,)),v))
		elif k < 0:
		    v = concatenate((v,zeros((-k,))))
		return multiply(eye(n, k=k), v)
	elif len(s)==2:
	    v = add.reduce(eye(s[0], s[1], k=k)*v)
	    i0=max(0,k)
	    i1=min(k+s[0],s[1])
	    if i0>i1:
		return array([])
	    else:
		return v[i0:i1]
		

		

def fliplr(m): 
    return m[:, ::-1]

def flipud(m):
    return m[::-1]

# reshape(x, m, n) is not used, instead use reshape(x, (m, n))

def rot90(m, k=1):
	k = k % 4
	if k == 0: return m
	elif k == 1: return fliplr(transpose(m))
	elif k == 2: return fliplr(flipud(m))
	elif k == 3: return transpose(fliplr(m))

def tril(m, k=0):
	return tri(m.shape[0], m.shape[1], k=k, typecode=m.typecode())*m

def triu(m, k=0):
	return (1-tri(m.shape[0], m.shape[1], k-1, m.typecode()))*m 

# Data analysis

# Basic operations
def mmax(m):
	return maximum.reduce(m)

def mmin(m):
	return minimum.reduce(m)

# Actually from BASIS, but it fits in so naturally here...

def ptp(m):
	return max(m)-min(m)

def mean(m):
	return add.reduce(m)/len(m)

# sort is done in C but is done row-wise rather than column-wise
def msort(m):
	return transpose(sort(transpose(m)))

def median(m):
	return msort(m)[m.shape[0]/2]

def std(m):
	mu = mean(m)
	return sqrt(add.reduce(pow(m-mu,2)))/sqrt(len(m)-1)

def sum(m):
	return add.reduce(m)

def cumsum(m):
	return add.accumulate(m)

def prod(m):
	return multiply.reduce(m)

def cumprod(m):
	return multiply.accumulate(m)

def trapz(y, x=None):
	"""Integrate f using the trapezoidal rule, where y is f(x).
	"""

	if x == None: d = 1
	else: d = diff(x)
	return sum(d * (y[1:]+y[0:-1])/2)

def diff(x, n=1):
	"""Discrete difference approximation to the derivative
	"""
	if n > 1:
	    return diff(x[1:]-x[:-1], n-1)
	else:
	    return x[1:]-x[:-1]
	
def corrcoef(x, y=None):
	"""The correlation coefficients
	"""
	if y==None: y=x
	c = cov(x, y)
	return c/sqrt(multiply.outer(diag(cov(x)),diag(cov(y))))

def cov(a,b=None):
    if b == None: b=a
    ma = mean(a)
    mb = mean(b)
    sum_cov = 0.0
    
    for ai,bi in map(lambda i,j: (i,j), a,b):
	sum_cov = sum_cov+multiply.outer(ai,bi)
    return (sum_cov-len(a)*multiply.outer(ma,mb))/(len(a)-1)




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

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

From jjh@goldilocks.lcs.mit.edu  Sun Aug 11 18:16:05 1996
From: jjh@goldilocks.lcs.mit.edu (Jim Hugunin)
Date: Sun, 11 Aug 1996 13:16:05 -0400
Subject: [PYTHON MATRIX-SIG] Default axis
Message-ID: <01BB8787.412159A0@ling-ling.lcs.mit.edu>


Several people how now brought up the issue of the default axis in the =
various functions in NumPy. The inconsistency of this definition is =
really a problem.  I think that it's really important to have a =
consistent default axis, and I propose that the default axis be made -1 =
(or -2 for things that expect 2d arrays).  This works fairly well for me =
in almost all cases (even though this is the opposite of the current =
behavior for things like add.reduce).  On machines with certain cache =
architectures (and with contiguous arrays) this even makes sense as the =
most computationally efficient choice.

My only problem with this is the concatenation function which I =
personally think should only be implemented along axis 0, though I've =
been convinced this is too limiting.  Having this default to a different =
axis than 0 really bothers me, but I suppose I'll get over it.

Comments are welcome - Jim

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

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

From jjh@goldilocks.lcs.mit.edu  Sun Aug 11 19:57:57 1996
From: jjh@goldilocks.lcs.mit.edu (Jim Hugunin)
Date: Sun, 11 Aug 1996 14:57:57 -0400
Subject: [PYTHON MATRIX-SIG] Win32 Distribution is Broken
Message-ID: <01BB8795.7C7B41B0@ling-ling.lcs.mit.edu>


I just tried to install the Win32 binary distribution on my home =
machine, and its definately broken.  I'm removing the zip file from my =
ftp site for now.

I need to learn a little bit more about PythonWin and Setup programs =
under Win32 in order to do this right.  Hope for a working distribution =
in alpha2.

Note: The two basic problems are 8.3 filenames and properly updating =
pythonwin to 1.4b2 from 1.4b1.

-Jim

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

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

From janne@avocado.pc.helsinki.fi  Sun Aug 11 21:59:32 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 11 Aug 1996 23:59:32 +0300
Subject: [PYTHON MATRIX-SIG] Release 1.0alpha1 now available
In-Reply-To: Konrad Hinsen's message of Sat, 10 Aug 1996 15:46:47 +0200
References: <9608101346.AA03384@acds21>
Message-ID: <oaivapy6vf.fsf@avocado.pc.helsinki.fi>

Konrad Hinsen      <hinsen@physik.rwth-aachen.de> writes:

> As soon as I am back in business, I will update my LAPACK interface
> for the new version. I don't pretend that it is the last word on
> linear algebra libraries (some problems, like application to different
> types of matrices (symmetric etc.) have been completely ignored
> until now), but it has worked quite well for me in the past, and I have
> a couple of application algorithms that use it.

Well, I need your LAPACK interface right now... see below. :)

By the way, dot(a,b) of the package Numeric now seems to reduce over
the same axis for both a and b. While this seems sensible and
efficient, especially if the axis is -1, the behaviour looks strange
for a newcomer who maybe expects to find a matrix multiplication
function. Should there be a function behaving like the ordinary matrix
multiplication for 2D arrays, say dot2(), so that dot(a,b) would be
equal to dot2(a,transpose(b)) (for 2D arrays)? On the other hand, this
kind of behaviour does not mean anything sensible for N-dimensional
arrays, or does it?

# This module contains high-level Python interfaces to the
# LAPACK library.
#
# Written by Konrad Hinsen <hinsenk@ere.umontreal.ca>
# last revision: 1996-3-13
#
# Modified 1996-3-19 by Doug Heisterkamp
#        Change type of pivots from "i" to "l" in solveLinearEquations
#
# Modified 1996-8-11 by Janne Sinkkonen <janne@iki.fi>
#        Made compatible with NumPy 1.0alpha1. A bug in eigenvalues()
#        (triggered by complex arguments) corrected. dot() is now
#        _dot2() and unitMatrix() is _unitMatrix().

# import Numeric,umath
import Numeric
import copy

transpose=Numeric.transpose
zeros=Numeric.zeros
cp=copy.copy

# Error object

LinAlgError = 'LinAlgError'

# Helper routines

_lapack_type = {'f': 0, 'd': 1, 'F': 2, 'D': 3}
_lapack_letter = ['s', 'd', 'c', 'z']
_array_kind = {'i':0, 'l': 0, 'f': 0, 'd': 0, 'F': 1, 'D': 1}
_array_precision = {'i': 1, 'l': 1, 'f': 0, 'd': 1, 'F': 0, 'D': 1}
_array_type = [['f', 'd'], ['F', 'D']]

def _commonType(*arrays):
    kind = 0
    precision = 0
    for a in arrays:
	t = a.typecode()
	kind = max(kind, _array_kind[t])
	precision = max(precision, _array_precision[t])
    return _array_type[kind][precision]

def _castCopyAndTranspose(type, *arrays):
    cast_arrays = ()
    for a in arrays:
	if a.typecode() == type:
	    cast_arrays = cast_arrays + (cp(transpose(a)),)
	else:
	    cast_arrays = cast_arrays + (transpose(a).asType(type),)
    if len(cast_arrays) == 1:
	return cast_arrays[0]
    else:
	return cast_arrays

def _findLapackRoutine(name, type):
    name = _lapack_letter[_lapack_type[type]] + name
    module = 'lapack_' + name[:3]
    exec 'import ' + module
    module = eval(module)
    return getattr(module, name)

def _assertRank2(*arrays):
    for a in arrays:
	if len(a.shape) != 2:
	    raise LinAlgError, 'Array must be two-dimensional'

def _assertSquareness(*arrays):
    for a in arrays:
	if max(a.shape) != min(a.shape):
	    raise LinAlgError, 'Array must be square'
    


# unit matrix

def _unitMatrix(n):
    i = Numeric.arange(n)
    return Numeric.equal(i[:,Numeric.NewAxis], i)

# A dot function behaving like matrix multiplication (for 2D arrays)

def _dot2(a1, a2):
    return(Numeric.dot(a1,transpose(a2)))




# Singular value decomposition

def singularValueDecomposition(a):
    _assertRank2(a)
    n = a.shape[1]
    m = a.shape[0]
    t =_commonType(a)
    real_t = _array_type[0][_array_precision[t]]
    lapack_routine = _findLapackRoutine('gesvd', t)
    a = _castCopyAndTranspose(t, a)
    s = zeros((min(n,m),), real_t)
    u = zeros((m,m,), t)
    vt =zeros((n,n,), t)
    lwork = 10*max(m,n) # minimum value: max(3*min(m,n)+max(m,n),5*min(m,n)-4)
    work = zeros((lwork,), t)
    if _array_kind[t] == 1: # Complex routines take different arguments
	rwork = zeros((max(3*min(m,n),5*min(m,n)-4),), real_t)
	results = lapack_routine('A', 'A', m, n, a, m, s, u, m, vt, n,
				 work, lwork, rwork, 0)
    else:
	results = lapack_routine('A', 'A', m, n, a, m, s, u, m, vt, n,
				 work, lwork, 0)
    if results['info'] > 0:
	raise LinAlgError, 'SVD did not converge'
    return cp(transpose(u)), s, cp(transpose(vt))


# Generalized inverse

def generalizedInverse(a):
    u, s, vt = singularValueDecomposition(a)
    m = u.shape[0]
    n = vt.shape[0]
    cutoff = 1.e-10*Numeric.maximum.reduce(s)
    sm = zeros((n,m,),s.typecode())
    for i in range(min(n,m)):
	if s[i] > cutoff:
	    sm[i,i] = 1./s[i]
    return _dot2(_dot2(transpose(vt), sm), transpose(u))


# Linear equations
	
def solveLinearEquations(a, b):
    one_eq = len(b.shape) == 1
    if one_eq:
	b = b[:, Numeric.NewAxis]
    _assertRank2(a, b)
    _assertSquareness(a)
    n_eq = a.shape[0]
    n_rhs = b.shape[1]
    if n_eq != b.shape[0]:
	raise LinAlgError, 'Incompatible dimensions'
    t =_commonType(a, b)
    lapack_routine = _findLapackRoutine('gesv', t)
    a, b = _castCopyAndTranspose(t, a, b)
    pivots = zeros((n_eq,), 'l')
    results = lapack_routine(n_eq, n_rhs, a, n_eq, pivots, b, n_eq, 0)
    if results['info'] > 0:
	raise LinAlgError, 'Singular matrix'
    if one_eq:
	return cp(Numeric.ravel(b))
    else:
	return cp(transpose(b))


# Matrix inversion

def inverse(a):
    return solveLinearEquations(a, _unitMatrix(a.shape[0]))




# Eigenvalues

def eigenvalues(a):
    _assertRank2(a)
    _assertSquareness(a)
    t =_commonType(a)
    real_t = _array_type[0][_array_precision[t]]
    lapack_routine = _findLapackRoutine('geev', t)
    a = _castCopyAndTranspose(t, a)
    n = a.shape[0]
    dummy = Numeric.zeros((1,), t)
    lwork = max(1,6*n) # minimum value: max(1,3*n) real, max(1,2*n) complex
    work = Numeric.zeros((lwork,), t)
    if _array_kind[t] == 1: # Complex routines take different arguments
	w = Numeric.zeros((n,), t)
	rwork = Numeric.zeros((n,),real_t)
	results = lapack_routine('N', 'N', n, a, n, w,
				 dummy, 1, dummy, 1, work, lwork, rwork, 0)
    else:
	wr = Numeric.zeros((n,), t)
	wi = Numeric.zeros((n,), t)
	results = lapack_routine('N', 'N', n, a, n, wr, wi,
				 dummy, 1, dummy, 1, work, lwork, 0)
	if Numeric.logicalAnd.reduce(Numeric.equal(wi, 0.)):
	    w = wr
	else:
	    w = wr+1j*wi
    if results['info'] > 0:
	raise LinAlgError, 'Eigenvalues did not converge'
    return w

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

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

From da@maigret.cog.brown.edu  Sun Aug 11 22:09:53 1996
From: da@maigret.cog.brown.edu (David Ascher)
Date: Sun, 11 Aug 1996 17:09:53 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] fromFunction...
Message-ID: <199608112109.RAA11928@maigret>

In 1.0a1, fromFunction is absent.  I miss it. =)  Now, the last we
talked about this, there were still some issues that had to be hacked
out, and Konrad pseudo-volunteered, but since then he took a vacation, a
job, moved, and is now somewhat netisolated.  Does anyone else feel up
to the task?  Or Konrad, are you still interested/able?

My requirements are fairly simple.  I want to do things like

	def f(x, y): return sin(x) + cos(y) 	# (1)
	a = fromFunction((200,200), f)

as efficiently as possible.  Maybe there are much better ways than
what I just wrote, but it sure was simple.  If someone can show me
how to do the above without fromFunction, that'd be nice too.  I
do think that the general notion is very useful, and I'd like to see it
survive.

One problem with the 0.36 version of fromFunction is that

	def f(x,y): return x			# (2)
	a = fromFunction((200,200), f)

returns something which is of shape (200,1), not (200,200), which is
what I'd expected.

Surprisingly (to the naive user at least),

	def f(x,y): return x + 0*y		# (3)
	a = fromFunction((200,200), f)

returns just what I expected (2) would above.

Cheers

-david


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

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

From Carlos Fonseca <fonseca@gaivota.demon.co.uk>  Sun Aug 11 22:59:53 1996
From: Carlos Fonseca <fonseca@gaivota.demon.co.uk> (Carlos Fonseca)
Date: Sun, 11 Aug 1996 22:59:53 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Bugs in 1.0alpha1
In-Reply-To: <oaafw20xgc.fsf@avocado.pc.helsinki.fi>
Message-ID: <Pine.LNX.3.94.960811220149.1651B-100000@gaivota.demon.co.uk>

On 11 Aug 1996, Janne Sinkkonen wrote:

> I think the following may be bugs:
> 
> arange(5,3,2) produces a core dump. This seems to come down to (for 
> example) zeros((-5,)) producing a core dump. 

In addition to this:

>>> a=arange(0)
>>> a
-1
>>> a.shape
Traceback (innermost last):
  File "<stdin>", line 1, in ?
AttributeError: attribute-less object

Version 0.36 produced some sort of empty array here.  Actually, this
raises the question of the dimensions of empty arrays:

>>> b
0 1 2 3 4
5 6 7 8 9
>>> b[1:1]
EmptyArray
>>> b[1:1,:]
Traceback (innermost last):
  File "<stdin>", line 1, in ?
IndexError: invalid slice

The Octave documentation mentions a paper (something like "An empty
exercise", sorry, I don't have it with me at the moment) where empty
arrays are discussed. Also, Octave follows this paper in how it handles
empty arrays. I haven't run into difficulties with this, but expressions
like b[1:1,:] and b[2:1,:] should work. 

> array() doesn't take a copy. Should it? (doc.html says it should) 
> >>> a=array([1,2,3,4,5]) 
> >>> b=array(a) 
> >>> a[0]=0 
> >>> b 
> 0 2 3 4 5 

I had wondered about this, too. It also happens with b=ravel(a), if a is
1d, and may happen with other funtions, too. This may save space and time
in some special cases, but it certainly isn't safe...  At least, it should
be spelled out loud in the final docs.  Another possibility is an optional
argument (something like b=ravel(a,alwayscopy=0/1)), but I don't know
whether I like this or not.

Carlos



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

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

From jbaddor@phy.ulaval.ca  Mon Aug 12 13:40:00 1996
From: jbaddor@phy.ulaval.ca (Jean-Bernard ADDOR)
Date: Mon, 12 Aug 1996 08:40:00 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] histogram
Message-ID: <Pine.SUN.3.91.960812083447.1813C-100000@mills>


Hi !

Does something already exit to calculate the histogram of a big array ?
Thanks for information.


	Jean-Bernard




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

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

From jbaddor@phy.ulaval.ca  Mon Aug 12 13:55:18 1996
From: jbaddor@phy.ulaval.ca (Jean-Bernard ADDOR)
Date: Mon, 12 Aug 1996 08:55:18 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] Standard Numerical Library
In-Reply-To: <01BB8621.3E6D8BF0@ling-ling.lcs.mit.edu>
Message-ID: <Pine.SUN.3.91.960812085219.1813D-100000@mills>

On Fri, 9 Aug 1996, Jim Hugunin wrote:
(...)
> 3) Implementing the "basic" functions
> 
> 1D FFT

Would it be possible to have 2D FFT (for images analysis) ?

> Matrix Inversion
> Matrix Eigenvalues
> Matrix Determinant
> Any requests?
> 
> I'm back - Jim
> 
> ========MATRIX-SIG  - SIG on Matrix Math for Python
> 
> send messages to: matrix-sig@python.org
> administrivia to: matrix-sig-request@python.org
> ========

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

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

From drh@oasis.unl.edu  Mon Aug 12 16:09:46 1996
From: drh@oasis.unl.edu (Doug Heisterkamp)
Date: Mon, 12 Aug 1996 10:09:46 -0500 (CDT)
Subject: [PYTHON MATRIX-SIG] Standard Numerical Library
In-Reply-To: <01BB8621.3E6D8BF0@ling-ling.lcs.mit.edu> from "Jim Hugunin" at Aug 9, 96 06:33:21 pm
Message-ID: <199608121509.KAA02824@oasis.unl.edu>

> 
> 1D FFT
and 2D FFT

> Matrix Inversion
> Matrix Eigenvalues
and Eigenvectors

> Matrix Determinant
> Any requests?
> 

SVD, solving systems of linear equations, least squares. 

Doug Heisterkamp
drh@oasis.unl.edu




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

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

From hugunin@mit.edu  Mon Aug 12 18:24:28 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Mon, 12 Aug 1996 13:24:28 -0400
Subject: [PYTHON MATRIX-SIG] Histogram?
Message-ID: <320F68CC.6E95@mit.edu>

This is not quite optimal (O(N lg N) instead of O(N)), but it is
adequate for my needs:

def histogram(a, bins):
"""Calculates the histogram of the values in the 1d array a.
bins is an array of the edges of the bins, there is one less
bin than items in this array.  Items that lie exactly on a bin
edge have a 50/50 chance of appearing in either bin."""
	n = binarysearch(sort(a), bins)
	n = concatenate( [n, [len(a)]] )
	return n[1:]-n[:-1]

Something like this will wind up in the standard library.

-Jim

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

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

From hugunin@mit.edu  Mon Aug 12 18:19:34 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Mon, 12 Aug 1996 13:19:34 -0400
Subject: [PYTHON MATRIX-SIG] Bugs in 1.0alpha1
References: <Pine.LNX.3.94.960811220149.1651B-100000@gaivota.demon.co.uk>
Message-ID: <320F67A6.7CAA@mit.edu>

Carlos Fonseca wrote:
> 
> On 11 Aug 1996, Janne Sinkkonen wrote:
> 
> > I think the following may be bugs:

I appreciate the desire to be kind, but any time you can produce a core
dump with NumPy, you're entitled to say, I found the following TERRIBLE
BUG!  Though I'd prefer it if you sent these really obvious bugs
straight to me...

> > arange(5,3,2) produces a core dump. This seems to come down to (for
> > example) zeros((-5,)) producing a core dump.
> 

...
> Version 0.36 produced some sort of empty array here.  Actually, this
> raises the question of the dimensions of empty arrays:
...
> empty arrays. I haven't run into difficulties with this, but expressions
> like b[1:1,:] and b[2:1,:] should work.

Empty arrays are now much cleaned up.  The reported bugs have been fixed
for alpha2 (sometime this week).  Note however, b[2:1, :] will not work
on an array of shape (2,3).  The reason this doesn't work should be
pretty clear.

For fun with empty arrays, try:

sum([[],[],[]], -1)

> > array() doesn't take a copy. Should it? (doc.html says it should)

It should and it does in alpha2.

> I had wondered about this, too. It also happens with b=ravel(a), if a is
> 1d, and may happen with other funtions, too. This may save space and time
> in some special cases, but it certainly isn't safe...  At least, it should
> be spelled out loud in the final docs.  Another possibility is an optional
> argument (something like b=ravel(a,alwayscopy=0/1)), but I don't know
> whether I like this or not.

I really don't like the idea of that optional argument, whether or not
these functions: reshape, ravel, and transpose should always return a
copy of their input array is a good question.  I'll think about this,
and will definately put a note in the docs if I decide to leave their
behavior unchanged.

-Jim

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

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

From hinsen@physik.rwth-aachen.de  Mon Aug 12 19:58:15 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Mon, 12 Aug 1996 20:58:15 +0200
Subject: [PYTHON MATRIX-SIG] histogram
In-Reply-To: <Pine.SUN.3.91.960812083447.1813C-100000@mills> (message from Jean-Bernard ADDOR on Mon, 12 Aug 1996 08:40:00 -0400 (EDT))
Message-ID: <9608121858.AA06035@acds21>


   Does something already exit to calculate the histogram of a big array ?

I have something like that as part of my WHAM package (which is a
rather specialized package for the evaluation of PMFs ; and if you don't
know what that is you don't need to know :-) Works fine. I'll see if I can
extract some general histogram code, but don't expect anything this week...

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsen@physik.rwth-aachen.de  Mon Aug 12 20:18:07 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Mon, 12 Aug 1996 21:18:07 +0200
Subject: [PYTHON MATRIX-SIG] First impressions from the docs
Message-ID: <9608121918.AA06110@acds21>

I couldn't resist downloading the new Numerical Python packageeven
though I don't have the Python 1.4 source code yet. So I'lljust
comment on what I read in the documentation for now:

In general, the current function set is a big step forward.  I
expectthat I can now replace most awkward constructions in my
applicationcode by something more concise and more efficient. More on
that whenI am finished...

I would like to see more flexibility in the constructor if it iscalled
with a non-sequence first argument. It should try to dosomething
meaningful whenever possible. If presented with a file,for example, it
should assume a text file with numbers and doits best to turn it into
an array (this is very important forreading data produced by other
programs). And for argumentsthat have no type/class with special
meaning, it should calla method toArray() if it exists.I do realize
that reading from a file intelligently is a non-trivialproblem, and
therefore the best solution is probably to provide afunction hook
similar to the one for array printing. Thatgives everyone ample
opportunity to play with array reading code.I have a function (in
Python) that reads 1D and 2D arrays wellenough for me, but it is not
very efficient. That could be astarting point for a more sophisticated
version.

I wonder what exactly resize() does. First, I don't understand whyit
is less efficient than reshape(); if the size remains the same,
itshould perform exactly the same operation. But I really wonder
what"strange" things can happen if I am not "careful". As long as
theshape argument makes sense (i.e. contains no negative numbers)
theresult should be well defined.

The function diagonal() is a typical example of a function thatwould
benefit from J-style function ranks. As it is defined now,it assumes
that higher-rank arrays are to be treated as arraysof 2D subarrays
(i.e. function rank 2). This is a useful function,but a "true"
higher-rank diagonal (the list of elements for whichall indices are
equal), corresponding to function rank infinity,is also useful. The
same applies to trace().

The axis defaults for sort() and argsort() should be 0.

There are two methods that I would like to see as functions:
shape()and asType(). Both occur commonly in numerical algorithms,
wheretheir argument might be a rank-0 array (i.e. a
scalar).(Alternatively the two methods could be added to the
Pythonscalar types, but I am not sure if Guido would approve such
achange.)

I still think that in the general spirit of Python, the defaultmath
module used by Numeric should be umath, not fast_umath.For someone who
doesn't know all the details, it is betterto be slow than to be wrong.


More when I have the code running...

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From jbaddor@phy.ulaval.ca  Mon Aug 12 19:51:59 1996
From: jbaddor@phy.ulaval.ca (Jean-Bernard ADDOR)
Date: Mon, 12 Aug 1996 14:51:59 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] Histogram?
In-Reply-To: <320F68CC.6E95@mit.edu>
Message-ID: <Pine.SUN.3.91.960812144744.4103A-100000@mills>

Thanks for your help.

Are binarysearch and concatenate in the new matrix module 1.0alpha1 ?

	Jean-Bernard


On Mon, 12 Aug 1996, Jim Hugunin wrote:

> This is not quite optimal (O(N lg N) instead of O(N)), but it is
> adequate for my needs:
> 
> def histogram(a, bins):
> """Calculates the histogram of the values in the 1d array a.
> bins is an array of the edges of the bins, there is one less
> bin than items in this array.  Items that lie exactly on a bin
> edge have a 50/50 chance of appearing in either bin."""
> 	n = binarysearch(sort(a), bins)
> 	n = concatenate( [n, [len(a)]] )
> 	return n[1:]-n[:-1]
> 
> Something like this will wind up in the standard library.
> 
> -Jim
> 
> =================
> MATRIX-SIG  - SIG on Matrix Math for Python
> 
> send messages to: matrix-sig@python.org
> administrivia to: matrix-sig-request@python.org
> =================
> 


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

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

From hinsen@physik.rwth-aachen.de  Mon Aug 12 20:31:26 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Mon, 12 Aug 1996 21:31:26 +0200
Subject: [PYTHON MATRIX-SIG] fromFunction...
In-Reply-To: <199608112109.RAA11928@maigret> (da@maigret.cog.brown.edu)
Message-ID: <9608121931.AA06170@acds21>


   In 1.0a1, fromFunction is absent.  I miss it. =)  Now, the last we
   talked about this, there were still some issues that had to be hacked
   out, and Konrad pseudo-volunteered, but since then he took a vacation, a
   job, moved, and is now somewhat netisolated.  Does anyone else feel up
   to the task?  Or Konrad, are you still interested/able?

Interested yes, but not yet able, and it might take a while.
Next week I'll take up my new job in France, and I might be
a bit busy for a while...

   as efficiently as possible.  Maybe there are much better ways than
   what I just wrote, but it sure was simple.  If someone can show me
   how to do the above without fromFunction, that'd be nice too.  I

Well, the old fromFunction was a rather simple Python function, which
you might just grab from the old Numeric.py. I don't like its limitations,
but if it works for you, use it!

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From fonseca@gaivota.demon.co.uk  Mon Aug 12 20:47:55 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Mon, 12 Aug 1996 20:47:55 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Empty matrix implementation references
Message-ID: <Pine.LNX.3.94.960812203708.763B-100000@gaivota.demon.co.uk>

I mentioned these in a previous message, so here they are:

The relevant Octave documentation page is on the www: 

http://www.che.wisc.edu/cgi-bin/info2www?(octave)Empty%20Matrices

The papers cited are

Carl de Boor, `An Empty Exercise', SIGNUM, Volume 25, pages 2-6, 1990

C. N. Nett and W. M.  Haddad, `A System-Theoretic Appropriate
Realization of the Empty Matrix Concept', IEEE Transactions on
Automatic Control, Volume 38, Number 5, May 1993.

>From the URL above:
>	Briefly, given a scalar `s', and an M by N matrix `M(mxn)', and
>	an M by N empty matrix `[](mxn)' (with either one or both
>	dimensions equal to zero), the following are true:
>
>	     s * [](mxn) = [](mxn) * s = [](mxn)
>	     
>		 [](mxn) + [](mxn) = [](mxn)
>	     
>		 [](0xm) * M(mxn) = [](0xn)
>	     
>		 M(mxn) * [](nx0) = [](mx0)
>	     
>		 [](mx0) * [](0xn) = 0(mxn)

This covers 2d arrays only, but it should be possible to extend it to
n-dimensional arrays, n>=1, by adding missing dimensions to arrays as
usual. For example, if a.shape=(0,n), it should probably behave as if
a.shape=(1,1,0,n), when involved in an operation with a (possibly
empty) 4-d array. This doesn't seem to conflict with the present
handling of 0-d arrays (scalars), either.

It would be nice if all functions and operators in the standard
distribution could handle empty matrices as a special case, and do the
right thing (whatever that may be in each case). Again, the aim would be
to eliminate having to test for empty matrices explicitly in python code. 
Empty matrices do occur reasonably often in state-space descriptions of
systems.

Whether this is important enough at this stage is another matter...

Carlos


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

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

From Carlos Fonseca <fonseca@gaivota.demon.co.uk>  Mon Aug 12 20:36:38 1996
From: Carlos Fonseca <fonseca@gaivota.demon.co.uk> (Carlos Fonseca)
Date: Mon, 12 Aug 1996 20:36:38 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Default axis
In-Reply-To: <01BB8787.412159A0@ling-ling.lcs.mit.edu>
Message-ID: <Pine.LNX.3.94.960812093745.291A-100000@gaivota.demon.co.uk>

On Sun, 11 Aug 1996, Jim Hugunin wrote:

> ...
> My only problem with this is the concatenation function which I
> personally think should only be implemented along axis 0, though I've
> been convinced this is too limiting.  Having this default to a different

Being able to cleanly concatenate arrays along other axes would indeed be
useful. Otherwise, we'll end up transposing the concatenation of
transposed arrays sooner or later.

> Having this default to a different axis than 0 really bothers me, but
> I suppose I'll get over it.
> 
> Comments are welcome - Jim

Concatenation does seem to be a special case, and there may a reason to
make it the exception. For example,

>>> a
 0  1  2  3
 4  5  6  7
 8  9 10 11
>>> b
0 1 2 3

Since these arrays are aligned in the usual sense (a+b would work),
one would expect concatenate((a,b)) to work by default. This means
axis=0. What do others think?

Actually, the above would not work in the present implementation if
b.shape=(4,), but one would have to write concatenate((a,b[NewAxis,:])).
Should it be so or should the new axis be prepended automatically? Along
the same lines, shouldn't axes with a single element be "broadcast" as for
addition? 

Carlos



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

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

From hinsen@physik.rwth-aachen.de  Mon Aug 12 20:37:25 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Mon, 12 Aug 1996 21:37:25 +0200
Subject: [PYTHON MATRIX-SIG] Default axis
In-Reply-To: <01BB8787.412159A0@ling-ling.lcs.mit.edu> (message from Jim Hugunin on Sun, 11 Aug 1996 13:16:05 -0400)
Message-ID: <9608121937.AA06206@acds21>


   Several people how now brought up the issue of the default axis in the =
   various functions in NumPy. The inconsistency of this definition is =
   really a problem.  I think that it's really important to have a =
   consistent default axis, and I propose that the default axis be made -1 =
   (or -2 for things that expect 2d arrays).  This works fairly well for me =

The matter is really a bit more complicated. Basically, the problem
occurs for arrays whose indices should logically be divided into
two sections: a "superarray" with elements that are subarrays (in J these
are called frames and cells, respectively). There are operations
that act on the superarray, like reduction, and the best default axis
for those is 0. Other operations act on cells (e.g. 1D FFT), and their
default axis should be -1. (In J the first type of function would have
infinite default rank, and the second one would have default rank 1).
The distinction makes sense in practice and I am inclilned to keep it.
Nobody will be happy with a setup in which you almost always have to
specify an axis explicitly due to a bad default value.

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From drh@oasis.unl.edu  Mon Aug 12 23:03:25 1996
From: drh@oasis.unl.edu (Doug Heisterkamp)
Date: Mon, 12 Aug 1996 17:03:25 -0500 (CDT)
Subject: [PYTHON MATRIX-SIG] identity?  and asarray?
Message-ID: <199608122203.RAA00661@oasis.unl.edu>

Hi,

The function identity(n) does not return an n by n identity matrix. If 
the current definition is changed from:

def identity(n):
    return resize([1]+n*[n], (n,n))

to

def identity(n):
    return resize([1]+n*[0], (n,n))

then it does what I think the function means. The asarray(a,t) function 
is not returning a new matrix of type t.  To do so, change from:

def asarray(a, typecode=None):
    if type(a) == arraytype and (typecode == None or typecode == a.typecode()): 
        return a
    elif typecode == None:
        return array(a)
    else:
        return a

to

def asarray(a, typecode=None):
    if type(a) == arraytype and (typecode == None or typecode == a.typecode()): 
        return a
    elif typecode == None:
        return array(a)
    else:
        return array(a,typecode)

When should a.asType(t) be use instead of asarray(a,t)?  Is asType faster,
always give a new copy, and/or safe?

Doug Heisterkamp
drh@oasis.unl.edu


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

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

From hinsen@physik.rwth-aachen.de  Tue Aug 13 08:57:39 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Tue, 13 Aug 1996 09:57:39 +0200
Subject: [PYTHON MATRIX-SIG] Empty matrix implementation references
In-Reply-To: <Pine.LNX.3.94.960812203708.763B-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Mon, 12 Aug 1996 20:47:55 +0100 (BST))
Message-ID: <9608130757.AA07268@acds21>

   n-dimensional arrays, n>=1, by adding missing dimensions to arrays as
   usual. For example, if a.shape=(0,n), it should probably behave as if
   a.shape=(1,1,0,n), when involved in an operation with a (possibly
   empty) 4-d array. This doesn't seem to conflict with the present
   handling of 0-d arrays (scalars), either.

Any good book on APL2 contains a detailed discussion on empty arrays
in complicated cases. Empty arrays are not just a curiosity, but an essential
part of APL-style programming.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Tue Aug 13 14:51:25 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 13 Aug 1996 09:51:25 -0400
Subject: [PYTHON MATRIX-SIG] Empty matrix implementation references
References: <9608130757.AA07268@acds21>
Message-ID: <3210885D.4221@mit.edu>

Konrad Hinsen wrote:
> 
>    n-dimensional arrays, n>=1, by adding missing dimensions to arrays as
>    usual. For example, if a.shape=(0,n), it should probably behave as if
>    a.shape=(1,1,0,n), when involved in an operation with a (possibly
>    empty) 4-d array. This doesn't seem to conflict with the present
>    handling of 0-d arrays (scalars), either.
> 
> Any good book on APL2 contains a detailed discussion on empty arrays
> in complicated cases. Empty arrays are not just a curiosity, but an essential
> part of APL-style programming.

Let me repeat here.  I think empty arrays are very important, and unlike
the 0.36 release, this new release really does handle empty arrays. 
Please do continue to point out specific problems, but I think I have
the basic design well under control.  If you find this isn't true, I'd
like to see some examples of code that doesn't work as expected.

-Jim

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

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

From drh@oasis.unl.edu  Tue Aug 13 14:47:54 1996
From: drh@oasis.unl.edu (Doug Heisterkamp)
Date: Tue, 13 Aug 1996 08:47:54 -0500 (CDT)
Subject: [PYTHON MATRIX-SIG] Eigenvectors
Message-ID: <199608131347.IAA01538@oasis.unl.edu>

Hi,

Here's an eigenvector function to add to the updated LinAlg.py module that
Janne Sinkkonen posted a few days ago.  If anyone has other LAPACK access
functions and wishes to share them, email them to me and I'll merge them
in with LinAlg.py.   

Doug Heisterkamp
drh@oasis.unl.edu


# Eigenvectors

def eigenvectors(a):
    """eigenvectors(a) returns u,v  where u is the eigenvalues and
v is a matrix of eigenvectors with vector v[i] corresponds to 
eigenvalue u[i].  The eigenvectors are the rows of the matrix v. 
Satisfies the equation dot(a,v[i]) = u[i]*v[i]
"""
    _assertRank2(a)
    _assertSquareness(a)
    t =_commonType(a)
    real_t = _array_type[0][_array_precision[t]]
    lapack_routine = _findLapackRoutine('geev', t)
    a = _castCopyAndTranspose(t, a)
    n = a.shape[0]
    dummy = Numeric.zeros((1,), t)
    lwork = max(1,8*n) # minimum value: max(1,3*n) real, max(1,2*n) complex
    work = Numeric.zeros((lwork,), t)
    if _array_kind[t] == 1: # Complex routines take different arguments
        w = Numeric.zeros((n,), t)
        rwork = Numeric.zeros((n,),real_t)
        v = Numeric.zeros((n,n), t)
        results = lapack_routine('N', 'V', n, a, n, w,
                                  dummy, 1, v, n, work, lwork, rwork, 0)
    else:
        wr = Numeric.zeros((n,), t)
        wi = Numeric.zeros((n,), t)
        vr = Numeric.zeros((n,n), t)
        results = lapack_routine('N', 'V', n, a, n, wr, wi,
                                  dummy, 1, vr, n, work, lwork, 0)
        if Numeric.logicalAnd.reduce(Numeric.equal(wi, 0.)):
            w = wr
            v = vr
        else:
            w = wr+1j*wi
            v = Numeric.array(vr,Numeric.Complex())
            ind = Numeric.nonzero(
                          Numeric.equal(
                              Numeric.equal(wi,0.0) # true for real e-vals
                                       ,0)          # true for complex e-vals
                                 )                  # indices of complex e-vals
            for i in range(len(ind)/2):
                print "processing i=",i
                v[ind[2*i]] = vr[ind[2*i]] + 1j*vr[ind[2*i+1]]
                v[ind[2*i+1]] = vr[ind[2*i]] - 1j*vr[ind[2*i+1]]
                print "New v = ",v
    if results['info'] > 0:
        raise LinAlgError, 'Eigenvalues did not converge'
    return w,v


   


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

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

From drh@oasis.unl.edu  Tue Aug 13 15:35:25 1996
From: drh@oasis.unl.edu (Doug Heisterkamp)
Date: Tue, 13 Aug 1996 09:35:25 -0500 (CDT)
Subject: [PYTHON MATRIX-SIG] RE: Eigenvalues
Message-ID: <199608131435.JAA01619@oasis.unl.edu>

I should know better then to mail anything out before my second
cup of coffee.  The previous mailing with the eigenvector function
has some print statements left over from debugging.  Just remove
them.  

...
            for i in range(len(ind)/2):
------>         print "processing i=",i
                v[ind[2*i]] = vr[ind[2*i]] + 1j*vr[ind[2*i+1]]
                v[ind[2*i+1]] = vr[ind[2*i]] - 1j*vr[ind[2*i+1]]
------>         print "New v = ",v
    if results['info'] > 0:
...


Doug Heisterkamp
drh@oasis.unl.edu





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

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

From hugunin@mit.edu  Tue Aug 13 16:04:16 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 13 Aug 1996 11:04:16 -0400
Subject: [PYTHON MATRIX-SIG] Histogram?
References: <md5:6D7684F22B856C446C30E25FB3E93E3D>
Message-ID: <32109970.3BE4@mit.edu>

Jean-Bernard ADDOR wrote:
> 
> Thanks for your help.
> 
> Are binarysearch and concatenate in the new matrix module 1.0alpha1 ?
> 
>         Jean-Bernard

Yes, and even in doc.html - Jim

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

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

From hugunin@mit.edu  Tue Aug 13 16:12:33 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 13 Aug 1996 11:12:33 -0400
Subject: [PYTHON MATRIX-SIG] First impressions from the docs
References: <md5:AF01DF51D8E402A32C4A4F3C4D4FEF41>
Message-ID: <32109B61.26E9@mit.edu>

Konrad Hinsen wrote:
...
> In general, the current function set is a big step forward.  I
> expectthat I can now replace most awkward constructions in my
> applicationcode by something more concise and more efficient. More on
> that whenI am finished...

Well of course you think its a big step forward, I did almost everything
you asked for... ;)

> I would like to see more flexibility in the constructor if it iscalled
> with a non-sequence first argument. It should try to dosomething
> meaningful whenever possible. If presented with a file,for example, it
> should assume a text file with numbers and doits best to turn it into
> an array (this is very important forreading data produced by other
> programs). And for argumentsthat have no type/class with special
> meaning, it should calla method toArray() if it exists.I do realize
> that reading from a file intelligently is a non-trivialproblem, and
> therefore the best solution is probably to provide afunction hook
> similar to the one for array printing. Thatgives everyone ample
> opportunity to play with array reading code.I have a function (in
> Python) that reads 1D and 2D arrays wellenough for me, but it is not
> very efficient. That could be astarting point for a more sophisticated
> version.

I completely disagree with this.  I think that reading an array from a
text file should probably be a function that comes with the standard
distribution, but I see NO good reason to overload the array creation
operator with this.  There is support for something like a toArray
method, I'll have to remember what this is and add it to ths docs.

I'd be happy to add your fromFile function to Numeric if you want to
send it to me.

> I wonder what exactly resize() does. First, I don't understand whyit
> is less efficient than reshape(); if the size remains the same,
> itshould perform exactly the same operation. But I really wonder
> what"strange" things can happen if I am not "careful". As long as
> theshape argument makes sense (i.e. contains no negative numbers)
> theresult should be well defined.

If the size remains the same, resize is exactly as efficient as
reshape.  All of my warnings are there because I think many people will
find resize a slightly unusual concept.  I think it needs some sort of
dangerous bend signs around it so that novice users won't be confused. 
If I think I'm just applying a reshape function, but I make a mistake in
my matrix size, I personally want to see an exception.  resize will
instead give me a very different array from what I expected.  That's the
strange thing that can happen.

> The function diagonal() is a typical example of a function thatwould
> benefit from J-style function ranks. As it is defined now,it assumes
> that higher-rank arrays are to be treated as arraysof 2D subarrays
> (i.e. function rank 2). This is a useful function,but a "true"
> higher-rank diagonal (the list of elements for whichall indices are
> equal), corresponding to function rank infinity,is also useful. The
> same applies to trace().

I agree with this, but I've decided to keep ranks out of the 1.0
release  as a general rule.  I'm more concerned at the moment with
getting something coherent out the door.

> The axis defaults for sort() and argsort() should be 0.

Default axes...this merits a new thread...

> There are two methods that I would like to see as functions:
> shape()and asType(). Both occur commonly in numerical algorithms,
> wheretheir argument might be a rank-0 array (i.e. a
> scalar).(Alternatively the two methods could be added to the
> Pythonscalar types, but I am not sure if Guido would approve such
> achange.)

I'll add shape, I find I need it all the time too, its really nice to be
able to get the shape of a list or a tuple.

> I still think that in the general spirit of Python, the defaultmath
> module used by Numeric should be umath, not fast_umath.For someone who
> doesn't know all the details, it is betterto be slow than to be wrong.

This also needs its own thread as there are several issues here.

> More when I have the code running...

Glad to see that you're back with us too - Jim

> Konrad.

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

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

From hugunin@mit.edu  Tue Aug 13 16:18:38 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 13 Aug 1996 11:18:38 -0400
Subject: [PYTHON MATRIX-SIG] Comments on building dynamic libraries
Message-ID: <32109CCE.608C@mit.edu>

Just a comment to those out there trying to build NumPy as a dynamic
library.  First, thanks for checking this out!

Second, due to a bug in 1.4b2, dynamic modules cannot be loaded from the
current directory.  This will be fixed in 1.4b3, but until then you need
to make sure that your dynamic modules are in your PYTHON_PATH and that
you are in a different directory from where the modules exist.

-Jim

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

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

From hugunin@mit.edu  Tue Aug 13 16:28:31 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 13 Aug 1996 11:28:31 -0400
Subject: [PYTHON MATRIX-SIG] Default axis
References: <md5:8B524AFF9C38436A5D4928020564ACA1>
Message-ID: <32109F1F.5852@mit.edu>

Konrad Hinsen wrote:
> 
>    Several people how now brought up the issue of the default axis in the =
>    various functions in NumPy. The inconsistency of this definition is =
>    really a problem.  I think that it's really important to have a =
>    consistent default axis, and I propose that the default axis be made -1 =
>    (or -2 for things that expect 2d arrays).  This works fairly well for me =
> 
> The matter is really a bit more complicated. Basically, the problem
> occurs for arrays whose indices should logically be divided into
> two sections: a "superarray" with elements that are subarrays (in J these
> are called frames and cells, respectively). There are operations
> that act on the superarray, like reduction, and the best default axis
> for those is 0. Other operations act on cells (e.g. 1D FFT), and their
> default axis should be -1. (In J the first type of function would have
> infinite default rank, and the second one would have default rank 1).
> The distinction makes sense in practice and I am inclilned to keep it.
> Nobody will be happy with a setup in which you almost always have to
> specify an axis explicitly due to a bad default value.
> 
> Konrad.

I find myself almost always typing add.reduce(a, -1).  What I mean by
this function is to do the reduction along all of the vectors in my
matrix.

Why is it unreasonable to assume that functions like add.reduce act on
the cells of the array?

As far as sort is concerned, this function only makes sense to me as
operating on 1d arrays (where scalars are the elements to be sorted) if
you want to sort anything else then you need to define a python
comparison function, and at that point you might as well just write the
whole thing as python code.

Since sort naturally applies only to 1d arrays, I think its default axis
should be -1.

Now concatenate is another story entirely, and my current thoughts there
are to leave axis=0 as its default.  This will be the one exception to
the axis=-1 rule.  I also disagree that concatenate should broadcast its
arguments.  should concatenate([[1,2,3],[4,5,6]], 0) ->
[[1,2,3],[4,5,6],[0,0,0]]?

I certainly hope not!

on the other hand, to steal from another post:

Carlos Fonseca wrote:
> >>> a
>  0  1  2  3
>  4  5  6  7
>  8  9 10 11
> >>> b
> 0 1 2 3
> 
> Since these arrays are aligned in the usual sense (a+b would work),
> one would expect concatenate((a,b)) to work by default. This means
> axis=0. What do others think?
> 
> Actually, the above would not work in the present implementation if
> b.shape=(4,), but one would have to write concatenate((a,b[NewAxis,:])).

What you have to write in the current implementation is concatenate( (a,
[b]) ).  This to me is not too much work to make sure that the user
understands what s/he's doing, and this is perfectly in line with the
notion of concatentation found in the rest of python.

-Jim

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

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

From acannon@geog.ubc.ca  Tue Aug 13 18:51:35 1996
From: acannon@geog.ubc.ca (Alex Cannon)
Date: Tue, 13 Aug 1996 10:51:35 -0700 (PDT)
Subject: [PYTHON MATRIX-SIG] Gist under 1.4b2/NumPy 1.0a1
In-Reply-To: <32109B61.26E9@mit.edu>
Message-ID: <Pine.SUN.3.95.960813104607.13325B-100000@phoebe>

Having gotten the new extension installed and running, and before I try
more installation, does anyone know whether the Gist module is still
functional under NumPy 1.0a1? 

Alex

------------------------------------------------------------
Alex Cannon  (acannon@geog.ubc.ca)       Geography 240C
Atmospheric Science Programme            Tel: (604) 822-2269
University of British Columbia, B.C.     Fax: (604) 822-6150


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

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

From tim@lassi.ece.uiuc.edu  Tue Aug 13 19:17:51 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Tue, 13 Aug 1996 13:17:51 -0500
Subject: [PYTHON MATRIX-SIG] little buggies
Message-ID: <199608131816.OAA16768@python.org>


Hi,

Here some problems I found when playing around with the new version of
numerical python. Sorry if they've allready been noted.

1) divmod crashes the interpreter when invoked with array arguments.
>>> a  
1 1 1 1 1
>>> b
2 2 2 2 2
>>> print divmod(a,b)
Segmentation fault

2) Choose faults also for bad indices.
>>> choose((0,1,2),(a,b))
Segmentation fault

3) Where insists that condition be 0,1 instead of 0, nonzero : is this
right?

-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hugunin@mit.edu  Tue Aug 13 21:18:39 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 13 Aug 1996 16:18:39 -0400
Subject: [PYTHON MATRIX-SIG] alpha2 and default axes
Message-ID: <3210E31F.6522@mit.edu>

Thanks to all for your bug reports.  There were actually less than I
expected, I hope this is a comment on the quality of the code, and not
the quantity of the testing.

I want to get a new release out this week with all these little bug
fixes, but I'd prefer to address one major issue before then.

What to do about default axes?

I'd really like some more feedback from you people out there as to what
the default axes for the various NumPy functions should be.  The basic
functions I see here are:

ufunc.reduce, ufunc.accumulate, sort, argsort, argmax, ...
fft
take, choose, repeat, compress
concatenate

My current plan is to make the default argument for everything -1,
except use 0 for concatenate.  So far the only other proposal is from
Konrad and it suggests using 0 as the default argument for everything
except fft.  I disagree with this, but could easily see keeping 0 as the
default argument for take, choose, repeat, and compress.

More opinions would be helpful - Jim

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

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

From janne@avocado.pc.helsinki.fi  Tue Aug 13 22:22:36 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 14 Aug 1996 00:22:36 +0300
Subject: [PYTHON MATRIX-SIG] default axes
In-Reply-To: Jim Hugunin's message of Tue, 13 Aug 1996 16:18:39 -0400
References: <3210E31F.6522@mit.edu>
Message-ID: <oabugf7zdv.fsf@avocado.pc.helsinki.fi>

Jim Hugunin <hugunin@mit.edu> writes:

> ufunc.reduce, ufunc.accumulate, sort, argsort, argmax, ...
> fft

For ufunc.add.reduce(), sort() & Co., and fft(), -1 seems the most
natural choice for me.

> take, choose, repeat, compress

About take(), I don't really know. Maybe 0. choose()... does it have a
default axis? repeat() is like concatenate(), the default axis should
be 0. compress()... no idea.

trace() and diagonal()... should they operate on the diagonal between
-1 and -2, especially if reduce and the others will use the default
axis -1. If the default conceptualization is that there is an
N-1-dimensional array of vectors, for trace() it would seem natural to
think that the array is an N-2-dimensional array of
matrices. Likewise, dot() should reduce -1.

-- 
Janne Sinkkonen      <janne@iki.fi>      <URL: http://www.iki.fi/~janne/ >

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

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

From tim@lassi.ece.uiuc.edu  Wed Aug 14 00:41:20 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Tue, 13 Aug 1996 18:41:20 -0500
Subject: [PYTHON MATRIX-SIG] Re: Strange behaviour with make.
In-Reply-To: <32109B61.26E9@mit.edu> (message from Jim Hugunin on Tue, 13 Aug
 1996 11:12:33 -0400)
Message-ID: <199608132339.TAA17773@python.org>


I though I'd mention this to see if anyone else had this problem:

When I first tried to make the Numeric, 
make Makefile -f Makefile.pre.in
sent my machine into infinite loop.

I mucked around a bit and got it to work. However, when I tried to
recreate it I got stumped. Once I unpacked it fresh and it looped
again. When I copied the Makefile.pre.in from the working version of
NumPy over, it worked.

"AH HA! I just need to dof a diff and I'll know the problem."  So I
did a diff against the original and there was NO DIFFERENCE. So I
unpacked NumPy again into another directory and this time it worked.
And it worked several more times. So now I'm stumped.

Did anyone else see this? 


On a different note: zeros is sort of uninformative if you give it a
number instead of a tuple (an easy mistake...).
>>> from Numeric import *
>>> zeros(5)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
AttributeError: __len__
>>> zeros((5))
Traceback (innermost last):
  File "<stdin>", line 1, in ?
AttributeError: __len__
>>> zeros((5,))
0 0 0 0 0


-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From jbaddor@phy.ulaval.ca  Wed Aug 14 01:39:56 1996
From: jbaddor@phy.ulaval.ca (Jean-Bernard ADDOR)
Date: Tue, 13 Aug 1996 20:39:56 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] strange behaviour
In-Reply-To: <199608132339.TAA17773@python.org>
Message-ID: <Pine.SUN.3.91.960813203750.15478C-100000@mills>

>>> max(arange(5),3)
0 1 2 3 4
>>> min(arange(5),3)
3

	Jean-Bernard



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

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

From tim@lassi.ece.uiuc.edu  Wed Aug 14 14:41:22 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Wed, 14 Aug 1996 08:41:22 -0500
Subject: [PYTHON MATRIX-SIG] Re: Strange behaviour with make.
In-Reply-To: <199608132339.TAA17773@python.org> (tim@lassi.ece.uiuc.edu)
Message-ID: <199608141342.JAA18977@python.org>


>I though I'd mention this to see if anyone else had this problem:
>
>When I first tried to make the Numeric, 
>make Makefile -f Makefile.pre.in
>sent my machine into infinite loop.


Never mind, I figured it out. (I'm using a laptop running linux, and
the clock stops whenever I shut the case. So, the date creeps back
until I resynchronize it with the system clock. In this case, the
NumPy files were newer than the current time on my machine. The reason
I could no longer recreate the looping is that my system time caught
up with the file creation time....)

-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From jbaddor@phy.ulaval.ca  Wed Aug 14 15:01:08 1996
From: jbaddor@phy.ulaval.ca (Jean-Bernard ADDOR)
Date: Wed, 14 Aug 1996 10:01:08 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] NumPy.html
Message-ID: <Pine.SUN.3.91.960814095629.19725F-100000@mills>

To add more explanation about the definition of shape could be usefull.

I hope that in the future some examples could be added.

(Firstly, I didn't understood that for 1D (n,) is needed.)


	Jean-Bernard



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

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

From hugunin@mit.edu  Wed Aug 14 15:12:51 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Wed, 14 Aug 1996 10:12:51 -0400
Subject: [PYTHON MATRIX-SIG] Re: zeros with single integer
References: <9608132339.AA11679@MIT.EDU>
Message-ID: <3211DEE3.7D2F@mit.edu>

tim@lassi.ece.uiuc.edu wrote:

> On a different note: zeros is sort of uninformative if you give it a
> number instead of a tuple (an easy mistake...).
> >>> from Numeric import *
> >>> zeros(5)

I find this so common that zeros will now accept a single integer
instead of a 1 dimensional tuple.  This makes the error message
completely go away.

-Jim

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

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

From hinsen@physik.rwth-aachen.de  Wed Aug 14 16:24:22 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Wed, 14 Aug 1996 17:24:22 +0200
Subject: [PYTHON MATRIX-SIG] First impressions from the docs
In-Reply-To: <32109B61.26E9@mit.edu> (message from Jim Hugunin on Tue, 13 Aug 1996 11:12:33 -0400)
Message-ID: <9608141524.AA11022@acds21>

   > should assume a text file with numbers and doits best to turn it into
   > an array (this is very important forreading data produced by other
   > programs). And for argumentsthat have no type/class with special
   > meaning, it should calla method toArray() if it exists.I do realize

   I completely disagree with this.  I think that reading an array from a
   text file should probably be a function that comes with the standard
   distribution, but I see NO good reason to overload the array creation
   operator with this.  There is support for something like a toArray

Consistency. If there can be a toArray() method for all objects, there should
be one for file objects too. Since it isn't possible to add methods to
C types, hard-coding this feature into the array module is the next best 
thing IMO.

   If the size remains the same, resize is exactly as efficient as
   reshape.  All of my warnings are there because I think many people will
   find resize a slightly unusual concept.  I think it needs some sort of

Well, it's in APL and in all languages derived from it, and it is
one of the most fequently used functions to form special matrices.
In fact, it would make sense to point out in the documentation that resize()
is exactly what APL calls "reshape". In APL, reshaping with a new size is 
definitely more common than reshaping with the same total size.

   dangerous bend signs around it so that novice users won't be confused. 

All it takes is an explanation of the difference...

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Wed Aug 14 16:30:36 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Wed, 14 Aug 1996 11:30:36 -0400
Subject: [PYTHON MATRIX-SIG] naming conventions
Message-ID: <3211F11C.5F70@mit.edu>

I'm cleaning up the naming conventions in preparation for the alpha2
release.  Basically there was a mixture of names like:

fromstring and arrayRange

Following the conventions of the python standard library, all of these
have been converted to:

arrayrange, astype, tolist, ...

I think this is the path of minimal confusion.

The functions that I'm not so happy with are the comparision functions
(for which I've never had great names anyway).

I decided to add an underscore to these names, which I think is also in
the python naming tradition, but is different from the other "two word"
names.

I now have: equal, not_equal, greater_equal, ...
and:  logical_and, boolean_and, ...

Also, I've decided to change the names of the precision functions
(previously Float, Integer, and Complex)

complexcode(32)
floatcode(32)
intcode(16)
...

These names are clearly much more consistent than the previous ones,
however, I still can see room for improvement.

As usual, comments are encouraged - Jim

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

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

From mclay@eeel.nist.gov  Wed Aug 14 12:26:19 1996
From: mclay@eeel.nist.gov (Michael McLay)
Date: Wed, 14 Aug 1996 11:26:19 GMT
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: <3211F11C.5F70@mit.edu>
References: <3211F11C.5F70@mit.edu>
Message-ID: <199608141126.LAA04342@fermi.eeel.nist.gov>

Jim Hugunin writes:

 > Also, I've decided to change the names of the precision functions
 > (previously Float, Integer, and Complex)
 > 
 > complexcode(32)
 > floatcode(32)
 > intcode(16)

Thank you for making this change.  The inclusion of the actual size
will make it clear that the same size numbers will be used on all
machines and it eliminates the need to remember the size names that
are abstract.  I am curious why the new notation looks like a function
call.  There should be a fairly short list of names needed.  Could it
be done  as a constant like complexcode32 complexcode64?  That would
be easier to type.  Also, isn't the code workd redundant?  How about
shortening the names to something like:

Float  -> float32
double -> float64  
Integer -> int32
Long ->    int64


Michael

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

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

From tim@lassi.ece.uiuc.edu  Wed Aug 14 17:43:03 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Wed, 14 Aug 1996 11:43:03 -0500
Subject: [PYTHON MATRIX-SIG] In place ufuncs.
In-Reply-To: <3211F11C.5F70@mit.edu> (message from Jim Hugunin on Wed, 14 Aug
 1996 11:30:36 -0400)
Message-ID: <199608141641.MAA00539@python.org>


What do people think of this?

Is there any possibility of having in-place ufuncs (analagous to *=,
+=, etc.). This seems like it might be both faster and save some space
where its usefull. Something like unfunc.inplace(a,b).

Usefull? Usefull? Hard? Trivial?


-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hugunin@mit.edu  Wed Aug 14 17:54:15 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Wed, 14 Aug 1996 12:54:15 -0400
Subject: [PYTHON MATRIX-SIG] In place ufuncs.
References: <199608141641.MAA00539@python.org>
Message-ID: <321204B7.1273@mit.edu>

tim@lassi.ece.uiuc.edu wrote:
> 
> What do people think of this?
> 
> Is there any possibility of having in-place ufuncs (analagous to *=,
> +=, etc.). This seems like it might be both faster and save some space
> where its usefull. Something like unfunc.inplace(a,b).
> 
> Usefull? Usefull? Hard? Trivial?

Trivial (you can have them now), but I refuse to document it because to
me it looks really ugly.  When python supports *=, etc. I'll be sure
that array objects support that properly (all that will take is somebody
contributing a clean set of patches to Guido).

If you really want inplace functions, try this:
>>> a = arange(3)
>>> add(a, 10, a)
10 11 12
>>> a
10 11 12

-Jim

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

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

From jbaddor@phy.ulaval.ca  Wed Aug 14 17:23:01 1996
From: jbaddor@phy.ulaval.ca (Jean-Bernard ADDOR)
Date: Wed, 14 Aug 1996 12:23:01 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: <3211F11C.5F70@mit.edu>
Message-ID: <Pine.SUN.3.91.960814121847.19725H-100000@mills>

On Wed, 14 Aug 1996, Jim Hugunin wrote:
> 
> complexcode(32)
> floatcode(32)
> intcode(16)
> ...
> 
What about floatcode(16), I have arrays of more than 1 000 000 elements, 
I need to save memory.

	Jean-Bernard

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

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

From hugunin@mit.edu  Wed Aug 14 18:00:58 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Wed, 14 Aug 1996 13:00:58 -0400
Subject: [PYTHON MATRIX-SIG] naming conventions
References: <3211F11C.5F70@mit.edu> <199608141126.LAA04342@fermi.eeel.nist.gov>
Message-ID: <3212064A.3F28@mit.edu>

Michael McLay wrote:
> 
> Jim Hugunin writes:
> 
>  > Also, I've decided to change the names of the precision functions
>  > (previously Float, Integer, and Complex)
>  >
>  > complexcode(32)
>  > floatcode(32)
>  > intcode(16)
> 
> Thank you for making this change.  The inclusion of the actual size
> will make it clear that the same size numbers will be used on all
> machines and it eliminates the need to remember the size names that
> are abstract.  I am curious why the new notation looks like a function
> call.  There should be a fairly short list of names needed.  Could it
> be done  as a constant like complexcode32 complexcode64?  That would
> be easier to type.  Also, isn't the code workd redundant?  How about
> shortening the names to something like:
> 
> Float  -> float32
> double -> float64
> Integer -> int32
> Long ->    int64

Okay, I like your names better than mine, though in this case I would
use capital letters.

Float32
Int32
...

This is consistent with the naming conventions for constants in python
as in Ellipses and None, (and in NumPy as in NewAxis).

My problem now is an easy way to specify that I want an array of floats
that are the same size as python floats.  I don't believe there is any
guarantee that this is the same as Float64 on all systems.

I used floatcode() as a way to specfify that in my system.

types.FloatType is an option, but a little bit cumbersome for my
tastes.  And I'd probably import that as well as IntType and ComplexType
into the Numeric namespace.  Other suggestions?  I could probably
support using float (the builtin function to convert to a python float)
as the parameter but that would be a definate kludge.

-Jim

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

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

From hugunin@mit.edu  Wed Aug 14 18:14:26 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Wed, 14 Aug 1996 13:14:26 -0400
Subject: [PYTHON MATRIX-SIG] naming conventions
References: <Pine.SUN.3.91.960814121847.19725H-100000@mills>
Message-ID: <32120972.224C@mit.edu>

Jean-Bernard ADDOR wrote:
> 
> On Wed, 14 Aug 1996, Jim Hugunin wrote:
> >
> > complexcode(32)
> > floatcode(32)
> > intcode(16)
> > ...
> >
> What about floatcode(16), I have arrays of more than 1 000 000 elements,
> I need to save memory.

Float16 will not be suported.  Float32 and Float64 are the only sizes of
float that I know are supported natively on architectures that I'm
familiar with.  I would guess that Float128 will work on Crays (and
others?)

I have no desire to support any data types other than the native C ones
(and complex numbers which are too important to ignore).

Besides, if you really want to store only 16 bits of precision you
should probably be using fixed precision numbers anyway (and Int16 will
work just fine).

-Jim

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

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

From janne@avocado.pc.helsinki.fi  Wed Aug 14 18:18:49 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 14 Aug 1996 20:18:49 +0300
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: Jim Hugunin's message of Wed, 14 Aug 1996 11:30:36 -0400
References: <3211F11C.5F70@mit.edu>
Message-ID: <oaafvxkhom.fsf@avocado.pc.helsinki.fi>

Jim Hugunin <hugunin@mit.edu> writes:

> These names are clearly much more consistent than the previous ones,

Could you provide a list of changes in the alpha2 release, like this

	oldname1 newname1
	oldname2 newname2 
	etc...

so it would be easier to convert existing code to use the new names.

> however, I still can see room for improvement.

Let's make all the improvements at once (for alpha2). It is much more
easier to write code if the names of library functions are not
constantly drifting... :)

-- 
Janne Sinkkonen      <janne@iki.fi>      <URL: http://www.iki.fi/~janne/ >

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

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

From hugunin@mit.edu  Wed Aug 14 18:26:36 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Wed, 14 Aug 1996 13:26:36 -0400
Subject: [PYTHON MATRIX-SIG] naming conventions
References: <3211F11C.5F70@mit.edu> <oaafvxkhom.fsf@avocado.pc.helsinki.fi>
Message-ID: <32120C4C.1643@mit.edu>

Janne Sinkkonen wrote:
> 
> Jim Hugunin <hugunin@mit.edu> writes:
> 
> > These names are clearly much more consistent than the previous ones,
> 
> Could you provide a list of changes in the alpha2 release, like this
> 
>         oldname1 newname1
>         oldname2 newname2
>         etc...
> 
> so it would be easier to convert existing code to use the new names.

Will do, I might even provide an automated tool for that if I get around
to it.

> > however, I still can see room for improvement.
> 
> Let's make all the improvements at once (for alpha2). It is much more
> easier to write code if the names of library functions are not
> constantly drifting... :)

That's the point about trying to get to a beta1 release.  As soon as I
reach that point, I will be promising to avoid incompatible changes (if
at all possible).  For now I am much more concerned with getting things
right than with being consistent (though I have every intention of
getting this naming thing over with in alpha2).

-Jim

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

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

From fonseca@gaivota.demon.co.uk  Wed Aug 14 18:22:10 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Wed, 14 Aug 1996 18:22:10 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] alpha2 and default axes
In-Reply-To: <3210E31F.6522@mit.edu>
Message-ID: <Pine.LNX.3.94.960814175609.256C-100000@gaivota.demon.co.uk>

On Tue, 13 Aug 1996, Jim Hugunin
wrote:
> [...]
>
> What to do about default axes?
> 
> I'd really like some more feedback from you people out there as to what
> the default axes for the various NumPy functions should be.  The basic
> functions I see here are:
> 
> ufunc.reduce, ufunc.accumulate, sort, argsort, argmax, ...
> fft

-1

> take

-1, so that take(b,argsort(a)) works

> choose, 

Not applicable?

> repeat,

repeats= could actually be a tuple containing the number of times each
dimension should be repeated. In this case, repeats[-1] should correspond
to the last dimension of a, and any missing dimensions in repeats= 
should default to one. So, axis=-1

> compress

-1, same as take()

> concatenate

0, I *think*.

In all cases, the ability to use non-default axes should be preserved.

Carlos



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

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

From Rob.Hooft@embl-heidelberg.de  Wed Aug 14 18:56:39 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Wed, 14 Aug 1996 19:56:39 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: <32120972.224C@mit.edu>
References: <Pine.SUN.3.91.960814121847.19725H-100000@mills>
 <32120972.224C@mit.edu>
Message-ID: <199608141756.TAA24610@nu>

>>>>> "JH" == Jim Hugunin <hugunin@mit.edu> writes:

 JH> Float16 will not be suported.  Float32 and Float64 are the only
 JH> sizes of float that I know are supported natively on
 JH> architectures that I'm familiar with.  I would guess that
 JH> Float128 will work on Crays (and others?)

I think the system where the size of the object is given as an integer
is much better than this concatenation trick. With this new scheme
you need more identifiers for less flexibility. What if I want Float48?
alpha1 would accept it, and give me Float64 instead. How do you want to
solve this now? Furthermore it is now more difficult to choose the
size at runtime.

Furthermore: If I have a Cray-python program that I load on my SGI,
I'd like to get an exception for the Float128, not a compiler error.

?

Rob.
-- 
=== Rob.Hooft@EMBL-Heidelberg.DE   http://www.Sander.EMBL-Heidelberg.DE/rob/ ==
==== In need of protein modeling?  http://www.Sander.EMBL-Heidelberg.DE/whatif/
Validation of protein structures?  http://biotech.EMBL-Heidelberg.DE:8400/ ====
== PGPid 0xFA19277D == Use Linux!  Free Software Rules The World! =============

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

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

From templon@studbolt.mit.edu  Wed Aug 14 18:59:12 1996
From: templon@studbolt.mit.edu (Jeffrey Templon)
Date: Wed, 14 Aug 1996 13:59:12 -0400
Subject: [PYTHON MATRIX-SIG] naming conventions
Message-ID: <199608141759.NAA00572@studbolt.mit.edu>


uh oh, will these names (e.g. FloatType) be something used within
C/C++ extensions, or are they something I will have to type in python
code?? (sorry, my use of NumPy is still at a low level.)  I hope not
the latter, it is really tiring to have to constantly peck at the
shift key.  having everything lowercase really speeds the typing up
and slows the frustration down.

I'd vote against making these types of names.

					Jeff

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

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

From barton@simsg1.mdc.com  Wed Aug 14 19:28:55 1996
From: barton@simsg1.mdc.com (Brien Barton)
Date: Wed, 14 Aug 1996 11:28:55 -0700 (PDT)
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: <3212064A.3F28@mit.edu>
Message-ID: <Pine.SGI.3.95.960814112206.28178B-100000@simsg1.mdc.com>

On Wed, 14 Aug 1996, Jim Hugunin wrote:

> Float32
> Int32
> ...
> 
> My problem now is an easy way to specify that I want an array of floats
> that are the same size as python floats.  ...

How about leaving off the number if you want the default size?

i.e. Float, Int

-- Brien

===============================================================================
Brien Barton      McDonnell Douglas Aerospace, Huntington Beach, CA

     email: barton@simsg1.mdc.com, voice: (714)896-2249, fax:(714)896-5939

"My witty proclivities are nothing compared to my ludicrous ineptitudes."
	- Bob Hope
===============================================================================


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

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

From da@maigret.cog.brown.edu  Wed Aug 14 20:52:18 1996
From: da@maigret.cog.brown.edu (David Ascher)
Date: Wed, 14 Aug 1996 15:52:18 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: <3211F11C.5F70@mit.edu> from "Jim Hugunin" at Aug 14, 96 11:30:36 am
Message-ID: <199608141952.PAA22561@maigret>

> Also, I've decided to change the names of the precision functions
> (previously Float, Integer, and Complex)
> 
> complexcode(32)
> floatcode(32)
> intcode(16)

I don't like the word code, mostly because it can mean so many things.
I can think of at least N different meanings. =)

Any other suggestions?  "type"?

--da

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

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

From tim@lassi.ece.uiuc.edu  Thu Aug 15 00:06:28 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Wed, 14 Aug 1996 18:06:28 -0500
Subject: [PYTHON MATRIX-SIG] In place ufuncs.
In-Reply-To: <321204B7.1273@mit.edu> (message from Jim Hugunin on Wed, 14 Aug
 1996 12:54:15 -0400)
Message-ID: <199608142305.TAA01814@python.org>


The '**' operator doesn't work as I'd expect. Is this the intended behaviour?

>>> power(arange(4),2.)		# Works OK.
 0.  1.  4.  9.
>>> arange(4) ** 2		# Also OK
0 1 4 9
>>> arange(4) ** 2.		# Huh?
Traceback (innermost last):
  File "<stdin>", line 1, in ?
TypeError: illegal argument type for built-in operation
>>pow(arange(4),2.)		# Oh, its same as pow.
Traceback (innermost last):
  File "<stdin>", line 1, in ?
TypeError: illegal argument type for built-in operation
>>> 





-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From tim@lassi.ece.uiuc.edu  Thu Aug 15 00:55:19 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Wed, 14 Aug 1996 18:55:19 -0500
Subject: [PYTHON MATRIX-SIG] Re: Another way to crash the interpreter.
In-Reply-To: <199608142305.TAA01814@python.org> (tim@lassi.ece.uiuc.edu)
Message-ID: <199608142353.TAA01946@python.org>


Admittedly this isn't a good idea, but it still shouldn't crash...

>>> from Numeric import *
>>> arange(4)[::0]
Floating point exception


-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From tim@lassi.ece.uiuc.edu  Thu Aug 15 03:07:29 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Wed, 14 Aug 1996 21:07:29 -0500
Subject: [PYTHON MATRIX-SIG] Bug? inn fft module
In-Reply-To: <199608142353.TAA01946@python.org> (tim@lassi.ece.uiuc.edu)
Message-ID: <199608150206.WAA02265@python.org>


Hi,

I found what may be another bug. fft corrupts its argument when
passed a complex argument. With a double argument it seems OK.

>>> a = ones((4,), Complex())
>>> fft(a)				# OK
 (4.+0.j)  (0.+0.j)  (0.+0.j)  (0.+0.j)
>>> a					# OK
 (4.+0.j)  (0.+0.j)  (0.+0.j)  (0.+0.j)
>>> a = ones((4,), Complex())  
>>> b = ones((4,), Float())
>>> fft(a), fft(b)			# Both OK
( (4.+0.j)  (0.+0.j)  (0.+0.j)  (0.+0.j),  (4.+0.j)  (0.+0.j)
(0.+0.j)  (0.+0.j))
>>> a					# Ooops
 (4.+0.j)  (0.+0.j)  (0.+0.j)  (0.+0.j)
>>> b					# But this is still OK
 1.  1.  1.  1.
>>> 


-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From drh@cherokee.unl.edu  Thu Aug 15 05:12:54 1996
From: drh@cherokee.unl.edu (Doug Heisterkamp)
Date: Wed, 14 Aug 1996 23:12:54 -0500 (CDT)
Subject: [PYTHON MATRIX-SIG] Linear Least Squares for LinAlg.py
Message-ID: <9608150412.AA02735@cherokee.unl.edu>

Hi,

I've written a linear least square function to add to LinAlg.py.  Let
me know if you find any problems with it.  

Doug Heisterkamp
drh@cherokee.unl.edu



# Linear Least Squares 
	
def solveLinearLeastSquares(a, b, rcond=1.e-10):
    """solveLinearLeastSquares(a,b) returns x,resids,rank,s  
where x minimizes 2-norm(|b - Ax|)
      resids is the sum square residuals
      rank is the rank of A
      s is an rank of the singual values of A in desending order
If b is a matrix then x is also a matrix with corresponding columns.
If the rank of A is less than the number of columns of A or greater than
the numer of rows, then residuals will be returned as an empty array
otherwise resids = sum((b-dot(A,x)**2).
Singular values less than s[0]*rcond are treated as zero.
"""
    one_eq = len(b.shape) == 1
    if one_eq:
	b = b[:, Numeric.NewAxis]
    _assertRank2(a, b)
#   _assertSquareness(a)
    m  = a.shape[0]
    n  = a.shape[1]
    n_rhs = b.shape[1]
    ldb = max(n,m)
    if m != b.shape[0]:
        raise LinAlgError, 'Incompatible dimensions'
    t =_commonType(a, b)
    real_t = _array_type[0][_array_precision[t]]
    lapack_routine = _findLapackRoutine('gelss', t)
    bstar = Numeric.zeros((ldb,n_rhs),t)
    bstar[:b.shape[0],:n_rhs] = cp(b)
    a,bstar = _castCopyAndTranspose(t, a, bstar)
#   minimum value of lwork:3*min(n,m) + max([2*min(m,n),max(m,n),n_rhs])
    lwork = 8*min(n,m) + max([2*min(m,n),max(m,n),n_rhs]) 
    s = Numeric.zeros((min(m,n),),real_t)
    work = Numeric.zeros((lwork,), t)
#   Note: in next version rcond will be passed directly to lapack module
#         by for now wrap it in an array
    arcond = Numeric.array([rcond],real_t)
    if _array_kind[t] == 1: # Complex routines take different arguments
	rwork = Numeric.zeros((5*min(m,n)-1,), real_t)
        results = lapack_routine( m, n, n_rhs, a, m, bstar,ldb , s, arcond,
			0,work,lwork,rwork,0 )
    else:
        results = lapack_routine( m, n, n_rhs, a, m, bstar,ldb , s, arcond,
			0,work,lwork,0 )
    if results['info'] > 0:
	raise LinAlgError, 'SVD did not converge in Linear Least Squares'
    resids = Numeric.array([],t)
    if one_eq:
	x = cp(Numeric.ravel(bstar)[:n])
        if (results['rank']==n) and (m>n):
            resids = Numeric.array([Numeric.sum((Numeric.ravel(bstar)[n:])**2)])
    else:
	x = cp(transpose(bstar)[:n,:])
        if (results['rank']==n) and (m>n):
            resids = cp(Numeric.sum((transpose(bstar)[n:,:])**2))
    return x,resids,results['rank'],cp(s[:min(n,m)]) 


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

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

From hinsen@physik.rwth-aachen.de  Thu Aug 15 09:26:03 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Thu, 15 Aug 1996 10:26:03 +0200
Subject: [PYTHON MATRIX-SIG] Default axis
In-Reply-To: <32109F1F.5852@mit.edu> (message from Jim Hugunin on Tue, 13 Aug 1996 11:28:31 -0400)
Message-ID: <9608150826.AA12033@acds21>


   I find myself almost always typing add.reduce(a, -1).  What I mean by
   this function is to do the reduction along all of the vectors in my
   matrix.

   Why is it unreasonable to assume that functions like add.reduce act on
   the cells of the array?

Anything must be possible; the question is just which
version is most frequent and should be the default. If you follow
the J convention for arrays with subarrays, i.e. the first indices
label the frames and the last the cells, then a sum over a list
of vectors would be add.reduce with axis 0. With axis -1 you would
get a list of the sum of the elements of each vector. Both are
reasonable, but the first one is much more frequent. On the other
hand, there are operations tyhat in such cases would typically
operate on the individual vectors (such as sort), and those would
typically be applied to axis -1.
Of course you can also adopt the opposite convention for index assignment,
but that doesn't change the fact that different functions should have
different default axes.

   Now concatenate is another story entirely, and my current thoughts there
   are to leave axis=0 as its default.  This will be the one exception to
   the axis=-1 rule.  I also disagree that concatenate should broadcast its
   arguments.  should concatenate([[1,2,3],[4,5,6]], 0) ->
   [[1,2,3],[4,5,6],[0,0,0]]?

   I certainly hope not!

I certainly hope that it does! Adding a zero column or row to
an array is a frequent function, and in the old version extremely
complicated (and probably slow). A good example is my interpolation code
(which I don't havew at hand right now, but I think I have posted it a while
ago).

And replying to Carlos' question:
   > Since these arrays are aligned in the usual sense (a+b would work),
   > one would expect concatenate((a,b)) to work by default. This means
   > axis=0. What do others think?

I agree.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsen@physik.rwth-aachen.de  Thu Aug 15 09:37:44 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Thu, 15 Aug 1996 10:37:44 +0200
Subject: [PYTHON MATRIX-SIG] default axes
In-Reply-To: <oabugf7zdv.fsf@avocado.pc.helsinki.fi> (message from Janne Sinkkonen on 14 Aug 1996 00:22:36 +0300)
Message-ID: <9608150837.AA12057@acds21>

   For ufunc.add.reduce(), sort() & Co., and fft(), -1 seems the most
   natural choice for me.

I agree about sort and fft, but not about reduce etc.
(Besides, another argument is compatibility with the Python built-in
reduce(), which when applied to a nested list reduces along the
outermost nesting level, i.e. the first axis.

   > take, choose, repeat, compress

   About take(), I don't really know. Maybe 0. choose()... does it have a
   default axis? repeat() is like concatenate(), the default axis should
   be 0. compress()... no idea.

I'd say 0 for all of them.

   trace() and diagonal()... should they operate on the diagonal between
   -1 and -2, especially if reduce and the others will use the default

Definitely.

   matrices. Likewise, dot() should reduce -1.

Actually, dot() is the only function about which I am not sure.
There are several options that make sense:
1) Axis -1 for both arguments. Good for vectors and lists of vectors.
2) Axis -1 for the first and -2 for the second. Good for matrices
   and lists of matrices.
3) Axis -1 for the first and 0 for the second. Good for higher-rank
   tensors.
My personal favourite is 3), but I can't give any relly good argument.
But evidently dot() needs two optional axis arguments to cover all cases.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsen@physik.rwth-aachen.de  Thu Aug 15 09:47:54 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Thu, 15 Aug 1996 10:47:54 +0200
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: <3211F11C.5F70@mit.edu> (message from Jim Hugunin on Wed, 14 Aug 1996 11:30:36 -0400)
Message-ID: <9608150847.AA12104@acds21>

   Following the conventions of the python standard library, all of these
   have been converted to:

   arrayrange, astype, tolist, ...

I'd prefer either capitalized versions or added underscores.

   Also, I've decided to change the names of the precision functions
   (previously Float, Integer, and Complex)

   complexcode(32)
   floatcode(32)
   intcode(16)
   ...


Adding "code" makes sense from your point of view, but for
soimeone jusrt reading a program it is confusing. I'd assume that
"code" stands for "program code" if no other meaning is
evident from context. How about "inttype(32)" etc.?

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsen@physik.rwth-aachen.de  Thu Aug 15 09:56:53 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Thu, 15 Aug 1996 10:56:53 +0200
Subject: [PYTHON MATRIX-SIG] In place ufuncs.
In-Reply-To: <199608142305.TAA01814@python.org> (tim@lassi.ece.uiuc.edu)
Message-ID: <9608150856.AA12113@acds21>


   The '**' operator doesn't work as I'd expect. Is this the intended behaviour?

Of course not, since ** and power() should always be exactly
equivalent. Unfortunately I can't check what's wrong without
having Python 1.4 :-(

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From jbaddor@phy.ulaval.ca  Thu Aug 15 12:18:53 1996
From: jbaddor@phy.ulaval.ca (Jean-Bernard ADDOR)
Date: Thu, 15 Aug 1996 07:18:53 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: <32120972.224C@mit.edu>
Message-ID: <Pine.SUN.3.91.960815065657.27953A-100000@mills>

So, it seems that intcode(8) would continue to be supported, it would be 
great to save space.

How to detect overflows (and correct by setting to the minimum or maximum 
value)?

	Jean-Bernard


On Wed, 14 Aug 1996, Jim Hugunin wrote:

> Jean-Bernard ADDOR wrote:
> > 
> > On Wed, 14 Aug 1996, Jim Hugunin wrote:
> > >
> > > complexcode(32)
> > > floatcode(32)
> > > intcode(16)
> > > ...
> > >
> > What about floatcode(16), I have arrays of more than 1 000 000 elements,
> > I need to save memory.
> 
> Float16 will not be suported.  Float32 and Float64 are the only sizes of
> float that I know are supported natively on architectures that I'm
> familiar with.  I would guess that Float128 will work on Crays (and
> others?)
> 
> I have no desire to support any data types other than the native C ones
> (and complex numbers which are too important to ignore).
> 
> Besides, if you really want to store only 16 bits of precision you
> should probably be using fixed precision numbers anyway (and Int16 will
> work just fine).
> 
> -Jim
> 
> =================
> MATRIX-SIG  - SIG on Matrix Math for Python
> 
> send messages to: matrix-sig@python.org
> administrivia to: matrix-sig-request@python.org
> =================
> 

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

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

From janne@avocado.pc.helsinki.fi  Thu Aug 15 14:18:25 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 15 Aug 1996 16:18:25 +0300
Subject: [PYTHON MATRIX-SIG] default axes
In-Reply-To: Konrad Hinsen's message of Thu, 15 Aug 1996 10:37:44 +0200
References: <9608150837.AA12057@acds21>
Message-ID: <oarap8vl9a.fsf@avocado.pc.helsinki.fi>

Konrad Hinsen      <hinsen@physik.rwth-aachen.de> writes:

> Actually, dot() is the only function about which I am not sure.
> There are several options that make sense:
> 1) Axis -1 for both arguments. Good for vectors and lists of vectors.

2D-matrices are lists of vectors. The interpretation just depends. :)

> 2) Axis -1 for the first and -2 for the second. Good for matrices
>    and lists of matrices.

This would require the second argument to be two-dimensional. I would
prefer a dot() which would give a scalar when applied to two vectors.
This holds for 1) and 3).

> 3) Axis -1 for the first and 0 for the second. Good for higher-rank
>    tensors.
> My personal favourite is 3), but I can't give any relly good argument.

I prefer 3) now.

3) would be nice for 2D matrices, because then 0 would be the
same as -2.

dot() refers to the mathematical concept of dot product or inner
product, and I guess 3) would fulfill some clean formal definition
provided both arguments are real objects and not lists of objects.

If add.reduce() would operate on -1, then a dot like proposed in 1)
would be equivalent to add.reduce(a*b) which is not too difficult to
write, thus that kind of dot() would be more redundant than 3). On the
other hand, Konrad had a good argument against reducing -1 (python's
standard reduce reduces axis 0), so I'm not sure anymore about that.

How about two functions? dot() would be like 3), and then there could
be 'vdot()' (vector dot) like 1)? vdot() would eliminate the commonly
needed add.reduce(a,b,-1), thus add.reduce() could reduce over 0 by
default.

> But evidently dot() needs two optional axis arguments to cover all cases.

I agree.

--
Janne

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

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

From hugunin@mit.edu  Thu Aug 15 14:34:30 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 15 Aug 1996 09:34:30 -0400
Subject: [PYTHON MATRIX-SIG] Re: Bug? inn fft module
References: <9608150205.AA29492@MIT.EDU>
Message-ID: <32132766.277A@mit.edu>

tim@lassi.ece.uiuc.edu wrote:
> 
> Hi,
> 
> I found what may be another bug. fft corrupts its argument when
> passed a complex argument. With a double argument it seems OK.

Clearly a bug.  I'll fix it - Jim

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

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

From hugunin@mit.edu  Thu Aug 15 15:21:34 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 15 Aug 1996 10:21:34 -0400
Subject: [PYTHON MATRIX-SIG] In place ufuncs.
References: <9608142304.AA11756@MIT.EDU>
Message-ID: <3213326E.A9F@mit.edu>

tim@lassi.ece.uiuc.edu wrote:
> 
> The '**' operator doesn't work as I'd expect. Is this the intended behaviour?
...

This is actually a bug in the interpreter (it's there in 1.3 too, but
nobody noticed).  I've just sent off a patch for this to Guido.

-Jim

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

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

From Rob.Hooft@embl-heidelberg.de  Thu Aug 15 17:29:43 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Thu, 15 Aug 1996 18:29:43 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] Fun: hacking some Numerics.
Message-ID: <199608151629.SAA17976@nu>

I'm running python-1.4b2 + Numeric on an ALPHA. Just for fun I was hacking
together a script to do dumb factorization. I have a few problems that could
be due to this being a 64bit python, but I don't have 1.4b2 on any other
machine here to test. Please help.

My script and the output are appended below. Two questions with simpler
cases are extracted from the script:

1)
       nu[160]NumPy% python
       Python 1.4b2 (Aug 12 1996) [C]
       Copyright 1991-1996 Stichting Mathematisch Centrum, Amsterdam
       >>> from Numeric import *
       >>> array([], 'l')   
       EmptyArray
       >>> array([], 'l')[0]
       4294967296
       >>> array([], 'l')[1]
       Traceback (innermost last):
         File "<stdin>", line 1, in ?
       IndexError: index out of bounds
       >>> for i in array([], 'l'):
       ...     print i
       ... 
       4294967296
2)
       nu[161]NumPy% python
       Python 1.4b2 (Aug 12 1996) [C]
       Copyright 1991-1996 Stichting Mathematisch Centrum, Amsterdam
       >>> from Numeric import *
       >>> where([0,1,1,0,1,1],[0,0,0,0,0,0],[1,1,1,1,1,1])
       1 0 0 1 0 0
       >>> where([0,1,2,0,1,2],[0,0,0,0,0,0],[1,1,1,1,1,1])
       1 0 0 0 0 0

Thanks in advance,

Rob.
------------------------------------------------------------------------
from Numeric import *
import math

def sieve(max):
	numbers=range(max+1)
	size=int(math.sqrt(max))
	if size<5:
		trials=[2,3]
	else:
		trials=sieve(size)
	for i in trials:
		try:
			j=i*i
			while 1:
				numbers[j]=0
				j=j+i
		except IndexError:
			pass
	return filter(lambda x:x>1,numbers)

def asieve(max):
	numbers=arange(max+1)
	# one is not prime
        numbers[1]=0
	size=int(math.sqrt(max))
	if size<5:
		trials=[2,3]
	else:
		trials=asieve(size)
	print "We need to try all in "+`trials`
	for i in trials:
		print "Filtering by %d"%i
		cond=numbers%i
		cond[i]=1
		print cond
		print numbers
		numbers=where(cond,numbers,0)
		print numbers
	return nonzero(numbers)

def factor(num,upto=1000000):
	for p in sieve(upto):
		if num%p==0:
			print "Can divide by %d"%p

def afactor(num,upto=1000000):
	for p in asieve(upto):
		if num%p==0:
			print "Can divide by %d"%p

factor(129753308,upto=99)
afactor(129753308,upto=99)
---------------------------------------------------------------
Can divide by 2
Can divide by 29
We need to try all in [2, 3]
Filtering by 2
0 0 1 1 0 1 0 1 0 1
0 0 2 3 4 5 6 7 8 9
0 0 2 3 0 5 0 7 0 9
Filtering by 3
0 0 2 1 0 2 0 1 0 0
0 0 2 3 0 5 0 7 0 9
0 0 0 0 0 0 0 0 0 0
We need to try all in array([], 'l')
Filtering by 4294967296
 1  0  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
      26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
      50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
      74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
      98 99
 0  0  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
      26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
      50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
      74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
      98 99
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
--------------------------------------------------------------------
-- 
=== Rob.Hooft@EMBL-Heidelberg.DE   http://www.Sander.EMBL-Heidelberg.DE/rob/ ==
==== In need of protein modeling?  http://www.Sander.EMBL-Heidelberg.DE/whatif/
Validation of protein structures?  http://biotech.EMBL-Heidelberg.DE:8400/ ====
== PGPid 0xFA19277D == Use Linux!  Free Software Rules The World! =============

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

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

From hugunin@mit.edu  Thu Aug 15 17:51:04 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 15 Aug 1996 12:51:04 -0400
Subject: [PYTHON MATRIX-SIG] Fun: hacking some Numerics.
References: <199608151629.SAA17976@nu>
Message-ID: <32135578.77C9@mit.edu>

Rob.Hooft@embl-heidelberg.de wrote:
> 
> I'm running python-1.4b2 + Numeric on an ALPHA. Just for fun I was hacking
> together a script to do dumb factorization. I have a few problems that could
> be due to this being a 64bit python, but I don't have 1.4b2 on any other
> machine here to test. Please help.
...

First, I'm glad you're playing with this on an alpha.  I have a couple
around here, but don't have that much time to test on 64-bit systems.

1) where is fixed in alpha2
2) array([], 'l')[0] is a bug (even on 32bit machines) I'll fix it.
3) for i in array([], 'l') is the same bug.

Thanks for the bugs - Jim

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

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

From hugunin@mit.edu  Thu Aug 15 19:45:43 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 15 Aug 1996 14:45:43 -0400
Subject: [PYTHON MATRIX-SIG] Poll - Lapack and FFTPack
Message-ID: <32137057.4579@mit.edu>

I've discovered once again that building Lapack on a system without a
FORTRAN compiler is a lot of ugly work, and you get something
significantly slower than the "real" version in the bargain.

Nonetheless, I've managed to convince myself that LAPACK is clearly the
right way to go as far a standard linear algebra library is concerned
for NumPy.  Doug Heisterkamp's (and Konrad's) lapack interface module
covers most of what people have been asking for in a standard library.

Possible solution:

1) Everybody buys a FORTRAN compiler ;)

2) Everyone goes through a hellish day of porting to get lapack compiled
on their system

3) I distribute precompilied lapack and fftpack libraries (with the
blas) for ALL the common architectures.

So, here's the poll:

If you have a way to produce lapack/fftpack library binaries for a given
platform and are able and willing to allow those binaries to be freely
distributed, please send me a piece of mail listing your computer/os and
what libraries you could provide.

I'm assuming here that if you give me a statically linked lapack
library, linked against libblas and libf77, then I can link this into my
C module with no problem.  If this isn't true, please help me understand
this better.

A little bit at my wits end over the whole standard library business...

- Jim

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

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

From hohn@math.utah.edu  Thu Aug 15 20:52:16 1996
From: hohn@math.utah.edu (Michael Hohn)
Date: Thu, 15 Aug 1996 13:52:16 -0600 (MDT)
Subject: [PYTHON MATRIX-SIG] Poll - Lapack and FFTPack
In-Reply-To: <32137057.4579@mit.edu> (message from Jim Hugunin on Thu, 15 Aug
 1996 14:45:43 -0400)
Message-ID: <199608151952.NAA11267@alab07.math.utah.edu>



>> ...
>> Possible solution:
>> 
>> 1) Everybody buys a FORTRAN compiler ;)
>> 
>> 2) Everyone goes through a hellish day of porting to get lapack compiled
>> on their system
>> ...

Actually, LAPACK seems to work with g77, the gnu fortran compiler (at
least with version 0.5.17);  installing it requires some disk space
(~100Mb) as well as the gcc-2.7* source.

Mike

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

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

From fonseca@gaivota.demon.co.uk  Thu Aug 15 19:39:10 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Thu, 15 Aug 1996 19:39:10 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] default axes
In-Reply-To: <oarap8vl9a.fsf@avocado.pc.helsinki.fi>
Message-ID: <Pine.LNX.3.94.960815190125.411D-100000@gaivota.demon.co.uk>

On 15 Aug 1996, Janne Sinkkonen wrote:
>
> If add.reduce() would operate on -1, then a dot like proposed in 1)
> would be equivalent to add.reduce(a*b) which is not too difficult to
> write, thus that kind of dot() would be more redundant than 3). On the
> other hand, Konrad had a good argument against reducing -1 (python's
> standard reduce reduces axis 0), so I'm not sure anymore about that.

I really think dot(a,b) should behave _exactly_ like

add.reduce(a*b,axis=-1)

The big difference is that, unlike the expression above, there would be no
need to allocate memory to store a*b, just the final result.

If, for example,

a.shape=(m,n)
b.shape=(n,p)

then

dot(a[...,NewAxis],b,axis=-2).shape = (m,p) -> matrix multiplication

whithout having to allocate an array of shape=(m,n,p), as add.reduce
would.

In general, by adding axes as needed and broadcasting dimensions, one can
perform anything from "vectorized" dot products to "vectorized" array
multiplication of arbitrary rank. I proposed this to the list one or two
months ago, but then never got back to it. 

Clearly, dot() should allow the default axis to be specified. Note that
*one* axis seems to be enough: for a dot product of row vectors, all axes
must be aligned. For "intermediate" rank multiplication, some axes must be
aligned (assume the outer), while correctly adding the necessary
additional axes will align the inner. 

Full rank multiplication of two arrays could be written:

dot(a[...,(n-1)*(NewAxis,)],b,axes=-n)

where n is the number of dimensions of b, and assuming the last dimension
of a matches the first of b.

> How about two functions? dot() would be like 3), and then there could
> be 'vdot()' (vector dot) like 1)? vdot() would eliminate the commonly
> needed add.reduce(a,b,-1), thus add.reduce() could reduce over 0 by
> default.

I believe this would be the way to go. Not that it really matters, but I
would call your vdot() just dot(), and give matrix multiplication another
name (mtimes(), mmult(), mprod(), whatever). All cases of matrix
multiplication are possible with [v]dot(), yet I agree that adding axes by
hand could be done better in a function built on top of dot().

Konrad> But evidently dot() needs two optional axis arguments to cover
all cases.
> 
> I agree.
> --
> Janne

See above.

Carlos



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

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

From guido@CNRI.Reston.Va.US  Thu Aug 15 22:41:11 1996
From: guido@CNRI.Reston.Va.US (Guido van Rossum)
Date: Thu, 15 Aug 1996 17:41:11 -0400
Subject: [PYTHON MATRIX-SIG] naming conventions
In-Reply-To: Your message of "Wed, 14 Aug 1996 13:26:36 EDT."
 <32120C4C.1643@mit.edu>
References: <3211F11C.5F70@mit.edu> <oaafvxkhom.fsf@avocado.pc.helsinki.fi>
 <32120C4C.1643@mit.edu>
Message-ID: <199608152141.RAA09148@monty>

> > so it would be easier to convert existing code to use the new names.
> 
> Will do, I might even provide an automated tool for that if I get around
> to it.

There's a tool that should be pretty close to what you want (it lexes
C code, but should be adaptable to lex Python code -- note there's a
Python tokenizer in Lib/tokenizer.py): Tools/scripts/fixcid.py.

I intend to use fixcid.py for the Great Renaming.  (I still need to
postprocess the output manually, for a variety of reasons, one of
which is that I'm a perfectionist and would like to take the
opportunity to do a general clean-up...).

--Guido van Rossum (home page: http://www.python.org/~guido/)

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

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

From phil@geog.ubc.ca  Fri Aug 16 00:25:23 1996
From: phil@geog.ubc.ca (Phil Austin)
Date: Thu, 15 Aug 1996 16:25:23 -0700 (PDT)
Subject: [PYTHON MATRIX-SIG] Poll - Lapack and FFTPack
In-Reply-To: <32137057.4579@mit.edu>
References: <32137057.4579@mit.edu>
Message-ID: <199608152325.QAA10650@coot.geog.ubc.ca>

Jim Hugunin writes:
 > 
 > So, here's the poll:
 > 
 > If you have a way to produce lapack/fftpack library binaries for a given
 > platform and are able and willing to allow those binaries to be freely
 > distributed, please send me a piece of mail listing your computer/os and
 > what libraries you could provide.
 > 

We could do any of:

Solaris 2.5 (Sparc 20) with f77 4.0

Sunos 4.1.4 (Sparc 20) with f77 2.0.1

AIX 3.2 with xlf (version ?)

IRIX 6.2 with f77 6.2 (R5000 and R8000)

IRIX 4.0.5 with f77 6.2 (R3000)

Also the f2c'd version of fftpack that comes with Mumit Khan's
fftpack++ has built on all of the above with gcc 2.7.2:

(see http://www.xraylith.wisc.edu/~khan/software/fftpack/fftpack.html)



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

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

From hinsen@physik.rwth-aachen.de  Fri Aug 16 10:21:23 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Fri, 16 Aug 1996 11:21:23 +0200
Subject: [PYTHON MATRIX-SIG] Poll - Lapack and FFTPack
In-Reply-To: <32137057.4579@mit.edu> (message from Jim Hugunin on Thu, 15 Aug 1996 14:45:43 -0400)
Message-ID: <9608160921.AA14451@acds21>

   3) I distribute precompilied lapack and fftpack libraries (with the
   blas) for ALL the common architectures.

Netlib has LAPACK binaries for most common platforms.
I remember that the SGI version they have is only for
R4xxx processors, so I had to compile my own for the R3000,
which I can offer to anyone who needs it.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsen@physik.rwth-aachen.de  Fri Aug 16 10:32:35 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Fri, 16 Aug 1996 11:32:35 +0200
Subject: [PYTHON MATRIX-SIG] default axes
In-Reply-To: <oarap8vl9a.fsf@avocado.pc.helsinki.fi> (message from Janne Sinkkonen on 15 Aug 1996 16:18:25 +0300)
Message-ID: <9608160932.AA14512@acds21>

   > 2) Axis -1 for the first and -2 for the second. Good for matrices
   >    and lists of matrices.

   This would require the second argument to be two-dimensional. I would
   prefer a dot() which would give a scalar when applied to two vectors.
   This holds for 1) and 3).

Good point. I was actually assuming that axis=-2 is taken to mean -1
whenever there are not enough dimensions, an similrly axis=1
means axis=0 for a 1D array. But I am not at all sure if
that is how the current code behaves.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsenk@ere.umontreal.ca  Fri Aug 16 10:36:00 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Fri, 16 Aug 1996 05:36:00 -0400
Subject: [PYTHON MATRIX-SIG] default axes
In-Reply-To: <Pine.LNX.3.94.960815190125.411D-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Thu, 15 Aug 1996 19:39:10 +0100 (BST))
Message-ID: <199608160936.FAA20848@cyclone.ERE.UMontreal.CA>

> I really think dot(a,b) should behave _exactly_ like
> 
> add.reduce(a*b,axis=-1)

Why?

> Full rank multiplication of two arrays could be written:
> 
> dot(a[...,(n-1)*(NewAxis,)],b,axes=-n)

That is a lot too complicated for a frequent operation, especially
considering that n might not be available as a variable or constant,
i.e. it would have to be written as shape(b)[0].

Konrad.
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From Rob.Hooft@embl-heidelberg.de  Fri Aug 16 11:14:05 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Fri, 16 Aug 1996 12:14:05 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] Another problem?
Message-ID: <199608161014.MAA19954@nu>


While hacking some more on my "code-cracker" :-) script, I found what I think
is another problem:

   nu[101]NumPy% python
   Python 1.4b2 (Aug 12 1996) [C]
   Copyright 1991-1996 Stichting Mathematisch Centrum, Amsterdam
   >>> from Numeric import *
   >>> nonzero([0,2,0,4])
   1 1 3 3 3 3
   >>> 

from the description I read nonzero should return [1,3] here. It looks
like a mixture with repeat... 

Furthermore, I did some more work on the script, got it working, but
the results are very disappointing:

  Can divide by 2
  Can divide by 29
  factor took  10.577 seconds
  Can divide by 2
  Can divide by 29
  afactor took   7.916 seconds

It gets WORSE if I increase the size of the problem. Profiling (run
appended) changes the ratio between conventional and numeric
dramatically, so that is rather useless in this case.

Can anyone help me to make optimal use of the arrays here? The script
is of no serious use whatsoever (it may make a simple demo), but my
understanding of Numeric might be boosted....

Rob.
----------------------------------------------------------
from Numeric import *
import math

def sieve(max):
	numbers=range(max+1)
	size=int(math.sqrt(max))
	if size<5:
		trials=[2,3]
	else:
		trials=sieve(size)
	for i in trials:
		try:
			j=i*i
			while 1:
				numbers[j]=0
				j=j+i
		except IndexError:
			pass
	return filter(lambda x:x>1,numbers)

def asieve(max,atype='l'):
	numbers=array([1],atype)
	numbers=resize(numbers,[max+1])
	# one is not prime
        numbers[1]=0
	size=int(math.sqrt(max))
	if size<5:
		trials=[2,3]
	else:
		trials=asieve(size)
	#print "We need to try all in "+`trials`
	for i in trials:
		#print "Filtering %d by %d"%(max,i)
		cond=concatenate((array([1],atype),zeros([i-1],atype)))
		#print cond
		cond=resize(cond,[max+1])
		#print cond
		cond[i]=0
		#print cond
		#print numbers
		numbers=where(cond,0,numbers)
		#print numbers
	return nonzero(numbers)

def factor(num,upto=1000000):
	for p in sieve(upto):
		if num%p==0:
			print "Can divide by %d"%p

def afactor(num,upto=1000000):
	for p in asieve(upto):
		if num%p==0:
			print "Can divide by %d"%p

import timing
timing.start()
factor(129753308,upto=99999)
timing.finish()
print "factor took %7.3f seconds"%(timing.micro()/1.e6)
timing.start()
afactor(129753308,upto=99999)
timing.finish()
print "afactor took %7.3f seconds"%(timing.micro()/1.e6)
import profile

#profile.run("factor(129753308,upto=99999)")
#profile.run("afactor(129753308,upto=99999)")

----------------------------------------------------------
nu[120]NumPy% python ~/x.py
Can divide by 2
Can divide by 29
         100341 function calls (100339 primitive calls) in 284.433 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1  216.867  216.867  284.433  284.433 profile:0(factor(129753308,upto=99999))
        0    0.000             0.000          profile:0(profiler)
        1    0.000    0.000   67.567   67.567 python:0(14222.C.1)
   100335   29.233    0.000   29.233    0.000 x.py:19(<lambda>)
      3/1   38.133   12.711   67.367   67.367 x.py:4(sieve)
        1    0.200    0.200   67.567   67.567 x.py:45(factor)


Can divide by 2
Can divide by 29
         397 function calls (395 primitive calls) in 15.233 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       77    0.033    0.000    0.033    0.000 Numeric.py:152(ravel)
        3    0.033    0.011    0.233    0.078 Numeric.py:158(nonzero)
        3    0.150    0.050    0.200    0.067 Numeric.py:16(arrayRange)
       74    3.767    0.051    3.767    0.051 Numeric.py:171(where)
        3    0.050    0.017    0.050    0.017 Numeric.py:192(ones)
      151    2.133    0.014    2.133    0.014 Numeric.py:43(concatenate)
       77    0.250    0.003    2.383    0.031 Numeric.py:81(resize)
        3    0.000    0.000    0.000    0.000 Precision.py:34(Integer)
        1    8.483    8.483   15.233   15.233 profile:0(afactor(129753308,upto=99999))
        0    0.000             0.000          profile:0(profiler)
        1    0.000    0.000    6.750    6.750 python:0(14222.C.2)
      3/1    0.117    0.039    6.533    6.533 x.py:21(asieve)
        1    0.217    0.217    6.750    6.750 x.py:50(afactor)
-------------------------------------------------------------

-- 
=== Rob.Hooft@EMBL-Heidelberg.DE   http://www.Sander.EMBL-Heidelberg.DE/rob/ ==
==== In need of protein modeling?  http://www.Sander.EMBL-Heidelberg.DE/whatif/
Validation of protein structures?  http://biotech.EMBL-Heidelberg.DE:8400/ ====
== PGPid 0xFA19277D == Use Linux!  Free Software Rules The World! =============

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

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

From tim@lassi.ece.uiuc.edu  Fri Aug 16 15:56:13 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Fri, 16 Aug 1996 09:56:13 -0500
Subject: [PYTHON MATRIX-SIG] Another problem?
In-Reply-To: <199608161014.MAA19954@nu> (Rob.Hooft@embl-heidelberg.de)
Message-ID: <199608161454.KAA07145@python.org>


I was about to send some mail myself about the non-zero problem. I
tracked it down in the numeric library and it looks like,

def nonzero(a):
    """Return the indices of the elements of a which are not zero, a
must be 1d
    """
    return repeat(arange(len(a)), a)

should be:

def nonzero(a):
    """Return the indices of the elements of a which are not zero, a
must be 1d
    """
    return repeat(arange(len(a)), nonZero(a))

At least that gives the behaviour I expect.

-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hugunin@mit.edu  Fri Aug 16 16:14:41 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 16 Aug 1996 11:14:41 -0400
Subject: [PYTHON MATRIX-SIG] Another problem?
References: <199608161014.MAA19954@nu>
Message-ID: <32149061.45BC@mit.edu>

Rob.Hooft@embl-heidelberg.de wrote:
> 
> While hacking some more on my "code-cracker" :-) script, I found what I think
> is another problem:
> 
>    nu[101]NumPy% python
>    Python 1.4b2 (Aug 12 1996) [C]
>    Copyright 1991-1996 Stichting Mathematisch Centrum, Amsterdam
>    >>> from Numeric import *
>    >>> nonzero([0,2,0,4])
>    1 1 3 3 3 3
>    >>>
> 
> from the description I read nonzero should return [1,3] here. It looks
> like a mixture with repeat...

nonzero is implemented using repeat, I made a mistake in writing it to
give that strange mixture.  This is fixed in alpha2 which will be
released before I go home tonight.

> Furthermore, I did some more work on the script, got it working, but
> the results are very disappointing:
> 
>   Can divide by 2
>   Can divide by 29
>   factor took  10.577 seconds
>   Can divide by 2
>   Can divide by 29
>   afactor took   7.916 seconds

I'm running on a faster machine than you, so my numbers are faster in
both cases, still the relative comparision is valid.

Standard python version
factor took   2.708 seconds
Using NumPy  - properly ;)
afactor took   0.322 seconds

Here's my new version of your afactor and asieve functions.  The changes
to afactor are actually not needed to get the speed improvement.  I'd be
tempted to claim that the new version of asieve is easier to understand
as well as faster, the changes to afactor are a little awkward but I
thought you might be interested in seeing the style anyway.

I doubt that my new version is more than a factor of 2 slower than a C
implementation of the same algorithm (though feel free to show me wrong
with a code sample).

def asieve(max,atype='l'):
        size=int(sqrt(max))
        if size<5:
                known_primes=[2,3]
        else:
                known_primes=asieve(size)

	#Initially assume all numbers are prime
	numbers=ones([max+1], atype)
	#0 and 1 are not prime
	numbers[0:2]=0
	#print trials
        for i in known_primes:
	        #Set multiples of i to be nonprime
	        numbers[(i*i)::i] = 0
	#Those entries which are nonzero are prime
        return nonzero(numbers)


def afactor(num,upto=1000000):
        #Calculate all of the primes up to upto
        s = asieve(upto)
        #Return just those primes that divide evenly into num
        for d in take(s, nonzero(equal(num % s, 0))):
	        print "Can divide by %d"%d



-Jim

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

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

From tim@lassi.ece.uiuc.edu  Fri Aug 16 16:29:48 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Fri, 16 Aug 1996 10:29:48 -0500
Subject: [PYTHON MATRIX-SIG] Factoring?
In-Reply-To: <199608161014.MAA19954@nu> (Rob.Hooft@embl-heidelberg.de)
Message-ID: <199608161528.LAA07312@python.org>


Here's another factoring routine. It runs pretty fast (under a second
using the profiler for '129753308'), but I have no idea if its very
good algorithymically. I doubt that this is really what you want, but
its yours to play with. I've been tweaking it recently, so if you find
any bugs, let me know. Enjoy.

def factor(n):
    """Return a tuple containing the factors of n.
    This is probably not the best way to do this, but hey, 
    it's simple.
    """ 
    # Take care of special cases.
    if   n <= 0: raise ValueError      
    elif n <= 3: return [n]
    elif n <= 5: c = arange(2,n+1)
    else:				# General case.
	sr = int(sqrt(n))
	c = concatenate((arange(2, n/sr), n/arange(sr,0,-1)))
    c = compress(equal(n%c,0), c)
    factors = [c[0]]
    while len(c) > 1:
	c = choose(notEqual(c[1:]%c[0],0), (c[1:]/c[0], c[1:]))
	if c[0] != 1:
	    factors.append(c[0])
    return factors

-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hugunin@mit.edu  Fri Aug 16 17:03:06 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 16 Aug 1996 12:03:06 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
Message-ID: <32149BBA.14D2@mit.edu>

I've made my decisions on the final conventions for alpha2, but I
thought I'd give people a chance to comment on them before the end of
the day today when the release goes out.  Yep, you heard right, alpha2
will be available before I go home tonight.

These are also very likely to be the conventions for the final release,
but I'm not making any promises until 1.0beta1.

1) Explicitly declaring an array's type

Note: most people will never need to use any of these names as the
typical array functions will produce the right type by default.

For types constants will be defined within Numeric.py.  They will have
the following names (on a typical system, on a supercomputer their might
be different values available):

Float - the size of a python float, generally the largest float
available on your system
Float0 - the smallest float on your system (usually Float32)

Float32 - usually how you get a C float
Float64 - usually how you get a C double

For integers:
Integer and Integer0 as before

UnsignedInteger8
Integer8
Integer16
Integer32
Integer64 (if you're lucky)

For complex numbers:
Complex, Complex0
Complex32 and Complex64

This solution is clearly a compromise, but the best compromise I could
come up with.

2) Default axes

After reading all of the discussion over what are the appropriate axes
for the various operations, I've become convinced that there is no
obvious choice.  Therefore I think it is really important to have a
single default axis so that at least people will only have one rule to
remember.

Because I can't possibly conceive of doing "fft" and its ilk with a
default axis other than -1, every function in NumPy will have a default
axis of -1 (or -2 for matrix operations).  This currently includes all
of the following functions.

sort, argsort, argmax, argmin, fft, 
take, repeat, compress, concatenate, 
ufunc.reduce, ufunc.accumulate

I wish I could come up with a better compromise, but I myself was
finding it hard to remember what the default axes were for different
operations, and that's just intolerable.

I will add keyword arguments to all of the functions that accept an axis
so that you can at least write concatenate([a,b], axis=0) which I think
is much more readable than the non-keyword alternative.

-Jim

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

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

From tim@lassi.ece.uiuc.edu  Fri Aug 16 17:40:24 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Fri, 16 Aug 1996 11:40:24 -0500
Subject: [PYTHON MATRIX-SIG] Yet another way to crash the interpreter.
In-Reply-To: <32149061.45BC@mit.edu> (message from Jim Hugunin on Fri, 16 Aug
 1996 11:14:41 -0400)
Message-ID: <199608161638.MAA07431@python.org>


Hi,

Here's one more:  Numeric's sqrt doesn't work with long its. And other
Numerical stuff seems to crash the interpreter when combined with long
ints. For example:

>>> from Numeric import *
>>> sqrt(4l)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
AttributeError: attribute-less object
>>> 4/arange(1,3)
4 2
>>> 4l/arange(1,3)
Segmentation fault

...Later

>>> from Numeric import *
>>> 4l*arange(1,3)
Segmentation fault


-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hugunin@mit.edu  Fri Aug 16 17:49:41 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 16 Aug 1996 12:49:41 -0400
Subject: [PYTHON MATRIX-SIG] Re: Yet another way to crash the interpreter.
References: <9608161637.AA21236@MIT.EDU>
Message-ID: <3214A6A5.1FDB@mit.edu>

tim@lassi.ece.uiuc.edu wrote:
> 
> Hi,
> 
> Here's one more:  Numeric's sqrt doesn't work with long its. And other
> Numerical stuff seems to crash the interpreter when combined with long
> ints. For example:
> 
> >>> from Numeric import *
> >>> sqrt(4l)
> Traceback (innermost last):
>   File "<stdin>", line 1, in ?
> AttributeError: attribute-less object

That's life...  Well seriously, what do you expect to happen here? 
Taking the sqrt of a long int is a fairly involved process, and I'd hate
to be the one who had to write the code to find the sin of one.

If a python object has a __sqrt__ method, then the sqrt function will
work properly on it.  Since long ints don't export any such methods
there's not really any good options.  Sorry.

> >>> 4/arange(1,3)
> 4 2
> >>> 4l/arange(1,3)
> Segmentation fault
> 
> ...Later
> 
> >>> from Numeric import *
> >>> 4l*arange(1,3)
> Segmentation fault

These are very strange, and don't happen to me on either solaris of NT
with alpha2.  Please test them out again with alpha2 on your system and
if the problem persists we might have to track it down together.

BTW - what system are you working on?

-Jim

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

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

From hinsenk@ere.umontreal.ca  Fri Aug 16 18:28:05 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Fri, 16 Aug 1996 13:28:05 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <32149BBA.14D2@mit.edu> (message from Jim Hugunin on Fri, 16 Aug 1996 12:03:06 -0400)
Message-ID: <199608161728.NAA19827@cyclone.ERE.UMontreal.CA>

> After reading all of the discussion over what are the appropriate axes
> for the various operations, I've become convinced that there is no
> obvious choice.  Therefore I think it is really important to have a
> single default axis so that at least people will only have one rule to
> remember.

I'd rather remember a more complicated rule than type explicit axis
specifications for almost every function!

> Because I can't possibly conceive of doing "fft" and its ilk with a
> default axis other than -1, every function in NumPy will have a default
> axis of -1 (or -2 for matrix operations).  This currently includes all

Could it be that you have a special bias for FFT? I don't consider
FFTs so fundamental that they should set the default for all
array functions. Statistically most functions would best have
a default of 0, those that should have another default are the
exceptions.

> I wish I could come up with a better compromise, but I myself was
> finding it hard to remember what the default axes were for different
> operations, and that's just intolerable.

Using -1 for everything is more intolerable than anything else.
A quick glance at my existing code shows that I would need
an explicit axis specifications for 80% of my function calls!

Actually the default axis discussion has a long history in the APL
community. The original APL allowed axis specifications in the same
style as Python now does. The default axis was always zero, but for
reduce and accuulate an alternate form with a default of -1 was
provided. The various problems with this approach (and other
limitations in APL) led to the rank concept in J. For most
applications there is not much difference between function ranks and
axis specifications, since the effect for simple arrays is rather
similar. But J also gave up the "the same default for everyone"
rule. However, it is possible to inquire about the default rank
of any J function, which helps to reduce confusion and bad memory
problems ;-)

> I will add keyword arguments to all of the functions that accept an axis
> so that you can at least write concatenate([a,b], axis=0) which I think
> is much more readable than the non-keyword alternative.

Definitely. But what happens to dot(), which needs two axes?

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Fri Aug 16 18:50:43 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 16 Aug 1996 13:50:43 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
References: <199608161728.NAA19827@cyclone.ERE.UMontreal.CA>
Message-ID: <3214B4F3.2AC1@mit.edu>

Konrad HINSEN wrote:

> > Because I can't possibly conceive of doing "fft" and its ilk with a
> > default axis other than -1, every function in NumPy will have a default
> > axis of -1 (or -2 for matrix operations).  This currently includes all
> 
> Could it be that you have a special bias for FFT? I don't consider
> FFTs so fundamental that they should set the default for all
> array functions. Statistically most functions would best have
> a default of 0, those that should have another default are the
> exceptions.

I don't have a particular bias towards fft, but I do have one towards
the huge collection of non-strctural numeric operations that have the
same properties.  Things like histogram, spline, sort, argmax, etc.

> > I wish I could come up with a better compromise, but I myself was
> > finding it hard to remember what the default axes were for different
> > operations, and that's just intolerable.
> 
> Using -1 for everything is more intolerable than anything else.
> A quick glance at my existing code shows that I would need
> an explicit axis specifications for 80% of my function calls!

If this really troubles you, write:

def take(a, axis=0): Numeric.take(a, axis)

at the start of your modules (though not at the start of modules that
you want me to be able to read).

> Actually the default axis discussion has a long history in the APL
> community. The original APL allowed axis specifications in the same
> style as Python now does. The default axis was always zero, but for
> reduce and accuulate an alternate form with a default of -1 was
> provided. The various problems with this approach (and other
> limitations in APL) led to the rank concept in J. For most
> applications there is not much difference between function ranks and
> axis specifications, since the effect for simple arrays is rather
> similar. But J also gave up the "the same default for everyone"
> rule. However, it is possible to inquire about the default rank
> of any J function, which helps to reduce confusion and bad memory
> problems ;-)

And one of my greatest complaints with J is similar to the complaints
you are always hearing about perl, it makes for very concise but hard to
read code.  Python has always made the tradeoff for greater readability
over less typing where the question has come up.  I really think that
I'm following in that tradition here.

> > I will add keyword arguments to all of the functions that accept an axis
> > so that you can at least write concatenate([a,b], axis=0) which I think
> > is much more readable than the non-keyword alternative.
> 
> Definitely. But what happens to dot(), which needs two axes?

Probably gets axis=(axis1, axis2), but I'm not overly concerned about
dot at this point.  Right now, and probably until after the 1.0 release
dot does not allow non default axis specification.

-Jim

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

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

From hinsenk@ere.umontreal.ca  Fri Aug 16 18:59:13 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Fri, 16 Aug 1996 13:59:13 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <3214B4F3.2AC1@mit.edu> (message from Jim Hugunin on Fri, 16 Aug 1996 13:50:43 -0400)
Message-ID: <199608161759.NAA22334@cyclone.ERE.UMontreal.CA>

> I don't have a particular bias towards fft, but I do have one towards
> the huge collection of non-strctural numeric operations that have the
> same properties.  Things like histogram, spline, sort, argmax, etc.

That may be a long list, but how often are they applied to arrays
of rank higher than 1? In other words, how frequently would one
have to override a default of zero?

If we settle for a single default for every function (which I still
consider a bad solution), the best test would be to write a lot
of code with explicit axis specifications for everything and then
count which one occurs most often. I bet that is going to be zero.

> If this really troubles you, write:
> 
> def take(a, axis=0): Numeric.take(a, axis)
> 
> at the start of your modules (though not at the start of modules that
> you want me to be able to read).

That's the point, we don't want to create dialects. The problem is
that *I* don't want to read code that is compatible with a general
default of -1.

> And one of my greatest complaints with J is similar to the complaints
> you are always hearing about perl, it makes for very concise but hard to
> read code.  Python has always made the tradeoff for greater readability

But for different reasons. BTW, I don't particularly like J either;
I can never remember all the funny symbols after not using them for
two days. But I never had problems with remembering the default ranks,
because in almost all cases you can deduce them by considering the
most typical application of a function. Basically, the default
should be zero for structural operations, -1 for non-structural
operations acting on vectors, and -2 for non-structural operations
acting on matrices (e.g. inversion). I don't think this is difficult
to remember, and I can't think of a function for which the answer
according to this rule is not obvious.

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Fri Aug 16 19:18:08 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 16 Aug 1996 14:18:08 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
References: <199608161759.NAA22334@cyclone.ERE.UMontreal.CA>
Message-ID: <3214BB60.352D@mit.edu>

Konrad HINSEN wrote:

> If we settle for a single default for every function (which I still
> consider a bad solution), the best test would be to write a lot
> of code with explicit axis specifications for everything and then
> count which one occurs most often. I bet that is going to be zero.

I happen to disagree with you about what such a comparision would
reveal, but I could see the value in performing it.

> > And one of my greatest complaints with J is similar to the complaints
> > you are always hearing about perl, it makes for very concise but hard to
> > read code.  Python has always made the tradeoff for greater readability
> 
> But for different reasons. BTW, I don't particularly like J either;
> I can never remember all the funny symbols after not using them for
> two days. But I never had problems with remembering the default ranks,
> because in almost all cases you can deduce them by considering the
> most typical application of a function. Basically, the default
> should be zero for structural operations, -1 for non-structural
> operations acting on vectors, and -2 for non-structural operations
> acting on matrices (e.g. inversion). I don't think this is difficult
> to remember, and I can't think of a function for which the answer
> according to this rule is not obvious.

Okay, here's an example of my problems:

argmax(x) has a natural default axis of -1, right?

So, what is the natural default axis of maximum.reduce(x)?  If it's not
also -1, I'd argue that you have a confusing situation.

-Jim

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

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

From hinsenk@ere.umontreal.ca  Fri Aug 16 19:25:59 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Fri, 16 Aug 1996 14:25:59 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <3214BB60.352D@mit.edu> (message from Jim Hugunin on Fri, 16 Aug 1996 14:18:08 -0400)
Message-ID: <199608161825.OAA24108@cyclone.ERE.UMontreal.CA>

> > If we settle for a single default for every function (which I still
> > consider a bad solution), the best test would be to write a lot
> > of code with explicit axis specifications for everything and then
> > count which one occurs most often. I bet that is going to be zero.
> 
> I happen to disagree with you about what such a comparision would
> reveal, but I could see the value in performing it.

That's why I looked at all my code, and found that with a default
of -1 I'd have to add axis specifications to 80% of all function calls.
With a default of 0 I couldn't find any code that would need modification.
I don't claim that my code is representative, but I want to see the
code that benefits from a default of -1 before I believe in its
existence.

> Okay, here's an example of my problems:
> 
> argmax(x) has a natural default axis of -1, right?
> 
> So, what is the natural default axis of maximum.reduce(x)?  If it's not
> also -1, I'd argue that you have a confusing situation.

Why? argmax() and maximum.reduce() are two very different things.
Any reduction is a structural operation with a default of zero.
argmax() is not a reduction, and also returns very different
information (an index rather than an array element).

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From Rob.Hooft@embl-heidelberg.de  Fri Aug 16 19:36:25 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Fri, 16 Aug 1996 20:36:25 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] Another problem?
In-Reply-To: <32149061.45BC@mit.edu>
References: <199608161014.MAA19954@nu>
 <32149061.45BC@mit.edu>
Message-ID: <199608161836.UAA20142@nu>

>>>>> "JH" == Jim Hugunin <hugunin@mit.edu> writes:

 JH> Rob.Hooft@embl-heidelberg.de wrote:

 >> factor took 10.577 seconds
 >> afactor took 7.916 seconds

 JH> I'm running on a faster machine than you, so my numbers are
 JH> faster in both cases, still the relative comparision is valid.

 JH> factor took 2.708 seconds
 JH> afactor took 0.322 seconds

Your machine isn't much faster, it is the python virtual machine that
is much faster :-\. With your version on my box:

factor took  10.327 seconds
afactor took   0.475 seconds

see? I'm running on a 150MHz alpha here, so speed isn't that bad, it is
just that python is juggling 64bit entities everywhere....

 JH> Here's my new version of your afactor and asieve functions.

 JH> #Set multiples of i to be nonprime
 JH> numbers[(i*i)::i] = 0

Right. That is the key. I've been wondering how to do that without
realizing that slices like this are incredibly powerful.

BUT: there is a bug in your script: try running it with upto=999999

  IndexError: invalid slice

:-) If the bug is fixed, the behaviour is almost o(N).


BTW: I'm running on an ALPHA, and I also get a crash when combining arrays 
with long integers. "gdb" tells me we're somewhere in "PyObject_Str"....

Rob.
-- 
=== Rob.Hooft@EMBL-Heidelberg.DE   http://www.Sander.EMBL-Heidelberg.DE/rob/ ==
==== In need of protein modeling?  http://www.Sander.EMBL-Heidelberg.DE/whatif/
Validation of protein structures?  http://biotech.EMBL-Heidelberg.DE:8400/ ====
== PGPid 0xFA19277D == Use Linux!  Free Software Rules The World! =============

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

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

From Carlos Fonseca <fonseca@gaivota.demon.co.uk>  Fri Aug 16 19:31:16 1996
From: Carlos Fonseca <fonseca@gaivota.demon.co.uk> (Carlos Fonseca)
Date: Fri, 16 Aug 1996 19:31:16 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] default axes
In-Reply-To: <199608160936.FAA20848@cyclone.ERE.UMontreal.CA>
Message-ID: <Pine.LNX.3.94.960816190723.321C-100000@gaivota.demon.co.uk>

On Fri, 16 Aug 1996, Konrad HINSEN wrote:
> > I really think dot(a,b) should behave _exactly_ like
> > 
> > add.reduce(a*b,axis=-1)
> 
> Why?

Perhaps I should have put it a different way:

I would like the functionality of add.reduce(a*b,axis=-1), but without the
need to allocate memory to store a*b, to be available. Why, because it
appears to be as simple and general as it can get. I also thought that the
name dot() would fit this description, but looking at the definition of
dot() in Numeric.py, perhaps this functionality should simply be provided
by multiarray.innerproduct() 

> > Full rank multiplication of two arrays could be written:
> > 
> > dot(a[...,(n-1)*(NewAxis,)],b,axes=-n)

[ actually, it should be dot(a[(Ellipses,)+(n-1)*(NewAxis,)],b,axes=-n) ]
> 
> That is a lot too complicated for a frequent operation, especially
> considering that n might not be available as a variable or constant,
> i.e. it would have to be written as shape(b)[0].

I agree, and this is why I wrote further down in the same post that I
agreed with the idea of writing two functions. innerproduct(a,b,axis) as
add.reduce(a*b,axis) provides all the functionality that is needed to
write dot() for general matrix multiplication.

Carlos




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

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

From Rob.Hooft@embl-heidelberg.de  Fri Aug 16 20:57:47 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Fri, 16 Aug 1996 21:57:47 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] Another problem?
In-Reply-To: <32149061.45BC@mit.edu>
References: <199608161014.MAA19954@nu>
 <32149061.45BC@mit.edu>
Message-ID: <199608161957.VAA21810@nu>

>>>>> "JH" == Jim Hugunin <hugunin@mit.edu> writes:

 JH> I doubt that my new version is more than a factor of 2 slower
 JH> than a C implementation of the same algorithm (though feel free
 JH> to show me wrong with a code sample).

I decided to accept that challenge:

   nu[263]~% cc -O4 -o x x.c -lm -non_shared
   nu[264]~% time ./x                       
   Can divide by 2
   Can divide by 29
   ./x  0.03s user 0.02s system 83% cpu 0.060 total

Remember:

   nu[265]~% python ./x.py 
   Can divide by 2
   Can divide by 29
   factor took  10.354 seconds
   Can divide by 2
   Can divide by 29
   afactor took   0.573 seconds

and, yes the machine is "empty", so clock-times are comparable. And:
changing the array to type='b' makes the python version slower, so
I'm not being unfair.... The only trick I've added is making the thing
non-recursive, but I doubt that change would make the python version
much faster.

   nu[266]~% python
   Python 1.4b2 (Aug 12 1996) [C]
   Copyright 1991-1996 Stichting Mathematisch Centrum, Amsterdam
   >>> 0.573/0.060 > 2.0
   1
   >>> 

-----------------------------------

#include <stdio.h>
#include <math.h>
#include <malloc.h>

#define bool char
int *sieve(int max)
{
  bool *sieve;
  int *result;
  int i,j,limit;
  sieve=(bool *)malloc((max+1)*sizeof(bool));
  for (i=0;i<=max;i++) sieve[i]=1;
  sieve[0]=0;
  sieve[1]=0;
  limit=floor(sqrt((float)max));
  for (i=2;i<=limit;i++) {
    if (sieve[i]) {
      for (j=i*i;j<=max;j+=i) sieve[j]=0;
    }
  }
  j=0;
  for (i=2;i<=max;i++) j+=sieve[i];
  /*printf("Sieve contains %d primes\n",j);*/
  result=(int *)malloc((j+1)*sizeof(int));
  j=0;
  for (i=2;i<=max;i++) if (sieve[i]) result[j++]=i;
  result[j]=0;
  free(sieve);
  return(result);
}

void factor(int a,int max)
{
  int *s;
  int i;
  if (max<2) return;
  s=sieve(max);
  for (i=0;s[i];i++) {
    if (!(a%s[i])) {
      printf("Can divide by %d\n",s[i]);
    }
  }
  free(s);
}

int main() {
  factor(129753308,99999);
  exit(0);
}

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

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

From mclay@eeel.nist.gov  Fri Aug 16 15:57:25 1996
From: mclay@eeel.nist.gov (Michael McLay)
Date: Fri, 16 Aug 96 14:57:25 GMT
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <199608161728.NAA19827@cyclone.ERE.UMontreal.CA>
References: <32149BBA.14D2@mit.edu>
 <199608161728.NAA19827@cyclone.ERE.UMontreal.CA>
Message-ID: <199608161653.QAA15807@fermi.eeel.nist.gov>

Konrad HINSEN writes:
 > > After reading all of the discussion over what are the appropriate axes
 > > for the various operations, I've become convinced that there is no
 > > obvious choice.  Therefore I think it is really important to have a
 > > single default axis so that at least people will only have one rule to
 > > remember.
 > 
 > I'd rather remember a more complicated rule than type explicit axis
 > specifications for almost every function!
 > 
 > > Because I can't possibly conceive of doing "fft" and its ilk with a
 > > default axis other than -1, every function in NumPy will have a default
 > > axis of -1 (or -2 for matrix operations).  This currently includes all
 > 
 > Could it be that you have a special bias for FFT? I don't consider
 > FFTs so fundamental that they should set the default for all
 > array functions. Statistically most functions would best have
 > a default of 0, those that should have another default are the
 > exceptions.

Let me qualify this by saying I'm not entirely sure I understand the
definition of axis.  I guess that qualifies me as a novice user.
For a novice user making the default -1 would not be as intuitive as
making it 0. Also, since Konrad seems to think that the majority of
functions would use 0 as the default, then perhaps that should be the
default value.  

I still favor keeping the rule simple and requiring an explicit value
for changing axis to something other than the default.  

I suppose asking you to change the default to something other than
what you use the most would be a good test of the irritation factor of
having to always specify the axis.  If you are not willing to type
axis=-1 in every function, then perhaps keeping a simple rule is not
the correct tradeoff.

Michael


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

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

From hugunin@mit.edu  Sat Aug 17 00:10:09 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 16 Aug 1996 19:10:09 -0400
Subject: [PYTHON MATRIX-SIG] Release 1.0alpha2 available
Message-ID: <3214FFD1.7714@mit.edu>

NumPy-1.0a2 is now available at the usual location:

ftp://ftp.sls.lcs.mit.edu/pub/jjh/NumPy-1.0a2.tar.gz

I've removed the fftmodule for this iteration while I work out the best
way to handle the standard library.

This version contains many small bug fixes, a large number of name
changes and a new standard for default axes.

Axis 0 is now always the default axis.  This is the one feature in
alpha2 that I think has a reasonable chance of changing incompatibly
before the beta1 release.

There is also a script fixnames.py that can be used to fix names from
the 1.0a1 conventions to 1.0a2.  Read INSTALL for more information on
this.

Please do try the dynamic installation thing again and let me know your
successes and failures on different platforms.

As usual, have fun and let me know how it goes - Jim

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

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

From fonseca@gaivota.demon.co.uk  Sat Aug 17 21:04:47 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Sat, 17 Aug 1996 21:04:47 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <199608161759.NAA22334@cyclone.ERE.UMontreal.CA>
Message-ID: <Pine.LNX.3.94.960817203231.1545B-100000@gaivota.demon.co.uk>

On Fri, 16 Aug 1996, Konrad HINSEN wrote:

> > I don't have a particular bias towards fft, but I do have one towards
> > the huge collection of non-strctural numeric operations that have the
> > same properties.  Things like histogram, spline, sort, argmax, etc.
> 
> That may be a long list, but how often are they applied to arrays
> of rank higher than 1? In other words, how frequently would one
> have to override a default of zero?

Everytime one wanted to evaluate the fft (or whatever) of multiple
one-dimensional signals at once. In genetic algorithms (GAs, what I would
like to write code for), individuals can all be evaluated independently
from each other, which is ideal for vectorized operations.  If assessing
each individual involves computing the fft of a different 1d signal, then
axis=-1. 

If one can say that individuals (in GAs, that is) will mostly be described
by 1d (vector of decision variables, vector of objective values, etc) or
2d structures (a covariance matrix, a 2d pattern), and that outer
dimensions will be used to structure the population, since most
computations will be local to the individual itself, -1 and -2 will
definetely be the most common choices for axes. 

I am still new to Python (but experieced with MATLAB), and I've only
written a couple of functions so far. But the answer to your question is
"very often", in my case...

> most typical application of a function. Basically, the default
> should be zero for structural operations, -1 for non-structural
> operations acting on vectors, and -2 for non-structural operations
> acting on matrices (e.g. inversion). I don't think this is difficult
> to remember, and I can't think of a function for which the answer
> according to this rule is not obvious.
> 
> Konrad.

I am afraid I do not understand what you mean by structural and
non-structural operations.  In particular, why is take() structural and
argsort() non-structural? For take(a,argsort(a)) to make sense, both
should have the same defaults, whatever the dimensions of a.

Carlos


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

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

From fonseca@gaivota.demon.co.uk  Sat Aug 17 20:07:10 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Sat, 17 Aug 1996 20:07:10 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] take() in 1.0a2 (longish, sorry)
Message-ID: <Pine.LNX.3.94.960817191241.1316A-100000@gaivota.demon.co.uk>

Hi,

I don't know if the following is intentional or not:

>>> from Numeric import *
>>> a=array([[2,3,7,6,4,7],[6,9,6,4,3,2]])
>>> a
2 3 7 6 4 7
6 9 6 4 3 2
>>> sort(a,-1)
2 3 4 6 7 7
2 3 4 6 6 9
>>> argsort(a,-1)
0 1 4 3 2 5
5 4 3 0 2 1
>>> take(a,argsort(a,-1),-1)
2 3 4 6 7 7
7 4 6 2 7 3

6 9 3 4 6 2
2 3 4 6 6 9
>>> 

I.e., when take is given a 2 dimensional indices array, it adds yet
another dimension to a. This should not happen if take(a,argsort(a,-1),-1) 
is to be equivalent to sort(a,-1). Note that, in the example above,
indices is perfectly aligned with a.

In general, if 

        b=take(a,indices,axis)

then

        b[i,...,j,...,k]=a[i,...,indices[i,...,j,...,k],...,k]
                ^
              axis 

with broadcasting of dimensions for all axes other than the "active" axis. 

Since a and indices would normally be aligned at the last dimension,
at least the following should be true:

a
2 3 7 6 4 7
6 9 5 4 3 2

take(a,[1,0,1],-1)  # select columns
3 2 3
9 6 9

take(a,[1,0,1],-2)
Arrays not aligned!

take(a,[[1],[0],[1]],-1)
Arrays not aligned!

take(a,[[1],[0],[1]],-2) # select rows
6 9 5 4 3 2
2 3 7 6 4 7
6 9 5 4 3 2

As for the default axes, oh well... :-)

Carlos



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

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

From fonseca@gaivota.demon.co.uk  Sat Aug 17 20:15:57 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Sat, 17 Aug 1996 20:15:57 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] sum() in 1.0a2
Message-ID: <Pine.LNX.3.94.960817200713.1316B-100000@gaivota.demon.co.uk>

I think sum(a) (and other reductions) should return an array with shape ()
when a is 1d, and not a scalar.  Currently, sum(a).anyarraymethod and
sum(a)[0] will fail if a is 1d. 

Carlos



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

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

From Rob.Hooft@embl-heidelberg.de  Sun Aug 18 02:03:04 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Sun, 18 Aug 1996 03:03:04 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] argsort() on array([1,1],'b')
Message-ID: <199608180103.DAA26454@nu>

I guess you don't want to know that this happened while I was trying
to improve on Jim's last version of sieve? This happens on a Linux box
(1.0a2) as well as on an ALPHA (1.0a1).

   amigo[639]test%  python
   Python 1.4b2 (Aug  7 1996)  [GCC 2.7.2p snapshot 960426]
   Copyright 1991-1996 Stichting Mathematisch Centrum, Amsterdam
   >>> 
   >>> from Numeric import *
   >>> argsort([0,1])
   0 1
   >>> a=array([0,1],'b')
   >>> argsort(a)
   zsh: segmentation fault  python

Rob.

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

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

From hinsen@physik.rwth-aachen.de  Sun Aug 18 08:59:11 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Sun, 18 Aug 1996 09:59:11 +0200
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <Pine.LNX.3.94.960817203231.1545B-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Sat, 17 Aug 1996 21:04:47 +0100 (BST))
Message-ID: <9608180759.AA16966@acds21>

   Everytime one wanted to evaluate the fft (or whatever) of multiple
   one-dimensional signals at once. In genetic algorithms (GAs, what I would

Obviously, but how often does this occur? (Of course I am not
asking how often such code gets executed, but how often you have to
type such a function call.) In all of my array code, which is not
just Python code but also a few MB of APL code, such applications
are extremely rare. Even if such an operation is central to GA
applications, that doesn't mean that the majority of array functions
in a complete program (i.e. including setup or reading of input
arrays, analysis, output formatting, etc.) would benefit from a
default axis of -1.

But of course you can convince me that I am wrong by sending me a few
complete programs that do something useful and that need an axis
specification of -1 in the majority of axis-related operations.

   I am afraid I do not understand what you mean by structural and
   non-structural operations.  In particular, why is take() structural and
   argsort() non-structural? For take(a,argsort(a)) to make sense, both
   should have the same defaults, whatever the dimensions of a.

Basically a structural operation is one that acts on or modifies
the shape of an array, as opposed to a non-structural operation
that cares mostly about the values of the array elements.
take() is clearly structural (it doesn't care at all about the
values of array elements), whereas argsort is not (the values
matter a lot, and intrinsically it can't deal with higher-rank
arrays). And I am sure that for most applications of take()
a default axis of 0 is appropriate, whereas most applications
of argsort() would benefit from -1.

Of course that means that take(a,argsort(a)) doesn't do anything
useful. But in what situation would you use it anyway? To sort the 1D
subarrays of a, you would write sort(a) (which being non-structural
should have a default axis of -1).  Using take() makes sense e.g. if
you only want a subset of the elements, but I can't believe that this
is a frequent operation. Besides, my APL experience tells me that
argsort() is never used on anything but a rank-1 array.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsen@physik.rwth-aachen.de  Sun Aug 18 09:10:59 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Sun, 18 Aug 1996 10:10:59 +0200
Subject: [PYTHON MATRIX-SIG] take() in 1.0a2 (longish, sorry)
In-Reply-To: <Pine.LNX.3.94.960817191241.1316A-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Sat, 17 Aug 1996 20:07:10 +0100 (BST))
Message-ID: <9608180810.AA16974@acds21>

   I.e., when take is given a 2 dimensional indices array, it adds yet
   another dimension to a. This should not happen if take(a,argsort(a,-1),-1) 

I hope that this intentional, since it is a very useful function
for the construction of higher-rank arrays.

   is to be equivalent to sort(a,-1). Note that, in the example above,

If sort(a,-1) is what you want, then that is what you should write.
take() is meant for different (and much more diverse) applications,
and I don't see a reason to limit its flexibility just to create
a less efficient synonym for sort().

My definition for take(), using the convenient J concepts of
frames and cells, would be: the result has the frames of the
index argument with elements picked from the value argument,
i.e. if
   b = take(a, i, axis)
then
   b[n_1,..,n_k] = a[(axis-1)*(All,), i[n_1,..,n_k], ...]
with k being the rank of i.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsen@physik.rwth-aachen.de  Sun Aug 18 09:18:05 1996
From: hinsen@physik.rwth-aachen.de (Konrad Hinsen)
Date: Sun, 18 Aug 1996 10:18:05 +0200
Subject: [PYTHON MATRIX-SIG] sum() in 1.0a2
In-Reply-To: <Pine.LNX.3.94.960817200713.1316B-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Sat, 17 Aug 1996 20:15:57 +0100 (BST))
Message-ID: <9608180818.AA16982@acds21>


   I think sum(a) (and other reductions) should return an array with shape ()
   when a is 1d, and not a scalar.  Currently, sum(a).anyarraymethod and
   sum(a)[0] will fail if a is 1d. 

Which is precisely why I have always insisted that array operations
should be implemented as functions and not as methods.

Of course the alternative would be to make rank-0 arrays distinct from
scalars, and this alternative has been discussed a lot in the early
days of the Matrix SIG. But it creates a few fundamental
problems. Everyones idea of arrays is that they are collections of
scalars, and one expects to be able to pick the scalars from an array
by indexing. But if rank-0 arrays are distinct from scalars,
indexing a rank-1 array would return a rank-0 array. Worse, there
would be no obvious way to extract a real scalar from a rank-0
array, so another conversion function would be necessary. The
resulting system would be extremely confusing to users.

Not having specific rank-0 objects is therefore the lesser evil,
but then we have to live with the implementation limitations
given by the Python interpreter.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de Chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. A                | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From fonseca@gaivota.demon.co.uk  Sun Aug 18 16:10:52 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Sun, 18 Aug 1996 16:10:52 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <9608180759.AA16966@acds21>
Message-ID: <Pine.LNX.3.94.960818154300.328B-100000@gaivota.demon.co.uk>

On Sun, 18 Aug 1996, Konrad Hinsen wrote:

> Obviously, but how often does this occur? (Of course I am not
> asking how often such code gets executed, but how often you have to
> type such a function call.) In all of my array code, which is not
> just Python code but also a few MB of APL code, such applications
> are extremely rare. Even if such an operation is central to GA
> applications, that doesn't mean that the majority of array functions
> in a complete program (i.e. including setup or reading of input
> arrays, analysis, output formatting, etc.) would benefit from a
> default axis of -1.

In wanting to write generic GA code, where the structures that
characterize the individual typically have known dimensions (fitness is a
scalar, performance is at most a vector (in multiobjective optimization),
but the structure of the population is a decision of who actually puts the
GA together, the code must be written relative the last dimension of the
array. Thus, -1 are -2 the axes that end up making sense.
If the population was assumed to be unstructured, then one of these would
equivalent to 0, but not in general.

> But of course you can convince me that I am wrong by sending me a few
> complete programs that do something useful and that need an axis
> specification of -1 in the majority of axis-related operations.

Not having a working take() (see one of my earlier messages) hasn't helped
:-(

> [explation of structural vs. non-structural]
>
> Of course that means that take(a,argsort(a)) doesn't do anything
> useful. But in what situation would you use it anyway? To sort the 1D
> subarrays of a, you would write sort(a) (which being non-structural
> should have a default axis of -1). 

But suppose I have to arrays, a and b, both aligned and three dimensional,
and that there is a ono to one correspondence between the elements of a
and those of b. I need to sort a and, at the same time, rearrange b so
that the original relationship is retained:

ix=argsort(a)
A=take(a,ix)
B=take(b,ix)

This should be enough.


> Using take() makes sense e.g. if
> you only want a subset of the elements, but I can't believe that this
> is a frequent operation.

This is called "selection" (one of the 3 main operators) operators.

> Besides, my APL experience tells me that
> argsort() is never used on anything but a rank-1 array.
> 
> Konrad.
> 

My experience is different. But Matlab doesn't let me write something
like the above even for 2d arrays, so I end up using a for-loop. 

Something else:

How can I achieve

rank = argsort(argsort(cost))

without having to call argsort twice? Something like an inverted take
(ekat below :-)

rank = ekat(arange(n),argsort(cost))

would be ideal. This would be like take, but "indices" would refer to the
output matrix, and not to the input.

Carlos


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

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

From hugunin@mit.edu  Sun Aug 18 16:27:49 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Sun, 18 Aug 1996 11:27:49 -0400
Subject: [PYTHON MATRIX-SIG] sum() in 1.0a2
References: <Pine.LNX.3.94.960817200713.1316B-100000@gaivota.demon.co.uk>
Message-ID: <32173675.531E@mit.edu>

Carlos Fonseca wrote:
> 
> I think sum(a) (and other reductions) should return an array with shape ()
> when a is 1d, and not a scalar.  Currently, sum(a).anyarraymethod and
> sum(a)[0] will fail if a is 1d.

Sorry about this, but there has already been much discussion of this
issue and the agreement was that array functions that returns 0d arrays
should return python scalars.  I agree that this can occasionally be
confusing, but I think that our conclusion when we last discussed this
was sound (look at the archives if you're feeling brave).

-Jim

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

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

From fonseca@gaivota.demon.co.uk  Sun Aug 18 16:21:07 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Sun, 18 Aug 1996 16:21:07 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] take() in 1.0a2 (longish, sorry)
In-Reply-To: <9608180810.AA16974@acds21>
Message-ID: <Pine.LNX.3.94.960818161114.328C-100000@gaivota.demon.co.uk>

On Sun, 18 Aug 1996, Konrad Hinsen wrote:

>    I.e., when take is given a 2 dimensional indices array, it adds yet
>    another dimension to a. This should not happen if take(a,argsort(a,-1),-1) 
> 
> I hope that this intentional, since it is a very useful function
> for the construction of higher-rank arrays.

But the point is that higher-rank arrays can be easily and efficiently
constructed by adding dummy dimensions and relying on broadcasting,
whereas the reverse is not possible if functions insist on producing
higher-rank arrays. At least, it means that more memory must be allocated
before the higher-rank arrays can be indexed at all.

>    is to be equivalent to sort(a,-1). Note that, in the example above,
> 
> If sort(a,-1) is what you want, then that is what you should write.
> take() is meant for different (and much more diverse) applications,
> and I don't see a reason to limit its flexibility just to create
> a less efficient synonym for sort().

I have answered this in my previous message. Also, see above.

> My definition for take(), using the convenient J concepts of
> frames and cells, would be: the result has the frames of the
> index argument with elements picked from the value argument,
> i.e. if
>    b = take(a, i, axis)
> then
>    b[n_1,..,n_k] = a[(axis-1)*(All,), i[n_1,..,n_k], ...]
> with k being the rank of i.
> 
> Konrad.

This behaviour can be achieved efficiently with the definition I
proposed via broadcasting. The opposite behaviour can only be achived from
this one, if at all, via indexing. Meanwhile, lots of memory have already
had to be allocated.

Carlos



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

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

From Carlos Fonseca <fonseca@gaivota.demon.co.uk>  Sun Aug 18 15:40:54 1996
From: Carlos Fonseca <fonseca@gaivota.demon.co.uk> (Carlos Fonseca)
Date: Sun, 18 Aug 1996 15:40:54 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Re: sum() in 1.0a2 + indexing BUG
In-Reply-To: <9608180818.AA16982@acds21>
Message-ID: <Pine.LNX.3.94.960818150116.328A-100000@gaivota.demon.co.uk>

First, the bug:

>>> from Numeric import *
>>> array(0)[0:]

On Sun, 18 Aug 1996, Konrad Hinsen wrote:
>
>    I think sum(a) (and other reductions) should return an array with shape ()
>    when a is 1d, and not a scalar.  Currently, sum(a).anyarraymethod and
>    sum(a)[0] will fail if a is 1d. 
> 
> Which is precisely why I have always insisted that array operations
> should be implemented as functions and not as methods.
> 
> Of course the alternative would be to make rank-0 arrays distinct from
> scalars, and this alternative has been discussed a lot in the early
> days of the Matrix SIG. But it creates a few fundamental
> problems. Everyones idea of arrays is that they are collections of
> scalars, and one expects to be able to pick the scalars from an array
> by indexing. But if rank-0 arrays are distinct from scalars,
> indexing a rank-1 array would return a rank-0 array. Worse, there
> would be no obvious way to extract a real scalar from a rank-0
> array, so another conversion function would be necessary. The
> resulting system would be extremely confusing to users.

My message referred to reductions, not to indexing. Indexing could still
return scalars, where appropriate. 

I understand that indexing with scalars (but not with slices!) could be
seen as a reduction, and thus made to return a null-shape array, leading
to the situation you describe. Perhaps indexing into a null-shape array
could return the scalar? This works in the present implementation. But see
below...

> Not having specific rank-0 objects is therefore the lesser evil,
> but then we have to live with the implementation limitations
> given by the Python interpreter.
> 
> Konrad.
> 

But we *do* have them:

>>> from Numeric import *
>>> a=array(5)
>>> a.shape
()
>>> a[0]
5

It is fair to expect the array constructor to return an array. Perhaps
it should return one with shape (1,)? But then, what about array([5])?

Carlos


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

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

From Rob.Hooft@embl-heidelberg.de  Sun Aug 18 17:23:11 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Sun, 18 Aug 1996 18:23:11 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] arange(with one integer parameter)
Message-ID: <199608181623.SAA17078@nu>

I had yet another look at the sieve script. With the help of Jim's 
time() calls, I saw that a lot of time was spent in the statement
"arange(max)". Looking at the definition this is not surprising: the
code is so general that the easy cases like this suffer immensely.

On my machine, 

     add.accumulate(1+zeros([1000000]))-1

(4 operations on the whole array, but I think the most efficient we
can do at this moment since these are implemented in C) is two times
faster than

     arange(1000000)

Maybe arange, or this special case of arange with one parameter,
deserve to be implemented in C? This form is called quite often, even
in Numeric.py!

Rob.
-- 
=== Rob.Hooft@EMBL-Heidelberg.DE   http://www.Sander.EMBL-Heidelberg.DE/rob/ ==
==== In need of protein modeling?  http://www.Sander.EMBL-Heidelberg.DE/whatif/
Validation of protein structures?  http://biotech.EMBL-Heidelberg.DE:8400/ ====
== PGPid 0xFA19277D == Use Linux!  Free Software Rules The World! =============

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

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

From hugunin@mit.edu  Sun Aug 18 17:44:10 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Sun, 18 Aug 1996 12:44:10 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
References: <Pine.LNX.3.94.960818154300.328B-100000@gaivota.demon.co.uk>
Message-ID: <3217485A.4C27@mit.edu>

Carlos Fonseca wrote:
> 
> On Sun, 18 Aug 1996, Konrad Hinsen wrote:
> 
> > Obviously, but how often does this occur? (Of course I am not
...
> array. Thus, -1 are -2 the axes that end up making sense.
> If the population was assumed to be unstructured, then one of these would
> equivalent to 0, but not in general.

I'm going to stay out of this discussion for now, but please continue!

> > [explation of structural vs. non-structural]
> >
> > Of course that means that take(a,argsort(a)) doesn't do anything
> > useful. But in what situation would you use it anyway? To sort the 1D
> > subarrays of a, you would write sort(a) (which being non-structural
> > should have a default axis of -1).
> 
> But suppose I have to arrays, a and b, both aligned and three dimensional,
> and that there is a ono to one correspondence between the elements of a
> and those of b. I need to sort a and, at the same time, rearrange b so
> that the original relationship is retained:
> 
> ix=argsort(a)
> A=take(a,ix)
> B=take(b,ix)
>
> This should be enough.

You have a good point here, but I think that the issue is you want a
different function from Konrad.  Alright, writing functions is something
I can do.  What would you like it to be called?
 
> My experience is different. But Matlab doesn't let me write something
> like the above even for 2d arrays, so I end up using a for-loop.

So at least we aren't in danger of having you defect back to matlab :)

> Something else:
> 
> How can I achieve
> 
> rank = argsort(argsort(cost))
<
> without having to call argsort twice? Something like an inverted take
> (ekat below :-)

I see what you're looking for here, but I'm not convinced that having to
call argsort twice is enough of a burden to justify the function you're
asking for.  I'd either like to see more examples of how this would be
useful, or have you wait and ask for this in version 1.1.
 
> rank = ekat(arange(n),argsort(cost))
> 
> would be ideal. This would be like take, but "indices" would refer to the
> output matrix, and not to the input.
> 
> Carlos

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

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

From Carlos Fonseca <fonseca@gaivota.demon.co.uk>  Sun Aug 18 17:54:09 1996
From: Carlos Fonseca <fonseca@gaivota.demon.co.uk> (Carlos Fonseca)
Date: Sun, 18 Aug 1996 17:54:09 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Re: Array indexing bug + strange behaviour
In-Reply-To: <Pine.LNX.3.94.960813230613.1884B-100000@gaivota.demon.co.uk>
Message-ID: <Pine.LNX.3.94.960818174233.813D-100000@gaivota.demon.co.uk>

This bug is still in 1.0a2. This happens under Linux 2.0.12, gcc 2.7.2
(from the Debian distribution, which has the strength-reduce bug fixed). 
I've linked NumPy dynamically, but it also happens with NumPy statically
linked. 

On Tue, 13 Aug 1996, Carlos Fonseca wrote:
> This seems to be reproducible. Found it by chance...
> 
> Python 1.4b2 (Aug 11 1996)  [GCC 2.7.2]
> Copyright 1991-1996 Stichting Mathematisch Centrum, Amsterdam
> >>> from Numeric import *
> >>> a=arange(10)
> >>> a[10:10].shape
> (0,)
> >>> a[-1:10].shape
> IndexError: index out of bounds
> >>> a[-1:10].shape
> (1,)
> >>> 
> 
> Carlos

The only thing unusual with my setup is that I compiled the interpreter
with -O4. If nobody else can reproduce this, I'll try recompiling it with
a more conservative setting. The numeric modules themselves were compiled
with -g (the default).

The other bug reported by Jean-Bernard ADDOR is also there:

>>> max(arange(5),3)
0 1 2 3 4
>>> min(arange(5),3)
3

Carlos



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

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

From hugunin@mit.edu  Sun Aug 18 18:10:57 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Sun, 18 Aug 1996 13:10:57 -0400
Subject: [PYTHON MATRIX-SIG] Don't use max and min with Numeric Python!
Message-ID: <32174EA1.5A19@mit.edu>

Carlos Fonseca wrote:

> The other bug reported by Jean-Bernard ADDOR is also there:
> 
> >>> max(arange(5),3)
> 0 1 2 3 4
> >>> min(arange(5),3)
> 3

This is not a bug!  This is an unfortunate design decision in the python
interpreter, but there's nothing I can do about it.

What you usually think of as max should be writen maximum under Numeric
Python.  I'm sure that this will trip up a lot of people, but I don't
have a good solution to this until Guido adds the ability to use
exceptions with comparision operations.

I guess I could override these builtin functions if you do from Numeric
import *, but that doesn't seem like good behavior.

Repeat: use maximum and minimum instead of max and min with array
objects.

-Jim

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

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

From fonseca@gaivota.demon.co.uk  Sun Aug 18 22:09:04 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Sun, 18 Aug 1996 22:09:04 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <3217485A.4C27@mit.edu>
Message-ID: <Pine.LNX.3.94.960818213455.1484A-100000@gaivota.demon.co.uk>

On Sun, 18 Aug 1996, Jim Hugunin wrote:

> Carlos Fonseca wrote:
> 
> > ix=argsort(a)
> > A=take(a,ix)
> > B=take(b,ix)
> >
> > This should be enough.
> 
> You have a good point here, but I think that the issue is you want a
> different function from Konrad.  Alright, writing functions is something
> I can do.  What would you like it to be called?

How do you feel about index(a,indices,axis). Alternatively, select(...) 
would also make sense, I think. Thanks for looking into this.

> > My experience is different. But Matlab doesn't let me write something
> > like the above even for 2d arrays, so I end up using a for-loop.
> 
> So at least we aren't in danger of having you defect back to matlab :)

:-)

> > Something else:
> > 
> > How can I achieve
> > 
> > rank = argsort(argsort(cost))
> <
> > without having to call argsort twice? Something like an inverted take
> > (ekat below :-)
> 
> I see what you're looking for here, but I'm not convinced that having to
> call argsort twice is enough of a burden to justify the function you're
> asking for.  I'd either like to see more examples of how this would be
> useful, or have you wait and ask for this in version 1.1.

Plain indexing should always be more efficient than sorting, but this is
certainly not a problem for me at the moment. I agree that there is
more than enough to concentrate on until v1.0.

Carlos



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

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

From hugunin@mit.edu  Mon Aug 19 14:38:35 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Mon, 19 Aug 1996 09:38:35 -0400
Subject: [PYTHON MATRIX-SIG] linear algebra
Message-ID: <32186E5B.4BA8@mit.edu>

I'm finally having some good success at putting together a standard
library for NumPy.  There will be easy to compile, small C versions of
all the necessary Lapack and Blas routines available so that anybody
with a C compiler can use the standard lib.  Now I have a question for
those people out there who use linear algebra more than I do.

All of the current interface routines (from LinAlg.py) do the following:

return transpose(lapackfunction(transpose(input_matrix)))

Should these two transpositions be there?  This is obviously related to
the different index order between NumPy and FORTRAN.  Still, I've always
personally considered it a superficial difference that is best ignored.

If I remember by Linear Algebra correctly
transpose(inverse(transpose(m))) == inverse(m).

However, I very rarely use any linear algebra functions in my code so
I'm not the right person to be making that decision.  Opinions?

-Jim

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

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

From hinsenk@ere.umontreal.ca  Mon Aug 19 17:16:52 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Mon, 19 Aug 1996 12:16:52 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <Pine.LNX.3.94.960818154300.328B-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Sun, 18 Aug 1996 16:10:52 +0100 (BST))
Message-ID: <199608191616.MAA18876@cyclone.ERE.UMontreal.CA>

> In wanting to write generic GA code, where the structures that
> characterize the individual typically have known dimensions (fitness is a
> scalar, performance is at most a vector (in multiobjective optimization),
> but the structure of the population is a decision of who actually puts the
> GA together, the code must be written relative the last dimension of the
> array. Thus, -1 are -2 the axes that end up making sense.
> If the population was assumed to be unstructured, then one of these would
> equivalent to 0, but not in general.

I readily believe that, but this is the same example that you have given
before. My question was not about this one data object, but about the
frequency of axes other than 0 in a complete program. I guess the
only thing that will convince me is such a program...

> But suppose I have to arrays, a and b, both aligned and three dimensional,
> and that there is a ono to one correspondence between the elements of a
> and those of b. I need to sort a and, at the same time, rearrange b so
> that the original relationship is retained:
> 
> ix=argsort(a)
> A=take(a,ix)
> B=take(b,ix)

Well, in this case you would need an explicit axis specification.
And I don't see what would be so bad about it. You can always come
up with an example which shows than axis=n should be the default,
probably for any n ;-) (the proof is left as an exercise for the
reader). For deciding which is the best default argument for each
function, I'd apply the following criteria:
1) What is the most common axis for each individual function?
2) How can the resulting list best be approximated by a sufficiently
   simple rule?

> > Using take() makes sense e.g. if
> > you only want a subset of the elements, but I can't believe that this
> > is a frequent operation.
> 
> This is called "selection" (one of the 3 main operators) operators.

I am not sure what you are referring to. Is that a special term from
GA applications?

> My experience is different. But Matlab doesn't let me write something
> like the above even for 2d arrays, so I end up using a for-loop. 

Which is terribly inefficient. I have long given up Matlab due to
such limitations...

> How can I achieve
> 
> rank = argsort(argsort(cost))
> 
> without having to call argsort twice? Something like an inverted take
> (ekat below :-)
> 
> rank = ekat(arange(n),argsort(cost))

Unless your array is very big, this variant might actually be more
expensive than the first one, because it involves three interpreted
function calls. The best solution for such applications would be
a special function that inverts a permutation (which is O(N), unlike
sorting). Than you would write

  rank = inv_permutation(argsort(cost))

This function would potentially be more generally useful than your
ekat().

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsenk@ere.umontreal.ca  Mon Aug 19 17:32:28 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Mon, 19 Aug 1996 12:32:28 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <Pine.LNX.3.94.960818213455.1484A-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Sun, 18 Aug 1996 22:09:04 +0100 (BST))
Message-ID: <199608191632.MAA20254@cyclone.ERE.UMontreal.CA>

> On Sun, 18 Aug 1996, Jim Hugunin wrote:
> 
> > Carlos Fonseca wrote:
> > 
> > > ix=argsort(a)
> > > A=take(a,ix)
> > > B=take(b,ix)
> > >
> > > This should be enough.
> > 
> > You have a good point here, but I think that the issue is you want a
> > different function from Konrad.  Alright, writing functions is something
> > I can do.  What would you like it to be called?
> 
> How do you feel about index(a,indices,axis). Alternatively, select(...) 
> would also make sense, I think. Thanks for looking into this.

Before we add functions that differ only in details, let's consider
the APL approach to this kind of problem: concatenate the two arrays,
sort the result, and split them again. How efficient would that
be in Python? It mostly depends on the concatenation (which APL
implementations treat with special care because it is extremely
frequently used).

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsenk@ere.umontreal.ca  Mon Aug 19 17:27:32 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Mon, 19 Aug 1996 12:27:32 -0400
Subject: [PYTHON MATRIX-SIG] arange(with one integer parameter)
In-Reply-To: <199608181623.SAA17078@nu> (Rob.Hooft@embl-heidelberg.de)
Message-ID: <199608191627.MAA20040@cyclone.ERE.UMontreal.CA>

> Maybe arange, or this special case of arange with one parameter,
> deserve to be implemented in C? This form is called quite often, even
> in Numeric.py!

Definitely. Arange() is one of the most frequent array constructors.

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsenk@ere.umontreal.ca  Mon Aug 19 17:25:15 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Mon, 19 Aug 1996 12:25:15 -0400
Subject: [PYTHON MATRIX-SIG] Re: sum() in 1.0a2 + indexing BUG
In-Reply-To: <Pine.LNX.3.94.960818150116.328A-100000@gaivota.demon.co.uk> (message from Carlos Fonseca on Sun, 18 Aug 1996 15:40:54 +0100 (BST))
Message-ID: <199608191625.MAA19687@cyclone.ERE.UMontreal.CA>

> My message referred to reductions, not to indexing. Indexing could still
> return scalars, where appropriate. 

But having indexing work differently from reduction only adds to
the confusion.

> to the situation you describe. Perhaps indexing into a null-shape array
> could return the scalar? This works in the present implementation. But see

Again this is hardly an obvious behaviour. The number of indices must
always be equal to the rank of an array, so a rank-0 array needs
exactly zero indices ;-)

> But we *do* have them:
> 
> >>> from Numeric import *
> >>> a=array(5)
> >>> a.shape
> ()
> >>> a[0]
> 5
> 
> It is fair to expect the array constructor to return an array. Perhaps
> it should return one with shape (1,)? But then, what about array([5])?

That is indeed a problem. You are right that the array constructor should
return an array, but on the other hand there are no rank-0 arrays.
Since we have decided not to have rank-0 array objects, I can think
of two solutions:
1) Declare scalars to be special cases of arrays, and let the
   constructor return a scalar.
2) Raise an exception.
I definitely favour the first, because I can imagine that array(x)
with scalar x can occur as a special case of an application where
x could be an arbitrary nested list. In that case returning a
scalar would most probably work. On the other hand, I can't think
of too many cases where one would type array(5) by mistake and not
notice the error without an exception.

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From paul@aem.umn.edu  Mon Aug 19 17:41:32 1996
From: paul@aem.umn.edu (Ralph Paul)
Date: Mon, 19 Aug 1996 11:41:32 -0500
Subject: [PYTHON MATRIX-SIG] linear algebra
In-Reply-To: <32186E5B.4BA8@mit.edu>
Message-ID: <paul-960819114131.A011067@tornado>

On Mon, 19 Aug 1996 09:38:35 -0400  owner-matrix-sig@python.org wrote:
> Should these two transpositions be there?  This is obviously related to
> the different index order between NumPy and FORTRAN.  Still, I've always
> personally considered it a superficial difference that is best ignored.
> 
> If I remember by Linear Algebra correctly
> transpose(inverse(transpose(m))) == inverse(m).
> 
> However, I very rarely use any linear algebra functions in my code so
> I'm not the right person to be making that decision.  Opinions?

Hi,

I would like to comment on that. 
It probably does not make a big difference if stick with limited 
matrix- vector operations like : b=A*x <=> b=x'*A' but if go one level
lower I think it gets quite annoying to have to switch your indexing around.

Just to throw in a suggestion let me tell what the Ada95 standard does to 
work around this problem. In Ada95 the compiler has to have  a 
" pragma Convention (Fortran, Fortran_Matrix);" which changes the way 
an array is actually stored in memory.
For the programmer there is no change at all, the compiler takes care of all
necessary changes to make the array Fortran as well as Ada compatible.

Would this be possible in python without a serious perfomance overhead ?


Ralph Paul

	paul@aem.umn.edu
or	ralph@ifr.luftahrt.uni-stuttgart.de




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

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

From hinsenk@ere.umontreal.ca  Mon Aug 19 17:42:04 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Mon, 19 Aug 1996 12:42:04 -0400
Subject: [PYTHON MATRIX-SIG] linear algebra
In-Reply-To: <32186E5B.4BA8@mit.edu> (message from Jim Hugunin on Mon, 19 Aug 1996 09:38:35 -0400)
Message-ID: <199608191642.MAA24938@cyclone.ERE.UMontreal.CA>

> All of the current interface routines (from LinAlg.py) do the following:
> 
> return transpose(lapackfunction(transpose(input_matrix)))
> 
> Should these two transpositions be there?  This is obviously related to
> the different index order between NumPy and FORTRAN.  Still, I've always
> personally considered it a superficial difference that is best ignored.
> 
> If I remember by Linear Algebra correctly
> transpose(inverse(transpose(m))) == inverse(m).

True for inversion, but for little else, except in the special case of
symmetric matrices.

Personally I think it is important to work with the "right" index
order that everyone is used to. Python users should not have to know
anything about implementation details.

Besides, if I understand everything correctly, transposition should
cost almost nothing, right?

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Mon Aug 19 17:46:30 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Mon, 19 Aug 1996 12:46:30 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
References: <199608191632.MAA20254@cyclone.ERE.UMontreal.CA>
Message-ID: <32189A66.34E5@mit.edu>

Konrad HINSEN wrote:
> 
> > On Sun, 18 Aug 1996, Jim Hugunin wrote:
> >
> > > Carlos Fonseca wrote:
> > >
> > > > ix=argsort(a)
> > > > A=take(a,ix)
> > > > B=take(b,ix)
> > > >
> > > > This should be enough.
> > >
> > > You have a good point here, but I think that the issue is you want a
> > > different function from Konrad.  Alright, writing functions is something
> > > I can do.  What would you like it to be called?
> >
> > How do you feel about index(a,indices,axis). Alternatively, select(...)
> > would also make sense, I think. Thanks for looking into this.
> 
> Before we add functions that differ only in details, let's consider
> the APL approach to this kind of problem: concatenate the two arrays,
> sort the result, and split them again. How efficient would that
> be in Python? It mostly depends on the concatenation (which APL
> implementations treat with special care because it is extremely
> frequently used).

Concatenation is reasonably efficient.  It could be better, but I'm
holding off on any non-trivial efficiency improvements until after
release 1.0.  Right now I think a solid, stable and reasonably complete
implementation is much more important.

I don't see any good way to solve Carlos's problem using concatenation
(without including arbitrary comparision functions for sort which I
don't want to do).  How would you reccommend he gets the equivalent of:

ix=argsort(a)
A=take(a,ix)
B=take(b,ix)

for > 1d arrays without some take-like function?

-Jim

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

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

From hugunin@mit.edu  Mon Aug 19 17:50:14 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Mon, 19 Aug 1996 12:50:14 -0400
Subject: [PYTHON MATRIX-SIG] linear algebra
References: <199608191642.MAA24938@cyclone.ERE.UMontreal.CA>
Message-ID: <32189B46.114C@mit.edu>

Konrad HINSEN wrote:
> 
> > All of the current interface routines (from LinAlg.py) do the following:
> >
> > return transpose(lapackfunction(transpose(input_matrix)))
> >
> > Should these two transpositions be there?  This is obviously related to
> > the different index order between NumPy and FORTRAN.  Still, I've always
> > personally considered it a superficial difference that is best ignored.
> >
> > If I remember by Linear Algebra correctly
> > transpose(inverse(transpose(m))) == inverse(m).
> 
> True for inversion, but for little else, except in the special case of
> symmetric matrices.
> 
> Personally I think it is important to work with the "right" index
> order that everyone is used to. Python users should not have to know
> anything about implementation details.
> 
> Besides, if I understand everything correctly, transposition should
> cost almost nothing, right?

Transposition costs almost nothing.  Transposition followed by a copy is
O(n).  These FORTRAN routines expect contiguous arrays, which requires
the transposed array to be copied before calling them.  Therefore this
is a non-trivial amount of computation.

I agree that python users should not have to know anything about
implementation details.  I'm just wondering why the transposed order is
more natural than the native one.

-Jim

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

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

From hinsenk@ere.umontreal.ca  Mon Aug 19 18:10:47 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Mon, 19 Aug 1996 13:10:47 -0400
Subject: [PYTHON MATRIX-SIG] linear algebra
In-Reply-To: <paul-960819114131.A011067@tornado>
Message-ID: <199608191710.NAA26967@cyclone.ERE.UMontreal.CA>

> Just to throw in a suggestion let me tell what the Ada95 standard does to 
> work around this problem. In Ada95 the compiler has to have  a 
> " pragma Convention (Fortran, Fortran_Matrix);" which changes the way 
> an array is actually stored in memory.
> For the programmer there is no change at all, the compiler takes care of all
> necessary changes to make the array Fortran as well as Ada compatible.
> 
> Would this be possible in python without a serious perfomance overhead ?

One could have a second kind of array object that used Fortran conventions
for storage and inverts indexing. But I doubt that this is worth the
effort.

Konrad.


-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Mon Aug 19 18:22:09 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Mon, 19 Aug 1996 13:22:09 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
References: <199608191714.NAA27307@cyclone.ERE.UMontreal.CA>
Message-ID: <3218A2C1.72D9@mit.edu>

Konrad HINSEN wrote:
> 
> > Concatenation is reasonably efficient.  It could be better, but I'm
> > holding off on any non-trivial efficiency improvements until after
> > release 1.0.  Right now I think a solid, stable and reasonably complete
> > implementation is much more important.
> >
> > I don't see any good way to solve Carlos's problem using concatenation
> > (without including arbitrary comparision functions for sort which I
> > don't want to do).  How would you reccommend he gets the equivalent of:
> >
> > ix=argsort(a)
> > A=take(a,ix)
> > B=take(b,ix)
> >
> > for > 1d arrays without some take-like function?
> 
> Concatenation is indeed not what is needed, it is what APL
> calls lamination (but it is implemented as a special case
> of concatenation): the creation of a new axis along which
> the index 0 refers to a and the index 1 to b. Sort() then
> reshuffles all elements automatically, and a simple indexing
> recovers the sorted a and b.

by lamination you mean array([a,b])?  This still doesn't solve the
problem.  in this case and an b will each be sorted according to their
own values.  

-Jim

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

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

From hinsenk@ere.umontreal.ca  Mon Aug 19 18:18:05 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Mon, 19 Aug 1996 13:18:05 -0400
Subject: [PYTHON MATRIX-SIG] linear algebra
In-Reply-To: <32189B46.114C@mit.edu> (message from Jim Hugunin on Mon, 19 Aug 1996 12:50:14 -0400)
Message-ID: <199608191718.NAA27456@cyclone.ERE.UMontreal.CA>

> Transposition costs almost nothing.  Transposition followed by a copy is
> O(n).  These FORTRAN routines expect contiguous arrays, which requires
> the transposed array to be copied before calling them.  Therefore this
> is a non-trivial amount of computation.

Fortran routines rarely require contiguous arrays, and LAPACK routines
definitely don't. It's just a matter of correct interfacing, but
this would have to be done at the C level, since on the Python level
the necessary data about the memory layout is no longer available.

The current low-level LAPACK interface expects Fortran-layout
arrays, but one could as well have one that handles the "transposition"
itself, although that would be a more difficult task. So maybe we
should leave everything as it is for now and improve the interface
later.

> I agree that python users should not have to know anything about
> implementation details.  I'm just wondering why the transposed order is
> more natural than the native one.

No more natural, but conventional.

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From hinsenk@ere.umontreal.ca  Mon Aug 19 18:14:18 1996
From: hinsenk@ere.umontreal.ca (Konrad HINSEN)
Date: Mon, 19 Aug 1996 13:14:18 -0400
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <32189A66.34E5@mit.edu> (message from Jim Hugunin on Mon, 19 Aug 1996 12:46:30 -0400)
Message-ID: <199608191714.NAA27307@cyclone.ERE.UMontreal.CA>

> Concatenation is reasonably efficient.  It could be better, but I'm
> holding off on any non-trivial efficiency improvements until after
> release 1.0.  Right now I think a solid, stable and reasonably complete
> implementation is much more important.
> 
> I don't see any good way to solve Carlos's problem using concatenation
> (without including arbitrary comparision functions for sort which I
> don't want to do).  How would you reccommend he gets the equivalent of:
> 
> ix=argsort(a)
> A=take(a,ix)
> B=take(b,ix)
> 
> for > 1d arrays without some take-like function?

Concatenation is indeed not what is needed, it is what APL
calls lamination (but it is implemented as a special case
of concatenation): the creation of a new axis along which 
the index 0 refers to a and the index 1 to b. Sort() then
reshuffles all elements automatically, and a simple indexing
recovers the sorted a and b.

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                     | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie             | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal            | Fax:  +1-514-343-7586
C.P. 6128, succ. Centre-Ville     | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7             | Francais (phase experimentale)
-------------------------------------------------------------------------------

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

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

From drh@cherokee.unl.edu  Mon Aug 19 19:10:33 1996
From: drh@cherokee.unl.edu (Doug Heisterkamp)
Date: Mon, 19 Aug 1996 13:10:33 -0500 (CDT)
Subject: [PYTHON MATRIX-SIG] asarray and Complex?
Message-ID: <9608191810.AA08422@cherokee.unl.edu>

asarray is not converting the array to a different type when the 
typecode is given:
>>> from Numeric import *
>>> a = arange(4)
>>> b = asarray(a,Complex32)
>>> b
0 1 2 3

Also, the Complex type code is not working for me, but Complex32 is:
>>> d = a.astype(Complex)
>>> d
 0.  1.  2.  3.
>>> d[0] = 1 -1j
>>> d
 1.  1.  2.  3.


>>> d = a.astype(Complex32)
>>> d
 (0.+0.j)  (1.+0.j)  (2.+0.j)  (3.+0.j)  (4.+0.j)  (5.+0.j)  (6.+0.j)
       (7.+0.j)  (8.+0.j)

Doug
drh@cherokee.unl.edu


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

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

From drh@cherokee.unl.edu  Mon Aug 19 19:39:12 1996
From: drh@cherokee.unl.edu (Doug Heisterkamp)
Date: Mon, 19 Aug 1996 13:39:12 -0500 (CDT)
Subject: [PYTHON MATRIX-SIG] linear algebra
In-Reply-To: <32186E5B.4BA8@mit.edu> from "Jim Hugunin" at Aug 19, 96 09:38:35 am
Message-ID: <9608191839.AA08503@cherokee.unl.edu>

> All of the current interface routines (from LinAlg.py) do the following:
> 
> return transpose(lapackfunction(transpose(input_matrix)))
> 
> Should these two transpositions be there?  This is obviously related to
> the different index order between NumPy and FORTRAN.  Still, I've always
> personally considered it a superficial difference that is best ignored.
> 
> If I remember by Linear Algebra correctly
> transpose(inverse(transpose(m))) == inverse(m).
> 

For functions like inverse and eigenvalues, the transpose is not needed.
To skip the transpose for other functions is really just pushing the
transpose back to when the user is placing data in the matrix. This
would probably cause to much confusion in a standard library.

I have a version of LinAlg.py in which I do not transpose the matrices.
That version does not even copy the matrices.  I just catch the
exception when the array is not contiguous and then copy it.  When
I use that version, I know the data should be contiguous and is all
ready stored for Fortran use.

Doug Heisterkamp
drh@cherokee.unl.edu


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

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

From paul@aem.umn.edu  Mon Aug 19 20:01:51 1996
From: paul@aem.umn.edu (Ralph Paul)
Date: Mon, 19 Aug 1996 14:01:51 -0500
Subject: [PYTHON MATRIX-SIG] linear algebra
In-Reply-To: <199608191718.NAA27456@cyclone.ERE.UMontreal.CA>
Message-ID: <paul-960819140150.A012142@tornado>

On Mon, 19 Aug 1996 13:18:05 -0400  owner-matrix-sig@python.org wrote:
[ ...snip... ] 
> The current low-level LAPACK interface expects Fortran-layout
> arrays, but one could as well have one that handles the "transposition"
> itself, although that would be a more difficult task. So maybe we
> should leave everything as it is for now and improve the interface
> later.

How about providing functions that make the conversion obvious. Something
like "To_Fortran" . That way you know what is happening but you don't
have to know about the column oriented storage ( = transpose ) Fortran uses. 
Since you can code this in C, you can probably make it pretty fast.


Ralph Paul

	paul@aem.umn.edu
or	ralph@ifr.luftahrt.uni-stuttgart.de




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

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

From drh@cherokee.unl.edu  Mon Aug 19 20:16:50 1996
From: drh@cherokee.unl.edu (Doug Heisterkamp)
Date: Mon, 19 Aug 1996 14:16:50 -0500 (CDT)
Subject: [PYTHON MATRIX-SIG] EmptyArray as false
Message-ID: <9608191916.AA08623@cherokee.unl.edu>

It would be useful if an empty array acted as false, in the
same way that an empty list does.

>>> from Numeric import *
>>> a = array([])
>>> a
EmptyArray
>>> if a: print "a==TRUE"
... 
a==TRUE
>>> if []: print "[] == TRUE"
... 
>>> 

Doug Heisterkamp
drh@cherokee.unl.edu

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

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

From phil@geog.ubc.ca  Mon Aug 19 20:54:50 1996
From: phil@geog.ubc.ca (Phil Austin)
Date: Mon, 19 Aug 1996 12:54:50 -0700 (PDT)
Subject: [PYTHON MATRIX-SIG] linear algebra (Column major arrays)
In-Reply-To: <199608191710.NAA26967@cyclone.ERE.UMontreal.CA>
References: <paul-960819114131.A011067@tornado>
 <199608191710.NAA26967@cyclone.ERE.UMontreal.CA>
Message-ID: <199608191954.MAA12771@coot.geog.ubc.ca>

>>>>> "Konrad" == Konrad HINSEN <hinsenk@ere.umontreal.ca> writes:

    >> Just to throw in a suggestion let me tell what the Ada95
    >> standard does to work around this problem. In Ada95 the
    >> compiler has to have a " pragma Convention (Fortran,
    >> Fortran_Matrix);" which changes the way an array is actually
    >> stored in memory.  For the programmer there is no change at
    >> all, the compiler takes care of all necessary changes to make
    >> the array Fortran as well as Ada compatible.
    >> 
    >> Would this be possible in python without a serious perfomance
    >> overhead ?

    Konrad> One could have a second kind of array object that used
    Konrad> Fortran conventions for storage and inverts indexing. But
    Konrad> I doubt that this is worth the effort.

We're hoping that users can implement column-major arrays without
large performance penalties if they aren't intrinsic to the Python
matrix library.  Settling on one index order among our binary data api
(netcdf), other matrix packages (splus), and our compiled code (F77,
HPF, F90, and C++ using MV++,r A++/P++ or Barton and Nackman--all
column major), eliminates a vexing source of confusion and cuts a
suprising amount of work from debugging, tutorial writing, etc.

Phil Austin		INTERNET: phil@geog.ubc.ca
(604) 822-2175		FAX:	  (604) 822-6150

http://www.geog.ubc.ca/~phil
Associate Professor
Atmospheric Sciences Programme
Geography #217
University of British Columbia
1984 W Mall
Vancouver, BC  V6T 1Z2
CANADA

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

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

From pas@lems.brown.edu  Mon Aug 19 20:51:57 1996
From: pas@lems.brown.edu (Perry A. Stoll)
Date: Mon, 19 Aug 1996 15:51:57 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] repr vs. str
Message-ID: <Pine.SUN.3.91.960819153455.17759A-100000@lems34>



Currently the str and repr functions call the same function
to print an array object, namely string_repr.  From the manual 
http://www.python.org/doc/ref/node23.html#SECTION00431000000000000000

__repr__(self) 
     Called by the repr() built-in function and by string conversions 
(reverse or backward quotes) to compute the string
     representation of an object.                

__str__(self) 
     Called by the str() built-in function and by the print statement 
compute the string representation of an object.       


Seems like print and str should return the same string, which in this 
case would be whatever the array print function is.  I thought repr 
should try to return a string which could be used to reconstruct the 
object and str was purely for human consumption. Is that correct?



-Perry
 <pas@lems.brown.edu>


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

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

From hugunin@mit.edu  Mon Aug 19 21:10:18 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Mon, 19 Aug 1996 16:10:18 -0400
Subject: [PYTHON MATRIX-SIG] linear algebra (Column major arrays)
References: <paul-960819114131.A011067@tornado>
 <199608191710.NAA26967@cyclone.ERE.UMontreal.CA> <199608191954.MAA12771@coot.geog.ubc.ca>
Message-ID: <3218CA2A.3E22@mit.edu>

Phil Austin wrote:
> 
> >>>>> "Konrad" == Konrad HINSEN <hinsenk@ere.umontreal.ca> writes:
> 
>     >> Just to throw in a suggestion let me tell what the Ada95
>     >> standard does to work around this problem. In Ada95 the
>     >> compiler has to have a " pragma Convention (Fortran,
>     >> Fortran_Matrix);" which changes the way an array is actually
>     >> stored in memory.  For the programmer there is no change at
>     >> all, the compiler takes care of all necessary changes to make
>     >> the array Fortran as well as Ada compatible.
>     >>
>     >> Would this be possible in python without a serious perfomance
>     >> overhead ?
> 
>     Konrad> One could have a second kind of array object that used
>     Konrad> Fortran conventions for storage and inverts indexing. But
>     Konrad> I doubt that this is worth the effort.
> 
> We're hoping that users can implement column-major arrays without
> large performance penalties if they aren't intrinsic to the Python
> matrix library.  Settling on one index order among our binary data api
> (netcdf), other matrix packages (splus), and our compiled code (F77,
> HPF, F90, and C++ using MV++,r A++/P++ or Barton and Nackman--all
> column major), eliminates a vexing source of confusion and cuts a
> suprising amount of work from debugging, tutorial writing, etc.

I have to admit to a certain bafflement as to the importance of this
issue to people...

Nonetheless, there are many ways of implementing column major arrays
with close to zero performance hit within NumPy.  The use of general
strides allows for you to force Array objects to access their data
exactly as if they were a FORTRAN column-major array.  Personally I find
this approach rather distasteful, but a number of diehard FORTRAN users
were thrilled when they figured out they could do this, so if it's
useful to you...

Also, the transpose function is extremely efficient (almost
negligible).  So long as your C/FORTRAN functions can handle
discontiguous strided arrays (as apparently Lapack can) then this option
will also work for you.

-Jim

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

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

From tim@lassi.ece.uiuc.edu  Mon Aug 19 23:23:42 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Mon, 19 Aug 1996 17:23:42 -0500
Subject: [PYTHON MATRIX-SIG] Another way to crash the interpreter using long ints...
In-Reply-To: <3218CA2A.3E22@mit.edu> (message from Jim Hugunin on Mon, 19 Aug
 1996 16:10:18 -0400)
Message-ID: <199608192222.SAA15772@python.org>


Check this out:

>>> from Numeric import *
>>> c = concatenate((arange(1l,5l),))
>>> c.shape
(4,)
>>> c
Segmentation fault



-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From fonseca@gaivota.demon.co.uk  Mon Aug 19 21:37:49 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Mon, 19 Aug 1996 21:37:49 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
In-Reply-To: <199608191616.MAA18876@cyclone.ERE.UMontreal.CA>
Message-ID: <Pine.LNX.3.94.960819212012.600C-100000@gaivota.demon.co.uk>

On Mon, 19 Aug 1996, Konrad HINSEN wrote:

> > This is called "selection" (one of the 3 main operators) operators.
> 
> I am not sure what you are referring to. Is that a special term from
> GA applications?

Sorry, I edited that line about three times and it doesn't make sense.
Selection is one of the three main GA operators, i.e., just about every GA
would include a line:

Offspring = my_take(Parents,indices,axis=(-1 or -2))

I will not insist on the default axis issue, since you have obviously
given a lot more thought to the subject than I can claim to have done. As
long as the default values are documented and explained, that should be
fine. But even if take and friends should have axis=0 by default, please,
not sort(), argsort() and fft(), and any other matrix operations.  :-) 

> Unless your array is very big, this variant might actually be more
> expensive than the first one, because it involves three interpreted
> function calls. The best solution for such applications would be
> a special function that inverts a permutation (which is O(N), unlike
> sorting). Than you would write
> 
>   rank = inv_permutation(argsort(cost))
> 
> This function would potentially be more generally useful than your
> ekat().
> 
> Konrad.

I hadn't thought of that, but I agree with you here.

Carlos


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

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

From fonseca@gaivota.demon.co.uk  Mon Aug 19 22:10:37 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Mon, 19 Aug 1996 22:10:37 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] linear algebra
In-Reply-To: <32186E5B.4BA8@mit.edu>
Message-ID: <Pine.LNX.3.94.960819213828.600D-100000@gaivota.demon.co.uk>

On Mon, 19 Aug 1996, Jim Hugunin wrote:

> All of the current interface routines (from LinAlg.py) do the following:
> 
> return transpose(lapackfunction(transpose(input_matrix)))
> 
> Should these two transpositions be there?  This is obviously related to
> the different index order between NumPy and FORTRAN.  Still, I've always
> personally considered it a superficial difference that is best ignored.
> 
> If I remember by Linear Algebra correctly
> transpose(inverse(transpose(m))) == inverse(m).
> 
> However, I very rarely use any linear algebra functions in my code so
> I'm not the right person to be making that decision.  Opinions?
> 
> -Jim

As long as the result is mathematically equivalent, there should be no
need to have transpose() there. Any equivalences of this kind should
be exploited as much as possible, even if they apply to only a small
number of operations.

Thus, if Lapack implements C= A^(-1).B efficiently (in Fortran style),
then Python should compute c=b.a^(-1) equally efficiently, just by passing
the c-arrays unchanged to the fortran code (and the appropriately swapped
dimensions, without any need for copying or transposing the result). In
general, python should be as good with row vectors (1d vectors *are* row
vectors in python) as LAPACK with column vectors. In matlab A\b is more
efficient than b/A (the second is implemented as (A'\b')'), but both are
available. I am happy if python comes to expect row vectors if this makes
the interface code simpler and more efficient. (Sorry, I can't comment on
whether LAPACK requires contiguous arrays or not.) 

Carlos



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

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

From fonseca@gaivota.demon.co.uk  Tue Aug 20 03:14:01 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Tue, 20 Aug 1996 03:14:01 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] take() again
Message-ID: <Pine.LNX.3.94.960820024348.232A-100000@gaivota.demon.co.uk>

I was thinking about take(), indexing, structural operations, etc., and
got some more ideas on take() which should make it possible to combine
both mine and Konrad's expectations into a single function. The source of
confusion in my mind seems to have been that, whereas a+b expects arrays
to be aligned at their last dimension, indexing works on the outer
dimension. In the case of take(), it should work on the outer
dimension*s*.

My proposal is a take(a,indices,axis) where

* the dimensions of indices must be aligned with the *outer* (or leftmost) 
dimensions of a (and not the inner ones, as I proposed before).

* the default axis is the inner axis of _indices_. This is not necessarily
the inner axis of a, as indices my have lower rank than a. We would still
say axis=-1, but this would refer to indices, not to a. 

Now, for some examples:

If indices is 1d, axis=-1 is the same as axis=0, and we have the current
behaviour. 

If indices has the same shape as a, then take(a,argsort(a,-1)) will work
as expected.

Even better, if indices has shape (m,n) and a has shape (m,n,p),
take(a,indices) will rearrange (or select) the rows of a. I believe this
to be consistent with the idea of a structural operation, and is what I
will actually need in my application. 

If indices is 2d and we want the current behaviour, then take([a],indices)
will do it. In this way, the rank of the result will only increase if we
explicitly want it to. 

Note that in all of the above situations, the default axis produced the
desired results.

Would this be acceptable?

Carlos



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

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

From hugunin@mit.edu  Tue Aug 20 14:04:08 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 20 Aug 1996 09:04:08 -0400
Subject: [PYTHON MATRIX-SIG] Another way to crash the interpreter using long ints...
References: <199608192222.SAA15772@python.org>
Message-ID: <3219B7C8.7DBD@mit.edu>

tim@lassi.ece.uiuc.edu wrote:
> 
> Check this out:
> 
> >>> from Numeric import *
> >>> c = concatenate((arange(1l,5l),))
> >>> c.shape
> (4,)
> >>> c
> Segmentation fault

The problem in all of these cases is apparently in the array printing
functions when long ints are contained in the array.  My problem is that
this doesn't show up on my primary developement platform.  I'll look
into it on other platforms around here.

-Jim

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

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

From hugunin@mit.edu  Tue Aug 20 14:27:42 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 20 Aug 1996 09:27:42 -0400
Subject: [PYTHON MATRIX-SIG] asarray and Complex?
References: <9608191810.AA08422@cherokee.unl.edu>
Message-ID: <3219BD4E.6E5D@mit.edu>

Doug Heisterkamp wrote:
> 
> asarray is not converting the array to a different type when the
> typecode is given:

typo in Numeric.py.  Fixed

> Also, the Complex type code is not working for me, but Complex32 is:

typo in Precision.py.  Fixed

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

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

From hugunin@mit.edu  Tue Aug 20 14:36:21 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 20 Aug 1996 09:36:21 -0400
Subject: [PYTHON MATRIX-SIG] repr vs. str
References: <Pine.SUN.3.91.960819153455.17759A-100000@lems34>
Message-ID: <3219BF55.66FD@mit.edu>

Perry A. Stoll wrote:
> 
> Currently the str and repr functions call the same function
> to print an array object, namely string_repr.  From the manual
> http://www.python.org/doc/ref/node23.html#SECTION00431000000000000000
> 
> __repr__(self)
>      Called by the repr() built-in function and by string conversions
> (reverse or backward quotes) to compute the string
>      representation of an object.
> 
> __str__(self)
>      Called by the str() built-in function and by the print statement
> compute the string representation of an object.
> 
> Seems like print and str should return the same string, which in this
> case would be whatever the array print function is.  I thought repr
> should try to return a string which could be used to reconstruct the
> object and str was purely for human consumption. Is that correct?

This sounds good to me.  I've made your requested change.

-Jim

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

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

From tim@lassi.ece.uiuc.edu  Tue Aug 20 15:18:18 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Tue, 20 Aug 1996 09:18:18 -0500
Subject: [PYTHON MATRIX-SIG] Another way to crash the interpreter using long ints...
In-Reply-To: <3219B7C8.7DBD@mit.edu> (message from Jim Hugunin on Tue, 20 Aug
 1996 09:04:08 -0400)
Message-ID: <199608201416.KAA17862@python.org>


I've been trying to look into it from this end, unfortunatley, my
understanding of the python internals is somewhat (ok very)
sketchy. For what its worth, here's what I've noticed:

1) Long ints work most of the time on alpha2:

>>> arange(1,5l,2)
1L 3L
>>> arange(1,5l)[::2]
1L 3L

Concatenating arrays of long ints is the only thing that I've found
that breaks on my machine.

2) I've inluded the stack trace for:
> >>> from Numeric import *
> >>> c = concatenate((arange(1l,5l),))
> >>> c.shape
> (4,)
> >>> c
> Segmentation fault

Way down at the bottom for what it's worth. Poking around the only
thing that looked obviously wrong (recall I know little about the guts
of python) was that in builtin_str, it's passed a tuple with
ob_refcnt=3, and this gets passed to newgetargs which returns what
seems to be garbage:

	if (!newgetargs(args, "O:str", &v))
		return NULL;
	return strobject(v);

(gdb) p *v->ob_type
$20 = {ob_refcnt = 135100992, ob_type = 0x80d7a20, ob_size = 65537,  
                   ^^^^^^^^^
tp_name = 0x80d7a40 "Tpz\r\b`z\r\b\001", tp_basicsize = 0,  <ETC....>
                     ^^^^^^^^^^^^^^^^^
 
3) This also breaks the interpreter, and I don't think it calls the
array printing code. It does have that same goofy object floating
around though...

That's all I can think of, for now.

-tim


#0  0x80d78e0 in UP ()
#1  0x806ea2b in PyObject_Str (v=0x80d7a40) at object.c:231
#2  0x8040cc9 in builtin_str (self=0x0, args=0x80d1380)
    at bltinmodule.c:1386
#3  0x8047b1d in call_builtin (func=0x80a6d40, arg=0x80d1380, 
    kw=0x0) at ceval.c:2401
#4  0x80479a1 in PyEval_CallObjectWithKeywords (func=0x80a6d40, 
    arg=0x80d1380, kw=0x0) at ceval.c:2366
#5  0x80458c1 in eval_code2 (co=0x80cc580, globals=0x80d7f80, 
    locals=0x0, args=0x80d156c, argcount=1, kws=0x0, kwcount=0, 
    defs=0x0, defcount=0, owner=0x0) at ceval.c:1629
#6  0x8047fcd in call_function (func=0x80ca0c0, arg=0x80d1560, 
    kw=0x0) at ceval.c:2518
#7  0x8047981 in PyEval_CallObjectWithKeywords (func=0x80ca0c0, 
    arg=0x80d1560, kw=0x0) at ceval.c:2364
#8  0x8047862 in PyEval_CallObject (func=0x80ca0c0, arg=0x80d1560)
    at ceval.c:2335
#9  0x803f0fd in builtin_map (self=0x0, args=0x80ceba0)
    at bltinmodule.c:676
#10 0x8047b1d in call_builtin (func=0x80a6e30, arg=0x80ceba0, 
    kw=0x0) at ceval.c:2401
#11 0x80479a1 in PyEval_CallObjectWithKeywords (func=0x80a6e30, 
    arg=0x80ceba0, kw=0x0) at ceval.c:2366
#12 0x80458c1 in eval_code2 (co=0x80cc240, globals=0x80d7f80, 
    locals=0x0, args=0x80d79cc, argcount=1, kws=0x0, kwcount=0, 
    defs=0x80c63ec, defcount=3, owner=0x0) at ceval.c:1629
#13 0x8047fcd in call_function (func=0x80d7ee0, arg=0x80d79c0, 
    kw=0x0) at ceval.c:2518
#14 0x8047981 in PyEval_CallObjectWithKeywords (func=0x80d7ee0, 
    arg=0x80d79c0, kw=0x0) at ceval.c:2364
#15 0x8047862 in PyEval_CallObject (func=0x80d7ee0, arg=0x80d79c0)
    at ceval.c:2335
#16 0x800dc55 in array_print (self=0x80d6940, fp=0x809fa90, flags=0)
    at ./arrayobject.c:1037
#17 0x806e877 in PyObject_Print (op=0x80d6940, fp=0x809fa90, 
    flags=0) at object.c:190
#18 0x8063841 in PyFile_WriteObject (v=0x80d6940, f=0x80a53e0, 
    flags=0) at fileobject.c:793
#19 0x80436d4 in eval_code2 (co=0x80d6980, globals=0x80ad820, 
    locals=0x80ad820, args=0x0, argcount=0, kws=0x0, kwcount=0, 
    defs=0x0, defcount=0, owner=0x0) at ceval.c:894
#20 0x80419a2 in PyEval_EvalCode (co=0x80d6980, globals=0x80ad820, 
    locals=0x80ad820) at ceval.c:282
#21 0x8058021 in run_node (n=0x80d7880, 
    filename=0x808a8aa "<stdin>", globals=0x80ad820, 
    locals=0x80ad820) at pythonrun.c:426
#22 0x8057766 in PyRun_InteractiveOne (fp=0x809fb50, 
    filename=0x808a8aa "<stdin>") at pythonrun.c:208
#23 0x805754f in PyRun_InteractiveLoop (fp=0x809fb50, 
    filename=0x808a8aa "<stdin>") at pythonrun.c:149
#24 0x805740a in PyRun_AnyFile (fp=0x809fb50, 
    filename=0x808a8aa "<stdin>") at pythonrun.c:126
#25 0x80035b8 in main (argc=1, argv=0xbffffd30) at main.c:207
#26 0x8003075 in ___crt_dummy__ ()
#27 0xbffffbb8 in UP ()
#28 0x2fc45 in ?? ()

--
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hugunin@mit.edu  Tue Aug 20 15:30:46 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Tue, 20 Aug 1996 10:30:46 -0400
Subject: [PYTHON MATRIX-SIG] Another way to crash the interpreter using long ints...
References: <9608201415.AA24291@MIT.EDU>
Message-ID: <3219CC16.1A1D@mit.edu>

tim@lassi.ece.uiuc.edu wrote:
> 
> I've been trying to look into it from this end, unfortunatley, my
> understanding of the python internals is somewhat (ok very)
> sketchy. For what its worth, here's what I've noticed:
> 
> 1) Long ints work most of the time on alpha2:
> 
> >>> arange(1,5l,2)
> 1L 3L
> >>> arange(1,5l)[::2]
> 1L 3L

I've figured out the source of the bug here.  I'm going to explain in
some detail for those who are interested.

1) An array of long ints is represented as an array of generic python
objects.  Elements of this array could be anything from a user-defined
class to other strange builtin types.  Operations on these arrays are
obviously going to be less efficient that on corresponding arrays of raw
C data, but they shouldn't be too bad.

2) Many C functions (take, concatenate, repeat, choose, ...) use memcpy
on portions of an array in order to copy the raw contents of one array
to a new one.

3) When you copy a pointer to a PyObject, you need to remember to INCREF
that object.  This is in contrast to every other potential type of
array.

4) I forgot to add in the PyArray_INCREF call (INCREF's all the python
objects in the array) to virtually all of the array C functions when I
rewrote them (to avoid other potential memory leaks) for 1.0a1.

I've now fixed the obvious problems for alpha3, but I'd have to admit
that remembering all of the required INCREF's and DECREF's can sometimes
be a confusing process (and tracking down the error can be even worse).

-Jim

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

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

From hinsen@ibs.ibs.fr  Tue Aug 20 19:54:03 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Tue, 20 Aug 1996 19:54:03 +0100
Subject: [PYTHON MATRIX-SIG] Re: take() again
Message-ID: <321A09CB.384E@ibs.ibs.fr>

> My proposal is a take(a,indices,axis) where
>
> * the dimensions of indices must be aligned with the *outer* (or leftmost)
> dimensions of a (and not the inner ones, as I proposed before).
>
> * the default axis is the inner axis of _indices_. This is not necessarily
> the inner axis of a, as indices my have lower rank than a. We would still
> say axis=-1, but this would refer to indices, not to a.

You would be welcome in the J development team, because what you have
just described is exactly how J behaves with a modified rank for its
left argument (i.e. the indices). I agree that this is very useful,
but modifying the access to the other argument is also useful.
Obviously the best way out is to have two axis argument, then we
would almost have the full J functionality. But I am not sure whether
that is a realistic proposal.

> If indices is 2d and we want the current behaviour, then take([a],indices)
> will do it. In this way, the rank of the result will only increase if we
> explicitly want it to.

Yes, but what if we want the current behaviour with an arbitrary axis
specification? That would be lost.

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From hinsen@ibs.ibs.fr  Tue Aug 20 19:50:43 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Tue, 20 Aug 1996 19:50:43 +0100
Subject: [PYTHON MATRIX-SIG] Final conventions for alpha2
Message-ID: <321A0903.3CA3@ibs.ibs.fr>

> fine. But even if take and friends should have axis=0 by default, please,
> not sort(), argsort() and fft(), and any other matrix operations.  :-)

I agree, of course!

Konrad.

-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From tim@lassi.ece.uiuc.edu  Wed Aug 21 00:09:22 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Tue, 20 Aug 1996 18:09:22 -0500
Subject: [PYTHON MATRIX-SIG] Indexing bug?
In-Reply-To: <3219CC16.1A1D@mit.edu> (message from Jim Hugunin on Tue, 20 Aug
 1996 10:30:46 -0400)
Message-ID: <199608202307.TAA19369@python.org>


I think this is a bug:

>>> a = arange(8)
>>> a
0 1 2 3 4 5 6 7
>>> a[::2]
0 2 4 6
>>> a[1::2]
1 3 5
>>> 

Shouldn't this return 1 3 5 7?



-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hugunin@mit.edu  Wed Aug 21 17:09:29 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Wed, 21 Aug 1996 12:09:29 -0400
Subject: [PYTHON MATRIX-SIG] Re: Indexing bug?
References: <9608202306.AA27623@MIT.EDU>
Message-ID: <321B34B9.184E@mit.edu>

tim@lassi.ece.uiuc.edu wrote:
> 
> I think this is a bug:
> 
> >>> a = arange(8)
> >>> a
> 0 1 2 3 4 5 6 7
> >>> a[::2]
> 0 2 4 6
> >>> a[1::2]
> 1 3 5
> >>>
> 
> Shouldn't this return 1 3 5 7?

Certainly should.  This got lost in the translation to the new built-in
slices that come with 1.4b2.  It's fixed in alpha3.

-Jim

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

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

From fonseca@gaivota.demon.co.uk  Wed Aug 21 22:46:12 1996
From: fonseca@gaivota.demon.co.uk (Carlos Fonseca)
Date: Wed, 21 Aug 1996 22:46:12 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] Re: take() again
In-Reply-To: <321A09CB.384E@ibs.ibs.fr>
Message-ID: <Pine.LNX.3.94.960821222340.2424A-100000@gaivota.demon.co.uk>

On Tue, 20 Aug 1996, Konrad Hinsen wrote:

> You would be welcome in the J development team, because what you have
> just described is exactly how J behaves with a modified rank for its
> left argument (i.e. the indices). I agree that this is very useful,
> but modifying the access to the other argument is also useful.
> Obviously the best way out is to have two axis argument, then we
> would almost have the full J functionality. But I am not sure whether
> that is a realistic proposal.

I am not familiar with J, but from what I've read in this list, it would
seem to have very complete multidimensional array handling. Why would
"full" functionality not be realistic? Too complex, perhaps?

> > If indices is 2d and we want the current behaviour, then take([a],indices)
> > will do it. In this way, the rank of the result will only increase if we
> > explicitly want it to.
> 
> Yes, but what if we want the current behaviour with an arbitrary axis
> specification? That would be lost.
> 

One could always write take(a,[indices]) to get the current behaviour with
axis=2, if indices is 1d. More generally, one could write

take( a[(ni-1)*(NewAxis,)],indices[(Ellipses,)+ax*(NewAxis,)+(All,)] )

where ni is the number of dimensions in indices, and ax is the desired
axis in a. Many other combinations would also be possible, of course.

The above may not look nice, but it would work for *all* cases, and the
default values should cover *most* cases. Currently, take()'s
functionality is still incomplete, as I hope to have convinced everybody
by now. 

What else can we do about take, so that it works for at least the two
of us? ;-)

Carlos



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

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

From tim@lassi.ece.uiuc.edu  Thu Aug 22 05:23:43 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Wed, 21 Aug 1996 23:23:43 -0500
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
Message-ID: <199608220421.AAA22858@python.org>


I have an idea about default axes. I'm not entirely satisfied with it,
but its been bugging me for a week or so, so I figured I'd let it bug
you'all instead.

To the best of my recollection, the arguments about default axes go
like this (apologies in advance for any misrepresentation of someone's
posistion):

Jim Hugunin:
	Remembering what are the default axes is too comlicated. We
	should pick a single default axes and stick with it. (With
	perhaps 1 or 2 exceptions for some weird functions).

Konrad Hinsen:
	It's absurd to make people type axis=? for a whole class of
	functions that normally use an axis other than the
	default. The array functions divide naturally into two
	classes, those that normally use axis=0 and those that use the
	last possible axis (-1 for vector ops, -2 for 2d matrix ops,
	etc.). Therefore, it should be possible to figure out with a
	minimum of effort what the natural axis is.

I agree with both these posistions! It would be annoying to have to
type axis=0 (or conversely axis=-1) all over the place if there's a
single default axis. On the other hand, I'm not sure the difference
between structural and non-strucural matrix ops is clear for all
cases. Particularly for people new to NumPy. And, some people may have
different ideas about what is the natural axis for a particular
operation (Carlos said something about this, I think?).

A problem I see with both posistions, particuarly Jim's, is that there
will be a temptation to redefine the functions when the desired
default axis  with the default, e.g (as Jim posted),

def fft(f):
	fft(f, axis=-1)

Which leads to a problem with code readability for people who don't
use your conventions.

Some sort of naming convention could provide a way out of this
box. That is, indicate by the name of the function what the default
axis is, e.g.,

fft(f)  <=> fft(f,axis=0)
fft_(f) <=> fft(f,axis=-1)     # _ <=> farther away <=> -1 (or -2...)
	
A complete set of both functions could be provided, or just guidelines
on how people are to name their own should they need the other axis.

Pros: 
	1) No need to type axis=? for what should be the default case.
	2) Obvious at a glance what the default axis is.
	3) Removes incentive to create private versions of functions.

Cons:
	1) Aesthetics?
	2) Requires a certain amount of function renaming.
	3) Doesn't help with dot (**).
	4) ....

Opinions?



________________________________________________________________


(**) Another naming convention that is too ugly too live, but would
take care of dot, is:
dot00(f,g) = dot(f,g,axis=(0,0))
dot01(f,g) = dot(f,g,axis=(0,-1))
fft1(f) = fft(f,axis=-1)
etc.


-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From janne@avocado.pc.helsinki.fi  Thu Aug 22 09:02:53 1996
From: janne@avocado.pc.helsinki.fi (Janne Sinkkonen)
Date: 22 Aug 1996 11:02:53 +0300
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
In-Reply-To: tim@lassi.ece.uiuc.edu's message of Wed, 21 Aug 1996 23:23:43 -0500
References: <199608220421.AAA22858@python.org>
Message-ID: <oa4tlv26du.fsf@avocado.pc.helsinki.fi>

tim@lassi.ece.uiuc.edu writes:

> Opinions?

Here is a related idea: the default axis could be (could it be
technically and easily? i'm somewhat new to python) an attribute of
the functions, so one could write:

	fft.default_axis=-1

or

	for f in Numeric.ufuncs: f.default_axis=-1

Code reability would suffer badly, of course. I don't know whether
this is a good idea or not, it just came to my mind.

On the long run, the only sensible solution is to add some information
about the semantics of the axes to the objects (arrays) themselves.

-- 
Janne Sinkkonen      <janne@iki.fi>      <URL: http://www.iki.fi/~janne/ >

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

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

From hugunin@mit.edu  Thu Aug 22 16:02:38 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 22 Aug 1996 11:02:38 -0400
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
References: <199608220421.AAA22858@python.org> <oa4tlv26du.fsf@avocado.pc.helsinki.fi>
Message-ID: <321C768E.63D8@mit.edu>

tim@lassi.ece.uiuc.edu wrote:
> 
> I have an idea about default axes. I'm not entirely satisfied with it,
> but its been bugging me for a week or so, so I figured I'd let it bug
> you'all instead.

I'm glad you brought this idea up, it seems there might be a solution in
it somewhere.

> Some sort of naming convention could provide a way out of this
> box. That is, indicate by the name of the function what the default
> axis is, e.g.,
> 
> fft(f)  <=> fft(f,axis=0)
> fft_(f) <=> fft(f,axis=-1)     # _ <=> farther away <=> -1 (or -2...)
> 
> A complete set of both functions could be provided, or just guidelines
> on how people are to name their own should they need the other axis.

I really don't think that a complete set of both function should be
provided.  The great value in this proposal is it lets me define the
"proper" default axis for each function without fear of people not being
able to remember which one that is.

> Pros:
>         1) No need to type axis=? for what should be the default case.
>         2) Obvious at a glance what the default axis is.
>         3) Removes incentive to create private versions of functions.

The pros all sound good to me.

> Cons:
>         1) Aesthetics?

I don't like fft_ for the last axis.  _ is getting a little bit
overloaded in python these days.

>         2) Requires a certain amount of function renaming.

Still not a big concern to me.

>         3) Doesn't help with dot (**).

I don't think this should be too much of a concern.

Now my comments in full:

0) I've been writing code all this week using alpha2 and I've found
myself quite happy writing fft(a, axis=-1) everywhere.  This isn't
actually all that much extra baggage to be carrying around.  That
said...

1) A naming convention to distinguish between structural and
non-structural operations might satisfy both Konrad and myself.  I'm
still not sure what that naming convention should look like.

2) This naming convention should not become a substitute for non-default
axis specification.  ie. people should not define concatenate_ as a
substitute for concatenate( arrays, axis=-1).  Using this keyword
argument seems to me a great way to change the default axis when you
need to.

I can't think of any good naming conventions off hand, but just to make
things concrete, here's a list of some names to discuss:

structural operations: concatenate, reduce, take, repeat, ...
nonstructural operation: sort, argsort, fft, argmax, (sum?), ...

And here are several bad proposals (I'm not planning on implementing any
of these):

nonstructural_sort, nonstructural_fft, ...
ns_sort, ns_fft, ...
sort_last_axis, fft_last_axis, ...

If the names of these functions somehow made their categories obvious,
then I'd be happy to set the default axis for the nonstructural
operations to be -1.

Now to shoot down a few directions I don't want this conversation to go.

> ________________________________________________________________
> 
> (**) Another naming convention that is too ugly too live, but would
> take care of dot, is:
> dot00(f,g) = dot(f,g,axis=(0,0))
> dot01(f,g) = dot(f,g,axis=(0,-1))
> fft1(f) = fft(f,axis=-1)
> etc.

Definately too ugly to live ;-)  To say it again.  The point here is to
make it obvious by the name what type of function this is (structural or
non) not to replace the perfectly good way we already have of overriding
the default axis.


On another note:

Janne Sinkkonen wrote:

> Here is a related idea: the default axis could be (could it be
> technically and easily? i'm somewhat new to python) an attribute of
> the functions, so one could write:

This is reasonably easy technically, but see my comments later for why I
won't do it.

>         fft.default_axis=-1
> 
> or
> 
>         for f in Numeric.ufuncs: f.default_axis=-1
> 
> Code reability would suffer badly, of course. I don't know whether
> this is a good idea or not, it just came to my mind.

Code readability would suffer far too much for my tastes.  This is just
another variant on the:

def fft(x,axis=-1): fft(x,axis)

solution.  This is the sort of thing that everybody would probably enjoy
when writing their own functions, but which would make reading other
people's code impossible.

-Jim

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

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

From hugunin@mit.edu  Thu Aug 22 16:32:56 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 22 Aug 1996 11:32:56 -0400
Subject: [PYTHON MATRIX-SIG] Re: take() again
References: <Pine.LNX.3.94.960821222340.2424A-100000@gaivota.demon.co.uk>
Message-ID: <321C7DA8.52DC@mit.edu>

Carlos Fonseca wrote:
...
> One could always write take(a,[indices]) to get the current behaviour with
> axis=2, if indices is 1d. More generally, one could write
> 
> take( a[(ni-1)*(NewAxis,)],indices[(Ellipses,)+ax*(NewAxis,)+(All,)] )

You aren't seriously suggesting that people write python code that looks
like this?

I think that everybody could be made happy if I added the following
function to alpha3:

permute(a, permutation)

a and permutation must be aligned for as many axes as there are in
permutation.  The elements of a will be resorted according to the
elements of permutation.

ie. permute(a, argsort(a)) <==> sort(a)

I think that with this function and take almost everything that you want
to do with Carlos' fancy take would be possible.  I also think that
having two fairly easy to understand functions is a better situation
than having one really complicated one.

Note:
permute(a, indices) <==> take(a, indices)
	iff:	len(indices) = len(a)
		len(indices.shape) = 1

Opinions? - Jim

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

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

From tim@lassi.ece.uiuc.edu  Thu Aug 22 17:10:40 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Thu, 22 Aug 1996 11:10:40 -0500
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
In-Reply-To: <321C768E.63D8@mit.edu> (message from Jim Hugunin on Thu, 22 Aug
 1996 11:02:38 -0400)
Message-ID: <199608221610.MAA24096@python.org>


Here some more random naming conventions for your amusement:

Capitalize structural ops:
	Concatenate, Reduce, Take, Repeat, ...
	sort, argsort, fft, argmax, ...
	
	"Simple, but looks like a Class constructor..."

Use 'of' with nonstructural ops (as "the argsort of x"):
	concatenate, reduce, take, repeat, ...
	sort_of, argsort_of, fft_of, argmax_of, ...
	
	"Weird"

Turn nonstructural operations into adjectives, leave structural ones as verbs:
	concatenate, reduce, take, repeat, ...
	sorted, argsorted, ffted, argmaxed, ...

	"Weirder!"

Spell nonstructural operations backwards:
	concatenate, reduce, take, repeat, ...
	tors, torsgra, tff, xamgra, ...

	"Very weird! Impossible to spell. Fails for palindromes."



-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hinsen@ibs.ibs.fr  Thu Aug 22 20:01:53 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 22 Aug 1996 20:01:53 +0100
Subject: [PYTHON MATRIX-SIG] Re: take() again
References: <Pine.LNX.3.94.960821222340.2424A-100000@gaivota.demon.co.uk>
Message-ID: <321CAEA1.3AB8@ibs.ibs.fr>

Carlos Fonseca wrote:
> 
> I am not familiar with J, but from what I've read in this list, it would
> seem to have very complete multidimensional array handling. Why would
> "full" functionality not be realistic? Too complex, perhaps?

The implementation might take so long that we'll never get to beta
stage.
I don't see any problems in principle.

> One could always write take(a,[indices]) to get the current behaviour with
> axis=2, if indices is 1d. More generally, one could write
> 
> take( a[(ni-1)*(NewAxis,)],indices[(Ellipses,)+ax*(NewAxis,)+(All,)] )

Would you really like to write that? Or read it?

> The above may not look nice, but it would work for *all* cases, and the
> default values should cover *most* cases. Currently, take()'s

For any reasonably frequent expression there should be a readable
form. This doesn't have to be the default, but what you have written
above doesn't qualify as Python code in my eyes ;-)

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From hinsen@ibs.ibs.fr  Thu Aug 22 20:27:20 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 22 Aug 1996 20:27:20 +0100
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
References: <199608220421.AAA22858@python.org> <oa4tlv26du.fsf@avocado.pc.helsinki.fi> <321C768E.63D8@mit.edu>
Message-ID: <321CB498.4F4A@ibs.ibs.fr>

Jim Hugunin wrote:
> 
> I really don't think that a complete set of both function should be
> provided.  The great value in this proposal is it lets me define the
> "proper" default axis for each function without fear of people not being
> able to remember which one that is.

That supposes that the naming convention is easier to remember than
the default axis, which is not obvious to me. I can imagine people
wondering whether the correct function is fft or fft_.

> If the names of these functions somehow made their categories obvious,
> then I'd be happy to set the default axis for the nonstructural
> operations to be -1.

I can't think of a naming scheme that would work like that.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Thu Aug 22 19:48:21 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 22 Aug 1996 14:48:21 -0400
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
References: <199608220421.AAA22858@python.org> <oa4tlv26du.fsf@avocado.pc.helsinki.fi> <321C768E.63D8@mit.edu> <321CB498.4F4A@ibs.ibs.fr>
Message-ID: <321CAB75.2236@mit.edu>

Konrad Hinsen wrote:
> 
> Jim Hugunin wrote:
> >
> > I really don't think that a complete set of both function should be
> > provided.  The great value in this proposal is it lets me define the
> > "proper" default axis for each function without fear of people not being
> > able to remember which one that is.
> 
> That supposes that the naming convention is easier to remember than
> the default axis, which is not obvious to me. I can imagine people
> wondering whether the correct function is fft or fft_.

I'd argue here that if you can remember that fft operates on the -1
axis, you can remember that all functions that operate by default on the
-1 axis have an underscore after them (which by the way is not a naming
convention I find reasonable).

What I like about this is that if you forget that fft operates on
axis=-1 by default you get an exception (for example the name fft is
undefined).  Otherwise, you instead get a perfectly legal array back
who's values are completely different from what you expected.  I find
these bugs extremely hard to track down (from personal experience).

Your concern about people wondering whether it's fft or fft_ is exactly
my concern about people wondering if its axis=-1 or axis=0.

> > If the names of these functions somehow made their categories obvious,
> > then I'd be happy to set the default axis for the nonstructural
> > operations to be -1.
> 
> I can't think of a naming scheme that would work like that.

I can't either, but I do think this would be a fine solution if somebody
can come up with the right names.

-Jim

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

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

From hinsen@ibs.ibs.fr  Thu Aug 22 20:52:10 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 22 Aug 1996 20:52:10 +0100
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
References: <199608220421.AAA22858@python.org> <oa4tlv26du.fsf@avocado.pc.helsinki.fi> <321C768E.63D8@mit.edu> <321CB498.4F4A@ibs.ibs.fr> <321CAB75.2236@mit.edu>
Message-ID: <321CBA6A.675E@ibs.ibs.fr>

Jim Hugunin wrote:
> 
> Konrad Hinsen wrote:
> >
> > Jim Hugunin wrote:
> > >
> > > I really don't think that a complete set of both function should be
> > > provided.  The great value in this proposal is it lets me define the
> > > "proper" default axis for each function without fear of people not being
> > > able to remember which one that is.
> >
> > That supposes that the naming convention is easier to remember than
> > the default axis, which is not obvious to me. I can imagine people
> > wondering whether the correct function is fft or fft_.
> 
> I'd argue here that if you can remember that fft operates on the -1
> axis, you can remember that all functions that operate by default on the
> -1 axis have an underscore after them (which by the way is not a naming
> convention I find reasonable).

I agree, but such a naming convention is useful if it is *easier*
to remember, not just as easy.

> Your concern about people wondering whether it's fft or fft_ is exactly
> my concern about people wondering if its axis=-1 or axis=0.

That was the point of my example!

> > > If the names of these functions somehow made their categories obvious,
> > > then I'd be happy to set the default axis for the nonstructural
> > > operations to be -1.
> >
> > I can't think of a naming scheme that would work like that.
> 
> I can't either, but I do think this would be a fine solution if somebody
> can come up with the right names.

Actually, of all the "weird" proposals made by Tim, I give the best
chances to something like the "verb/adjective" distinction. At least
this is a clear distinction, which does not depend on some trivial
add-on that could or could not be there. But of course I can't propose
any working scheme that looks reasonable...

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Thu Aug 22 20:01:25 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 22 Aug 1996 15:01:25 -0400
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
References: <199608220421.AAA22858@python.org> <oa4tlv26du.fsf@avocado.pc.helsinki.fi> <321C768E.63D8@mit.edu> <321CB498.4F4A@ibs.ibs.fr> <321CAB75.2236@mit.edu> <321CBA6A.675E@ibs.ibs.fr>
Message-ID: <321CAE85.5D9@mit.edu>

Konrad Hinsen wrote:
> 
> Jim Hugunin wrote:
> >
> > Konrad Hinsen wrote:
> > >
> > > Jim Hugunin wrote:
> > > >
> > > > I really don't think that a complete set of both function should be
> > > > provided.  The great value in this proposal is it lets me define the
> > > > "proper" default axis for each function without fear of people not being
> > > > able to remember which one that is.
> > >
> > > That supposes that the naming convention is easier to remember than
> > > the default axis, which is not obvious to me. I can imagine people
> > > wondering whether the correct function is fft or fft_.
> >
> > I'd argue here that if you can remember that fft operates on the -1
> > axis, you can remember that all functions that operate by default on the
> > -1 axis have an underscore after them (which by the way is not a naming
> > convention I find reasonable).
> 
> I agree, but such a naming convention is useful if it is *easier*
> to remember, not just as easy.

This I disagree with.  The advantage of the naming convention (provided
one can be discovered) is that you get an error if you remember
incorrectly rather than getting a strange array back.  This to me is
REALLY important.

-Jim

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

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

From Marko Balabanovic <marko@cs.stanford.edu>  Thu Aug 22 20:12:43 1996
From: Marko Balabanovic <marko@cs.stanford.edu> (Marko Balabanovic)
Date: Thu, 22 Aug 96 12:12:43 PDT
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
In-Reply-To: Your message of Thu, 22 Aug 1996 15:01:25 -0400
Message-ID: <CMM.0.90.4.840741163.marko@scottie.Stanford.EDU>

> Konrad Hinsen wrote:
> > 
> > Jim Hugunin wrote:
> > >
> > > Konrad Hinsen wrote:
> > > >
> > > > Jim Hugunin wrote:
> > > > >
> > > > > I really don't think that a complete set of both function should be
> > > > > provided.  The great value in this proposal is it lets me define the
> > > > > "proper" default axis for each function without fear of people not being
> > > > > able to remember which one that is.
> > > >
> > > > That supposes that the naming convention is easier to remember than
> > > > the default axis, which is not obvious to me. I can imagine people
> > > > wondering whether the correct function is fft or fft_.
> > >
> > > I'd argue here that if you can remember that fft operates on the -1
> > > axis, you can remember that all functions that operate by default on the
> > > -1 axis have an underscore after them (which by the way is not a naming
> > > convention I find reasonable).
> > 
> > I agree, but such a naming convention is useful if it is *easier*
> > to remember, not just as easy.
> 
> This I disagree with.  The advantage of the naming convention (provided
> one can be discovered) is that you get an error if you remember
> incorrectly rather than getting a strange array back.  This to me is
> REALLY important.
> 

Don't forget there are two people involved, the writer of the code and
potentially the reader.  Of course the reader might just be the writer
3 months later after he/she has forgotten everything about it.

The naming convention might still involve work on the writers part,
looking in the manual to see whether it is fft or fft_ or whatever (or
extra debugging when the exception occurs if the wrong function name
is used).  However once the reader has learned the simple rule, then
the code should be much more obvious to understand.

Marko


.Marko Balabanovic.......Department of Computer Science....................
.Stanford University     Email: marko@cs.stanford.edu   Office: Gates 132 .
.Gates Building 1A       Phone: 415 725 8783            Fax: 415 725 1449 .
.Stanford CA 94305-9010  Url:   http://robotics.stanford.edu/people/marko .
.USA.......................................................................

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

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

From tim@lassi.ece.uiuc.edu  Thu Aug 22 20:41:04 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Thu, 22 Aug 1996 14:41:04 -0500
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
In-Reply-To: <321C768E.63D8@mit.edu> (message from Jim Hugunin on Thu, 22 Aug
 1996 11:02:38 -0400)
Message-ID: <199608221939.PAA24675@python.org>


Following up on my last post: after thinking about it some more, I'm
beginning to like the parts of speech convention for structural
vs. non-strucural ops better (but implemented differently). So I'll
throw out a proposal for your dismemberment....

________________________________

Proposal: All structural operation names will be present tense verbs
(e.g., run, walk, skip; not walked, tree, overThere). The names of
sort, and argSort will be changed to sorted and argSorted since sort
is both a verb and a noun.

________________________________

This leads to:

structural: concatenate, reduce, take, repeat, choose, reduce,
accumulate, reduceAt, compress

non-structural: sorted, argSorted, diagonal, trace, dot, sum, product, cumSum,
cumProduct, allTrue, someTrue, fft

________________________________

Things that don't agree with the current defaults.
-------------------------------------------------

diagonal, trace: These are diagonals, not axes. However, I would argue
	that the current default is wrong; the default should be the
	last diagonal, not the first. So, this does make sense.

sum, product, cumSum, cumProduct: I think these would make sense with
	a default of -1, instead of zero. (As I think Jim alluded to
	in an earlier post...)

allTrue, someTrue: ????


________________________________

I was going to write more, but I think I'll throw this into the ring
now since there seems to be some interest.


-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hugunin@mit.edu  Fri Aug 23 17:19:20 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 23 Aug 1996 12:19:20 -0400
Subject: [PYTHON MATRIX-SIG] Simple Questions...
References: <199608231533.LAA06169@maigret>
Message-ID: <321DDA08.46F0@mit.edu>

I know I'm violating nettiquette by forwarding personal mail to the
list, but given the recent trend towards esoteric discussion on the
list, I thought that this might help encourage people to ask simple
questions.  My apologies to David. :-)

David Ascher wrote:
> 
> In the numeric package, is there a way to go from
> 
>         a = array([1,2,2,1,2])
> 
>         via something like a.indices(2) ==> (1,2,4) ?
> 
>         [by extension to the index() method on lists].
> 
> I get lost between select, choose, etc.

>>> from Numeric import *
>>> a = array([1,2,2,1,2])
>>> nonzero(equal(a,2))
1 2 4

equal will return an array that is one everywhere the arrays are equal
and zero everywhere else.

nonzero will return the indices of those elements in the array which are
non-zero. (nonzero is implemented using repeat, but you shouldn't really
need to know that).

-Jim

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

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

From tim@lassi.ece.uiuc.edu  Mon Aug 26 03:20:38 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Sun, 25 Aug 1996 21:20:38 -0500
Subject: [PYTHON MATRIX-SIG] Some thoughts on default axes.
In-Reply-To: <199608221939.PAA24675@python.org> (tim@lassi.ece.uiuc.edu)
Message-ID: <199608260218.WAA03183@python.org>


Following up on my last post (again) about distinguishing structural
operations from non-structural operations based on their parts of
speach. I did some research into how well this would work.

I sent my proposal to a friend with no knowledge of Python and asked
him to sort the NumPy operations into structural and non-structural
operations based on the rule in my proposal:

>Proposal: All structural operation names will be present tense verbs
>(e.g., run, walk, skip; not walked, tree, overThere). The names of
>sort, and argSort will be changed to sorted and argSorted since sort
>is both a verb and a noun.

The results were a disaster! Both my rule and the names of the
operations were much more ambiguous than I had suspected. (There are
far too many words that are both verbs and nouns...). 

I did some fine tuning of the rule, and made some changes to the names
of some operations. I then repeated my experiment with two more
individuals. This time I had more success. Between the two of them
only one operation was identified wrongly (reduceAt) and it was
misidentified only one. Once again these individuals had no prior
knowledge on Numerical Python (or Python for that matter).

My conclusion is that this would probably be a viable way to
distinguish between structural and non-structural operations. Here are
some possible areas of concern:

o	The rule is might be too complicated to remember (I don't
	think so, but I've been looking at it too much to know.)
o	Esthetics (again). 

Below is the rule and list of operation names that I sent out. I've
marked the changed operation names with *s.  A (clumsily worded)
mnemonic for this set of rules is 'Structural operations ACT
(->p.t. verb phrases) on the structure the matrix,, while
non-structural operations return OBJECTS (->other phrases) derived
from the matrix.'

What do people think of this? Does this make it sufficently easy to
determine which kind of operation each name corresponds to? Is fftOf
too ugly to live? Also, do people agree or disagree with the way I've
reassigned the default axes/diagonals of trace, diagonal, and product
and its ilk?

>o	Structural operation names are be present tense verbs phrases
>	such as walk, runOver, fly.
>o	Non-Structural operation names are all other phrases (e.g.,
>	car, walkedOn). 
>o	If a word is both a noun and a verb treat it as a verb.
>
>Which of the following are structural and which are non-structural:
>(Just tack on a NSO or SO after each operation name).
>
>allTrue    	
>sorted		*
>diagonal 	
>cumProduct 	
>concatenate 	
>dotProd	* 	
>take 		
>argSorted	*
>repeat 	
>choose 	
>reduce 	
>someTrue 	
>summation 	*
>accumulate 	
>product 	
>traceOf 	*
>reduceAt	
>compress 	
>cumSummation 	*
>fftOf		*
>			
>(cum stands for cummulative)



-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hinsen@ibs.ibs.fr  Tue Aug 27 20:55:57 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Tue, 27 Aug 96 20:55:57 +0100
Subject: [PYTHON MATRIX-SIG] LinearAlgebra.py
Message-ID: <199608271859.UAA25754@ibs.ibs.fr>

I remember that several people have worked on adapting
my LinearAlgebra.py to the new function set, but I can't
access my archive now. Would anyone be so kind as to
send me a copy?

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From hugunin@mit.edu  Wed Aug 28 23:34:38 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Wed, 28 Aug 1996 18:34:38 -0400
Subject: [PYTHON MATRIX-SIG] Just checking in
Message-ID: <9608282232.AA26365@goldilocks.LCS.MIT.EDU>


Just to keep people posted.  I have the alpha3 release almost ready to go,
I'm waiting on a few issues that need to be thought out.

1) Naming conventions/default axes
2) Dynamic linking (problems on many architectures)

If you have any opinions on the whole naming conventions/default axis issue
that has been recently discussed I'd like to hear them.  I still haven't
found a proposal that I like better than my current version:

All default axes are 0
Functions like fft, sort, argmax, ... should generally be called with an
explicit axis specification of -1.  ie. fft(wave, axis=-1).  This explicit
axis specification is only necessary when working on 2 or more dimensional
arrays.

-Jim

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

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

From guido@CNRI.Reston.Va.US  Thu Aug 29 04:18:23 1996
From: guido@CNRI.Reston.Va.US (Guido van Rossum)
Date: Wed, 28 Aug 1996 23:18:23 -0400
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: Your message of "Wed, 28 Aug 1996 18:34:38 EDT."
 <9608282232.AA26365@goldilocks.LCS.MIT.EDU>
References: <9608282232.AA26365@goldilocks.LCS.MIT.EDU>
Message-ID: <199608290318.XAA20736@monty>

> 2) Dynamic linking (problems on many architectures)

What is the nature of these problems?  I believe that Python 1.4beta3 supports
dynamic linking on most architectures.  (BTW for NT I had to replace the
static initialization of the type pointers in type objects with dynamic
initializations -- no big deal, one of those linker limitations where
one bows to Microsoft -- although perhaps compiling with C++ would have
helped too.)

--Guido

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

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

From hinsen@ibs.ibs.fr  Thu Aug 29 09:53:01 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 29 Aug 96 09:53:01 +0100
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608290318.XAA20736@monty> (message from Guido van Rossum on
 Wed, 28 Aug 1996 23:18:23 -0400)
Message-ID: <199608290756.JAA03305@ibs.ibs.fr>

> > 2) Dynamic linking (problems on many architectures)
> 
> What is the nature of these problems?  I believe that Python 1.4beta3 supports
> dynamic linking on most architectures.  (BTW for NT I had to replace the

As for HP systems, I am reasonably convinced that the problem with
NumPy alpha2 is the fake module "libnumpy". After a careful study of
the HP documentation, I conclude that there are two ways to use
shared libraries:

1) Explicit loading, which is what Python does when importing
   a module.

2) Linking with a shared library, which is then loaded as soon as
   one of its functions is called. This works only if the shared
   library is in the same place as it was during linking. (Other
   systems, e.g. SGI, let the user specify a search path for this
   case.)

NumPy uses the second method for libnumpy (which contains
arrayobject.o and ofuncobject.o), but after installation it must fail.

A possible solution would be to make libnumpy a real importable
module and import it from the modules that need it.

Konrad.

-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From Rob.Hooft@embl-heidelberg.de  Thu Aug 29 11:57:18 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Thu, 29 Aug 1996 12:57:18 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <9608282232.AA26365@goldilocks.LCS.MIT.EDU>
References: <9608282232.AA26365@goldilocks.LCS.MIT.EDU>
Message-ID: <199608291057.MAA21061@nu>

>>>>> "JH" == Jim Hugunin <hugunin@mit.edu> writes:

 JH> Dynamic linking (problems on many architectures)

So I felt pressed to at least try dynamic linking once. The effect:

1) I have to "make" instead of "make dynamic", because I need the 
   changed sys.path with ".../numeric" in there.

2) nu[208]test%% python sieve.py
   Traceback (innermost last):
     File "sieve.py", line 2, in ?
       from Numeric import *
     File "/nu1/hooft/lib/python1.4/numeric/Numeric.py", line 4, in ?
       import multiarray
   ImportError: dlopen: cannot load /nu1/hooft/lib/python1.4/sharedmodules/multiarraymodule.so

I think I'll go back to static. Unfortunately I'm not an expert on dl on
DecUnix 4.0, so I don't expect to be of any more help...

Rob.
-- 
=== Rob.Hooft@EMBL-Heidelberg.DE   http://www.Sander.EMBL-Heidelberg.DE/rob/ ==
==== In need of protein modeling?  http://www.Sander.EMBL-Heidelberg.DE/whatif/
Validation of protein structures?  http://biotech.EMBL-Heidelberg.DE:8400/ ====
== PGPid 0xFA19277D == Use Linux!  Free Software Rules The World! =============

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

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

From guido@CNRI.Reston.Va.US  Thu Aug 29 14:48:36 1996
From: guido@CNRI.Reston.Va.US (Guido van Rossum)
Date: Thu, 29 Aug 1996 09:48:36 -0400
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: Your message of "Thu, 29 Aug 1996 09:53:01 BST."
 <199608290756.JAA03305@ibs.ibs.fr>
References: <199608290756.JAA03305@ibs.ibs.fr>
Message-ID: <199608291348.JAA24669@monty>

> As for HP systems, I am reasonably convinced that the problem with
> NumPy alpha2 is the fake module "libnumpy". After a careful study of
> the HP documentation, I conclude that there are two ways to use
> shared libraries:
> 
> 1) Explicit loading, which is what Python does when importing
>    a module.
> 
> 2) Linking with a shared library, which is then loaded as soon as
>    one of its functions is called. This works only if the shared
>    library is in the same place as it was during linking. (Other
>    systems, e.g. SGI, let the user specify a search path for this
>    case.)
> 
> NumPy uses the second method for libnumpy (which contains
> arrayobject.o and ofuncobject.o), but after installation it must fail.

This makes sense after all.  Unless libNumPy.sl is placed in one of
the standard places where the linker looks for shared libraries, it
will need some strong hints.  It could be that this problem doesn't
occur on Solaris because the linker will look in the same directory
where the referring shared library is coming from.

However, if I read the "ld" man page right for HP-UX, the "+b" option
should let you specify a list of directories to search for shared
libraries at run-time.  It may be that this information only gets used
when building the main executable, in which case you can specify a
SHLIB_PATH environment variable pointing to the directory containing
libNumPy.sl (see the +s option).

> A possible solution would be to make libnumpy a real importable
> module and import it from the modules that need it.

Yes, that's another approach.  The Object/cobject.c file contains a
little-known trick to make this easier.  However I'm not sure it's
worth it, assuming this problem is HP specific.  The environment
variable trick seems okay.  (Note that in 1.4b3 you can use
os.putenv() to modify the real environment of the current process, so
you could even hide this in a wrapper written in Python!)

--Guido van Rossum (home page: http://www.python.org/~guido/)


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

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

From tim@lassi.ece.uiuc.edu  Thu Aug 29 15:01:01 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Thu, 29 Aug 1996 09:01:01 -0500
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608290756.JAA03305@ibs.ibs.fr> (message from Konrad Hinsen on
 Thu, 29 Aug 96 09:53:01 +0100)
Message-ID: <199608291359.JAA23575@python.org>



>> > 2) Dynamic linking (problems on many architectures)
>> 
>> What is the nature of these problems?  I believe that Python 1.4beta3 supports
>> dynamic linking on most architectures.  (BTW for NT I had to replace the
>
>As for HP systems, I am reasonably convinced that the problem with
>NumPy alpha2 is the fake module "libnumpy". After a careful study of
>the HP documentation, I conclude that there are two ways to use
>shared libraries:

On Linux 1.2.13, libnumpy also gave me some problems. It turned out it
had to go in /usr/lib, not /usr/local/lib. This I discovered by trial
and error, not by a thorough (or any for that matter) study of the
documentation ;)

This is the error I was getting before moving libnumpy. Is this the
error that most people are getting when the dynamic loading doesn't work?

>>> import Numeric
Traceback (innermost last):
  File "<stdin>", line 1, in ?
  File "/usr/local/lib/python1.4/numeric/Numeric.py", line 4, in ?
    import multiarray
ImportError: File not found
>>> 



-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hinsen@ibs.ibs.fr  Thu Aug 29 16:18:33 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 29 Aug 96 16:18:33 +0100
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608291348.JAA24669@monty> (message from Guido van Rossum on
 Thu, 29 Aug 1996 09:48:36 -0400)
Message-ID: <199608291421.QAA05615@ibs.ibs.fr>

> However, if I read the "ld" man page right for HP-UX, the "+b" option
> should let you specify a list of directories to search for shared
> libraries at run-time.  It may be that this information only gets used

Right, but unless all systems have such a feature, we should
better not rely on it.

> when building the main executable, in which case you can specify a
> SHLIB_PATH environment variable pointing to the directory containing
> libNumPy.sl (see the +s option).

I don't like using such global variables. I definitely would not
like to install and maintain two packages that both manipulate
this environment variable! Just imagine wanting to install
two different versions of Python (say, 1.4 and 1.5 ;-) on the
same system.

> variable trick seems okay.  (Note that in 1.4b3 you can use
> os.putenv() to modify the real environment of the current process, so
> you could even hide this in a wrapper written in Python!)

That sounds a lot more attractive to me.

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From hinsen@ibs.ibs.fr  Thu Aug 29 16:05:01 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 29 Aug 96 16:05:01 +0100
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <9608282232.AA26365@goldilocks.LCS.MIT.EDU> (hugunin@mit.edu)
Message-ID: <199608291408.QAA05489@ibs.ibs.fr>

> If you have any opinions on the whole naming conventions/default axis issue
> that has been recently discussed I'd like to hear them.  I still haven't
> found a proposal that I like better than my current version:
> 
> All default axes are 0
> Functions like fft, sort, argmax, ... should generally be called with an
> explicit axis specification of -1.  ie. fft(wave, axis=-1).  This explicit
> axis specification is only necessary when working on 2 or more dimensional
> arrays.

I still think that a two-class system (structural functions with a
default axis of zero, others with a default of 1) is the better
solution.

But I mainly write to express dissatisfaction with the way dot() works
now. I have been doing some matrix work recently, and not being able
to use dot() for matrix multiplication is a real nuisance. I ended up
redefining dot() to be LinAlg._dot2, which is exactly the kind of
thing to be avoided.

So unless someone can give a good argument (preferably based on a
real-life application) that dot() should behave as it does now, I
propose that dot() should act along axis -1 of its first and axis 0 of
its second argument. This is the right choice for scalar products,
matrix-vector multiplication, and matrix-matrix multiplication.  I
think these are more frequent than list-of-vector scalar products.

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From Rob.Hooft@embl-heidelberg.de  Thu Aug 29 16:50:06 1996
From: Rob.Hooft@embl-heidelberg.de (Rob.Hooft@embl-heidelberg.de)
Date: Thu, 29 Aug 1996 17:50:06 +0200 (MET DST)
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608291408.QAA05489@ibs.ibs.fr>
References: <9608282232.AA26365@goldilocks.LCS.MIT.EDU>
 <199608291408.QAA05489@ibs.ibs.fr>
Message-ID: <199608291550.RAA22455@nu>

>>>>> "KH" == Konrad Hinsen <hinsen@ibs.ibs.fr> writes:

 >> All default axes are 0 Functions like fft, sort, argmax,
 >> ... should generally be called with an explicit axis specification
 >> of -1.  ie. fft(wave, axis=-1).  This explicit axis specification
 >> is only necessary when working on 2 or more dimensional arrays.

 KH> I still think that a two-class system (structural functions with
 KH> a default axis of zero, others with a default of 1) is the better
 KH> solution.

I agree that it might be a bit of a nuisance to give "axis" arguments.
But I prefer readability over writability myself, and the difference
between structural versus other functions is not clear to me yet....

 KH> But I mainly write to express dissatisfaction with the way dot()
 KH> works now. I have been doing some matrix work recently, and not
 KH> being able to use dot() for matrix multiplication is a real
 KH> nuisance. I ended up redefining dot() to be LinAlg._dot2, which
 KH> is exactly the kind of thing to be avoided.

Why don't you define a MatrixMultiply routine that calls LinAlg._dot2?
You don't need to redefine dot, do you?

Rob
-- 
=== Rob.Hooft@EMBL-Heidelberg.DE   http://www.Sander.EMBL-Heidelberg.DE/rob/ ==
==== In need of protein modeling?  http://www.Sander.EMBL-Heidelberg.DE/whatif/
Validation of protein structures?  http://biotech.EMBL-Heidelberg.DE:8400/ ====
== PGPid 0xFA19277D == Use Linux!  Free Software Rules The World! =============

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

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

From sean@embl-grenoble.fr  Thu Aug 29 17:16:39 1996
From: sean@embl-grenoble.fr (Sean Mcsweeney)
Date: Thu, 29 Aug 1996 18:16:39 +0200
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608291408.QAA05489@ibs.ibs.fr>
References: <9608282232.AA26365@goldilocks.LCS.MIT.EDU>
 <199608291408.QAA05489@ibs.ibs.fr>
Message-ID: <199608291616.SAA08967@classic.embl-grenoble.fr>

Konrad Hinsen writes:
 > > If you have any opinions on the whole naming conventions/default axis issue
 > > that has been recently discussed I'd like to hear them.  I still haven't
 > > found a proposal that I like better than my current version:
 > > 
 > > All default axes are 0
 > > Functions like fft, sort, argmax, ... should generally be called with an
 > > explicit axis specification of -1.  ie. fft(wave, axis=-1).  This explicit
 > > axis specification is only necessary when working on 2 or more dimensional
 > > arrays.
 > 
 > I still think that a two-class system (structural functions with a
 > default axis of zero, others with a default of 1) is the better
 > solution.
 > 
 

My solution would be to let the function determin the default axis -- if
the functions natural usage is axis=0, then this should be the
default, or otherwise as appropriate. 

by natural I mean if 99 times out of 100 I will use

super_whizzo(A,B,C, axis=0) 

I don't see why I should type the axis =0 part just because its
**possible** I may want axis=-1 , the one other time. and/or some default has
specified that this is an axis=-1 function. 

Of course the implementation would document the functionality rather
better than the above ;-)

S


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

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

From jim.fulton@digicool.com  Thu Aug 29 17:20:48 1996
From: jim.fulton@digicool.com (Jim Fulton)
Date: Thu, 29 Aug 1996 12:20:48 -0400
Subject: [PYTHON MATRIX-SIG] Just checking in
References: <199608290756.JAA03305@ibs.ibs.fr> <199608291348.JAA24669@monty>
Message-ID: <3225C360.C00@digicool.com>

Guido van Rossum wrote:
> 
> > As for HP systems, I am reasonably convinced that the problem with
> > NumPy alpha2 is the fake module "libnumpy". After a careful study of
> > the HP documentation, I conclude that there are two ways to use
> > shared libraries:
> >
> > 1) Explicit loading, which is what Python does when importing
> >    a module.
> >
> > 2) Linking with a shared library, which is then loaded as soon as
> >    one of its functions is called. This works only if the shared
> >    library is in the same place as it was during linking. (Other
> >    systems, e.g. SGI, let the user specify a search path for this
> >    case.)
> >
> > NumPy uses the second method for libnumpy (which contains
> > arrayobject.o and ofuncobject.o), but after installation it must fail.
> 
> This makes sense after all.  Unless libNumPy.sl is placed in one of
> the standard places where the linker looks for shared libraries, it
> will need some strong hints.  It could be that this problem doesn't
> occur on Solaris because the linker will look in the same directory
> where the referring shared library is coming from.
> 
> However, if I read the "ld" man page right for HP-UX, the "+b" option
> should let you specify a list of directories to search for shared
> libraries at run-time.  It may be that this information only gets used
> when building the main executable, in which case you can specify a
> SHLIB_PATH environment variable pointing to the directory containing
> libNumPy.sl (see the +s option).

But all of this is alot of work.  What's worse, it's work
for the user, rather than the author of a module.  The user has to 
remember to set some goofy environment variable because of some
arcane detail of how a program was built. Yuck.

> 
> > A possible solution would be to make libnumpy a real importable
> > module and import it from the modules that need it.
> 
> Yes, that's another approach.  The Object/cobject.c file contains a
> little-known trick to make this easier.  However I'm not sure it's
> worth it, assuming this problem is HP specific.

No, the problem occurs on DG and DEC too, but the details vary from
system
to system, just to make things interesting. 8-[ It's a real hassle,
which is
why I came up with the cobject type.  I'll admit, that for a large
C API, cobject could be quite a hassle.  I'd hoped to put something
together 
for the numerics stuff, but haven't had time, and with my current job,
have
less motivation.

> The environment
> variable trick seems okay.  (Note that in 1.4b3 you can use
> os.putenv() to modify the real environment of the current process, so
> you could even hide this in a wrapper written in Python!)

putenv helps, but tha hack will have to be system dependent.

I think it would be much better to "import" the interface.  I'm sorry
I can't help out more.

One more point, I suspect that in many cases, it might be just as easy
to use the Python Numeric API from C.  I hope to do this for FIDL.

Jim

> =================
> MATRIX-SIG  - SIG on Matrix Math for Python
> 
> send messages to: matrix-sig@python.org
> administrivia to: matrix-sig-request@python.org
> =================

-- 
Jim Fulton         Digital Creations
jim@digicool.com   540.371.6909
## Python is my favorite language ##
##     http://www.python.org/     ##

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

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

From hinsen@ibs.ibs.fr  Thu Aug 29 18:45:02 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 29 Aug 96 18:45:02 +0100
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608291616.SAA08967@classic.embl-grenoble.fr> (message from
 Sean Mcsweeney on Thu, 29 Aug 1996 18:16:39 +0200)
Message-ID: <199608291648.SAA06569@ibs.ibs.fr>

> Konrad Hinsen writes:
>...
>  > I still think that a two-class system (structural functions with a
>  > default axis of zero, others with a default of 1) is the better
>  > solution.
>  > 
> 
> My solution would be to let the function determin the default axis -- if
> the functions natural usage is axis=0, then this should be the
> default, or otherwise as appropriate. 

That comes down to the same as my proposal.

Konrad
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From hinsen@ibs.ibs.fr  Thu Aug 29 19:25:04 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 29 Aug 96 19:25:04 +0100
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608291550.RAA22455@nu> (Rob.Hooft@embl-heidelberg.de)
Message-ID: <199608291728.TAA06720@ibs.ibs.fr>

>  KH> But I mainly write to express dissatisfaction with the way dot()
>  KH> works now. I have been doing some matrix work recently, and not
>  KH> being able to use dot() for matrix multiplication is a real
>  KH> nuisance. I ended up redefining dot() to be LinAlg._dot2, which
>  KH> is exactly the kind of thing to be avoided.
> 
> Why don't you define a MatrixMultiply routine that calls LinAlg._dot2?
> You don't need to redefine dot, do you?

I am using this interactively, so "MatrixMultiply" has no chance.  I
redefined dot() because to me this is what dot() should do, and I have
no use at all for the standard dot(). I like to type something
sensible, even interactively.

Of course I am not saying that I can't live with the current version
of dot(). But unless someone can give arguments why the current
version is *better* (or at least as good), I stick to my proposal.

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From tim@lassi.ece.uiuc.edu  Thu Aug 29 19:32:26 1996
From: tim@lassi.ece.uiuc.edu (tim@lassi.ece.uiuc.edu)
Date: Thu, 29 Aug 1996 13:32:26 -0500
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608291728.TAA06720@ibs.ibs.fr> (message from Konrad Hinsen on
 Thu, 29 Aug 96 19:25:04 +0100)
Message-ID: <199608291846.OAA24515@python.org>



KH writes:
>I am using this interactively, so "MatrixMultiply" has no chance.  I
>redefined dot() because to me this is what dot() should do, and I have
>no use at all for the standard dot(). I like to type something
>sensible, even interactively.
>
>Of course I am not saying that I can't live with the current version
>of dot(). But unless someone can give arguments why the current
>version is *better* (or at least as good), I stick to my proposal.

I would argue that dot should act on axes (-1,-1), i.e. it should dot
the vector that compose the array's together.

Isn't matrix multiplication the same as the inner product for
matrices, so couldn't you use define a convenience function inner(A,B)
for this? Or am I off in LA LA land here?


-- 
	-tim

+--------------------------------------------------------------------+
| Tim Hochberg               Ultrahigh Speed Digital Electronics Lab |
| tim@lassi.ece.uiuc.edu              University of Illinois         |
| http://dogbert.ece.uiuc.edu/~tim         (217) 333-6014            |
+--------------------------------------------------------------------+

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

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

From hinsen@ibs.ibs.fr  Thu Aug 29 20:35:28 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Thu, 29 Aug 96 20:35:28 +0100
Subject: [PYTHON MATRIX-SIG] Just checking in
In-Reply-To: <199608291831.UAA06945@ibs.ibs.fr> (tim@lassi.ece.uiuc.edu)
Message-ID: <199608291838.UAA06964@ibs.ibs.fr>

> I would argue that dot should act on axes (-1,-1), i.e. it should dot
> the vector that compose the array's together.

Why? What is the frequent application for which such a definition
is useful?

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From stjohn@gav.gat.com  Thu Aug 29 22:32:25 1996
From: stjohn@gav.gat.com (Holger St. John)
Date: Thu, 29 Aug 1996 13:32:25 -0800
Subject: [PYTHON MATRIX-SIG] dynamic linking And Linux
Message-ID: <199608292032.QAA24833@python.org>

 There may be something more than just the location of the libnumpy
module involved in dynamic linking under Linux (1.2.13). The reason
I say this is that I have both dynamic and static versions of Numerical
Python running on my 90Mhz Pentium box. The static version runs sieve and
test_all without a problem. The dynamic version (I used make dynamic)
runs the sieve script ok (in 17 secs. incidentally). However when I run
test_all I get the (by now) infamous
            "module not found: Integer"
 Since the
static version works it must be that Integer is a built in module?  Other
people must be having this problem ?

Holger St. John

General Atomics



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

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

From hugunin@mit.edu  Thu Aug 29 21:55:17 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Thu, 29 Aug 1996 16:55:17 -0400
Subject: [PYTHON MATRIX-SIG] dynamic linking And Linux
Message-ID: <9608292053.AA07160@goldilocks.LCS.MIT.EDU>

>  There may be something more than just the location of the libnumpy
> module involved in dynamic linking under Linux (1.2.13). The reason
> I say this is that I have both dynamic and static versions of Numerical
> Python running on my 90Mhz Pentium box. The static version runs sieve and
> test_all without a problem. The dynamic version (I used make dynamic)
> runs the sieve script ok (in 17 secs. incidentally). However when I run
> test_all I get the (by now) infamous
>             "module not found: Integer"

This is a completely different bug in the test_all.py module.  I have an
Integer.py file on my machine that I forgot to include in the distribution.
 If you remove the import Integer from the top of test_all.py (or maybe
test_items.py) this problem will go away.

Please tell me if the dynamic version works for you with this small fix.

-Jim

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

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

From K.Maguire@dl.ac.uk  Fri Aug 30 20:14:10 1996
From: K.Maguire@dl.ac.uk (Kevin Maguire)
Date: Fri, 30 Aug 1996 20:14:10 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] NumericalPython
Message-ID: <Pine.OSF.3.93.960830195907.29811B-100000@tca1.dl.ac.uk>

Hi

When I requested the archive for this SIG I only received messages up
until the end of May, why is this ??  Has nothing been posted since
then ???

Okay, I ftp'd and installed python1.4beta3 and NumPy-1.0a2 (which took
a bit of finding) on my DEC Alpha running V3.0 of OSF1 (now renamed
Digital Unix).  The core python installation went reasonably smoothly,
and I followed the instructions in INSTALL and Makefile.pre.in to add
the Numerical support (why no make install in this package ?? ).

However running the tests gives an error:

% ../python -iv test_all.py
...
...
...
array([[1, 66], [66, 12]], 'l')
array([0, 1, 2, 3, 4, 5], 'l')
TypeError: compare not supported for type
Traceback (innermost last):
  File "test_all.py", line 42, in ?
    test_lines(fp.readlines())
  File "test_all.py", line 22, in test_lines
    raise ValueError, "%s doesn't match expected %s" % (last_out,
line[1:-1])
ValueError: TypeError: compare not supported for type doesn't match
expected array([5, 3, 1, 0, 4, 2], 'l')

I don't really know this is about.  I went on and installed anyway,
copying the .py files Lib/* to /usr/local/lib/python1.4/numeric/
(which 'strings python' told me was built into the executable
somewhere, I missed any documentation that explained what to do to
'install' the new enhanced (?) python?

I then ran through the tutorial:  

http://maigret.cog.brown.edu/Python/Documentation/arraytut.html

Some things work, others don't.  For example:

>>> from Numeric import *
>>> x,y,z = 1,2,3
>>> a = array([x,y,z])
>>> a
1 2 3
>>> a = array([x,y,z], Float())
Traceback (innermost last):
  File "<stdin>", line 1, in ?
TypeError: call of non-function
>>> 

and 

>>> ma = array([[1,2,3],[4,5,6],[7,8,9]])
>>> ma
1 2 3
4 5 6
7 8 9
>>> ma.shape
(3, 3)
>>> flattened_ma = ma.reshape(9)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
AttributeError: reshape
>>> 

Several other functions didn't work properly, zeros, ones, etc being
examples.  So either I've done something wrong in the install, or I'm
missing something.  Please enlighten me ....

Cheers
Kevin
--
Kevin Maguire         __    __    __    __           Daresbury Laboratory
K.Maguire@dl.ac.uk   /  \  /  \  /  \  /  \      Warrington, Cheshire, UK
____________________/  __\/  __\/  __\/  __\_____________________________
___________________/  /__/  /__/  /__/  /________________________________
                   | / \   / \   / \   / \  \____   voice: (01925) 603221
                   |/   \_/   \_/   \_/   \    o \    FAX: (01925) 603634
                                           \_____/--<                    


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

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

From K.Maguire@dl.ac.uk  Fri Aug 30 20:14:10 1996
From: K.Maguire@dl.ac.uk (Kevin Maguire)
Date: Fri, 30 Aug 1996 20:14:10 +0100 (BST)
Subject: [PYTHON MATRIX-SIG] NumericalPython
Message-ID: <Pine.OSF.3.93.960830195907.29811B-100000@tca1.dl.ac.uk>

Hi

When I requested the archive for this SIG I only received messages up
until the end of May, why is this ??  Has nothing been posted since
then ???

Okay, I ftp'd and installed python1.4beta3 and NumPy-1.0a2 (which took
a bit of finding) on my DEC Alpha running V3.0 of OSF1 (now renamed
Digital Unix).  The core python installation went reasonably smoothly,
and I followed the instructions in INSTALL and Makefile.pre.in to add
the Numerical support (why no make install in this package ?? ).

However running the tests gives an error:

% ../python -iv test_all.py
...
...
...
array([[1, 66], [66, 12]], 'l')
array([0, 1, 2, 3, 4, 5], 'l')
TypeError: compare not supported for type
Traceback (innermost last):
  File "test_all.py", line 42, in ?
    test_lines(fp.readlines())
  File "test_all.py", line 22, in test_lines
    raise ValueError, "%s doesn't match expected %s" % (last_out,
line[1:-1])
ValueError: TypeError: compare not supported for type doesn't match
expected array([5, 3, 1, 0, 4, 2], 'l')

I don't really know this is about.  I went on and installed anyway,
copying the .py files Lib/* to /usr/local/lib/python1.4/numeric/
(which 'strings python' told me was built into the executable
somewhere, I missed any documentation that explained what to do to
'install' the new enhanced (?) python?

I then ran through the tutorial:  

http://maigret.cog.brown.edu/Python/Documentation/arraytut.html

Some things work, others don't.  For example:

>>> from Numeric import *
>>> x,y,z = 1,2,3
>>> a = array([x,y,z])
>>> a
1 2 3
>>> a = array([x,y,z], Float())
Traceback (innermost last):
  File "<stdin>", line 1, in ?
TypeError: call of non-function
>>> 

and 

>>> ma = array([[1,2,3],[4,5,6],[7,8,9]])
>>> ma
1 2 3
4 5 6
7 8 9
>>> ma.shape
(3, 3)
>>> flattened_ma = ma.reshape(9)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
AttributeError: reshape
>>> 

Several other functions didn't work properly, zeros, ones, etc being
examples.  So either I've done something wrong in the install, or I'm
missing something.  Please enlighten me ....

Cheers
Kevin
--
Kevin Maguire         __    __    __    __           Daresbury Laboratory
K.Maguire@dl.ac.uk   /  \  /  \  /  \  /  \      Warrington, Cheshire, UK
____________________/  __\/  __\/  __\/  __\_____________________________
___________________/  /__/  /__/  /__/  /________________________________
                   | / \   / \   / \   / \  \____   voice: (01925) 603221
                   |/   \_/   \_/   \_/   \    o \    FAX: (01925) 603634
                                           \_____/--<                    


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

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

From hugunin@mit.edu  Fri Aug 30 21:20:16 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 30 Aug 1996 16:20:16 -0400
Subject: [PYTHON MATRIX-SIG] Default Axes revisited
Message-ID: <9608302018.AA17769@goldilocks.LCS.MIT.EDU>


I'm been thinking a lot about all the responses (both public and private)
I've gotten on the default axis issue.  I have a new proposal for a naming
convention (I think Tim already proposed something very similar to this,
but...)

As Konrad rightly suggested at the beginning:

Structural Operations have a default axis of 0
Numeric/Computational Operations have a default axis of -1

However, because I don't think it's always obvious what's a structural and
what's a numeric operation, all numeric operations will have a "_" after
their name.

So we have:

take, concatenate, ...
argmax_, sort_, argsort_, fft_, ...

I will also probably define functions of the form:

def argmax(x,y=None):
	raise AttributeError, "argmax is a Numeric function, use argmax_"

in order to help out complete newbie's.

Is everybody reasonably happy with this? - Jim

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

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

From hugunin@mit.edu  Fri Aug 30 21:13:07 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 30 Aug 1996 16:13:07 -0400
Subject: [PYTHON MATRIX-SIG] NumericalPython
Message-ID: <9608302011.AA17714@goldilocks.LCS.MIT.EDU>


I need to look into the archive to figure out what's wrong.  There bit a
little ;-) traffic on this group since then.  My personal guess is that
we've managed to collectively overflow some archive size limit.

The latest release of NumPy is always announced on this list, so it is easy
to find if you were subscribed when the last version came out.

The error during testing is interesting and probably a 64-bit long quirk. 
I'll look into it.

The other problems that you have are due to the fact that the Tutorial is
way out of date.  Many function names and calling conventions have been
changed since the Tutorial was written (based on 0.36).  The file
"doc.html" should be up to date as far as naming conventions are concerned.

There is still one outstanding naming/calling convention that could lead to
a few more such changes before the beta1 release (after which time I won't
subject people to further major incompatible changes).  I'm guessing that
David Ascher is waiting to update his Tutorial until this final issue is
resolved (see my next post).

BTW - Did you make the static or the dynamic version?  I'm very interested
to learn about people's experiences building the dynamic system under DEC
OSF (or Digital Unix).

-Jim

----------
> From: Kevin Maguire <kcm@tca1.dl.ac.uk>
> To: matrix-sig@larch.python.org
> Subject: [PYTHON MATRIX-SIG] NumericalPython
> Date: Friday, August 30, 1996 3:14 PM
> 
> Hi
> 
> When I requested the archive for this SIG I only received messages up
> until the end of May, why is this ??  Has nothing been posted since
> then ???
> 
> Okay, I ftp'd and installed python1.4beta3 and NumPy-1.0a2 (which took
> a bit of finding) on my DEC Alpha running V3.0 of OSF1 (now renamed
> Digital Unix).  The core python installation went reasonably smoothly,
> and I followed the instructions in INSTALL and Makefile.pre.in to add
> the Numerical support (why no make install in this package ?? ).
> 
> However running the tests gives an error:
> 
> % ../python -iv test_all.py
> ...
> ...
> ...
> array([[1, 66], [66, 12]], 'l')
> array([0, 1, 2, 3, 4, 5], 'l')
> TypeError: compare not supported for type
> Traceback (innermost last):
>   File "test_all.py", line 42, in ?
>     test_lines(fp.readlines())
>   File "test_all.py", line 22, in test_lines
>     raise ValueError, "%s doesn't match expected %s" % (last_out,
> line[1:-1])
> ValueError: TypeError: compare not supported for type doesn't match
> expected array([5, 3, 1, 0, 4, 2], 'l')
> 
> I don't really know this is about.  I went on and installed anyway,
> copying the .py files Lib/* to /usr/local/lib/python1.4/numeric/
> (which 'strings python' told me was built into the executable
> somewhere, I missed any documentation that explained what to do to
> 'install' the new enhanced (?) python?
> 
> I then ran through the tutorial:  
> 
> http://maigret.cog.brown.edu/Python/Documentation/arraytut.html
> 
> Some things work, others don't.  For example:
> 
> >>> from Numeric import *
> >>> x,y,z = 1,2,3
> >>> a = array([x,y,z])
> >>> a
> 1 2 3
> >>> a = array([x,y,z], Float())
> Traceback (innermost last):
>   File "<stdin>", line 1, in ?
> TypeError: call of non-function
> >>> 
> 
> and 
> 
> >>> ma = array([[1,2,3],[4,5,6],[7,8,9]])
> >>> ma
> 1 2 3
> 4 5 6
> 7 8 9
> >>> ma.shape
> (3, 3)
> >>> flattened_ma = ma.reshape(9)
> Traceback (innermost last):
>   File "<stdin>", line 1, in ?
> AttributeError: reshape
> >>> 
> 
> Several other functions didn't work properly, zeros, ones, etc being
> examples.  So either I've done something wrong in the install, or I'm
> missing something.  Please enlighten me ....
> 
> Cheers
> Kevin
> --
> Kevin Maguire         __    __    __    __           Daresbury Laboratory
> K.Maguire@dl.ac.uk   /  \  /  \  /  \  /  \      Warrington, Cheshire, UK
> ____________________/  __\/  __\/  __\/  __\_____________________________
> ___________________/  /__/  /__/  /__/  /________________________________
>                    | / \   / \   / \   / \  \____   voice: (01925) 603221
>                    |/   \_/   \_/   \_/   \    o \    FAX: (01925) 603634
>                                            \_____/--<                    
> 
> 
> =================
> MATRIX-SIG  - SIG on Matrix Math for Python
> 
> send messages to: matrix-sig@python.org
> administrivia to: matrix-sig-request@python.org
> =================

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

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

From pas@lems.brown.edu  Fri Aug 30 22:33:45 1996
From: pas@lems.brown.edu (Perry A. Stoll)
Date: Fri, 30 Aug 1996 17:33:45 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] Default Axes revisited
In-Reply-To: <9608302018.AA17769@goldilocks.LCS.MIT.EDU>
Message-ID: <Pine.SUN.3.91.960830172347.26328C-100000@lems33>



On Fri, 30 Aug 1996, Jim Hugunin wrote:

> Structural Operations have a default axis of 0
> Numeric/Computational Operations have a default axis of -1


Sounds good to me. I recently understood this and completely agree. Does 
this mean that all functions that can operate on different axes will have 
an "axis" keyword?


> However, because I don't think it's always obvious what's a structural and
> what's a numeric operation, all numeric operations will have a "_" after
> their name.
> 
> So we have:
> 
> take, concatenate, ...
> argmax_, sort_, argsort_, fft_, ...
> 
> I will also probably define functions of the form:
> 
> def argmax(x,y=None):
> 	raise AttributeError, "argmax is a Numeric function, use argmax_"

But these imposter functions should exactly the same signature as their 
shadowed brethren. (Just checking - wouldn't there be an "axis" keyword 
as per the question above?)

> Is everybody reasonably happy with this? - Jim

Reasonably.

-Perry
 <pas@lems.brown.edu>

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

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

From da@maigret.cog.brown.edu  Fri Aug 30 22:37:51 1996
From: da@maigret.cog.brown.edu (David Ascher)
Date: Fri, 30 Aug 1996 17:37:51 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] Default Axes revisited
In-Reply-To: <9608302018.AA17769@goldilocks.LCS.MIT.EDU> from "Jim Hugunin" at Aug 30, 96 04:20:16 pm
Message-ID: <199608302137.RAA21569@maigret>

> Structural Operations have a default axis of 0
> Numeric/Computational Operations have a default axis of -1
> 
> However, because I don't think it's always obvious what's a structural and
> what's a numeric operation, all numeric operations will have a "_" after
> their name.

Ugh.  Not underscores again.  

I don't like this at all.  I'd much rather go for something more
explicit, like:

	do_sort, do_argmax, do_argsort, do_fft
or:
	doSort, doArgmax, doArgsort, doFft
or:
	sortOf, argmaxOf, argsortOf, fftOf

or any combination thereof

which at least can be *read* easily.  Otherwise we will end up with:

	def __numericprivatefunc_(foo, bar):...

someday, which I'd hate to explain to any newbie... =)

--da

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

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

From hugunin@mit.edu  Fri Aug 30 22:39:13 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 30 Aug 1996 17:39:13 -0400
Subject: [PYTHON MATRIX-SIG] Default Axes revisited
Message-ID: <9608302137.AA18483@goldilocks.LCS.MIT.EDU>

> On Fri, 30 Aug 1996, Jim Hugunin wrote:
> 
> > Structural Operations have a default axis of 0
> > Numeric/Computational Operations have a default axis of -1
> 
> 
> Sounds good to me. I recently understood this and completely agree. Does 
> this mean that all functions that can operate on different axes will have

> an "axis" keyword?

Definately.

> > However, because I don't think it's always obvious what's a structural
and
> > what's a numeric operation, all numeric operations will have a "_"
after
> > their name.
> > 
> > So we have:
> > 
> > take, concatenate, ...
> > argmax_, sort_, argsort_, fft_, ...
> > 
> > I will also probably define functions of the form:
> > 
> > def argmax(x,y=None):
> > 	raise AttributeError, "argmax is a Numeric function, use argmax_"
> 
> But these imposter functions should exactly the same signature as their 
> shadowed brethren. (Just checking - wouldn't there be an "axis" keyword 
> as per the question above?)

argmax takes a single argument.  y=None is my way of handling the default
axis argument.  I will use the word axis there in the real version.

> > Is everybody reasonably happy with this? - Jim
> 
> Reasonably.

If I can get all interested parties to say that I'll be happy.

-Jim

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

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

From klm@CNRI.Reston.Va.US  Fri Aug 30 22:33:50 1996
From: klm@CNRI.Reston.Va.US (Ken Manheimer)
Date: Fri, 30 Aug 1996 17:33:50 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] NumericalPython
In-Reply-To: <9608302011.AA17714@goldilocks.LCS.MIT.EDU>
Message-ID: <Pine.SOL.3.95.960830171727.16987A-100000@glyph>

Jim Hugunin:

> I need to look into the archive to figure out what's wrong.  There bit a
> little ;-) traffic on this group since then.  My personal guess is that
> we've managed to collectively overflow some archive size limit.
>
> > From: Kevin Maguire <kcm@tca1.dl.ac.uk>
> >
> > When I requested the archive for this SIG I only received messages up
> > until the end of May, why is this ??  Has nothing been posted since
> > then ???


I'm looking into this (barry's out today), and from what i can tell the
archive is intact, and the whole thing is being delivered.  I did notice
that my MUA (pine) behaves rather strangely - in a way that would
account exactly for the impression kevin had.  

Pine sees only 582 message, up to one dated May 8, with that last
message holding the remaining 250 or so messages.  Solaris 'mailx' seems
to do a better job parsing the mail file - 821 messages, and the dates
reported look good.  (Reports lots of Content-length errors, though,
parsing it.) 

Kevin, take a look at the mail file with a browser that lets you get to
the bottom easily, like 'less', or 'vi' (if it'll hold 2MB), and see if
the missing messages are really there, please...

Ken Manheimer		klm@cnri.reston.va.us	    703 620-8990 x268
	    (orporation for National Research |nitiatives

	# If you appreciate Python, consider joining the PSA! #
		  # <http://www.python.org/psa/>. #




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

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

From da@maigret.cog.brown.edu  Fri Aug 30 22:33:24 1996
From: da@maigret.cog.brown.edu (David Ascher)
Date: Fri, 30 Aug 1996 17:33:24 -0400 (EDT)
Subject: [PYTHON MATRIX-SIG] NumericalPython
In-Reply-To: <9608302011.AA17714@goldilocks.LCS.MIT.EDU> from "Jim Hugunin" at Aug 30, 96 04:13:07 pm
Message-ID: <199608302133.RAA21519@maigret>

> There is still one outstanding naming/calling convention that could lead to
> a few more such changes before the beta1 release (after which time I won't
> subject people to further major incompatible changes).  I'm guessing that
> David Ascher is waiting to update his Tutorial until this final issue is
> resolved (see my next post).

That's right.  I figure once I get the feeling that things like the axis
and names are settled, I'll update the tutorial.
 
--da

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

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

From hugunin@mit.edu  Fri Aug 30 22:39:13 1996
From: hugunin@mit.edu (Jim Hugunin)
Date: Fri, 30 Aug 1996 17:39:13 -0400
Subject: [PYTHON MATRIX-SIG] Default Axes revisited
Message-ID: <9608302137.AA18483@goldilocks.LCS.MIT.EDU>

> On Fri, 30 Aug 1996, Jim Hugunin wrote:
> 
> > Structural Operations have a default axis of 0
> > Numeric/Computational Operations have a default axis of -1
> 
> 
> Sounds good to me. I recently understood this and completely agree. Does 
> this mean that all functions that can operate on different axes will have

> an "axis" keyword?

Definately.

> > However, because I don't think it's always obvious what's a structural
and
> > what's a numeric operation, all numeric operations will have a "_"
after
> > their name.
> > 
> > So we have:
> > 
> > take, concatenate, ...
> > argmax_, sort_, argsort_, fft_, ...
> > 
> > I will also probably define functions of the form:
> > 
> > def argmax(x,y=None):
> > 	raise AttributeError, "argmax is a Numeric function, use argmax_"
> 
> But these imposter functions should exactly the same signature as their 
> shadowed brethren. (Just checking - wouldn't there be an "axis" keyword 
> as per the question above?)

argmax takes a single argument.  y=None is my way of handling the default
axis argument.  I will use the word axis there in the real version.

> > Is everybody reasonably happy with this? - Jim
> 
> Reasonably.

If I can get all interested parties to say that I'll be happy.

-Jim

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

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

From hinsen@ibs.ibs.fr  Sat Aug 31 09:31:04 1996
From: hinsen@ibs.ibs.fr (Konrad Hinsen)
Date: Sat, 31 Aug 96 09:31:04 +0100
Subject: [PYTHON MATRIX-SIG] Default Axes revisited
In-Reply-To: <9608302018.AA17769@goldilocks.LCS.MIT.EDU> (hugunin@mit.edu)
Message-ID: <199608310734.JAA14456@ibs.ibs.fr>

> I will also probably define functions of the form:
> 
> def argmax(x,y=None):
> 	raise AttributeError, "argmax is a Numeric function, use argmax_"

I don't think that this is a good idea. People who write argmax()
would get an exception anyway, although with a somewhat less
clear explanation. On the other hand, those who use dir() to check
out available functions (or those who use a yet-to-be-written
function browser) would be lead to believe that there actually
*is* a function argmax. If you want to help newbies, put a
explanatory sentence in boldface after every paragraph in the
documentation...

> Is everybody reasonably happy with this? - Jim

Otherwise, yes. I am not terribly excited by the underscores,
but of all the proposals I have seen, they still look like the
smallest evil.

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-76.88.54.94
41, Ave. des Martyrs                   | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------

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

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

From guido@CNRI.Reston.Va.US  Sat Aug 31 17:09:54 1996
From: guido@CNRI.Reston.Va.US (Guido van Rossum)
Date: Sat, 31 Aug 1996 12:09:54 -0400
Subject: [PYTHON MATRIX-SIG] Default Axes revisited
In-Reply-To: Your message of "Sat, 31 Aug 1996 09:31:04 BST."
 <199608310734.JAA14456@ibs.ibs.fr>
References: <199608310734.JAA14456@ibs.ibs.fr>
Message-ID: <199608311609.MAA02239@monty>

> I don't think that this is a good idea. People who write argmax()
> would get an exception anyway, although with a somewhat less
> clear explanation. On the other hand, those who use dir() to check
> out available functions (or those who use a yet-to-be-written
> function browser) would be lead to believe that there actually
> *is* a function argmax. If you want to help newbies, put a
> explanatory sentence in boldface after every paragraph in the
> documentation...

Amen.

--Guido

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

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