需要关于如何打印口齿不清矩阵意见(Need advice on how to print a mat

2019-10-18 15:47发布

我已经定义了一个矩阵,所以如果我这样做

(format t "~a" (get-real-2d 0 0))

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

如果我这样做

(format t "~a" (get-real-2d a 0 1))

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

如果我这样做

(format t "~a" (get-real-2d a 1 0))

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

矩阵a看起来是这样的

a =
((0 1 2)
(3 4 5)
(6 7 8))

我希望你能告诉我到底怎么写一dotimes循环或其他循环,将作为几行可能会使用打印出矩阵get-real-2d功能使输出看起来是这样的:

0 1 2 
3 4 5
6 7 8

我只是希望你能告诉我一个漂亮的循环,这将是真正的小,我可以用它来打印,我可以在我的LISP库实实在在的专业的使用,就像一个会只使用变量矩阵。 就像是:

(format t "~a" (get-real-2d i j))

而不是一堆:

(format t "~a" (get-real-2d 0 0))
(format t "~a" (get-real-2d 0 1))
(format t "~a" (get-real-2d 0 2))

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

(defparameter a (create-mat 3 3 +32fc1+))

创建一个3x3矩阵 - 创建垫是OpenCV的的cvCreateMat包装

从该命令在REPL输出是

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

I / E变量a是一个指针到3×3矩阵

然后我跑

(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)))

以创建矩阵中的数据 - 这是我接下来会分配给矩阵

从该命令在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)

I / E变量a是数据指针数据生病添加到矩阵

然后我打电话..

(set-data a data 12) to add the data to the matrix - set-data is a wrapper for opencv's cvSetData

所以现在当我运行 - (获取实时的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

从该命令在REPL输出是

CL-OPENCV> (get-real-2d a 0 0)
0.0d0

而现在,当我运行

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

从该命令在REPL输出是

CL-OPENCV> (get-real-2d a 0 1)
1.0d0

当我运行这个循环

 (dotimes (i 3)
  (dotimes (j 3)
(format t "~a~%" (get-real-2d a i j))))

从该命令在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

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

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

我得到的错误:

The value 0.0d0 is not of type LIST.
    [Condition of type TYPE-ERROR]

因为1次GET-实时2D的运行的输出仅仅是一个1号浮I / E

CL-OPENCV> (get-real-2d a 0 0)
0.0d0

与信息,你可以帮我打印矩阵,所以它看起来像这样

0.0d0 1.0d0 2.0d0 
3.0d0 4.0d0 5.0d0
6.0d0 7.0d0 8.0d0

Answer 1:

你提的问题可以从两个方面理解,这就是为什么它有两种解决方案:

  • 用于打印类型的矩阵的对象(在此情况下,它可以使用关于矩阵的内部结构的知识)定义方法:

     (defmethod print-object ((matrix matrix) stream) (format stream "~{~{~a~^ ~}~%~}" matrix)) 

    使用format为答案所示。

  • 定义可以使用对象的唯一方法客户端功能- get-real-2d

     (defun print-matrix (matrix dimension-x dimension-y) (dotimes (x dimension-x) (dotimes (y dimension-y) (princ (get-real-2d matrix xy)) (princ #\Space)) (princ #\Newline))) 

    只需使用dotimes



Answer 2:

您可以直接做format指令。 格式说明~{~}下降到一个列表结构。

(format t "~{~{~a~^ ~}~%~}" matrix)

外对~{ ~}遍历所述矩阵的第一级,因此,指示内能看到一个行一次。 内对~{ ~}遍历每个这样的行,从而使指令内能看到一个元件在一个时间。 ~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))

我不知道你的矩阵是如何映射到阵列,所以你将不得不更换array-dimensionaref与您的版本。



Answer 3:

这里只是两个dotimes循环,即你问了。 你需要注意的唯一的事情是什么时候打印空间和何时打印换行。

(dotimes (i 3)
  (dotimes (j 3)
    (princ (get-real-2d a i j))
    (if (< j 2)
      (princ #\Space)
      (terpri))))

或者,您可能要使用的format指令浮点印有总是好的列排列的数字。 您可以选择之间~F ,将永远不会打印一个指数, ~E将始终打印一个,并且~G ,根据大小的行为。 寻找细节,在这里的HyperSpec: http://www.lispworks.com/documentation/HyperSpec/Body/22_cc.htm 。

下面是一个使用的示例~F 5和1的小数数字的最大场宽度:

(dotimes (i 3)
  (dotimes (j 3)
    (format t "~5,1F" (get-real-2d a i j)))
  (terpri))


Answer 4:

这并不难,所以我宁愿把它留给你要弄清楚,但这里有一些提示,使一个“圆滑环” Lisp风格。 我建议的一个或多个实例mapc (或mapcar ),而不是dotimes 。 如果你不使用函数式编程这可能会觉得奇怪,但一旦你习惯了它,它更容易比阅读dotimes ,和你没有保持跟踪指数的,因此它可避免的错误。 你真的应该学会使用mapcar/mapc如果您不熟悉它们。 他们很酷。 或者,如果你想成为真的很酷:-)你可以使用递归遍历矩阵,但我认为,为了这个目的使用迭代mapc会更容易阅读。 (但是你应该学会做其他工作的递归的方式。如果您发现递归困惑-我没有理由认为你这样做,但有些人有麻烦了-我最喜爱的教程是小策士 。)

您可能还需要使用其他format指令,让您用空格键盘的数字,如果他们没有足够的数字。 在~%指令可能是有用的。 彼得·塞贝尔有一个非常漂亮的介绍格式 。



文章来源: Need advice on how to print a matrix in lisp