How do i print out all the elements in a N-D matrix?

Discussion of Common Lisp

How do i print out all the elements in a N-D matrix?

Postby joeish80829 » Tue Oct 01, 2013 1:20 am

How do i print out all the elements in a N-Dimensional matrix sequentially in Lisp/CFFI?


;all the code here except for princ and dotimes is either lisp wrappers for opencv or cffi

for example I can print a 3d matrix with this btw way i'm trying to make the print-nd-matrix (hypothetical) function just like the below function except for upping the dimensions to infinite:

(defun print-3d-matrix (matrix dim-i dim-j dim-k)
(dotimes (i dim-i)
(dotimes (j dim-j)
(dotimes (k dim-k)
(princ (get-real-3d matrix i j k))
(princ #\Space))
(princ #\Newline))
(princ #\Newline)))

but the variation for a n-dimensional matrix....a matrix with infinite dimensions

would include

a new "get-element function" in the above code I use get-real-3d which takes the two to set up

;;; this makes a pointer for the number of matrix elements i/e it makes it a 5x5x5 matrix - a 3-d matrix

(sizes (cffi:foreign-alloc :int :initial-contents
(list 5 5 5)))

;;this creates the matrix using sizes to set the matrix number of matrix elements
;;3 is the part that actually sets the matrix dimensions which here is 3

(mat (create-mat-nd 3 sizes +8uc1+))

for a n-dimensional matrix i would need to create the matrix the same way as above but for testing lets make a 5x5x5x5x5 matrix so:

(sizes (cffi:foreign-alloc :int :initial-contents
(list 5 5 5 5 5)))
(mat (create-mat-nd 5 sizes +8uc1+))

so to change the print-3d-matrix function above for the first line of it i would do

(defun print-nd-matrix (matrix indices)

indices is a variable for the get-real-nd function I'll need to use instead of the above get-real-3d it is a wrapper for the opencv function cvGetRealND here http://docs.opencv.org/modules/core/doc ... int*%20idx):
enter code here
it equal to this

(indices (cffi:foreign-alloc :int :initial-contents
'(0 0 0 0 0)))


and the get-real-nd function looks like this:

(get-real-nd mat indices)

so if i use

(get-real-nd mat indices)

it retrieves the element at 0x0x0x0x0 of the matrix "mat"

so if some one were to run my hypothetical print-nd-matrix function the first parameter would be mat and the second would be indices

so to change the print-3d-matrix function above for the next 3 lines of it i would do

(dotimes (i dim-i)
(dotimes (j dim-j)
(dotimes (k dim-k)

for dim-i,j,k so far i know i can use this:

(loop for i from 0 below 5
collect (cffi:mem-aref indices :int i))

whech dereferences the indice pointer and outputs this:

(0 0 0 0 0)

a list of 5 elements ...I can do

(length (loop for i from 0 below 5
collect (cffi:mem-aref indices :int i)))

which gives me length of list which id

5

but how wouuld i write a funtion that would "write itself" by creating the right amount of dotimes loops and nesting them properly along with adding the

(princ #\Space))
(princ #\Newline)
(princ #\Newline)

all in the right places for each one or is that not the right way to go....I would like it similiar to the print-3d-matrix for looks but it doesnt really matter because it will be buried in my library source code

If anyone can help me inerate over the elements of a n-dimensional matrix so the (princ) output is basic and looks like this (the below is 3d -matrix contents translated would be n(ulimited)-dimensions).....I would really appreciate it..

*3D Matrix Contents*

1.0d0 2.0d0 3.0d0 4.0d0 5.0d0
6.0d0 7.0d0 8.0d0 9.0d0 10.0d0
11.0d0 12.0d0 13.0d0 14.0d0 15.0d0
16.0d0 17.0d0 18.0d0 19.0d0 20.0d0
21.0d0 22.0d0 23.0d0 24.0d0 25.0d0

26.0d0 27.0d0 28.0d0 29.0d0 30.0d0
31.0d0 32.0d0 33.0d0 34.0d0 35.0d0
36.0d0 37.0d0 38.0d0 39.0d0 40.0d0
41.0d0 42.0d0 43.0d0 44.0d0 45.0d0
46.0d0 47.0d0 48.0d0 49.0d0 50.0d0

51.0d0 52.0d0 53.0d0 54.0d0 55.0d0
56.0d0 57.0d0 58.0d0 59.0d0 60.0d0
61.0d0 62.0d0 63.0d0 64.0d0 65.0d0
66.0d0 67.0d0 68.0d0 69.0d0 70.0d0
71.0d0 72.0d0 73.0d0 74.0d0 75.0d0

76.0d0 77.0d0 78.0d0 79.0d0 80.0d0
81.0d0 82.0d0 83.0d0 84.0d0 85.0d0
86.0d0 87.0d0 88.0d0 89.0d0 90.0d0
91.0d0 92.0d0 93.0d0 94.0d0 95.0d0
96.0d0 97.0d0 98.0d0 99.0d0 100.0d0

101.0d0 102.0d0 103.0d0 104.0d0 105.0d0
106.0d0 107.0d0 108.0d0 109.0d0 110.0d0
111.0d0 112.0d0 113.0d0 114.0d0 115.0d0
116.0d0 117.0d0 118.0d0 119.0d0 120.0d0
121.0d0 122.0d0 123.0d0 124.0d0 125.0d0

*3D Matrix Contents*
joeish80829
 
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

Re: How do i print out all the elements in a N-D matrix?

Postby Goheeca » Tue Oct 01, 2013 5:20 am

First of all you mean tensors ...
Here is a general printing function:
Code: Select all
(defun print-tensor (tensor dims access-fn format-element format-strings
                     &aux (indices (make-list (length dims) :initial-element 0)))
  (labels ((recurse (n)
             (loop initially (format t (first (nth n format-strings)))
                   for j below (nth n dims)
                   for inner = "" then (second (nth n format-strings))
                   do (setf (nth n indices) j)
                      (format t inner)
                   collect (if (= n (1- (length dims)))
                               (format t format-element (apply access-fn tensor indices))
                               (recurse (1+ n)))
                   finally (format t (third (nth n format-strings))))))
    (recurse 0) (values)))


Usage:
Code: Select all
(defvar *tensor*
 #3a(((1 0 0)
      (0 1 0)
      (0 0 1))
     ((2 0 0)
      (0 2 0)
      (0 0 2))
     ((3 0 0)
      (0 3 0)
      (0 0 3))))

(print-tensor *tensor* (array-dimensions *tensor*) #'aref "~a" '(("" "~&-------~%" "") ("" "~%" "") ("" " " "")))

(print-tensor *tensor* (array-dimensions *tensor*) #'aref "~a" '(("{" "~% " "}") ("[" "|" "]") ("(" "," ")")))
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version).
User avatar
Goheeca
 
Posts: 201
Joined: Thu May 10, 2012 12:54 pm

Re: How do i print out all the elements in a N-D matrix?

Postby joeish80829 » Tue Oct 01, 2013 7:22 am

Code: Select all
can you help me convert your code to use the funtions i put in my question I ould use help on the advanced stuff like that i/e conversion
i do appreciate you answering my ? btw =)
joeish80829
 
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

Re: How do i print out all the elements in a N-D matrix?

Postby Goheeca » Wed Oct 02, 2013 1:47 am

How does a get-real-nd wrapper look like? I suppose it takes a tensor and an array of indices.
Code: Select all
(defun print-opencv-tensor (tensor dimension)
  (let ((format-strings (append (loop repeat (1- dimension)
                                      collect (list "" "~%" ""))
                                (list "" " " ""))))
    (print-tensor tensor dimension
                  #'(lambda (tensor &rest indices) (get-real-nd tensor indices))
                  "~a" format-strings)))
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version).
User avatar
Goheeca
 
Posts: 201
Joined: Thu May 10, 2012 12:54 pm

Re: How do i print out all the elements in a N-D matrix?

Postby joeish80829 » Wed Oct 02, 2013 2:55 am

Thanks for getting back to me so quick your the on that answered my trackbar question so expertly and your idea worked like a charm...btw i did make an reply to that ? and if you ever got a chance to check that out that would be awesome!

but anyway=)... the get-real-nd wrapper looks like this


Code: Select all
;; double cvGetRealND(const CvArr* arr, const int* idx)
(cffi:defcfun ("cvGetRealND" get-real-nd) :double
  "Return a specific element of single-channel nD array."
  (arr cv-arr)
  (idx :pointer))


the

Code: Select all
(arr cv-arr)


part can be an image or a matrix....the opencv documentation for the opencv function is here:

http://docs.opencv.org/modules/core/doc ... #getreal-d

the

Code: Select all
(idx :pointer))


part is an array of indices defined like this

Code: Select all
(indices (cffi:foreign-alloc :int :initial-contents
                                       '(2 2 2)))


here a the function it is used in

Code: Select all
(defun set-nd-example ()
  "Set and Get Element 2x2x2 of ND-MATRIX"
  (let* ((sizes (cffi:foreign-alloc :int :initial-contents
                                         '(5 5 5)))
         (indices (cffi:foreign-alloc :int :initial-contents
                                       '(2 2 2)))
         (nd-matrix (create-mat-nd 3 sizes +32f+))
         (scalar (scalar 7)))
          (set-nd nd-matrix indices scalar)
          (format t "Element 2x2x2 of ND-MATRIX = ~a"
          (get-real-nd nd-matrix indices))
          (release-mat-nd nd-matrix)))


it basically sets the 2x2x2 element to 7 then uses get-real-nd to access it

here is a print-3d-matrix function that uses get-real-3d which behaves the same way except for 3d matrice so you can see what im after....
btw don't really understand tensors and there is nothing in the opencv documentatio about this function about or even referring to tensors

thanks for getting back to me so soon ....that was very kind and i wish you a great day =).
Last edited by joeish80829 on Wed Oct 02, 2013 7:48 am, edited 2 times in total.
joeish80829
 
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

Re: How do i print out all the elements in a N-D matrix?

Postby Goheeca » Wed Oct 02, 2013 3:38 am

joeish80829 wrote:but anyway to the get-real-nd wrapper looks like this
Code: Select all
;; double cvGetRealND(const CvArr* arr, const int* idx)
(cffi:defcfun ("cvGetRealND" get-real-nd) :double
  "Return a specific element of single-channel nD array."
  (arr cv-arr)
  (idx :pointer))

So I'd rename* it to get-real-nd% and define new function get-real-nd:
Code: Select all
(defun get-real-nd (arr indices)
  (get-real-nd% arr
               (cffi:foreign-alloc :int :initial-contents indices)))

and the aforeposted should work.
*You said that you are extending an existing binding for opencv library so adding % for a function which maps 1:1 to opencv may not be a good idea so cope with that with taking into account this.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version).
User avatar
Goheeca
 
Posts: 201
Joined: Thu May 10, 2012 12:54 pm

Re: How do i print out all the elements in a N-D matrix?

Postby joeish80829 » Wed Oct 02, 2013 5:59 am

ok i've trying your code and i really appreciate all your help on this ...you helped alot with your updated get-real-nd function i was able to make a lot of functions easier 2 use because of that (also when i call foreign-alloc in a defun how do i free the memry with foreugn free once i'm done using it) but i cant seem to get the print-tensor functions to work...i figure the below way is how i should use them

Code: Select all
(defun print-tensor (tensor dims access-fn format-element format-strings
                     &aux (indices (make-list (length dims) :initial-element 0)))
  (labels ((recurse (n)
             (loop initially (format t (first (nth n format-strings)))
                   for j below (nth n dims)
                   for inner = "" then (second (nth n format-strings))
                   do (setf (nth n indices) j)
                      (format t inner)
                   collect (if (= n (1- (length dims)))
                               (format t format-element (apply access-fn tensor indices))
                               (recurse (1+ n)))
                   finally (format t (third (nth n format-strings))))))
    (recurse 0) (values)))


(defun get-real-nd-example ()
  "Return a specific element of single-channel ND array."
  (let* ((sizes (cffi:foreign-alloc :int :initial-contents
                '(5 5 5 5 5)))
         (nd-matrix (create-mat-nd 5 sizes +32f+)))
    (set-real-nd nd-matrix '(4 4 4 4 4) 5.0d0)
    (format t "Element 4x4x4 of ND-MATRIX = ~a"
       (get-real-nd nd-matrix '(5 5 5 5 5)))
    (print-opencv-tensor1 nd-matrix (make-array 5 :initial-contents '(5 5 5 5 5)))
    (release-mat-nd nd-matrix)
    (cffi:foreign-free sizes)))





but in my get-real-nd-example funtion when i include yours if i use '( 5 5 5 5 5) for the argument to dimensions i get

Code: Select all
Argument X is not a NUMBER: (5 5 5 5 5)
   [Condition of type SIMPLE-TYPE-ERROR]


if i use 5 i get

Code: Select all
The value 5 is not of type SEQUENCE.
   [Condition of type TYPE-ERROR]


if i use (make-array 5 :initial-contents '(5 5 5 5 5)) the program hangs ......


oh and i just noticed you answered another one of my questions about printing 2d matrices and you gave me this code to use which i added to my library im building...so thanks alot! for that and i was wondering is there a way you can just update the code you provided me there to print nd matrices ....i think i understand it a bit better. i already converted it to print 3d matrices...I included it below just in case it could work... =).

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)))))
joeish80829
 
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am

Re: How do i print out all the elements in a N-D matrix?

Postby Goheeca » Fri Oct 04, 2013 5:18 am

You should write wrapping functions for freeing for each foreign object and then to write with macros for easier usage.

To the errors: It would be easier if you could provide a link to the git repository of your work, because without it I just must make a guess what's going on.

Of course, the function print-matrix could be generalized, but I'm going to merge both of them (print-tensor and print-matrix) probably, but first I want to solve your problem with errors and the best way will be access to your work on the code.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version).
User avatar
Goheeca
 
Posts: 201
Joined: Thu May 10, 2012 12:54 pm

Re: How do i print out all the elements in a N-D matrix?

Postby joeish80829 » Fri Oct 04, 2013 10:29 pm

hey...thanks for getting back to me.......I don't know how to git yet and i didnt really wanna make my work public yet but if sometime maybe you wanted to log on with teamviewer i could show you whats going on....it should be pretty easy I know the code so i could explain quicker than you having to look blindly through my code
joeish80829
 
Posts: 153
Joined: Tue Sep 03, 2013 5:32 am


Return to Common Lisp

Who is online

Users browsing this forum: No registered users and 2 guests

cron