需要有关如何在lisp中打印矩阵的建议

1 lisp printing opencv common-lisp cffi

如果我这样做,我有一个矩阵定义

(format t "~a" (get-real-2d 0 0))
Run Code Online (Sandbox Code Playgroud)

它打印出第一行第一列中的元素

如果我这样做

(format t "~a" (get-real-2d a 0 1))
Run Code Online (Sandbox Code Playgroud)

它打印出第一行第二列中的元素

如果我这样做

(format t "~a" (get-real-2d a 1 0))
Run Code Online (Sandbox Code Playgroud)

它打印出第二行第一列中的元素.

矩阵a看起来像这样

a =
((0 1 2)
(3 4 5)
(6 7 8))
Run Code Online (Sandbox Code Playgroud)

我希望你能告诉我如何写一个dotimes循环或其他循环,尽可能少的行将使用get-real-2d函数打印矩阵,所以输出如下所示:

0 1 2 
3 4 5
6 7 8
Run Code Online (Sandbox Code Playgroud)

我只是希望你能给我看一个非常小的光滑循环,我可以用来打印矩阵,我可以在我的lisp库中使用一些真正专业的东西,比如只使用变量的矩阵.就像是:

(format t "~a" (get-real-2d i j))
Run Code Online (Sandbox Code Playgroud)

而不是一堆:

(format t "~a" (get-real-2d 0 0))
(format t "~a" (get-real-2d 0 1))
(format t "~a" (get-real-2d 0 2))
Run Code Online (Sandbox Code Playgroud)

;;;;最新的编辑;;; 我打电话给这个简单

(defparameter a (create-mat 3 3 +32fc1+))
Run Code Online (Sandbox Code Playgroud)

创建一个3x3矩阵 - create-mat是opencv的cvCreateMat的包装器

repl中该命令的输出是

(defparameter a (create-mat 3 3 +32fc1+))
A
CL-OPENCV> a
#.(SB-SYS:INT-SAP #X7FFFD8000E00)
Run Code Online (Sandbox Code Playgroud)

i/e变量a是指向3x3矩阵的指针

然后我跑了

(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)))
Run Code Online (Sandbox Code Playgroud)

为矩阵创建数据 - 我接下来将分配给矩阵

repl中该命令的输出是

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)
Run Code Online (Sandbox Code Playgroud)

i/e变量a是数据指针,指向添加到矩阵的数据

然后我打电话..

(set-data a data 12) to add the data to the matrix - set-data is a wrapper for opencv's cvSetData
Run Code Online (Sandbox Code Playgroud)

所以现在当我运行 - (get-real-2d是opencv的cvGetReal2d的包装器)

(get-real-2d a 0 0)  it gets the element of matrix a at row 0 col 0 which is 0.0d0
Run Code Online (Sandbox Code Playgroud)

repl中该命令的输出是

CL-OPENCV> (get-real-2d a 0 0)
0.0d0
Run Code Online (Sandbox Code Playgroud)

而现在我跑的时候

(get-real-2d a 0 1)  it gets the element of matrix a at row 0 col 1 which is is 0.0d0
Run Code Online (Sandbox Code Playgroud)

repl中该命令的输出是

CL-OPENCV> (get-real-2d a 0 1)
1.0d0
Run Code Online (Sandbox Code Playgroud)

当我运行这个循环

 (dotimes (i 3)
  (dotimes (j 3)
(format t "~a~%" (get-real-2d a i j))))
Run Code Online (Sandbox Code Playgroud)

repl中该命令的输出是

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
Run Code Online (Sandbox Code Playgroud)

但是当我尝试你的方法@Svante

(dotimes (i 3)
  (dotimes (j 3)
(format t "~{~{~a~^ ~}~%~}" (get-real-2d a i j))))
Run Code Online (Sandbox Code Playgroud)

我收到错误:

The value 0.0d0 is not of type LIST.
    [Condition of type TYPE-ERROR]
Run Code Online (Sandbox Code Playgroud)

因为1-run-real-2d的输出只是1个浮点数i/e

CL-OPENCV> (get-real-2d a 0 0)
0.0d0
Run Code Online (Sandbox Code Playgroud)

有了这些信息,你可以帮我打印矩阵,看起来像这样

0.0d0 1.0d0 2.0d0 
3.0d0 4.0d0 5.0d0
6.0d0 7.0d0 8.0d0
Run Code Online (Sandbox Code Playgroud)

Sva*_*nte 5

您可以直接在format指令中执行此操作.格式指令~{~}下降到列表结构中.

(format t "~{~{~a~^ ~}~%~}" matrix)
Run Code Online (Sandbox Code Playgroud)

~{ ~}在矩阵的第一级上面的外部循环对,以便内部的指令一次看到一行.~{ ~}每对这样的行上面的内部循环对,以便内部的指令一次看到一个元素. ~A打印该元素.之间的部分~^~}被印刷的仅循环体的执行之间,而不是在端. ~%发出一个#\Newline.

按要求编辑

请注意,~{ ~}替换循环,我命名变量matrix,而不是element.你需要将整个矩阵放在那里,它应该是嵌套列表的形式.我从你的陈述中推断出这a一点((0 1 2) (3 4 5) (6 7 8)).所以,(format t "~{~{~a~^ ~}~%~}" a).

如果矩阵不是以嵌套列表的形式而是某种类型的数组,那么你真的需要遍历索引.首先,嵌套dotimes表格应该足够了:

(fresh-line)
(dotimes (i (array-dimension array 0))
  (dotimes (j (array-dimension array 1))
    (format t "~a " (aref array i j)))
  (terpri))
Run Code Online (Sandbox Code Playgroud)

我不知道你的矩阵是如何映射到阵列,所以你将不得不更换array-dimension,并aref与你的版本.