Raymond Toy | 18 Nov 15:34 2009

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Dieter Kaiser wrote:
> Update of /cvsroot/maxima/maxima/src
> In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv19322/src
>
> Modified Files:
>         gamma.lisp
> Log Message:
> Setting the simp flag more carefully in rational constants. Replacing expressions like (div 1 2) with a
simplified rational constant.
>
> No problems with the testsuite.
>
>
> Index: gamma.lisp
> ===================================================================
> RCS file: /cvsroot/maxima/maxima/src/gamma.lisp,v
> retrieving revision 1.44
> retrieving revision 1.45
> diff -u -d -r1.44 -r1.45
> --- gamma.lisp  7 Sep 2009 20:52:18 -0000       1.44
> +++ gamma.lisp  17 Nov 2009 21:47:19 -0000      1.45
>  <at>  <at>  -549,7 +549,7  <at>  <at> 
>                (mul -1
>                  (simplify (list '(%expintegral_ei) (mul -1 z))))
>                (mul
> -                (div 1 2)
> +                '((rat simp) 1 2)
>   
Wouldn't it have been better to modify div so that div of two integers
automatically returned a simplified rat expression?  Then every user of
(Continue reading)

Richard Fateman | 18 Nov 17:12 2009
Picon

Rational Numbers, was Re: [Maxima-commits] CVS: maxima/src gamma.lisp, 1.44, 1.45.

inserting quoted headers with  "simp" literally  may be a mistake. 

Ideally there should be only one copy of  the list (XXX simp) in the 
whole system, and that copy should be found by  (get 'XXX 'msimpind)

for example, (get 'mplus 'msimpind).

and the CAR of every mplus  should point to it.

In the case of a rational number,  there is no msimpind. I don't know why.

On the other hand, I just checked with the commercial Macsyma, and they 
seem to have flushed the whole  msimpind idea.

My suggestion  (I have occasionally implemented this in some 
experiments) is to use common lisp rational numbers for maxima rational 
numbers.
It is easy to do with a few patches, but the question remains as to 
whether all places have been fixed.  Note that (div 1 2) could be easily
fixed to return the common lisp rational number 1/2 .   finding all 
occurrences of  '((rat simp) 1 2)  would be more difficult.

RJf

Raymond Toy wrote:
> Dieter Kaiser wrote:
>   
>> Update of /cvsroot/maxima/maxima/src
>> In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv19322/src
>>
(Continue reading)

Raymond Toy | 18 Nov 17:26 2009

Re: Rational Numbers, was Re: [Maxima-commits] CVS: maxima/src gamma.lisp, 1.44, 1.45.

Richard Fateman wrote:
> inserting quoted headers with  "simp" literally  may be a mistake. 
>
> Ideally there should be only one copy of  the list (XXX simp) in the 
> whole system, and that copy should be found by  (get 'XXX 'msimpind)
>
> for example, (get 'mplus 'msimpind).
>
> and the CAR of every mplus  should point to it.
>   

I suspect the current code has been very careless about this.  I know I
have been, because I didn't know that.
> In the case of a rational number,  there is no msimpind. I don't know why.
>
> On the other hand, I just checked with the commercial Macsyma, and they 
> seem to have flushed the whole  msimpind idea.
>   
Is there a fundamental reason that there should only be one (XXX simp)? 
Was this just to save memory?  We've probably inadvertently flushed the
msimpind idea from Maxima anyway.  But I do see that eqtest has a check
for msimpind.

> My suggestion  (I have occasionally implemented this in some 
> experiments) is to use common lisp rational numbers for maxima rational 
> numbers.
> It is easy to do with a few patches, but the question remains as to 
> whether all places have been fixed.  Note that (div 1 2) could be easily
> fixed to return the common lisp rational number 1/2 .   finding all 
> occurrences of  '((rat simp) 1 2)  would be more difficult.
(Continue reading)

Richard Fateman | 18 Nov 17:46 2009
Picon

Re: Rational Numbers, was Re: [Maxima-commits] CVS: maxima/src gamma.lisp, 1.44, 1.45.

Raymond Toy wrote:..
...
> Is there a fundamental reason that there should only be one (XXX simp)? 
> Was this just to save memory? 
That was the original reason.
With today's computers I suppose it will also save time because it may 
reduce memory cache activity.
>  We've probably inadvertently flushed the
> msimpind idea from Maxima anyway.  But I do see that eqtest has a check
> for msimpind.
>
>   
>> My suggestion  (I have occasionally implemented this in some 
>> experiments) is to use common lisp rational numbers for maxima rational 
>> numbers.
>> It is easy to do with a few patches, but the question remains as to 
>> whether all places have been fixed.  Note that (div 1 2) could be easily
>> fixed to return the common lisp rational number 1/2 .   finding all 
>> occurrences of  '((rat simp) 1 2)  would be more difficult.
>>
>>   
>>     
> I think using Lisp rational numbers should be done. 
OK, I agree.  (There is one argument in favor of keeping ((rat ) n d) 
that I know of.  And that is we could
in principle, have rational number-like object that are an extension of 
common lisp rationals.  These are,
in particular, ((rat) 1 0)   for  "infinity"   and ((rat) 0 0)  for 
"undefined".  It turns out that these extended rational
numbers have some nice properties and combine with the regular numbers 
(Continue reading)

Steve Haflich | 18 Nov 17:57 2009
Picon

Re: Rational Numbers, was Re: [Maxima-commits] CVS: maxima/src gamma.lisp, 1.44, 1.45.

Richard Fateman <fateman <at> cs.berkeley.edu> wrote:

   > I think using Lisp rational numbers should be done. 
   OK, I agree.  (There is one argument in favor of keeping ((rat ) n d) 
   that I know of.  And that is we could
   in principle, have rational number-like object that are an extension of 
   common lisp rationals.  These are,
   in particular, ((rat) 1 0)   for  "infinity"   and ((rat) 0 0)  for 
   "undefined".  It turns out that these extended rational
   numbers have some nice properties and combine with the regular numbers 
   neatly.  But not entirely neatly.)

One issue is that CL ratios unconditionally do automatic gcd
simplification in two ways:

 cl-user(19): (/ 10 4)
 5/2	      	 ; a different, mathematically equal ratio
 cl-user(19): (/ 10 5)
 2	      	 ; an object of type integer, not type ratio

These are almost always what one wants, but does Maxima always behave
similarly in these two cases?  If not, is there any circumstance where
automatic simplification would not be wanted?
Raymond Toy | 18 Nov 19:43 2009

Re: Rational Numbers, was Re: [Maxima-commits] CVS: maxima/src gamma.lisp, 1.44, 1.45.

Steve Haflich wrote:
> One issue is that CL ratios unconditionally do automatic gcd
> simplification in two ways:
>
>  cl-user(19): (/ 10 4)
>  5/2	      	 ; a different, mathematically equal ratio
>  cl-user(19): (/ 10 5)
>  2	      	 ; an object of type integer, not type ratio
>
> These are almost always what one wants, but does Maxima always behave
> similarly in these two cases?  If not, is there any circumstance where
> automatic simplification would not be wanted?
>   
I think Maxima will eventually reduce the fraction just like CL does. 
But you can easily create fractions like ((rat) 10 4).  It seems that
operations on such things will eventually get reduced to lowest terms.

If you set simp:false, then the simplification doesn't happen.  This
seems to be an unusual thing to do, and if we use CL rationals, we won't
be able to turn this off.

Ray
Dieter Kaiser | 18 Nov 21:28 2009
Picon

Re: Rational Numbers, was Re: [Maxima-commits] CVS: maxima/src gamma.lisp, 1.44, 1.45.

Am Mittwoch, den 18.11.2009, 08:46 -0800 schrieb Richard Fateman:

> It probably has to be done in one gulp.  Also look for occurrences of 
> (numerator ..)  (denominator ...)
> or similar accessors. And let's hope that no one uses  (cadr <ratnum>) 
> to get the numerator etc.

I think the last point is the main problem. Here are some example of
code:

in bessel.lisp:

(defun max-numeric-ratio-p (e den)
  (if (and (listp e)
	   (eq 'rat (caar e))
	   (= den (third e))
	   (integerp (second e)))
      (/ (second e) (third e))
      nil))

in nforma.lisp:
((eq 'rat (caar form))
 (cond ((minusp (cadr form))
        (list '(mminus) (list '(rat) (- (cadr form)) (caddr form))))
       (t (cons '(rat) (cdr form)))))

in nisimp.lisp:
((eq 'rat (caar listpower))
 (setq p (cadr listpower) q (caddr listpower)))

(Continue reading)

Dieter Kaiser | 18 Nov 20:41 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Am Mittwoch, den 18.11.2009, 09:34 -0500 schrieb Raymond Toy:
> Wouldn't it have been better to modify div so that div of two integers
> automatically returned a simplified rat expression?  Then every user of
> div gets this fix.

First, I have changed (div 1 2) --> ((rat simp) 1 2) because I think
this is the most simple and efficient way to represent a constant
rational. Most code of Maxima does it this way too. I have implemented
rational constants with DIV at a time I did not know much about the way
Maxima simplifies expressions. 

The function DIV needs a lot of function calls to get the same result.

Furthermore, I think that it is not a good idea to modify the function
DIV. DIV is a general shortcut to call the simplifier, but we do not
need to call the simplifier for a constant expression.

We have some more ways in Maxima to get the rational constant ((rat
simp) 1 2). These macros and variables are defined in Maxima core:

(defvar 1//2 '((rat simp) 1 2))
(defmacro 1//2 () ''((rat simp) 1 2))	;1/2
(defmacro half () ''((rat simp) 1 2))	;1/2
(defmvar 1//2 '((rat simp) 1 2))

Dieter Kaiser
David Billinghurst | 18 Nov 21:54 2009
Picon

Definitions of 1//2, was Re: CVS: maxima/src gamma.lisp, 1.44, 1.45

Dieter Kaiser wrote:
> We have some more ways in Maxima to get the rational constant ((rat
> simp) 1 2). These macros and variables are defined in Maxima core:
>
> (defvar 1//2 '((rat simp) 1 2))
> (defmacro 1//2 () ''((rat simp) 1 2))	;1/2
> (defmacro half () ''((rat simp) 1 2))	;1/2
> (defmvar 1//2 '((rat simp) 1 2))
>   
Yes. Which form is best - one of the above or something else? Where 
should we put a single definition?
Stavros Macrakis | 18 Nov 22:15 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

I think the clean, general way to do this is to make DIV into a macro
in mopers.lisp. This takes zero function calls at runtime and every
user of div gets the improvement.  Something like this:

mopers.lisp:
(define-compiler-macro div (a b)
  (if (and (integerp a) (integerp b))
      `'((rat simp) ,(numerator (/ a b)) ,(denominator (/ a b)))
      `(div2 ,a ,b)))

opers.lisp:
(defmfun div2 (x y)
  (if (=1 x)
      (inv y)
      (mul x (inv y))))

On Wed, Nov 18, 2009 at 2:41 PM, Dieter Kaiser <drdieterkaiser <at> web.de> wrote:
> Am Mittwoch, den 18.11.2009, 09:34 -0500 schrieb Raymond Toy:
>> Wouldn't it have been better to modify div so that div of two integers
>> automatically returned a simplified rat expression?  Then every user of
>> div gets this fix.
>
> First, I have changed (div 1 2) --> ((rat simp) 1 2) because I think
> this is the most simple and efficient way to represent a constant
> rational. Most code of Maxima does it this way too. I have implemented
> rational constants with DIV at a time I did not know much about the way
> Maxima simplifies expressions.
>
> The function DIV needs a lot of function calls to get the same result.
>
(Continue reading)

Raymond Toy | 19 Nov 15:44 2009

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Stavros Macrakis wrote:
> I think the clean, general way to do this is to make DIV into a macro
> in mopers.lisp. This takes zero function calls at runtime and every
> user of div gets the improvement.  Something like this:
>   
> mopers.lisp:
> (define-compiler-macro div (a b)
>   (if (and (integerp a) (integerp b))
>       `'((rat simp) ,(numerator (/ a b)) ,(denominator (/ a b)))
>       `(div2 ,a ,b)))
>
> opers.lisp:
> (defmfun div2 (x y)
>   (if (=1 x)
>       (inv y)
>       (mul x (inv y))))
>   
I haven't tried this out yet, but I agree that this is the best way.  I
don't think you need to add a div2.  Leaving div as is and adding the
compiler macro should be enough.

Incidentally, I see there's a div* that simplifies the result.

And the best part is that all lisps that we support, including gcl (!),
has define-compiler-macro.

Ray
Stavros Macrakis | 19 Nov 16:59 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

On Thu, Nov 19, 2009 at 9:44 AM, Raymond Toy <raymond.toy <at> stericsson.com> wrote:
> Stavros Macrakis wrote:
>> I think the clean, general way to do this is to make DIV into a macro
>> in mopers.lisp....

> I haven't tried this out yet, but I agree that this is the best way.  I
> don't think you need to add a div2.  Leaving div as is and adding the
> compiler macro should be enough.

OK, define-compiler-macro was new to me -- I guess it is never used at
runtime.  Is that really true?  Does it mean that you can't debug
define-compiler-macro macros when running interpretively?  That seems
problematic.

> Incidentally, I see there's a div* that simplifies the result.

No! No! No!  ALL the arithmetic functions simplify the result.  The
difference between ARITH and ARITH* is that ARITH (like most Maxima
functions) assumes that its *arguments* are simplified, and ARITH*
does not.

It is *almost never* right to use ARITH*.  The * is there to show you
that it's a special case.

              -s

> And the best part is that all lisps that we support, including gcl (!),
> has define-compiler-macro.
>
> Ray
(Continue reading)

Raymond Toy | 19 Nov 17:08 2009

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Stavros Macrakis wrote:
> On Thu, Nov 19, 2009 at 9:44 AM, Raymond Toy <raymond.toy <at> stericsson.com> wrote:
>   
>> Stavros Macrakis wrote:
>>     
>>> I think the clean, general way to do this is to make DIV into a macro
>>> in mopers.lisp....
>>>       
>
>   
>> I haven't tried this out yet, but I agree that this is the best way.  I
>> don't think you need to add a div2.  Leaving div as is and adding the
>> compiler macro should be enough.
>>     
>
> OK, define-compiler-macro was new to me -- I guess it is never used at
> runtime.  Is that really true?  Does it mean that you can't debug
> define-compiler-macro macros when running interpretively?  That seems
> problematic.
>
>   
I don't use define-compiler-macro very often, so I always have to look
at the CLHS to know.  I think the way to debug compiler macros is to do
what the examples in the CLHS does:

 (funcall (compiler-macro-function 'square) '(square x) nil)

(It seems that gcl doesn't have compiler-macro-function, but it must
have something to get the compiler-macro.  I don't know what it is.)

(Continue reading)

Stavros Macrakis | 19 Nov 18:09 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

On Thu, Nov 19, 2009 at 11:08 AM, Raymond Toy
<raymond.toy <at> stericsson.com> wrote:
> Stavros Macrakis wrote:
>> On Thu, Nov 19, 2009 at 9:44 AM, Raymond Toy <raymond.toy <at> stericsson.com> wrote:
>>> Stavros Macrakis wrote:
> ...I don't use define-compiler-macro very often, so I always have to look
> at the CLHS to know.  I think the way to debug compiler macros is to do
> what the examples in the CLHS does:
>
>  (funcall (compiler-macro-function 'square) '(square x) nil)

Well, that lets you look at the expansion.  I was thinking of
black-box testing, where you could turn interpretive macro-expansion
on or off.

           -s
Steve Haflich | 19 Nov 17:45 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Stavros Macrakis <macrakis <at> alum.mit.edu> wrote:

   OK, define-compiler-macro was new to me -- I guess it is never used at
   runtime.  Is that really true?  Does it mean that you can't debug
   define-compiler-macro macros when running interpretively?  That seems
   problematic.

A single symbol name can carry both a compiler macro definition and a
regular function or macro.  The usual sane practice is to define a the
compiler macro to have the same behavior as the function or macro,
although this is not required.

There is not requirement in the ANS that the implementation's compiler
expand and use a compiler macro, although generally they do.  You'll
need to check each implementation to see if there are dependencies on
the several optimize declaration qualities.  (A compiler macro may _not_
be expanded by the compiler is the function or macro is locally declared
notinline.)  You cannot otherwise ever depend on a compiled macro not
being used, since implementations are permitted to accomplish
`interpreted' execution, aka eval, as:

  (defun eval (form) (funcall (compile nil `(lambda () ,form))))

Compiler macros can be are extremely important for runtime efficiency,
allowing small code snippets to be inlined, while allowing the
first-class function to exist, for instance, so it can be passed as a
:key or :test function argument to one of the sequence functions.
Stavros Macrakis | 19 Nov 18:08 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Steve,

Thanks for the info.  Comments/questions inline below.

           -s

On Thu, Nov 19, 2009 at 11:45 AM, Steve Haflich <smh <at> franz.com> wrote:
> Stavros Macrakis <macrakis <at> alum.mit.edu> wrote:
>
>   OK, define-compiler-macro was new to me -- I guess it is never used at
>   runtime.  Is that really true?  Does it mean that you can't debug
>   define-compiler-macro macros when running interpretively?  That seems
>   problematic.
>
> A single symbol name can carry both a compiler macro definition and a
> regular function or macro.  The usual sane practice is to define a the
> compiler macro to have the same behavior as the function or macro,
> although this is not required.

Presumably the idea is to have the same *black-box* behavior.  In the
current version of mopers/opers.lisp, it appears that the macro
definition has been *mechanically* converted to a regular function for
runtime use, which seems peculiar.  For example, we have

(defun add (&rest terms)
  (if (= (length terms) 2)
      (apply #'add2 terms)
      (apply #'addn `(,terms t))))

(define-compiler-macro add (&rest terms)
(Continue reading)

Steve Haflich | 19 Nov 23:53 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Stavros Macrakis <macrakis <at> alum.mit.edu> wrote:

   Presumably the idea is to have the same *black-box* behavior.  In the
   current version of mopers/opers.lisp, it appears that the macro
   definition has been *mechanically* converted to a regular function for
   runtime use, which seems peculiar.  For example, we have

   (defun add (&rest terms)
     (if (= (length terms) 2)
         (apply #'add2 terms)
         (apply #'addn `(,terms t))))

   (define-compiler-macro add (&rest terms)
     (if (= (length terms) 2)
         `(add2 , <at> terms)
         `(addn (list , <at> terms) t)))

Exactly.  Your compiler macro removes some needless fucntion call and
linking overhead.

   instead of what I'd have written by hand:

   (defun add (&rest terms)
     (if (= (length terms) 2)
         (add2 (car terms) (cadr terms))
         (addn terms t)))

   > There is not requirement in the ANS that the implementation's compiler
   > expand and use a compiler macro, although generally they do.

(Continue reading)

Richard Fateman | 18 Nov 22:22 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Dieter Kaiser wrote:

....

> We have some more ways in Maxima to get the rational constant ((rat
> simp) 1 2). These macros and variables are defined in Maxima core:
>
> (defvar 1//2 '((rat simp) 1 2))
> (defmacro 1//2 () ''((rat simp) 1 2))	;1/2
> (defmacro half () ''((rat simp) 1 2))	;1/2
> (defmvar 1//2 '((rat simp) 1 2))
>
> Dieter Kaiser
>
>   
Clearly these are not all necessary!  If we have a suitable compilation 
environment we can have
#.(div 1 2)   be used for any of these.  The appropriate constant will 
be computed at compile time,
whether it is common lisp 1/2  or '((rat simp) 1 2)   or something else, 
like (list (get 'rat 'simpind) 1 2)

The problem with inserting ((rat simp) 1 2)  as constant code should be 
clear -- it means that a change
to common lisp 1/2  needs to be done in each place.  relatively easy 
with a good editor, I suppose.
RJF

> _______________________________________________
> Maxima mailing list
(Continue reading)

Stavros Macrakis | 18 Nov 22:25 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

On Wed, Nov 18, 2009 at 4:22 PM, Richard Fateman
<fateman <at> cs.berkeley.edu> wrote:
> ...Clearly these are not all necessary!  If we have a suitable compilation
> environment we can have
> #.(div 1 2)   be used for any of these. ...

A "suitable compilation environment" meaning that the Maxima
simplifier is available?  Do we actually build Maxima that way?

         -s
Richard Fateman | 18 Nov 22:38 2009
Picon

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Stavros Macrakis wrote:
> On Wed, Nov 18, 2009 at 4:22 PM, Richard Fateman
> <fateman <at> cs.berkeley.edu> wrote:
>   
>> ...Clearly these are not all necessary!  If we have a suitable compilation
>> environment we can have
>> #.(div 1 2)   be used for any of these. ...
>>     
>
> A "suitable compilation environment" meaning that the Maxima
> simplifier is available?  Do we actually build Maxima that way?
>
>          -s
>   

no. not now, anyway but your macro suggestion  is part way.
Raymond Toy | 19 Nov 16:35 2009

Re: [Maxima-commits] CVS: maxima/src gamma.lisp,1.44,1.45

Dieter Kaiser wrote:
> Am Mittwoch, den 18.11.2009, 09:34 -0500 schrieb Raymond Toy:
>   
>> Wouldn't it have been better to modify div so that div of two integers
>> automatically returned a simplified rat expression?  Then every user of
>> div gets this fix.
>>     
>
> First, I have changed (div 1 2) --> ((rat simp) 1 2) because I think
> this is the most simple and efficient way to represent a constant
> rational. Most code of Maxima does it this way too. I have implemented
> rational constants with DIV at a time I did not know much about the way
> Maxima simplifies expressions. 
>
> The function DIV needs a lot of function calls to get the same result.
>   
If you don't mind, I think we should use Stavros' define-compiler-macro
to implement this.  I can make this change.

And it makes it much easier to try out Richard Fateman's patch for CL
rationals if we decide to do that.

This also gives a nice abstraction if the internals ever change.
> We have some more ways in Maxima to get the rational constant ((rat
> simp) 1 2). These macros and variables are defined in Maxima core:
>
> (defvar 1//2 '((rat simp) 1 2))
> (defmacro 1//2 () ''((rat simp) 1 2))	;1/2
> (defmacro half () ''((rat simp) 1 2))	;1/2
> (defmvar 1//2 '((rat simp) 1 2))
(Continue reading)


Gmane