Displaced multidimensional arrays in common lisp - multidimensional-array

So I have some code that needs a subset of a multidimensional array in such a way that it works a bit more like taking a subsection of a matrix, ideally it would work like a displaced array.
So let's say I have something that looks like this
(defvar *a* (make-array '(3 3) :initial-contents
'((1 2 3) (2 3 1) (3 1 2))
And I want it to be accessible with an array *b*
(defvar *b* (make-array '(2 2) :displaced-to *a* :displaced-index-offset
(array-major-row-index *a* '(1 1)))
Such that *b* will point to
#2a((3 1) (1 2))
instead of
#2a((3 1) (3 1))
I've already written myself a multidimensional slice function that copies the parts of the array I want, but it would be ideal to not need to copy back and forth manually, is there any solution that works like this in vanilla common lisp?
I understand that the way that displaced multidimensional arrays work in a way that coheres directly with (array-major-row-index) (namely that #2a((1 2 3) (2 3 4)) has row indices (0 1 2 3 4 5) and therefore the displaced array at '(1 0) of dimensions '(2 2) will point to #2a((2 3) (2 3)), so I need to wrap the new array such that it refers to specific places in the old one, but so far I don't know how to capture such a reference.
I'm not entirely sure that it is possible to get pointers to places in the array, so I would appreciate if that could be cleared up.

You can't directly do it, but FYI there used to be support for this in Symbolics Lisp Machines.
From Kent Pitman:
What was new with the LispM, and which did not carry into CL (perhaps
because of the lack of microcode assist for speed) was conformally
displaced arrays (I think you said :displaced-conformally t, or some
such) in which case you got a displaced region of the original square
(cube, etc) rather than a region of the linearized storage. This was
useful for displacing to screen memory, especially since the LispM
used DMA (direct memory access) display from a raster array that was,
I think, specially known by the screen to mean "this array's memor IS
the screen" and doing a SETF of AREF into that special array made
something appear on the screen. All windows had conformally displaced
indirect arrays that represented their part of the screen.
As pointed out by Rainer Joswig, there is a video on Youtube, from Kalman Reti, demonstrating conformally displaced arrays. It might be possible for implementations to provide support for this, but I don't know if any current one provides such displaced arrays. But other answers are fine suggesting alternatives.

Multidimensional arrays are stored in memory as a one-dimensional array in row-major order. That is, #2a((1 2 3) (2 3 1) (3 1 2)) is actually the same as #(1 2 3 2 3 1 3 1 2).
CL-USER> (let ((a (make-array '(3 3) :initial-contents
'((1 2 3) (2 3 1) (3 1 2)))))
(make-array 9 :displaced-to a))
#(1 2 3 2 3 1 3 1 2)
A displaced array is a contiguous subset of the actual array (sharing memory with it). Your desired *B* would not be contiguous, since it would have to arbitrarily jump over the last 3 in the array.
*B*
/ \
--- ---
1 2 3 2 3 1 3 1 2
You would have to either include the skipped over 3 in the displaced array, or use two separate displaced arrays.

As explained in the answer of jkiiski you cannot obtain directly what you want, but you could “approximate” such result by using array of arrays, instead of multi-dimensional arrays.
For instance:
(defvar *a* (make-array 3 :initial-contents '(#(1 2 3) #(2 3 1) #(3 1 2))))
and then *b* could be defined as an array whose elements are arrays displaced on the appropriate arrays of *a*:
(defvar *b*
(make-array 2 :initial-contents
(loop for row from 1 to 2
collect (make-array 2 :displaced-to (aref *a1* row) :displaced-index-offset 1))))
The main difference with respect to the multi-dimensional arrays is that instead of using:
(aref *b* 1 1)
you should use:
(aref (aref *b* 1) 1) ; => produces 2 for the example above
And of course you could define macros or reader macros to simplify this notation.

Related

Convert a polynomial represented as a list of coefficients to a string

I know this is a newbish question. I am trying to create a function 'displayPoly' to display a polynomial in scheme. For example a list given as
'(2 0 1 5.1 8) should display 2x^4 + x^2 + 5.1x + 8.
I have defined "degree" as the following:
(define degree
(lambda(list)
(if (null? list)
(- 1)
(+ 1 (degree (cdr list))))))
Please note I am strictly limited to basic scheme functions
•define, lambda, if, cond, cons,car, cdr, list , member, list-ref
•predicates : null? list? equal? string? number? member?
•arithmetic operators , relational operators, logical operators
•sort, map, filter, foldr, foldl, length, reverse, append, last , let, let*, letrec, print, begin, newline, display, expt, string-append, reduce, range
You need to write some helper functions.
Write a function that given a polynomial returns a list of the degrees.
Input: '(2 0 1 5.1 8)
Output: (4 3 2 1 0)
Write a function mono that given a coefficient and a degree outputs a monomial as a string.
Input: 2 4
Output: "2x^4"
Use (map mono '(2 0 1 5.1 8) (4 3 2 1 0)) to produce a list of the monomials.
Use add-between (or write one yourself) to add "+" between all your monomials.
Use (apply string-append your-list-of-monomials) to get you final string.
Note: It's possible to produce prettier output, but this is a good start.

Idiomatic Lisp way to create a list of sorted random numbers?

I'd like to find out what is the commonly accepted way to create a sorted list of random numbers in Common Lisp. In Clojure it is quite straightforward:
(sort (take 10 (repeatedly #(rand 10))))
I've found that in CL the following works:
(sort (loop for n below 10 collect (random 10)) #'<)
but does not read as well. Is there a cleaner way to express the same thing?
Almost:
(sort (loop repeat 10 collect (random 10)) #'<)
I think that sds's answer is a pretty good choice here, but there's also the potential to use the helpful map-into, which could be valuable if you need to do this a lot, and can reuse one of your existing lists (or vectors). It also has the advantage it separates the list generation code from the random number generation code; if you need to increase the number of elements in the list, you don't have to modify the sorting or random number generation code.
(sort (map-into (make-list 10) #'(lambda () (random 10))) '<)
;=> (0 2 2 2 4 5 6 6 8 9)
(let ((l (make-list 10)))
(sort (map-into l #'(lambda () (random 10))) '<))
;=> (1 1 3 3 4 6 7 8 8 9)

Destructive sorting in lisp

I'm reading Practical Common Lisp. In chapter 11, it says this about sorting:
Typically you won't care about the unsorted version of a sequence after you've sorted it, so it makes sense to allow SORT and STABLE-SORT to destroy the sequence in the course of sorting it. But it does mean you need to remember to write the following:
(setf my-sequence (sort my-sequence #'string<))
I tried the following code:
CL-USER> (defparameter *a* #( 8 4 3 9 5 9 2 3 9 2 9 4 3))
*A*
CL-USER> *a*
#(8 4 3 9 5 9 2 3 9 2 9 4 3)
CL-USER> (sort *a* #'<)
#(2 2 3 3 3 4 4 5 8 9 9 9 9)
CL-USER> *a*
#(2 2 3 3 3 4 4 5 8 9 9 9 9)
In this code we can see that the variable *a* has been changed by the sort function.
Then why do the book say that is necessary to do an assignment?
I'm using SBCL + Ubuntu 14.04 + Emacs + Slime
EDIT:
Following the comment of #Sylwester I add the evaluation of *a* so it's clear that the value has been changed.
It's necessary to do the assignment if you want your variable to contain the proper value of the sorted sequence afterwards. If you don't care about that and only want the return value of sort, you don't need an assignment.
There are two reasons for this. First, an implementation is allowed to use non-destructive copying to implement destructive operations. Secondly, destructive operations on lists can permute the conses such that the value passed into the operation no longer points to the first cons of the sequence.
Here's an example of the second problem (run under SBCL):
(let ((xs (list 4 3 2 1)))
(sort xs '<)
xs)
=> (4)
If we add the assignment:
(let ((xs (list 4 3 2 1)))
(setf xs (sort xs '<))
xs)
=> (1 2 3 4)
The variable can't be changed by the sort function, since the sort function does not know about the variable at all.
All the sort function gets is a vector or a list, but not variables.
In Common Lisp the sort function can be destructive. When it gets a vector for sorting, it can return the same vector or a new one. This is up to the implementation. In one implementation it might return the same vector and in another one it may return a new one. But in any case they will be sorted.
If there is a variable, which points to a sequence and for which the author expects that it will after sorting point to a sorted sequence: set the variable to the result of the sort operation. Otherwise there might be cases, where after potentially destructive sorting, the variable won't point to the SORT result, but still to an unsorted, or otherwise changed, sequence. In case of the vector this CAN be the old and unsorted vector.
REMEMBER
The only thing you can be sure: the SORT function returns a sorted sequence as its value.

Why is a macro necessary for assigning a symbol's value? [duplicate]

(setf list (loop for i from 1 to 12 collect i))
(defun removef (item seq)
(setf seq (remove item seq)))
CL-USER> (removef 2 list)
(1 3 4 5 6 7 8 9 10 11 12)
CL-USER> (removef 3 list)
(1 2 4 5 6 7 8 9 10 11 12)
Why doesn't removef really modify the variable?
In Common Lisp, parameters are passed "by identity" (this term goes back to D. Rettig, one of the developers of the Allegro Common Lisp implementation). Think of pointers (to heap objects) being passed by values, which is true for most Lisp objects (like strings, vectors, and, of course, lists; things are slightly more complicated, since implementations might also have immediate values, but that's beside the point here).
The setf of seq modifies the (private, lexical) variable binding of the function. This change is not visible outside of removef.
In order for removef to be able to affect the surrounding environment at the point of the call, you need to make it a macro:
(defmacro removef (element place)
`(setf ,place (remove ,element ,place)))
You might want to take at look at setf and the concept of generalized references. Note, that the macro version of removef I provided above is not how it should actually be done! For details, read about get-setf-expansion and its ugly details.
If all you want to do is to destructively modify the list, consider using delete instead of remove, but be aware, that this might have unintended consequences:
(delete 2 '(1 2 3 4))
is not allowed by the ANSI standard (you are destructively modifying a literal object, i.e., part of your code). In this example, the mistake is easy to spot, but if you are 7 frames deep in some callstack, processing values whose origin is not entirely clear to you, this becomes a real problem. And anyway, even
(setf list (list 1 2 3 4))
(delete 1 list)
list
might be surprising at first, even though
(setf list (list 1 2 3 4))
(delete 2 list)
list
seems to "work". Essentially, the first example does not work as intended, as the function delete has the same problem as your original version of removef, namely, it cannot change the caller's notion of the list variable, so even for the destructive version, the right way to do it is:
(setf list (delete 1 (list 1 2 3 4)))
Here is an example of an implementation of removef that is "able to affect the surrounding environment at the point of the call", as stated by #Dirk.
(defmacro removef (item place &rest args &key from-end test test-not start end count key &environment env)
(declare (ignore from-end test test-not start end count key))
(multiple-value-bind (vars vals store-vars writer-form reader-form)
(get-setf-expansion place env)
(assert (length= store-vars 1) ()
"removef only supports single-value places")
(let ((v.args (make-gensym-list (length args)))
(store-var (first store-vars)))
(once-only (item)
`(let* (,#(mapcar #'(lambda (var val)
`(,var ,val))
vars vals)
,#(mapcar #'(lambda (v.arg arg)
`(,v.arg ,arg))
v.args args)
(,store-var (remove ,item ,reader-form ,#v.args)))
,writer-form)))))
The utilities length= , make-gensym-list and once-only are available at Project Alexandria.
BTW exists at Alexandria a removef definition that uses define-modify-macro but requires an auxiliary definition. This version does not requires an auxiliary defintion.

What determines when a collection is created?

If I understand correctly Clojure can return lists (as in other Lisps) but also vectors and sets.
What I don't really get is why there's not always a collection that is returned.
For example if I take the following code:
(loop [x 128]
(when (> x 1)
(println x)
(recur (/ x 2))))
It does print 128 64 32 16 8 4 2. But that's only because println is called and println has the side-effect (?) of printing something.
So I tried replacing it with this (removing the println):
(loop [x 128]
(when (> x 1)
x
(recur (/ x 2))))
And I was expecting to get some collecting (supposedly a list), like this:
(128 64 32 16 8 4 2)
but instead I'm getting nil.
I don't understand which determines what creates a collection and what doesn't and how you switch from one to the other. Also, seen that Clojure somehow encourages a "functional" way of programming, aren't you supposed to nearly always return collections?
Why are so many functions that apparently do not return any collection? And what would be an idiomatic way to make these return collections?
For example, how would I solve the above problem by first constructing a collection and then iterating (?) in an idiomatic way other the resulting list/vector?
First I don't know how to transform the loop so that it produces something else than nil and then I tried the following:
(reduce println '(1 2 3))
But it prints "1 2nil 3nil" instead of the "1 2 3nil" I was expecting.
I realize this is basic stuff but I'm just starting and I'm obviously missing basic stuff here.
(P.S.: retag appropriately, I don't know which terms I should use here)
A few other comments have pointed out that when doesn't really work like if - but I don't think that's really your question.
The loop and recur forms create an iteration - like a for loop in other languages. In this case, when you are printing, it is indeed just for the side effects. If you want to return a sequence, then you'll need to build one:
(loop [x 128
acc []]
(if (< x 1)
acc
(recur (/ x 2)
(cons x acc))))
=> (1 2 4 8 16 32 64 128)
In this case, I replaced the spot where you were calling printf with a recur and a form that adds x to the front of that accumulator. In the case that x is less than 1, the code returns the accumulator - and thus a sequence. If you want to add to the end of the vector instead of the front, change it to conj:
(loop [x 128
acc []]
(if (< x 1)
acc
(recur (/ x 2)
(conj acc x))))
=> [128 64 32 16 8 4 2 1]
You were getting nil because that was the result of your expression -- what the final println returned.
Does all this make sense?
reduce is not quite the same thing -- it is used to reduce a list by repeatedly applying a binary function (a function that takes 2 arguments) to either an initial value and the first element of a sequence, or the first two elements of the sequence for the first iteration, then subsequent iterations are passed the result of the previous iteration and the next value from the sequence. Some examples may help:
(reduce + [1 2 3 4])
10
This executes the following:
(+ 1 2) => 3
(+ 3 3) => 6
(+ 6 4) => 10
Reduce will result in whatever the final result is from the binary function being executed -- in this case we're reducing the numbers in the sequence into the sum of all the elements.
You can also supply an initial value:
(reduce + 5 [1 2 3 4])
15
Which executes the following:
(+ 5 1) => 6
(+ 6 2) => 8
(+ 8 3) => 11
(+ 11 4) => 15
HTH,
Kyle
The generalized abstraction over collection is called a sequence in Clojure and many data structure implement this abstraction so that you can use all sequence related operations on those data structure without thinking about which data structure is being passed to your function(s).
As far as the sample code is concerned - the loop, recur is for recursion - so basically any problem that you want to solve using recursion can be solved using it, classic example being factorial. Although you can create a vector/list using loop - by using the accumulator as a vector and keep appending items to it and in the exist condition of recursion returning the accumulated vector - but you can use reductions and take-while functions to do so as shown below. This will return a lazy sequence.
Ex:
(take-while #(> % 1) (reductions (fn [s _] (/ s 2)) 128 (range)))

Resources