MATLAB to Python

395 views
Skip to first unread message

Hazem

unread,
Mar 27, 2009, 4:05:14 PM3/27/09
to sage-devel

Hi everyone,

I just stumbled upon this:

http://www.pubmedcentral.nih.gov/articlerender.fcgi?artid=2644618
http://ompc.juricap.com/

and was wondering if anybody here is working on, or knows somebody
working on a similar project. MATLAB-Python links are not new (see the
(defunct?) MatPy and PyMat projects), but it is nice to see new life
being injected into them.

In short, I want to know where is the best place to submit the above
links.

Thanks,

Hazem

William Stein

unread,
Mar 27, 2009, 4:20:08 PM3/27/09
to sage-...@googlegroups.com

It seems to me that it would be worth considering including this in
Sage. It only depends on matplotlib, numpy, and scipy, all of which
we include. Could somebody actually try it out?!

-- William

Harald Schilly

unread,
Mar 27, 2009, 5:58:47 PM3/27/09
to sage-devel


On Mar 27, 9:05 pm, Hazem <hazem.biqa...@gmail.com> wrote:
> http://ompc.juricap.com/

looks very interesting to me. It's also a new project, fresh ideas and
well, i think it would be very useful to include it in sage.
if you look at the timeline, http://ompc.juricap.com/timeline things
like plotting and structures still need to be done.
we should keep an eye on it.

h

Hazem

unread,
Mar 27, 2009, 6:00:02 PM3/27/09
to sage-devel

We can try it out online: http://ompclib.appspot.com/m2py

Since I am not familiar with Python all that much, I cannot judge the
quality of the Python code produced. I can only try to run it in Sage
(Python Mode) and see it behaves like the original m-code. I will be
trying this out over the next days and weeks to get an idea. Anybody
want to suggest some benchmark tests?

Generally I don't have alot of confidence in translators, but the
authors claim to aspire for 100% compatibility. Scilab includes an m-
file translator and it usually does not work without manual
intervention. Keep in mind that Scilab and MATLAB syntax and semantics
are very similar, much more so than with Python.

If this works reasonably well, then it would be an exciting addition
to Sage! Glad I found it!

Hazem

On Mar 27, 4:20 pm, William Stein <wst...@gmail.com> wrote:
>  -- William- Hide quoted text -
>
> - Show quoted text -

Minh Nguyen

unread,
Mar 27, 2009, 8:23:12 PM3/27/09
to sage-...@googlegroups.com
Hi Hazem,

On Fri, Mar 27, 2009 at 10:00 PM, Hazem <hazem....@gmail.com> wrote:
>
>
> We can try it out online: http://ompclib.appspot.com/m2py
>
> Since I am not familiar with Python all that much, I cannot judge the
> quality of the Python code produced. I can only try to run it in Sage
> (Python Mode) and see it behaves like the original m-code. I will be
> trying this out over the next days and weeks to get an idea. Anybody
> want to suggest some benchmark tests?
>
> Generally I don't have alot of confidence in translators, but the
> authors claim to aspire for 100% compatibility. Scilab includes an m-
> file translator and it usually does not work without manual
> intervention. Keep in mind that Scilab and MATLAB syntax and semantics
> are very similar, much more so than with Python.
>
> If this works reasonably well, then it would be an exciting addition
> to Sage! Glad I found it!

Don't be glad; be excited! :-) I must thank you for such links. Many
of us, at least myself, wouldn't have come across the above paper. But
then trawling the web is a non-trivial task, even for a researcher.
Once again, thank you very much!

--
Regards
Minh Van Nguyen

Jason Grout

unread,
Mar 27, 2009, 9:16:16 PM3/27/09
to sage-...@googlegroups.com
Hazem wrote:
>
> Hi everyone,
>
> I just stumbled upon this:
>
> http://www.pubmedcentral.nih.gov/articlerender.fcgi?artid=2644618


I thought this article was very interesting. Thanks for posting it!

One thing that I thought was very interesting was their way of allowing
for custom inline operators in python. It inspired the following
@inline_operator decorator. Would this be useful in Sage?

class inline_operator:
def __init__(self, function):
self.function = function
self.left = None
self.right = None

def __rmul__(self, left):
if self.right is None:
self.left = left
return self
else:
right = self.right
self.right = None
return self.function(left, right)

def __mul__(self, right):
if self.left is None:
self.right = right
return self
else:
left = self.left
self.left = None
return self.function(left, right)


# EXAMPLE

a=[1,2,3]
b=[3,4,5]

# This emul operator returns the element-wise product of two lists...
@inline_operator
def emul(a,b):
return [i*j for i,j in zip(a,b)]

# Returns [3,8,15]
a *emul* b

Thanks,

Jason

David Joyner

unread,
Mar 27, 2009, 9:52:55 PM3/27/09
to sage-...@googlegroups.com
This is very cool!

I remember wanting something like this awhile back but right now I
can't remember
what for. Anyway, I think it could be useful. Thanks!


On Fri, Mar 27, 2009 at 9:16 PM, Jason Grout
<jason...@creativetrax.com> wrote:
>

...

Hazem

unread,
Mar 27, 2009, 11:01:12 PM3/27/09
to sage-devel
You're welcome to all of you. I guess all those hours spent online
didn't go to waste :)

Hazem


On Mar 27, 9:52 pm, David Joyner <wdjoy...@gmail.com> wrote:
> This is very cool!
>
> I remember wanting something like this awhile back but right now I
> can't remember
> what for. Anyway, I think it could be useful. Thanks!
>
> On Fri, Mar 27, 2009 at 9:16 PM, Jason Grout
>

Minh Nguyen

unread,
Mar 28, 2009, 12:35:42 AM3/28/09
to sage-...@googlegroups.com

On a related note about open access to scientific papers, I've come
across this little beauty:

http://blog.wired.com/wiredscience/2009/03/openmit.html

Robert Bradshaw

unread,
Mar 28, 2009, 3:02:57 AM3/28/09
to sage-...@googlegroups.com
This is the same trick we use for the backslash operator in Sage.

- Robert

Florent Hivert

unread,
Mar 28, 2009, 7:31:10 AM3/28/09
to sage-...@googlegroups.com

+1 for integrating this in sage. One very common application:

a *tensor* b *tensor* c

If it's doable to extend the BackslashOperator trick to allows for the user to
define his new operator without changing the performance, I'd like to advocate
for it. My feeling that by default, we should stick to python syntax. Indeed,
we don't want the user which learn sage to learn a different syntax. Moreover
as burcin pointed out on irc, if we allows for to much different syntax, it
might be hard to transfer code around.

On the other hand, good mathematics relies heavily on good notations. And this
is particularly true in combinatorics. So that, in my opinion we should allows
the user to define new operators. Maybe with the intend to keep the use of
those notations at the interractive level.

Here is an example of usage: I'm working on a particular class of algebras
called dendriform algebras. Here the product * is decomposed as the sum of two
operations say >> and <<:
a * b = a << b + a >> b

The operations >> and >> are some action of the algebra over itself, they
verify some relations such as
(a << b) << c = a << (b * c)
(a * b) >> c = a >> (b >> c)

I can't imagine working in this without using a good *infix* notation. For
this particular case I can *abuse* __lshift__ but I'd rather being able to
define new notations.

Any comment,

Florent

Jason Grout

unread,
Mar 28, 2009, 8:16:36 AM3/28/09
to sage-...@googlegroups.com


Yep, I totally agree.

>
> On the other hand, good mathematics relies heavily on good notations. And this
> is particularly true in combinatorics. So that, in my opinion we should allows
> the user to define new operators. Maybe with the intend to keep the use of
> those notations at the interractive level.


Yep, that's what I was intending. We could have a predefined set of
operators that the user could import into the global namespace to give
some sort of "blessed" syntax for interactive use. For example, there
are lots of different kinds of graph products for which having infix
notation would be very convenient.


>
> Here is an example of usage: I'm working on a particular class of algebras
> called dendriform algebras. Here the product * is decomposed as the sum of two
> operations say >> and <<:
> a * b = a << b + a >> b
>
> The operations >> and >> are some action of the algebra over itself, they
> verify some relations such as
> (a << b) << c = a << (b * c)
> (a * b) >> c = a >> (b >> c)
>
> I can't imagine working in this without using a good *infix* notation. For


Yes, thanks. For some reason, I was drawing a blank when trying to
remember the word "infix". The subject should have read "Custom infix
operators in python".

> this particular case I can *abuse* __lshift__ but I'd rather being able to
> define new notations.


I'd like to extend the above decorator to handle several different
common precedence levels, maybe just addition, multiplication, and power.

Thanks,

Jason

Jason Grout

unread,
Mar 28, 2009, 8:28:42 AM3/28/09
to sage-...@googlegroups.com
Robert Bradshaw wrote:
> This is the same trick we use for the backslash operator in Sage.
>


Aha, the one custom infix operator that I know of in Sage.

In the backslash operator and in the article posted, the rmul only
stored the argument and the __mul__ only performed the operation. Are
you always guaranteed that __rmul__ will be called right before __mul__
for the same invocation of the operation?

Thanks,

Jason

Carl Witty

unread,
Mar 28, 2009, 10:37:11 AM3/28/09
to sage-...@googlegroups.com
On Sat, Mar 28, 2009 at 5:28 AM, Jason Grout
<jason...@creativetrax.com> wrote:
> Aha, the one custom infix operator that I know of in Sage.
>
> In the backslash operator and in the article posted, the rmul only
> stored the argument and the __mul__ only performed the operation.  Are
> you always guaranteed that __rmul__ will be called right before __mul__
> for the same invocation of the operation?

Hmm... probably not. Consider
A *emul* (B *emul* C)
Since multiplication is left-associative, this is:
(A*emul)*((B*emul)*C)

This is probably (I don't know if Python guarantees left-to-right
evaluation, but I'm guessing it does) evaluated in this order:

t1 = A*emul
t2 = B*emul
t3 = t2*C
t4 = t1*t3

So for safe general-purpose use, A*emul needs to return a new object.

Carl

Jason Grout

unread,
Mar 28, 2009, 11:33:43 AM3/28/09
to sage-...@googlegroups.com

Okay, how about this:

class inline_operator:
def __init__(self, function, left=None, right=None):
self.function = function
self.left = left
self.right = right

def __rmul__(self, left):
if self.right is None:

return inline_operator(self.function, left=left)
else:
return self.function(left, self.right)

def __mul__(self, right):
if self.left is None:

return inline_operator(self.function, right=right)
else:
return self.function(self.left, right)


# EXAMPLE

a=[1,2,3]
b=[3,4,5]

@inline_operator


def emul(a,b):
return [i*j for i,j in zip(a,b)]

# Returns [3,8,15]
a *emul* b


Jason

Florent Hivert

unread,
Mar 28, 2009, 1:13:16 PM3/28/09
to sage-...@googlegroups.com
Dear Jason,

> Okay, how about this:
>
> class inline_operator:

You probably mean :

class infix_operator:
...

"infix" remember "infix" :)

> # EXAMPLE
>
> a=[1,2,3]
> b=[3,4,5]
>
> @inline_operator
> def emul(a,b):
> return [i*j for i,j in zip(a,b)]
>
> # Returns [3,8,15]
> a *emul* b

Another suggestion: It allows also to define prefix postfix operator by
partial specialization::

sage: bla = emul*[1,2,3]
sage: [4,5,6]*bla
[4, 10, 18]

sage: bla = [1,2,3]*emul
sage: bla*[4,5,6]
[4, 10, 18]

which looks perfectly good to me. However I'd rather having an error it the
following two behavior::

sage: bla = emul*[1,2,3]*[1,2,4]
sage: [4,5,6]*bla
[4, 10, 24]

sage: bla = [1,2,4]*emul
sage: [1,1,1]*bla*[1,1,1]
[1, 1, 1]

That is when left or right are not None, multiplying raise an error instead of
replacing them silently::

def __rmul__(self, left):
if self.right is None:

if self.left is None:
return inline_operator(self.function, left=left)
else:
raise SyntaxError, "Infix operator already has its left argument"
else:
return self.function(left, self.right)

def __mul__(self, right):
if self.left is None:

if self.right is None:
return inline_operator(self.function, right=right)
else:
raise SyntaxError, "Infix operator already has its right argument"
else:
return self.function(self.left, right)

What do you think ?

Florent

Jason Grout

unread,
Mar 28, 2009, 1:19:47 PM3/28/09
to sage-...@googlegroups.com
Florent Hivert wrote:
> Dear Jason,
>> Okay, how about this:
>>
>> class inline_operator:
>
> You probably mean :
>
> class infix_operator:
> ...
>
> "infix" remember "infix" :)

Yes. Right. Thanks.

I think it's converging to a nice solution! Good job.

Jason

Florent Hivert

unread,
Mar 28, 2009, 1:37:57 PM3/28/09
to sage-...@googlegroups.com
> I'd like to extend the above decorator to handle several different
> common precedence levels, maybe just addition, multiplication, and power.

You mean that you what to support the following syntaxes ?

[1,2,3] +foo+ [1,2,3]
[1,2,3] **foo** [1,2,3]

I also like the following one because it has a very high precedence and also
because it reminds XML tags

[1,2,3] <foo> [1,2,3]

Cheers,

Florent, trying to imagine crazy strange syntaxes...

Carl Witty

unread,
Mar 28, 2009, 1:53:06 PM3/28/09
to sage-...@googlegroups.com
On Sat, Mar 28, 2009 at 10:37 AM, Florent Hivert
<florent...@univ-rouen.fr> wrote:
> I also like the following one because it has a very high precedence and also
> because it reminds XML tags
>
>   [1,2,3]  <foo>  [1,2,3]

That one is nice; it's very pretty. Unfortunately, it doesn't work
with the same implementation, because "A <foo> B" is equivalent to
"(A<foo) and (foo>B)". (It could probably work with the original
implementation, that stored A inside the global foo; but that doesn't
work with (A <foo> (B <foo> C)). Maybe it could work if foo had a
stack, where A<foo pushed A on the stack and foo>B popped a value off
the stack. That seems like it's getting fairly fragile, though.)

(BTW, I think you mean "very low precedence".)

Carl

Reply all
Reply to author
Forward
0 new messages