You are not logged in.

#1 2014-11-12 16:23:05

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,345

[SOLVED]Common Lisp Question

I have managed to avoid learning Lisp since I wrote my first program some 40 years ago.  Despite actually having spent some time with McCarthy and having visited the Symbolics plant in Chatsworth, I just never had the desire to learning anything not evolved from Algol or Fortran.  I have decided to fill that void in my experience and have been  playing with Common Lisp.  Emphasis on play.  Also, this may be an academic exercise, but this is not a homework assignment.

I put together a function that performs a modified sieve of Eratosthenes that does work.  I realize that this is an example of where iteration would provide a huge speed advantage over mapping, but that was not the point of writing this way.

Here is the code

(defun sieve (n)
  (let ((primes (list)))
    (do ((i 2 (1+ i)))
        ((> i n))
      (if (not
           (find 0 (mapcar (lambda (x) (mod i x)) primes)))
          (setf primes (append primes (list i)))))
    primes))

(print (sieve 100000))

This runs in about 3 seconds in sbcl and prints all the primes less than 100k.  clisp takes about 8 seconds.  I wanted to build a vector of primes, and then provide a map function to divide a scalar (which happens to be next number to be tested as to whether it is prime) by the vector of known primes to return a new vector of the modulo values.  If any of the modulo values are zero, it is not prime.  If it is prime, I wanted to add that prime to the vector of primes and continue.  I had no trouble using make-array to create an :adjustable collection, but then I ran into a road block:

I could not figure out how to create a map that would allow me to act on a scalar by a vector and return a vector.  To work around this, I re-wrote the code to use lists and to use mapcar.  As I said, it works, but I believe the setf to store the list each time is highly inefficient.  (The fact that I am doing a lot of unnecessary division because I am using mapping functions notwithstanding).  Every mapping function for arrays I could find required that the inputs be vectors and the output a single vector the size of the smallest input vector.

So, the real question is, is there an intrinsic way to create a map so that each element of a vector can be passed, along with a scalar to a function that produces an output vector the size of the input vector?

Last edited by ewaller (2014-11-13 02:19:19)


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#2 2014-11-13 02:16:16

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,345

Re: [SOLVED]Common Lisp Question

I found it smile

The function is map-vec

TFM wrote:

— Function: map-vec f v
Map the Lisp function f over the Calc vector v. For example, ‘(map-vec 'math-floor v)’ returns a vector of the floored components of vector v.


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

Board footer

Powered by FluxBB