here is more informationthe ideas you said didnt work...if this is uncouth pls ignore
to make this simple i call
(defparameter a (create-mat 3 3 +32fc1+))
to create a 3x3 matrix - create-mat is a wrapper for opencv's cvCreateMat
the output from that command at repl is
(defparameter a (create-mat 3 3 +32fc1+))
A
CL-OPENCV> a
#.(SB-SYS:INT-SAP #X7FFFD8000E00)
i/e the variable a is a pointer to the 3x3 matrix
then i run
(defparameter data (cffi:foreign-alloc :float :initial-contents
'(0.0f0 1.0f0 2.0f0 3.0f0 4.0f0 5.0f0 6.0f0 7.0f0 8.0f0)))
to create the data for the matrix - which i next will allocate to the matrix
the output from that command at repl is
CL-OPENCV> (defparameter data (cffi:foreign-alloc :float :initial-contents
'(0.0f0 1.0f0 2.0f0 3.0f0 4.0f0 5.0f0 6.0f0 7.0f0 8.0f0)))
DATA
CL-OPENCV> data
#.(SB-SYS:INT-SAP #X7FFFD8000E40)
i/e the variable a is data pointer to the data ill add to the matrix
then i call..
(set-data a data 12) to add the data to the matrix - set-data is a wrapper for opencv's cvSetData
so now when i run - (get-real-2d is a wrapper for opencv's cvGetReal2d)
(get-real-2d a 0 0) it gets the element of matrix a at row 0 col 0 which is 0.0d0
the output from that command at repl is
CL-OPENCV> (get-real-2d a 0 0)
0.0d0
and now when i run
(get-real-2d a 0 1) it gets the element of matrix a at row 0 col 1 which is is 0.0d0
the output from that command at repl is
CL-OPENCV> (get-real-2d a 0 1)
1.0d0
and when i run this loop
(dotimes (i 3)
(dotimes (j 3)
(format t "~a~%" (get-real-2d a i j))))
the output from that command at repl is
CL-OPENCV> (dotimes (i 3)
(dotimes (j 3)
(format t "~a~%" (get-real-2d a i j))))
0.0d0
1.0d0
2.0d0
3.0d0
4.0d0
5.0d0
6.0d0
7.0d0
8.0d0
NIL
but when i try this method
(dotimes (i 3)
(dotimes (j 3)
(format t "~{~{~a~^ ~}~%~}" (get-real-2d a i j))))
i get error:
The value 0.0d0 is not of type LIST.
[Condition of type TYPE-ERROR]
because the output of 1 run of get-real-2d is just a 1 number float i/e
CL-OPENCV> (get-real-2d a 0 0)
0.0d0
with that info can you help me print the matrix so it looks like this
0.0d0 1.0d0 2.0d0
3.0d0 4.0d0 5.0d0
6.0d0 7.0d0 8.0d0
need help printing matrix in lisp - rehash
-
- Posts: 153
- Joined: Tue Sep 03, 2013 5:32 am
Re: need help printing matrix in lisp - rehash
@joeish80829: Please do yourself a favour and learn how to use code tags (Outputting code or fixed width data), you probably will get more and better answers if you're not posting such a mess like your post above. Nobody wants to read unformatted source code. Thank you.
Here is an example of a CL-OPENCV floating-point matrix pretty-printer. The code is a bit antique, maybe somebody with better FORMAT-foo than me can improve it. See CLHS 22.3.3 FORMAT Floating-Point Printers for the related floating-point FORMAT directives.
To demonstrate the print-matrix function I'm using a dummy function, so I can use normal Lisp arrays:
First the example matrix from the post above:
And here a matrix with some real-world floats:
:digits n is the number of digits after the dot and :pad n is the number of horizontal space characters between the matrix elements.
Please note that the vertical alignment only works correctly with fixed-width fonts (with proportional fonts it will probably be a mess) and the print-matrix function doesn't test any of its arguments, so with wrong or nonsensical arguments it will probably end up in the debugger.
- edgar
Here is an example of a CL-OPENCV floating-point matrix pretty-printer. The code is a bit antique, maybe somebody with better FORMAT-foo than me can improve it. See CLHS 22.3.3 FORMAT Floating-Point Printers for the related floating-point FORMAT directives.
Code: Select all
(defun print-matrix (matrix rows columns &key (digits 2) (pad 1))
"Print MATRIX with padded and aligned elements."
(let ((format-string (format nil "~~,~de" digits))
(column-width (make-array columns)) ; initialized with fixnum zeros
(string-array (make-array (list rows columns) :initial-element nil)))
;; loop 1 - get the column width
(dotimes (i rows)
(dotimes (j columns)
(let ((string (format nil format-string (get-real-2d matrix i j)))
(width (aref column-width j)))
;; store the string so we don't need to FORMAT it twice
(setf (aref string-array i j) string)
;; update the column-width array
(setf (aref column-width j) (max width (length string))))))
;; loop 2 - print the matrix
(dotimes (i rows)
(dotimes (j columns)
(let ((string (aref string-array i j))
(width (aref column-width j)))
;; print the formatted matrix element
(princ string)
(if (eql j (1- columns))
;; after the last element in a row print a line-break
(terpri)
;; if not the last element print whitespace padding
(princ (make-string (+ pad (- width (length string)))
:initial-element #\Space))))))))
Code: Select all
(defun get-real-2d (array row column)
"Dummy function to access the elements of normal Lisp arrays."
(aref array row column))
Code: Select all
(defparameter a #2a((0.0d0 1.0d0 2.0d0)
(3.0d0 4.0d0 5.0d0)
(6.0d0 7.0d0 8.0d0)))
CL-USER> (print-matrix a 3 3)
0.00d+0 1.00d+0 2.00d+0
3.00d+0 4.00d+0 5.00d+0
6.00d+0 7.00d+0 8.00d+0
NIL
CL-USER> (print-matrix a 3 3 :digits 1)
0.0d+0 1.0d+0 2.0d+0
3.0d+0 4.0d+0 5.0d+0
6.0d+0 7.0d+0 8.0d+0
Code: Select all
(defparameter b #2a((3.3563d+50 6.56d+6 2.55460d-154)
(2.2542d+242 2.24542d-45 5.0d+7)
(6.34956d-3 7.43859d+245 8.3487d-38)))
CL-USER> (print-matrix b 3 3)
3.36d+50 6.56d+6 2.55d-154
2.25d+242 2.25d-45 5.00d+7
6.35d-3 7.44d+245 8.35d-38
NIL
CL-USER> (print-matrix b 3 3 :digits 5 :pad 2)
3.35630d+50 6.56000d+6 2.55460d-154
2.25420d+242 2.24542d-45 5.00000d+7
6.34956d-3 7.43859d+245 8.34870d-38
NIL
Please note that the vertical alignment only works correctly with fixed-width fonts (with proportional fonts it will probably be a mess) and the print-matrix function doesn't test any of its arguments, so with wrong or nonsensical arguments it will probably end up in the debugger.
- edgar
Re: need help printing matrix in lisp - rehash
Assuming that the alien array can only be accessed one element at a time and reading 22.3.3.2 Tilde E: Exponential Floating-Point several times again I found that if the exponent is formatted to a constant width of three digits the print-matrix function can be shortened to:
Using the same dummy function as above:
Here are the results:
- edgar
Code: Select all
(defun print-matrix (matrix rows columns &key (digits 2) (pad 1))
"Print MATRIX with padded and aligned elements."
(let ((format-string (format nil "~~,~d,3e" digits)))
(dotimes (i rows)
(dotimes (j columns)
(format t format-string (get-real-2d matrix i j))
(if (eql j (1- columns))
(terpri)
(princ (make-string pad :initial-element #\Space)))))))
Code: Select all
(defun get-real-2d (array row column)
"Dummy function to access the elements in the Lisp arrays."
(aref array row column))
Code: Select all
(defparameter a #2a((0.0d0 1.0d0 2.0d0)
(3.0d0 4.0d0 5.0d0)
(6.0d0 7.0d0 8.0d0)))
CL-USER> (print-matrix a 3 3)
0.00d+000 1.00d+000 2.00d+000
3.00d+000 4.00d+000 5.00d+000
6.00d+000 7.00d+000 8.00d+000
NIL
Code: Select all
(defparameter b #2a((3.3563d+50 6.56d+6 2.55460d-154)
(2.2542d+242 2.24542d-45 5.0d+7)
(6.34956d-3 7.43859d+245 8.3487d-38)))
CL-USER> (print-matrix b 3 3)
3.36d+050 6.56d+006 2.55d-154
2.25d+242 2.25d-045 5.00d+007
6.35d-003 7.44d+245 8.35d-038
NIL
Re: need help printing matrix in lisp - rehash
It can be improved not to generate a format string:
Code: Select all
(defun print-matrix (matrix rows columns &key (digits 2) (pad 1)
&aux (pad-string (make-string pad :initial-element #\Space)))
"Print MATRIX with padded and aligned elements."
(dotimes (i rows)
(dotimes (j columns)
(format t "~,v,3e" digits (get-real-2d matrix i j))
(if (eql j (1- columns))
(terpri)
(princ pad-string)))))
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.