From: Aleksander Nabaglo
Subject: (exp (/ z))
Date: 
Message-ID: <e68mf1$ddh$1@srv.cyf-kr.edu.pl>
!

How to make this code run faster ?

;;;;;;

#!/usr/local/bin/clisp -q -C

;;; Time-stamp: <2006-06-07 22:53:18 anab>

(setq *warn-on-floating-point-contagion* nil)

(defvar *EIPI23* (exp (* (/ 2D0 3D0) PI #C(0D0 1D0))))

(defun tphdt (ta tb nn)
   (declare (double-float ta tb) (fixnum nn)
	   (optimize (speed 3) (safety 0)))
   (+ ta (/ (- tb ta) nn 2)))

(defun xycorg (cx cy xab nx ny)
   (declare (double-float cx cy xab) (fixnum nx ny)
	   (optimize (speed 3) (safety 0)))
   (let ((dh (/ xab nx))
	(hx (/ xab 2))
	(hy (/ (* xab ny) nx 2)))
     (declare (double-float dh hx hy))
     (let ((xa (tphdt (- cx hx) (+ cx hx) nx))
	  (ya (tphdt (- cy hy) (+ cy hy) ny)))
       (declare (double-float xa ya))
       (values xa ya dh))))

(defun funijz (xa ya dh)
   (declare (double-float xa ya dh)
	   (optimize (speed 3) (safety 0)))
   #'(lambda (ii jj)
       (declare (fixnum ii jj)
	       (optimize (speed 3) (safety 0)))
       (complex (+ xa (* ii dh))
	       (+ ya (* jj dh)))))

(defun funcnt (nr nc)
   (declare (fixnum nr nc)
	   (optimize (speed 3) (safety 0)))
   #'(lambda (nn)
       (multiple-value-bind
        (r c) (floor nn nc)
        (declare (fixnum r c)
		(optimize (speed 3) (safety 0)))
        (values c (- nr 1 r)))))

(defun funcfz (fz fijz fcnt)
   (declare (fixnum nn)
	   (optimize (speed 3) (safety 0)))
   #'(lambda (nn)
       (multiple-value-bind
        (kx ky)
        (funcall fcnt nn)
        (let ((za (funcall fijz kx ky)))
	 (let ((zz (ignore-errors (funcall fz za))))
	   (if zz zz za))))))

(defun fcfz (cx cy ab nx ny fz)
   (declare (double-float cx cy ab) (fixnum nx ny)
	   (optimize (speed 3) (safety 0)))
   (multiple-value-bind
    (xa ya dh)
    (xycorg cx cy ab nx ny)
    (funcfz fz (funijz xa ya dh) (funcnt ny nx))))

(defun itlog (x)
   (declare (double-float x)
	   (optimize (speed 3) (safety 0)))
   (cond
    ((< 1 x) (decode-float (log x 1.5D0)))
    ((< x 0) (itlog (abs x)))
    (t (itlog (/ x)))))

(defun bylog (x)
   (declare (double-float x)
	   (optimize (speed 3) (safety 0)))
    (coerce
     (floor (- (* 512D0 (itlog x)) 256D0))
	      'unsigned-byte))

(defun rgbf (zz fb k)
   (declare (complex zz) (fixnum k)
	   (optimize (speed 3) (safety 0)))
   (let ((rr (realpart (* zz *EIPI23*)))
	(gg (realpart zz))
	(bb (realpart (/ zz *EIPI23*))))
     (declare (double-float rr gg bb))
     (let ((r (bylog rr))
	  (g (bylog gg))
	  (b (bylog bb)))
       (declare (fixnum r g b))
       (cond
        ((< r (min g b)) (setq r (ash (logxor g b) -1)))
        ((< g (min b r)) (setq g (ash (logxor b r) -1)))
        ((< b (min r g)) (setq b (ash (logxor r g) -1))))
     (setf
      (svref fb k) r
      (svref fb (+ 1 k)) g
      (svref fb (+ 2 k)) b))))

(defun zpnm (cx cy wx nc nr miraclez)
   (declare (double-float cx cy wx) (fixnum nc nr))
   (with-open-file
    (ppm "zpnm.ppm"
	:direction :output
	:element-type 'unsigned-byte)
    (let ((fb (make-array (* 3 nc nr) :element-type 'unsigned-byte))
	 (hd (format nil "P6~%~D ~D~%255~%" nc nr))
	 (ff (fcfz cx cy wx nc nr miraclez)))
      (map nil #'(lambda (cc) (write-byte (char-code cc) ppm)) hd)
      (dotimes (k (* nc nr))
        (when (= 0 (mod k nc)) (format t "~&~D " (/ k nc)))
        (rgbf (funcall ff k) fb (* 3 k)))
      (write-sequence fb ppm))))

(times
  (zpnm 0.5 0 1.5 800 600
        #'(lambda (z) (exp (/ z)))))

;;; Koniec ;;;

From: Frank Buss
Subject: Re: (exp (/ z))
Date: 
Message-ID: <4acc74q22p42.q119olg6sz4n$.dlg@40tude.net>
Aleksander Nabaglo wrote:

> How to make this code run faster ?

Try sbcl. Nice picture, which is generated by your program:

http://www.frank-buss.de/tmp/zpnm.png

Do you have some background information how your program works?

BTW: When trying to execute the compiled functions (which may help to speed
it up in CLISP, too), LispWorks says:

Error: ** Processor Fault #xC0000005 at #x201B18FB (#<function
SYSTEM::-$DOUBLE$DOUBLE 201B18F2>).

Maybe some declare statements are wrong. Without all declare statements the
picture is finished after 35 seconds.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Sacha
Subject: Re: (exp (/ z))
Date: 
Message-ID: <RdUhg.471344$gg6.11794529@phobos.telenet-ops.be>
"Frank Buss" <··@frank-buss.de> wrote in message 
···································@40tude.net...
> Try sbcl. Nice picture, which is generated by your program:
>
> http://www.frank-buss.de/tmp/zpnm.png
>

May I ask what library you're using for producing such png image ?

Sacha 
From: Zach Beane
Subject: Re: (exp (/ z))
Date: 
Message-ID: <m3ejxzeroa.fsf@unnamed.xach.com>
"Sacha" <··@address.spam> writes:

> "Frank Buss" <··@frank-buss.de> wrote in message 
> ···································@40tude.net...
> > Try sbcl. Nice picture, which is generated by your program:
> >
> > http://www.frank-buss.de/tmp/zpnm.png
> >
> 
> May I ask what library you're using for producing such png image ?

I don't know what Frank Buss used, but the Salza ZLIB/DEFLATE
compression library comes with a PNG writer in the examples/
directory. See http://cliki.net/salza to get Salza, and see
http://fract.ygingras.net/ for a website that uses Salza to generate
PNGs on the fly. http://wigflip.com/ also uses Salza and Skippy (a GIF
writing library) to create graphics on the fly with Lisp.

Zach
From: Sacha
Subject: Re: (exp (/ z))
Date: 
Message-ID: <UMXhg.471599$ta4.12337218@phobos.telenet-ops.be>
>> >
>> > http://www.frank-buss.de/tmp/zpnm.png
>> >
>>
>> May I ask what library you're using for producing such png image ?
>
> I don't know what Frank Buss used, but the Salza ZLIB/DEFLATE
> compression library comes with a PNG writer in the examples/
> directory. See http://cliki.net/salza to get Salza, and see
> http://fract.ygingras.net/ for a website that uses Salza to generate
> PNGs on the fly. http://wigflip.com/ also uses Salza and Skippy (a GIF
> writing library) to create graphics on the fly with Lisp.
>
> Zach

Thanks, I'll check this out

Sacha 
From: Frank Buss
Subject: Re: (exp (/ z))
Date: 
Message-ID: <ok2khechn3uo.pgnw94ym8q2t$.dlg@40tude.net>
Zach Beane wrote:

> I don't know what Frank Buss used, but the Salza ZLIB/DEFLATE
> compression library comes with a PNG writer in the examples/
> directory. See http://cliki.net/salza to get Salza, and see
> http://fract.ygingras.net/ for a website that uses Salza to generate
> PNGs on the fly. http://wigflip.com/ also uses Salza and Skippy (a GIF
> writing library) to create graphics on the fly with Lisp.

I tried this library:

http://www.cliki.net/CL-PNG

Maybe it works, when installing UFFI and the required zlib DLLs. The old
one at http://www.pvv.ntnu.no/~musum/lisp/ created PNG images, which
couldn't be opened with Photoshop or Internet Explorer.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Frank Buss
Subject: Re: (exp (/ z))
Date: 
Message-ID: <18gkv4nuj5ktv$.9ot2uk4uhoq0.dlg@40tude.net>
Sacha wrote:

> May I ask what library you're using for producing such png image ?

I gave up to use a PNG library for Lisp. cl-png needs a DLL on my Windows
machine, which I don't have and the old version of cl-png produces invalid
PNG images. Maybe the image-magicks Lisp wrapper is better, but there is no
documentation and libraries are missing, too. So I've used Gimp, the only
program on my computer which can open ppm images, to convert it to PNG.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Zach Beane
Subject: Re: (exp (/ z))
Date: 
Message-ID: <m3ac8neqzt.fsf@unnamed.xach.com>
Frank Buss <··@frank-buss.de> writes:

> Sacha wrote:
> 
> > May I ask what library you're using for producing such png image ?
> 
> I gave up to use a PNG library for Lisp. cl-png needs a DLL on my Windows
> machine, which I don't have and the old version of cl-png produces invalid
> PNG images. Maybe the image-magicks Lisp wrapper is better, but there is no
> documentation and libraries are missing, too. 

Salza's PNG writer does not use an external C library; it is pure
Common Lisp. However, it is undocumented, and only supports writing an
image when the entire image is in memory as an octet array.

Zach
From: Sacha
Subject: Re: (exp (/ z))
Date: 
Message-ID: <u0Vhg.471401$rg3.12274735@phobos.telenet-ops.be>
"Frank Buss" <··@frank-buss.de> wrote in message 
····································@40tude.net...
> Sacha wrote:
>
>> May I ask what library you're using for producing such png image ?
>
> I gave up to use a PNG library for Lisp. cl-png needs a DLL on my Windows
> machine, which I don't have and the old version of cl-png produces invalid
> PNG images. Maybe the image-magicks Lisp wrapper is better, but there is 
> no
> documentation and libraries are missing, too. So I've used Gimp, the only
> program on my computer which can open ppm images, to convert it to PNG.
>

Not the answer i was hoping for...
I'm working with windows too, developing a web site with lispworks,
Currently developing a graphic library with VML and SVG back-ends... I 
thought
doing raster could be easier, but yes, all these libraries need external 
DLLs.
So i jumped on the vector graphics wagon =)

Sacha 
From: Matthieu Villeneuve
Subject: Re: (exp (/ z))
Date: 
Message-ID: <448921e1$0$9607$636a55ce@news.free.fr>
Frank Buss a �crit :
> Sacha wrote:
> 
> 
>>May I ask what library you're using for producing such png image ?
> 
> 
> I gave up to use a PNG library for Lisp. cl-png needs a DLL on my Windows
> machine, which I don't have and the old version of cl-png produces invalid
> PNG images. Maybe the image-magicks Lisp wrapper is better, but there is no
> documentation and libraries are missing, too. So I've used Gimp, the only
> program on my computer which can open ppm images, to convert it to PNG.

Imago (http://common-lisp.net/project/imago/) can read PPM and write
PNG, and it is entirely written in Common Lisp. The PNG writing code
apparently works, but hasn't been tested very much (and it is slow).
Bug reports and improvements are welcome, though... :)


--
Matthieu Villeneuve
From: Frank Buss
Subject: Re: (exp (/ z))
Date: 
Message-ID: <1135ne3hcbghi.98kjwg6nwnjb$.dlg@40tude.net>
Matthieu Villeneuve wrote:

> Imago (http://common-lisp.net/project/imago/) can read PPM and write
> PNG, and it is entirely written in Common Lisp. The PNG writing code
> apparently works, but hasn't been tested very much (and it is slow).
> Bug reports and improvements are welcome, though... :)

ok, nice, but even my Lua Player can read and write PNG (with alpha channel
supported) and JPG with just Image.load("filename.jpg/.png"), which returns
an Image object and save with Image.save("filename.jpg/.png"). For Windows
I have used the image magick library for a C++ project, which can read JPG,
BMP, PNG, PCX, TIF, TGA, GIF, PNM, WBMP and XBM (theses are the formats
I've tested, there are more supported formats) and most of these formats
can be written, too (but I've tested PNG and JPG, only).

CL-Magic ( http://common-lisp.net/project/cl-magick/ ) looks a bit too
low-level for me. I can repack my Windows DLL to access it from Lisp with
CFFI (CL-Magic uses UFFI).

Any ideas how the Lisp interface should look like? To make things simpler,
I think every image should be stored as 4 bytes per pixels, in RGBA format.
There should be a load and a save function and maybe some functions for
loading and saving from/to streams and memory (which is useful e.g. when
up-/down-loading JPG or other images from network). An Image class could
provide all methods. Accessing pixels could be (set-pixel x y r g b a)
(with optional a) and (get-pixel x y), which returns r, g, b, a as multiple
values. Another idea would be to use a Color class, but I don't know if
this is fast enough, if you want to do lots of single pixel manipulation,
like creating Mandelbrot images.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Aleksander Nabaglo
Subject: Re: (exp (/ z))
Date: 
Message-ID: <e68uep$mv0$1@srv.cyf-kr.edu.pl>
!

Frank Buss napisał(a):
> Do you have some background information how your program works?
It visualizes complex function;
[col, row] -> [x, y] -> z -> f(z) -> [Red(f(z), Green(f(z)), Blue(f(z))]

> BTW: When trying to execute the compiled functions (which may help to speed
> it up in CLISP, too), LispWorks says:
> 
> Error: ** Processor Fault #xC0000005 at #x201B18FB (#<function
> SYSTEM::-$DOUBLE$DOUBLE 201B18F2>).
(ignore-error (funcall fz za)) should suppres arithmetical overlows
near fz singularities.

> 
> Maybe some declare statements are wrong. Without all declare statements the
> picture is finished after 35 seconds.
My Celeron 1.7GHz, clisp 2.37 takes 280 seconds.

-- 
A
.
From: Rainer Joswig
Subject: Re: (exp (/ z))
Date: 
Message-ID: <joswig-DEAAD4.10214711062006@news-europe.giganews.com>
In article <······························@40tude.net>,
 Frank Buss <··@frank-buss.de> wrote:

> Aleksander Nabaglo wrote:
> 
> > How to make this code run faster ?
> 
> Try sbcl. Nice picture, which is generated by your program:
> 
> http://www.frank-buss.de/tmp/zpnm.png
> 
> Do you have some background information how your program works?
> 
> BTW: When trying to execute the compiled functions (which may help to speed
> it up in CLISP, too), LispWorks says:
> 
> Error: ** Processor Fault #xC0000005 at #x201B18FB (#<function
> SYSTEM::-$DOUBLE$DOUBLE 201B18F2>).
> 
> Maybe some declare statements are wrong. Without all declare statements the
> picture is finished after 35 seconds.

The example call is wrong.

(defun zpnm (cx cy wx nc nr miraclez)
   (declare (double-float cx cy wx) (fixnum nc nr))
   (with-open-file
    (ppm "zpnm.ppm"
   :direction :output
   :element-type 'unsigned-byte)
    (let ((fb (make-array (* 3 nc nr) :element-type 'unsigned-byte))
    (hd (format nil "P6~%~D ~D~%255~%" nc nr))
    (ff (fcfz cx cy wx nc nr miraclez)))
      (map nil #'(lambda (cc) (write-byte (char-code cc) ppm)) hd)
      (dotimes (k (* nc nr))
        (when (= 0 (mod k nc)) (format t "~&~D " (/ k nc)))
        (rgbf (funcall ff k) fb (* 3 k)))
      (write-sequence fb ppm))))

(times
  (zpnm 0.5 0 1.5 800 600
        #'(lambda (z) (exp (/ z)))))

0 is not a double-float. Never. ;-)


LispWorks on my PowerMac G5 needs 8 seconds.

-- 
http://lispm.dyndns.org/
From: ······@corporate-world.lisp.de
Subject: Re: (exp (/ z))
Date: 
Message-ID: <1150020274.050737.133650@g10g2000cwb.googlegroups.com>
Rainer Joswig schrieb:

> In article <······························@40tude.net>,
>  Frank Buss <··@frank-buss.de> wrote:
>
> > Aleksander Nabaglo wrote:
> >
> > > How to make this code run faster ?
> >
> > Try sbcl. Nice picture, which is generated by your program:
> >
> > http://www.frank-buss.de/tmp/zpnm.png
> >
> > Do you have some background information how your program works?
> >
> > BTW: When trying to execute the compiled functions (which may help to speed
> > it up in CLISP, too), LispWorks says:
> >
> > Error: ** Processor Fault #xC0000005 at #x201B18FB (#<function
> > SYSTEM::-$DOUBLE$DOUBLE 201B18F2>).
> >
> > Maybe some declare statements are wrong. Without all declare statements the
> > picture is finished after 35 seconds.
>
> The example call is wrong.
>
> (defun zpnm (cx cy wx nc nr miraclez)
>    (declare (double-float cx cy wx) (fixnum nc nr))
>    (with-open-file
>     (ppm "zpnm.ppm"
>    :direction :output
>    :element-type 'unsigned-byte)
>     (let ((fb (make-array (* 3 nc nr) :element-type 'unsigned-byte))
>     (hd (format nil "P6~%~D ~D~%255~%" nc nr))
>     (ff (fcfz cx cy wx nc nr miraclez)))
>       (map nil #'(lambda (cc) (write-byte (char-code cc) ppm)) hd)
>       (dotimes (k (* nc nr))
>         (when (= 0 (mod k nc)) (format t "~&~D " (/ k nc)))
>         (rgbf (funcall ff k) fb (* 3 k)))
>       (write-sequence fb ppm))))
>
> (times
>   (zpnm 0.5 0 1.5 800 600
>         #'(lambda (z) (exp (/ z)))))
>
> 0 is not a double-float. Never. ;-)
>
>
> LispWorks on my PowerMac G5 needs 8 seconds.

SBCL on the MacBook needs 3 seconds...

> 
> -- 
> http://lispm.dyndns.org/