From: LuisGLopez
Subject: Simularion of a (modest) star cluster
Date: 
Message-ID: <1125836181.439401.54190@g44g2000cwa.googlegroups.com>
Hi!!!

I think I got a fairly-sligthly-modestly promising simulation of a star
cluster. :-) It's just a bunch of mass-points moving according Newton's
Laws.

As you know, I'm very newbie, so I took the opportunity to learn how to
use objects (well, in fact only one :-)).

I represented the 3D physical quantities (position, velocity,
aceleration and force) as lists, in order to manipulate them with
mapcar and apply. I don't know if that is efficient or not. I can
notice that the simulation goes "in steps" in my screen (I mean, the
star's paths are drawn in steps bigger than the computation steps)... I
don't know if that's a problem with the drawing algorithm or the
computational one. Any coments/suggestions/critics welcome!!!

I'm enjoying lisp more every day!!! :-)

-------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; X11 routines

(require :clx)
;(unuse-package :XLIB)

(defparameter *dpy* nil)
(defparameter *win* nil)
(defparameter *gctxt* nil)
(defparameter *window-width* 500)
(defparameter *window-height* 500)

(defun get-environment-variable (string)
  #-clisp (cdr (assoc string ext:*environment-list* :test #'string=))
  #+clisp (ext:getenv string))

(defun parse-display-variable (s)
  (let* ((colon (position #\: s))
         (dot (position #\. s :start colon))
         (host-name (if (zerop colon) "localhost" (subseq s 0 colon)))
         (display-number (parse-integer s :start (1+ colon) :end dot)))
    (values host-name display-number)))

(defun open-window ()
  (multiple-value-bind (host display)
      (parse-display-variable (get-environment-variable "DISPLAY"))
    (let* ((dpy (xlib:open-display host :display display))
           (screen (xlib:display-default-screen dpy))
           (black (xlib:screen-black-pixel screen))
           (white (xlib:screen-white-pixel screen))
           (win (xlib:create-window :parent (xlib:screen-root screen)
                                    :background white
                                    :x 0 :y 0 :width *window-width*
:height *window-height*))
           (gcontext (xlib:create-gcontext :drawable win
                                           :background white
                                           :foreground black)))
      (xlib:map-window win)
      (xlib:display-force-output dpy)
      (setf *dpy* dpy
            *win* win
            *gctxt* gcontext)
      win)))

(defun rgb (r g b)
  (xlib:make-color :red r :green g :blue b))

(defun set-color (color)
  (setf (xlib:GCONTEXT-FOREGROUND *gctxt*) color))

(defun set-color-rgb (r g b)
  (setf (xlib:GCONTEXT-FOREGROUND *gctxt*)
        (xlib:make-color :red r :green g :blue b)))

(defun draw-rectangle (x1 y1)
  (let ((x (+ x1 (/ *window-width* 2)))
	(y (+ y1 (/ *window-height* 2))))
    (when (and (plusp x) (< x *window-width*)
	       (plusp y) (< y *window-height*))
      (xlib:draw-rectangle *win* *gctxt*
			   (round x)
			   (round y)
			   1
			   1
			   'fill))))

(defun clear-window ()
  (xlib:clear-area *win* :width *window-width* :height *window-height*)
  (xlib:display-force-output *dpy*))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Code for the Star Cluster

(defconstant +G+ 39.0)

(defclass estrella ()
  ((masa        :initarg  :masa
	        :accessor masa-estrella)
   (posición    :initarg  :posición
	        :accessor posición-estrella)
   (velocidad   :initarg  :velocidad
	        :accessor velocidad-estrella)
   (aceleración :initarg :aceleración
		:initform '(0 0 0)
		:accessor aceleración-estrella)))

(defun random-between (min max)
  (+ (random (- max min)) min))

(defun crear-estrella (&key (radio-cúmulo 150.0)
			    (masa-mínima 0.1) (masa-máxima 10.0)
			    (velocidad-máxima 10.0))
  (let* ((longitud (random (* 2 pi)))
	 (latitud  (- (acos (random-between -1.0 1.0)) (/ pi 2)))
	 (rho      (* radio-cúmulo (expt (random 1.0) 1/3)))
	 (p        (* rho (cos latitud)))
	 (x        (* p (cos longitud)))
	 (y        (* p (sin longitud)))
	 (z        (* rho (sin latitud)))
	 (vx       (random-between (- velocidad-máxima) velocidad-máxima))
	 (vy       (random-between (- velocidad-máxima) velocidad-máxima))
	 (vz       (random-between (- velocidad-máxima) velocidad-máxima)))
    (make-instance 'estrella
		   :masa      (random-between masa-mínima masa-máxima)
		   :posición  (list x y z)
		   :velocidad (list vx vy vz))))

(defmethod actualizar-posición-velocidad ((e estrella) delta-t)
  (setf (posición-estrella e)
	(mapcar '+ (posición-estrella e)
		(mapcar #'(lambda (n) (* n delta-t)) (velocidad-estrella e))
		(mapcar #'(lambda (n) (* 1/2 n delta-t delta-t))
(aceleración-estrella e))))
  (setf (velocidad-estrella e)
	(mapcar '+ (velocidad-estrella e)
		(mapcar #'(lambda (n) (* n delta-t)) (aceleración-estrella e)))))

(defmethod actualizar-aceleración ((e estrella) f)
  (setf (aceleración-estrella e)
	(mapcar '+ (aceleración-estrella e)
		(mapcar #'(lambda (n) (/ n (masa-estrella e))) f))))

(defmethod calcular-distancia ((e1 estrella) (e2 estrella))
  (sqrt (apply '+ (mapcar #'(lambda (n) (* n n))
			  (mapcar '- (posición-estrella e1) (posición-estrella e2))))))

(defmethod calcular-fuerza ((e1 estrella) (e2 estrella))
  (let ((distancia (calcular-distancia e1 e2)))
    (cond
     ((zerop distancia) '(0 0 0))
     (t (let ((modulo-de-f (* +G+ (masa-estrella e1) (masa-estrella e2)
			      (/ (expt distancia 2)))))
	  (mapcar #'(lambda (n) (* n modulo-de-f (/ distancia)))
		  (mapcar '- (posición-estrella e2) (posición-estrella e1))))))))

(defun correr (&key (cantidad-de-estrellas 100) (iteraciones 1000))
  (let ((cúmulo  (make-array cantidad-de-estrellas
			     :fill-pointer 0 :adjustable t :element-type 'estrella))
	(delta-t 0.1))
    (open-window)
    (dotimes (i cantidad-de-estrellas)
      (vector-push (crear-estrella) cúmulo))
    (loop repeat iteraciones do
	  (loop for e1 across (subseq cúmulo 0 (1- cantidad-de-estrellas)) do
		(loop for e2 across
		      (subseq cúmulo (1+ (position e1 cúmulo))
cantidad-de-estrellas) do
		      (let ((f (calcular-fuerza e1 e2)))
			(actualizar-aceleración e1 f)
			(actualizar-aceleración e2 (mapcar #'(lambda (n) (* -1 n)) f)))))
	  (loop for e across cúmulo do
		(actualizar-posición-velocidad e delta-t)
		(draw-rectangle (first (posición-estrella e)) (second
(posición-estrella e)))
		(setf (aceleración-estrella e) '(0 0 0))))))

From: A.L.
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <6jsoh1tvn3ae7bn9vd4qet113cu7rjradv@4ax.com>
On 4 Sep 2005 05:16:21 -0700, "LuisGLopez" <············@gmail.com>
wrote:

>Hi!!!
>
>I think I got a fairly-sligthly-modestly promising simulation of a star
>cluster. :-) It's just a bunch of mass-points moving according Newton's
>Laws.
>
>As you know, I'm very newbie, so I took the opportunity to learn how to
>use objects (well, in fact only one :-)).
>
>I represented the 3D physical quantities (position, velocity,
>aceleration and force) as lists, in order to manipulate them with
>mapcar and apply. I don't know if that is efficient or not. 

It would be better to know. This is rather CPU demanding activity...

> I can
>notice that the simulation goes "in steps" in my screen (I mean, the
>star's paths are drawn in steps bigger than the computation steps)... I
>don't know if that's a problem with the drawing algorithm or the
>computational one. Any coments/suggestions/critics welcome!!!
>
>I'm enjoying lisp more every day!!! :-)
          

What is the advantage of using Lisp for this particular task?...

A.L.

P.S. In addition - it seems that you are using Euler method for
integrating difefrential equaltions. This is no good method for this
task since Euler method does not presevre energy. To solve problems
like this you need methods that are named "symplectic", that in
general preserve energetic invariants (Runge Kutta is no good
either). For details see the book "Geometric Numerical Integration:
Structure-Preserving Algorithms for Ordinary Differential Equations"
by E. Hairer, C. Lubich and G. Wanner, Springer Series in
Computational Mathematics, Vol. 31. Go to Prof. Hairer's page and
you will find some code. In what language?... Guess... Language
named Fortran. And Matlab. Somehow, Lisp is not the language of
choice in computational mathematics community...
From: LuisGLopez
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <1125966853.877849.160570@z14g2000cwz.googlegroups.com>
Hi!!!!

Nicola: Thank you so much! I'll see how to follow your advices.

A.L. ha escrito:

>
> What is the advantage of using Lisp for this particular task?...
>

As Paolo said, having fun is one. But another is that I'm trying to
learn this beautiful language, and after passing through the necessary
but trivial 'factorial', 'fibonacci', and so on, I wanted to try
something more... well, fun. :-) So the answer maybe is always 'having
fun', but learning too. By the way, I think it's obvious that I don't
pretend to do real 'science' with this code; the problem of the
dynamics of a stellar cluster (although far from being solved) has
already been worked far beyond what I could hardly achieve... :-)

Thank you so much for your bibliographic reference!!! I'll try to get
them.

> Somehow, Lisp is not the language of
> choice in computational mathematics community...

That's ok, but my name is not 'computational mathematics community'
(fortunately, I must confess). I'm just 'Luis', and my choice is just
to learn lisp. In other words, to have fun :-)

One more thing: A famous participant of c.l.l took my code, and made it
*real* lisp, and sent it to me privately. You wouldn't believe how
*beautiful* is its render... colorful stars on a black background...
And the code itself, another beauty. I hope he posts it public :-)
From: Paolo Amoroso
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <87y86b78ca.fsf@plato.moon.paoloamoroso.it>
A.L. <········@alamakota.com> writes:

> On 4 Sep 2005 05:16:21 -0700, "LuisGLopez" <············@gmail.com>
> wrote:
[...]
>>I'm enjoying lisp more every day!!! :-)
>           
>
> What is the advantage of using Lisp for this particular task?...

Having fun?


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
Recommended Common Lisp libraries/tools:
- ASDF/ASDF-INSTALL: system building/installation
- CL-PPCRE: regular expressions
- UFFI: Foreign Function Interface
From: A.L.
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <nn0ph15k4usd1rjgkfsf7pq8lf6h4dbkq6@4ax.com>
On Mon, 05 Sep 2005 19:06:13 +0200, Paolo Amoroso
<·······@mclink.it> wrote:

>A.L. <········@alamakota.com> writes:
>
>> On 4 Sep 2005 05:16:21 -0700, "LuisGLopez" <············@gmail.com>
>> wrote:
>[...]
>>>I'm enjoying lisp more every day!!! :-)
>>           
>>
>> What is the advantage of using Lisp for this particular task?...
>
>Having fun?
>

OK. What about Ruby?...

A.L.
From: Marco Antoniotti
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <wS%Se.73$DJ5.74903@typhoon.nyu.edu>
A.L. wrote:
> On Mon, 05 Sep 2005 19:06:13 +0200, Paolo Amoroso
> <·······@mclink.it> wrote:
> 
> 
>>A.L. <········@alamakota.com> writes:
>>
>>
>>>On 4 Sep 2005 05:16:21 -0700, "LuisGLopez" <············@gmail.com>
>>>wrote:
>>
>>[...]
>>
>>>>I'm enjoying lisp more every day!!! :-)
>>>
>>>          
>>>
>>>What is the advantage of using Lisp for this particular task?...
>>
>>Having fun?
>>
> 
> 
> OK. What about Ruby?...

Ruby is a SLDJ, not the real thing :)

Cheers
--
Marco
From: Pascal Costanza
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <3o3nviF3o1rfU1@individual.net>
Marco Antoniotti wrote:

> Ruby is a SLDJ, not the real thing :)

What's a SLDJ?

(The first link spit out by Google strangely returns a website that uses 
a logo that resembles the lambda symbol...)


Pascal

-- 
OOPSLA'05 tutorial on generic functions & the CLOS Metaobject Protocol
++++ see http://p-cos.net/oopsla05-tutorial.html for more details ++++
From: Marco Antoniotti
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <yF2Te.74$DJ5.75592@typhoon.nyu.edu>
Pascal Costanza wrote:
> Marco Antoniotti wrote:
> 
>> Ruby is a SLDJ, not the real thing :)
> 
> 
> What's a SLDJ?

Scripting Language Du Jour :)

Cheers
--
Marco
From: David Steuber
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <87wtlub1im.fsf@david-steuber.com>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> Pascal Costanza wrote:
> > Marco Antoniotti wrote:
> >
> >> Ruby is a SLDJ, not the real thing :)
> > What's a SLDJ?
> 
> Scripting Language Du Jour :)

I was going to have a look at Ruby, but I got derailed along the way.
Oh well.  I'm sure plenty of people have fun with it.

-- 
You should maybe check the chemical content of your breakfast
cereal. --- Bill Watterson
From: Nicolas Neuss
Subject: Re: Simularion of a (modest) star cluster
Date: 
Message-ID: <87zmqrijtf.fsf@ortler.iwr.uni-heidelberg.de>
"LuisGLopez" <············@gmail.com> writes:

> Hi!!!
>
> I think I got a fairly-sligthly-modestly promising simulation of a star
> cluster. :-) It's just a bunch of mass-points moving according Newton's
> Laws.
>
> As you know, I'm very newbie, so I took the opportunity to learn how to
> use objects (well, in fact only one :-)).
>
> I represented the 3D physical quantities (position, velocity,
> aceleration and force) as lists, in order to manipulate them with
> mapcar and apply. I don't know if that is efficient or not. I can
> notice that the simulation goes "in steps" in my screen (I mean, the
> star's paths are drawn in steps bigger than the computation steps)... I
> don't know if that's a problem with the drawing algorithm or the
> computational one. Any coments/suggestions/critics welcome!!!

Lists (and generic arithmetic) are probably not efficient enough here,
better will be uniform arrays of floats.  Here is a short guide to more
efficiency: profile your code to find out in which functions the time is
lost.  Insert "(declare (optimize speed))" in those functions and compile
them with CMUCL or SBCL.  Eliminate all compiler efficiency notes.

> I'm enjoying lisp more every day!!! :-)

Fine,

Nicolas.