|
|
re: matrix operations
Barry Margolin wrote:
> Zachary Turner <ztur...@bindview.com> wrote:
> >I've got a 3x3 matrix, stored as ((r1c1 r1c2 r1c3) (r2c1 r2c2 r2c3) (r3c1
> >r3c2 r3c3)). I want to check if any of the columns have the same three
> >elements. It's easy for rows, I can just use
> >(or
> > (every #'equal (car matrix))
> > (every #'equal (cadr matrix))
> > (every #'equal (caddr matrix)))
>
> Actually, that doesn't work. EVERY passes a single element to the test
> function, but EQUAL requires two arguments. What you need is:
>
> (or (every #'(lambda (x) (equal x (caar matrix)))
> (cdar matrix))
> (every #'(lambda (x) (equal x (caadr matrix)))
> (cdadr matrix))
> (every #'(lambda (x) (equal x (caaddr matrix)))
> (cdaddr matrix)))
That's hideous.
>
> >My questions are:
> >a) Can I do this more elegantly using a mapxxx function?
>
> (defun (all-elements-equal (list)
> (destructuring-bind (head . tail) list
> (every #'(lambda (x) (equal x head))
> tail))))
Racket:
(define (all-elements-equal elements)
(define head (first elements))
(andmap (curry equal? head) (rest elements)))
>
> (defun any-rows-equal (matrix)
> (any #'all-elements-equal matrix))
(define (any-row-uniform matrix)
(ormap all-elements-equal matrix))
>
> >b) How can I check columns using one of the map functions? It seems like
> >there should be a way using mapcar since it pulls elements from each list
> >and applies a function to each of them, but I don't know how to or the
> >results together. Or maybe there's even a better way that I'm not aware of.
>
> Well, here's a solution similar to my first rewrite:
>
> (or (every #'(lambda (x) (equal x (caar matrix)))
> (mapcar #'car (cdr matrix)))
> (every #'(lambda (x) (equal x (cadar matrix)))
> (mapcar #'cadr (cdr matrix)))
> (every #'(lambda (x) (equal x (caddar matrix)))
> (mapcar #'caddr (cdr matrix))))
(define (any-column-uniform matrix)
(apply ormap (compose all-elements-equal list) matrix))
|
|
0
|
|
|
|
Reply
|
w_a_x_man (2778)
|
6/1/2012 4:16:05 AM |
|
Why so complicates?
CL-USER> (defparameter matr1 #(#(1 2 3) #(2 3 4) #(5 6 7)))
MATR1
CL-USER> (defparameter matr2 #(#(1 2 3) #(2 3 4) #(5 6 7)))
MATR2
CL-USER> (equalp matr1 matr2)
T
CL-USER> (defparameter matr2 #(#(1 2 3) #(2 3 4) #(5 6 8)))
MATR2
CL-USER> (equalp matr1 matr2)
NIL
On 06/01/2012 06:16 AM, WJ wrote:
> Barry Margolin wrote:
>
>> Zachary Turner<ztur...@bindview.com> wrote:
>>> I've got a 3x3 matrix, stored as ((r1c1 r1c2 r1c3) (r2c1 r2c2 r2c3) (r3c1
>>> r3c2 r3c3)). I want to check if any of the columns have the same three
>>> elements. It's easy for rows, I can just use
>>> (or
>>> (every #'equal (car matrix))
>>> (every #'equal (cadr matrix))
>>> (every #'equal (caddr matrix)))
>>
>> Actually, that doesn't work. EVERY passes a single element to the test
>> function, but EQUAL requires two arguments. What you need is:
>>
>> (or (every #'(lambda (x) (equal x (caar matrix)))
>> (cdar matrix))
>> (every #'(lambda (x) (equal x (caadr matrix)))
>> (cdadr matrix))
>> (every #'(lambda (x) (equal x (caaddr matrix)))
>> (cdaddr matrix)))
>
> That's hideous.
>
>>
>>> My questions are:
>>> a) Can I do this more elegantly using a mapxxx function?
>>
>> (defun (all-elements-equal (list)
>> (destructuring-bind (head . tail) list
>> (every #'(lambda (x) (equal x head))
>> tail))))
>
> Racket:
>
> (define (all-elements-equal elements)
> (define head (first elements))
> (andmap (curry equal? head) (rest elements)))
>
>
>>
>> (defun any-rows-equal (matrix)
>> (any #'all-elements-equal matrix))
>
>
> (define (any-row-uniform matrix)
> (ormap all-elements-equal matrix))
>
>
>>
>>> b) How can I check columns using one of the map functions? It seems like
>>> there should be a way using mapcar since it pulls elements from each list
>>> and applies a function to each of them, but I don't know how to or the
>>> results together. Or maybe there's even a better way that I'm not aware of.
>>
>> Well, here's a solution similar to my first rewrite:
>>
>> (or (every #'(lambda (x) (equal x (caar matrix)))
>> (mapcar #'car (cdr matrix)))
>> (every #'(lambda (x) (equal x (cadar matrix)))
>> (mapcar #'cadr (cdr matrix)))
>> (every #'(lambda (x) (equal x (caddar matrix)))
>> (mapcar #'caddr (cdr matrix))))
>
>
> (define (any-column-uniform matrix)
> (apply ormap (compose all-elements-equal list) matrix))
|
|
0
|
|
|
|
Reply
|
jpthing (785)
|
6/8/2012 9:24:42 PM
|
|
John Thingstad <jpthing@online.no> writes:
> Why so complicates?
> CL-USER> (defparameter matr1 #(#(1 2 3) #(2 3 4) #(5 6 7)))
> MATR1
> CL-USER> (defparameter matr2 #(#(1 2 3) #(2 3 4) #(5 6 7)))
> MATR2
> CL-USER> (equalp matr1 matr2)
> T
> CL-USER> (defparameter matr2 #(#(1 2 3) #(2 3 4) #(5 6 8)))
> MATR2
> CL-USER> (equalp matr1 matr2)
> NIL
The OP asked for 3x3 matrices, not for vectors of vectors.
This is not C!
Those variables are special but you didn't earmuff them.
(defparameter *mat1* #2A((1 2 3) (4 5 6) (7 8 9)))
(defparameter *mat2* #2A((1 2 3) (4 5 6) (7 8 9)))
(equalp *mat1* *mat2*) --> T
Now, as for why one would want to write his own matrix equal operator:
(defparameter *mat1* #2A((#\D #\A) ("N" "G") (1.0 2.0))
(defparameter *mat2* #2A((#\D #\A) ("N" "G") (1 2))
(defparameter *mat3* #2A((#\d #\a) ("n" "g") (1.0 2))
(equalp *mat1* *mat2*) --> T
(equalp *mat1* *mat3*) --> T ; !
(equal *mat1* *mat2*) --> NIL ; !
(equal *mat1* *mat3*) --> NIL
(defun array-equal-p (a1 a2)
"RETURN: A1 and A2 have the same dimensions and their elements in the
same position are equal."
(and (equal (array-dimensions a1) (array-dimensions a2))
(loop
:for i :below (array-total-size a1)
:always (if (and (numberp (row-major-aref a1 i)) (numberp (row-major-aref a2 i)))
(= (row-major-aref a1 i) (row-major-aref a2 i))
(equal (row-major-aref a1 i) (row-major-aref a2 i))))))
(array-equal-p *mat1* *mat2*) --> T
(array-equal-p *mat1* *mat3*) --> NIL
Notice it also works on tensors, and other higher dimensions arrays:
(array-equal-p #3A(((1 2) (3 4)) (("five" "six") (7 9)))
#3A(((1.0 2.0) (3 4)) (("five" "six") (7 9)))) --> T
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
|
|
0
|
|
|
|
Reply
|
pjb (7645)
|
6/9/2012 1:33:08 AM
|
|
|
2 Replies
31 Views
(page loaded in 0.064 seconds)
Similiar Articles:9/11/2012 3:28:04 AM
|
|
|
|
|
|
|
|
|