From: CoRey
Subject: Upper/Lower Triangular Matrix-P?
Date: 
Message-ID: <6dqseb$5hk$1@news.uta.edu>
Greetings.  I have recently come to appreciate Lisp (CL in
particular), but in having come from a C background, I feel as
if that is holding me back.

To become more fluent, I have been writing some simple matrix
functions based on 2-dimensional lisp arrays (I have another package
called "QuickArrays" which represents arrays as vectors of vectors..
but changing that part of the program is trivial--the names of the
functions are the same, in most cases, except they are prefixed with
'q').  I have addition, multiplication, transpose, symmetric-p, minor
down, but I am having particular difficulty with the upper/lower
triangular-p functions, which I thought would be trivial..

The following is what I have at this point.  I find that no
matter what type of matrix I give this function, it always
returns t; I changed the last form to (return 'foo) and
it always returns foo, etc.  Perhaps because of a C-oriented
mindset, I am trying to do something which has no equivalent
in Lisp.  As soon as I find an element that is not 0 that
is in the upper/lower triangular part of the matrix, I wish
the function to return nil immediately, without even considering
other entires in the 'triangle'.  I realize I could create a
boolean with let in order to see if any non-zero elements 
were found in the triangle, but I think that is a losing solution.

Maybe this could be done better with loop? Alas, I haven't
mastered the intricacies of loop yet.. 

I tried modifying the following using tagbody, go, and lables,
but I had difficulty even getting it to compile...  

This is not homework for me, I just got interested in this
as I am in a Differential Equations/Linear Algebra class, and
thought it would be elucidatory to try and come up with a symbolic
math system on my own.  (I think I figured out the algorithm for
Gaussian elimination and Gauss-Jordan elmination, but I haven't
taken a stab at coding that yet).  

I looked around on the net and the various Lisp archives, but didn't
find any matrix code anywhere; surely someone has done this.  I have a
stripped down version of MACSYMA that came from Peter Norvig's book
too - I always was curious as to how calculus-type programs work; but
it contains no matrix code.  Is there a more comprehensive version of
this package that works under CL (I realize it started with MACLISP, I
have a TOPS20 account, but I am not really interested in MACLISP --
I have enough problems learning CL without having to know all the
weird LISP dialects at this point).
Maybe I can find a version of 'REDUCE' for CL also.

Please reply to ·······@omega.uta.edu.  When I get a working
version and figure this out, maybe I'll post the solution.  I'm
sure other people don't want to see this group clogged up with 
such simple problems!

; BROKEN
(defun mat-upper-triangular (a)
 (block nil
  (dotimes (i (array-dimension a 0))
   (dotimes (j (array-dimension a 1))
    (when (< i j) 
      (format t "~A, ~A: ~A~%" i j (aref a i j))
      (if (not (equal (aref a i j) 0))
	(return nil)))))
  (return t)))
;; always does the last (return t), even if return nil evals!

; example
(mat-upper-triangular #2A((1 0 0) (1 1 0) (1 1 1)))
> T

(mat-upper-triangular #2A((1 0 0) (1 1 1) (1 1 1)))
> T
;; shouldn't return T!!!

From: Paul Meurer
Subject: Re: Upper/Lower Triangular Matrix-P?
Date: 
Message-ID: <350121a7.862375@nntp.uib.no>
>The following is what I have at this point.  I find that no
>matter what type of matrix I give this function, it always
>returns t; I changed the last form to (return 'foo) and
>it always returns foo, etc.  Perhaps because of a C-oriented
>mindset, I am trying to do something which has no equivalent
>in Lisp.  As soon as I find an element that is not 0 that
>is in the upper/lower triangular part of the matrix, I wish
>the function to return nil immediately, without even considering
>other entires in the 'triangle'. 
>
>; BROKEN
>(defun mat-upper-triangular (a)
> (block nil
>  (dotimes (i (array-dimension a 0))
>   (dotimes (j (array-dimension a 1))
>    (when (< i j) 
>      (format t "~A, ~A: ~A~%" i j (aref a i j))
>      (if (not (equal (aref a i j) 0))
>	(return nil)))))
>  (return t)))
>;; always does the last (return t), even if return nil evals!
>
>; example
>(mat-upper-triangular #2A((1 0 0) (1 1 0) (1 1 1)))
>> T
>
>(mat-upper-triangular #2A((1 0 0) (1 1 1) (1 1 1)))
>> T
>;; shouldn't return T!!!

Hi.

The problem with your code is that return makes you jump out only from
the innermost block, which is the implicit block created by dotimes.
A slight variant of your code (with a named block) works:

(defun mat-upper-triangular (a)
 (block jump-out
  (dotimes (i (array-dimension a 0))
   (dotimes (j (array-dimension a 1))
    (when (< i j) 
      (format t "~A, ~A: ~A~%" i j (aref a i j))
      (when (/= (aref a i j) 0)
	(return-from jump-out nil)))))
  (return-from jump-out t)))

CL-USER 5 > (mat-upper-triangular #2A((1 0 0) (1 1 1) (1 1 1)))
0, 1: 0
0, 2: 0
1, 2: 1
NIL 

You see this implicit block created by dotimes if you evaluate e.g.

CL-USER 6 > (macroexpand '(dotimes (i 10) (print i)))
(BLOCK NIL (LET* ((#:DOTIMES-COUNTER114 10) (I 0)) (DECLARE) (TAGBODY
#:DO-LOOP-START115 (WHEN (>= I #:DOTIMES-COUNTER114) (RETURN-FROM NIL
(PROGN NIL))) (PRINT I) (SETQ I (1+ I)) (GO #:DO-LOOP-START115))))
T

Paul

Paul Meurer
Humanities Information Technology Research Programme
University of Bergen
All�gaten 27
N-5007 Bergen
Norway
From: Erik Naggum
Subject: Re: Upper/Lower Triangular Matrix-P?
Date: 
Message-ID: <3098261354783105@naggum.no>
* ·······@omega.uta.edu (CoRey)
| ; BROKEN
| (defun mat-upper-triangular (a)
|  (block nil
|   (dotimes (i (array-dimension a 0))
|    (dotimes (j (array-dimension a 1))
|     (when (< i j) 
|       (format t "~A, ~A: ~A~%" i j (aref a i j))
|       (if (not (equal (aref a i j) 0))
| 	(return nil)))))
|   (return t)))
| ;; always does the last (return t), even if return nil evals!

  it appears that you think you need the BLOCK named NIL to use RETURN.
  this is not so.  instead of RETURN, use RETURN-FROM, and exploit the fact
  that DEFUN creates a block with the same name as the function.

(defun mat-upper-triangular (a)
  (dotimes (i (array-dimension a 0))
    (dotimes (j (array-dimension a 1))
      (when (< i j) 
	(format t "~A, ~A: ~A~%" i j (aref a i j))
	(unless (zerop (aref a i j))
	  (return-from mat-upper-triangular nil)))))
  t)

#:Erik
-- 
  God grant me serenity to accept the code I cannot change,
  courage to change the code I can, and wisdom to know the difference.