Re: functional style compared to procedural style and comments on a Mathematica function I saw.
- From: "Richard J. Fateman" <fateman@xxxxxxxxxxxxxxxxx>
- Date: Mon, 22 Aug 2005 14:10:55 -0700
There is a huge "literature" on comparing functional and imperative styles and their various advantages. Mathematica is probably not the prime exemplar of functional programming though.
There is a functional programming newsgroup. There is a key interesting paper on FP by John Backus. There is also a literature on APL.
Error checking in each module may not be required if the program is going to be used in a context in which the input can only be a square matrix.
For my amusement I tried your task in Lisp.
Lisp can do this in a variety of ways, some more functional than others. You don't need Mathematica at all for this..
Assuming a matrix is represented as a list of lists (not the only way to do this, even in lisp), I could write two programs to model what Mathematica seems to do.
1. TMRD(m) ;; take a square matrix and remove its diagonal elements to produce another square matrix.
2. ZM(m) ;; return true if m is a matrix entirely of zeros.
3. The solution is then OnlyDiagonalTest(m):= ZM(TMRD(m))
(defun OnlyDiagonalTest(m)(ZM(TMRD m)))
(defun ZM(m) (every 'zerop (apply 'append m)))
(defun TMRD(r &optional (c 0)) (cond ((null r) nil) ((cons (remove-if 'identity (first r) :start c :end (1+ c)) (TMRD (rest r) (1+ c))))))
Here's another way for TMRD
(defun TMRD (let((p nil)) (dotimes (i (length m)(nreverse p)) (push (remove-if 'identity (elt m i) :start i :end (1+ i)) p))))
But this is a crappy way to do the problem.
Here's another decomposition of the problem.
Given a matrix, test row 1 and column 1 (except for element 1,1) for all zeros. If they are all zero,
recursively applying to the matrix with row and column 1 removed,
until you get to an empty matrix, which trivially has no non-zero
elements.
(defun ssz(m) ;;; return t if all sub and super diag elms are zero (cond ((null m) t) (t (and (every 'zerop (rest (first m))) ;;rest of row (every 'zerop (mapcar 'first (rest m))) ;;rest of col (ssz (mapcar 'rest (rest m)))))));; rest of submatrix
or equivalently, in old-fashioned lisp,
(defun ssz(m)
(or (null m)
(and (every 'zerop (cdar m))
(every 'zerop (mapcar 'car (cdr m)))
(ssz (mapcar 'cdr (cdr m))))))This lisp program is vastly faster than the mathematica one. The lisp program uses entirely routine syntax, and with the possible exception of the operator "every" uses programs from the first 3 weeks of an introductory lisp course. And the programmer does not have to know any precedence rules for operators.
The idea of testing to see if an nXn matrix is all zeros except on the diagonal by making another matrix without its diagonals takes space O(n^2) when it can be done in constant space. It takes O(n^2) time but any algorithm that has to check O(n^2) elements for zero must do that. The last program (ssz) takes space O(n).
The only advantage (?) for the mathematica version is shorter, about half the characters, but quite cryptic.
RJF
Nasser Abbasi wrote:
"Jon McLoone" <jonm@xxxxxxxxxxxxx> wrote in message news:1124716859.497107.15560@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Here is a version of the same code which tests for validity of input:
DiagonalQ[m_List] /; (TensorRank[m] === 2 && Apply[Equal,
Dimensions[m]]) := And @@ Flatten[MapIndexed[(#1 === 0 || Equal @@ #2)
&, m, {2}]];
<<< snip>>>
.
- Follow-Ups:
- References:
- Prev by Date: Re: a small observation on Mathematica Dimensions[]. Compare to Matlab
- Next by Date: Re: Coq + OCAML = Symbolic abstract math programs?
- Previous by thread: Re: functional style compared to procedural style and comments on a Mathematica function I saw.
- Next by thread: Re: functional style compared to procedural style and comments on a Mathematica function I saw.
- Index(es):
Relevant Pages
|