问题描述
4.3.3迭代。 http://www.common-lisp.net/project/antik/antik/index.html rel = nofollow> Antik手册具有以下代码示例:
4.3.3 Iterate of the Antik manual has this code example:
(defparameter m1 #m(1 2 3 ^ 0 6 8))
(iter:iter (iter:for e :matrix-element m1) (princ e) (princ " "))
;Output:
1.0 2.0 3.0 0.0 0.0 6.0 8.0
第1行第0列中的元素似乎要重复。这是故障还是有原因?
在Emacs中运行代码时,我得到类似的结果,但在他们的邮件列表中找不到信息,也找不到Google的原因。
对此的答案将帮助其他尝试迭代矩阵和向量元素的人。
The element in Row 1 Column 0 Seems to be repeated. Is this a glitch or is there a reason for it?I get similar results running the code in Emacs and I can't find info on their mailing list or searching Google for a reason.An answer to this would help others attempting to iterate over the elements of matrices and vectors.
推荐答案
注意:我花了一些时间才能从REPL的文档中运行示例。 reader宏的行分隔符是符号 grid:^
,因此代码示例实际上是:
Note: It took me a few moments to be able to run the example from the documentation at the REPL. The row separator for the reader macro is the symbol grid:^
, so the code example is actually:
(defparameter m1 #m(1 2 3 grid:^ 0 6 8))
(iter:iter (iter:for e :matrix-element m1) (princ e) (princ " "))
#m
reader宏似乎创建了预期的网格。
The #m
reader macro seems to create the kind of grid that would be expected.
CL-USER> m1
#2A((1.0 2.0 3.0) (0.0 6.0 8.0))
所以似乎任何问题都可能来自对Iterate的扩展的实现。我们可以对第二种形式进行宏扩展,看看它变成了什么,然后尝试找出是否有问题。
so it seems like any problem is probably coming from the implementation of the extension to Iterate. We can macroexpand the second form and see what it's being turned into, and try to figure out whether something has gone awry.
CL-USER> (macroexpand '(iter:iter (iter:for e :matrix-element m1) (princ e) (princ " ")))
(LET* ((#:M1182 M1) ; grid
(#:ROW-INDEX1178 0) ; i
(#:COL-INDEX1179 0) ; j
(#:ROW-SIZE1180 (FIRST (GRID:DIMENSIONS #:M1182))) ; nrows
(#:COL-SIZE1181 (SECOND (GRID:DIMENSIONS #:M1182))) ; ncols
(E NIL))
(BLOCK NIL
(TAGBODY
(PROGN)
LOOP-TOP-NIL
(PROGN
(PROGN
(SETQ E
(IF (>= #:ROW-INDEX1178 #:ROW-SIZE1180) ; if done with rows
(GO LOOP-END-NIL) ; then then the loop
(IF (>= #:COL-INDEX1179 #:COL-SIZE1181) ; else if done with the columns
(PROGN
(SETQ #:COL-INDEX1179 0) ; reset j = 0 for next row
(LET* ((#:G1184 1)
(#:NEW1183 (+ #:ROW-INDEX1178 #:G1184))) ; next row, i++
(SETQ #:ROW-INDEX1178 #:NEW1183))
(IF (>= #:ROW-INDEX1178 #:ROW-SIZE1180) ; if *now* done with rows
(GO LOOP-END-NIL) ; end the loop,
(GRID:AREF #:M1182 #:ROW-INDEX1178 ; otherwise E
#:COL-INDEX1179))) ; E = grid[i][0] (why?)
; shouldn't we (go loop-top-nil) ?
(PROG1 ; otherwise, not done with columns
(GRID:AREF #:M1182 #:ROW-INDEX1178 #:COL-INDEX1179) ; E = grid[i][j]
(LET* ((#:G1186 1)
(#:NEW1185 (+ #:COL-INDEX1179 #:G1186)))
(SETQ #:COL-INDEX1179 #:NEW1185))))))) ; j++
(PRINC E)
(PRINC " "))
(PROGN)
(GO LOOP-TOP-NIL)
LOOP-END-NIL
(PROGN))
NIL))
实际上看起来非常像迭代时到达一行的末尾,还有更多的行要走,而不是仅仅增加行计数器并将列计数器设置为零(对于下一行)并返回到循环的顶部,执行循环主体再次使用该行最后一列中的元素。看了这个扩展之后,我们可以通过尝试一些不同的网格来检验这个假设:
It actually looks very much like when the iteration gets to the end of a row and there are still more rows to go, rather than just incrementing the row counter and setting the column counter to zero (for the next row) and going back to the top of the loop, executes the loop body again with the element in the last column of the row. Having looked at this expansion, we can test this hypothesis by trying with some different grids:
CL-USER> (iter:iter (iter:for e :matrix-element #m(1 2 grid:^ 3 4 grid:^ 5 6)) (princ e) (princ " "))
1.0 2.0 3.0 3.0 4.0 5.0 5.0 6.0
CL-USER> (iter:iter (iter:for e :matrix-element #m(1 grid:^ 2 grid:^ 3)) (princ e) (princ " "))
1.0 2.0 2.0 3.0 3.0
对我来说这似乎是个错误。
This looks like a bug to me.
我刚从Antik-devel列表中收到一封电子邮件,指出该错误已得到修复:
I just received email from the Antik-devel list that the bug has been fixed:
这篇关于Antik迭代扩展在迭代中重复矩阵元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!