From jivestgarden at common-lisp.net Thu May 13 13:28:51 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 09:28:51 -0400 Subject: [lisplab-cvs] r154 - trunk/src/matrix Message-ID: Author: jivestgarden Date: Thu May 13 09:28:51 2010 New Revision: 154 Log: bugfix Modified: trunk/src/matrix/store-ordinary-functions.lisp Modified: trunk/src/matrix/store-ordinary-functions.lisp ============================================================================== --- trunk/src/matrix/store-ordinary-functions.lisp (original) +++ trunk/src/matrix/store-ordinary-functions.lisp Thu May 13 09:28:51 2010 @@ -210,8 +210,8 @@ ;;; Copies contents from real to complex (defun copy_dfa-to-cdfa (a out) (declare (type type-blas-store a out)) - (dotimes (i (floor (length a) 2)) + (dotimes (i (length a)) (let* ((2i (* 2 i))) (declare (type type-blas-idx i 2i)) - (setf (aref out 2i) (aref a 2i)))) + (setf (aref out 2i) (aref a i)))) out) From jivestgarden at common-lisp.net Thu May 13 13:34:29 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 09:34:29 -0400 Subject: [lisplab-cvs] r155 - trunk/src/draft Message-ID: Author: jivestgarden Date: Thu May 13 09:34:29 2010 New Revision: 155 Log: draft directory Added: trunk/src/draft/ From jivestgarden at common-lisp.net Thu May 13 13:37:34 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 09:37:34 -0400 Subject: [lisplab-cvs] r156 - in trunk/src: core draft matrix Message-ID: Author: jivestgarden Date: Thu May 13 09:37:34 2010 New Revision: 156 Log: moved unused code Added: trunk/src/draft/level2-array-functions.lisp - copied unchanged from r151, /trunk/src/matrix/level2-array-functions.lisp trunk/src/draft/template.lisp - copied unchanged from r151, /trunk/src/core/template.lisp Removed: trunk/src/core/template.lisp trunk/src/matrix/level2-array-functions.lisp From jivestgarden at common-lisp.net Thu May 13 13:39:15 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 09:39:15 -0400 Subject: [lisplab-cvs] r157 - trunk/src/core Message-ID: Author: jivestgarden Date: Thu May 13 09:39:15 2010 New Revision: 157 Log: moved unused code Removed: trunk/src/core/level0-default.lisp trunk/src/core/level0-expression.lisp From jivestgarden at common-lisp.net Thu May 13 13:39:28 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 09:39:28 -0400 Subject: [lisplab-cvs] r158 - trunk/src/draft Message-ID: Author: jivestgarden Date: Thu May 13 09:39:27 2010 New Revision: 158 Log: moved unused code Added: trunk/src/draft/level0-default.lisp - copied unchanged from r151, /trunk/src/core/level0-default.lisp trunk/src/draft/level0-expression.lisp - copied unchanged from r151, /trunk/src/core/level0-expression.lisp From jivestgarden at common-lisp.net Thu May 13 13:46:11 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 09:46:11 -0400 Subject: [lisplab-cvs] r159 - in trunk/src: core matrix Message-ID: Author: jivestgarden Date: Thu May 13 09:46:10 2010 New Revision: 159 Log: removed unused code Modified: trunk/src/core/level0-interface.lisp trunk/src/matrix/level1-constructors.lisp trunk/src/matrix/level1-ddiag.lisp trunk/src/matrix/level1-dge.lisp trunk/src/matrix/level1-dgt.lisp trunk/src/matrix/level1-ge.lisp trunk/src/matrix/level1-zge.lisp trunk/src/matrix/level2-matrix-zge.lisp Modified: trunk/src/core/level0-interface.lisp ============================================================================== --- trunk/src/core/level0-interface.lisp (original) +++ trunk/src/core/level0-interface.lisp Thu May 13 09:46:10 2010 @@ -20,15 +20,6 @@ (in-package :lisplab) -#+nil (defgeneric type-spec (object) - (:documentation "Some symbolic representation of the type.")) - -#+nil (defgeneric function-output-type-spec (fun input-spec) - (:documentation "Desides an output for the function with the given intput spec.")) - -#+nil (defgeneric operator-output-type-spec (fun input-spec1 input-spec2) - (:documentation "Desides an output for the operator with the two given inputs.")) - (defgeneric init-threads (num-threads) (:documentation "Request to use a certain number of threads for calculations.")) Modified: trunk/src/matrix/level1-constructors.lisp ============================================================================== --- trunk/src/matrix/level1-constructors.lisp (original) +++ trunk/src/matrix/level1-constructors.lisp Thu May 13 09:46:10 2010 @@ -43,110 +43,4 @@ (defmethod make-matrix-instance ((description list) dim value) (assert (= 3 (length description))) (make-matrix-instance (apply #'make-matrix-class description) - dim value)) - - - - -#| - - - -;; Hm jeg trenger ikke denne kompliserte greia for operatorer -;; Disse trenger bare virke like for like... - -;;; Rydd opp: denne finlen b?r bare ha construcucrene med spec. -;;; Fjern alt som har med spec ? gj?re andre steder.. -;;; Trenger mer generelt enn mcreate . Noe som ogs? tillater oppgradering -;;; elementer ... - -(defgeneric find-function-output-class (fun input-class)) - -(defgeneric find-operator-output-class (fun input-class1 input-class2)) - -(defgeneric find-element-type-combination-class (op element-type1 element-type2)) - -(defgeneric find-implementation-combination-class (op impl1 impl2)) - -(defgeneric find-implementation-combination-class (op structure1 structure2)) - -;;; Methods - -(defmethod find-function-output-class (fun input-class) - (make-matrix-class (find-class (element-type-class-name input-class)) - (find-class (structure-class-name input-class)) - (find-class (implementation-class-name input-class)))) - -(defmethod find-operator-output-class (fun input-class) - (make-matrix-class (find-class (element-type-class-name input-class)) - (find-class (structure-class-name input-class)) - (find-class (implementation-class-name input-class)))) - - - - - - -;; A scheme for matrix creations - -(defvar *matrix-class-to-description* (make-hash-table)) -(defvar *matrix-description-to-class* (make-hash-table :test #'equal)) - -(defun add-matrix-class (class element-type structure implementation) - (setf (gethash (list element-type structure implementation) - *matrix-description-to-class*) - class - (gethash class - *matrix-class-to-description* ) - (list element-type structure implementation))) - -(defun find-matrix-class (description) - (let* ((entry (gethash description - *matrix-description-to-class*))) - (unless entry - (error "No matrix of structure ~a." description)) - entry)) - -(defun find-matrix-description (class) - (let* ((entry (gethash class - *matrix-class-to-description*))) - (unless entry - (error "No matrix description of class ~a." class)) - entry)) - -(defun create-matrix-description (obj &key et s i) - "A simple language to modify matrix descriptions. Uses -the obejct as foundation of the description, but you can -override the description with the keywords." - (let ((d0 (find-matrix-description (class-name (class-of obj))))) - (list - (if et et (first d0)) - (if s s (second d0)) - (if i i (third d0))))) - -;;; The implementaiton of the level0 generic functions - -(defmethod type-spec ((obj matrix-base)) - (find-matrix-description (class-name (class-of obj)))) - -(defmethod function-output-type-spec (fun (input-spec list)) - ;;; A list signifies a matrix, Should be a another type of obejct at some point! - (cons (function-output-type-spec fun (car input-spec)) - (cdr input-spec))) - -(defmethod operator-output-type-spec (fun (a list) b) - ;;; A list signifies a matrix, Should be a another type of obejct at some point! - (cons (operator-output-type-spec fun (car a) b) - (cdr a))) - -(defmethod operator-output-type-spec (fun a (b list)) - ;;; A list signifies a matrix, Should be a another type of obejct at some point! - (cons (operator-output-type-spec fun a (car b)) - (cdr b))) - -(defmethod operator-output-type-spec (fun (a list) (b list)) - ;;; A list signifies a matrix, Should be a another type of obejct at some point! - ;; TODO: some better way to choose - (cons (operator-output-type-spec fun (car a) (car b)) - (cdr a))) -|# \ No newline at end of file + dim value)) \ No newline at end of file Modified: trunk/src/matrix/level1-ddiag.lisp ============================================================================== --- trunk/src/matrix/level1-ddiag.lisp (original) +++ trunk/src/matrix/level1-ddiag.lisp Thu May 13 09:46:10 2010 @@ -63,13 +63,6 @@ (defmethod make-matrix-class ((a (eql :d)) (b (eql :di)) (c (eql :any))) (find-class 'matrix-ddi)) - -;;; Add classes to the generic matrix creation scheme -#+todo-remove(add-matrix-class 'matrix-base-ddi :d :di :base) -#+todo-remove(add-matrix-class 'matrix-lisp-ddi :d :di :lisp) -#+todo-remove(add-matrix-class 'matrix-blas-ddi :d :di :blas) -#+todo-remove(add-matrix-class 'matrix-ddi :d :di :any) - ;;; Methods spezilied for the diagnoal matrices (defmethod mref ((matrix matrix-base-ddi) row col) Modified: trunk/src/matrix/level1-dge.lisp ============================================================================== --- trunk/src/matrix/level1-dge.lisp (original) +++ trunk/src/matrix/level1-dge.lisp Thu May 13 09:46:10 2010 @@ -66,13 +66,6 @@ (defmethod make-matrix-class ((a (eql :d)) (b (eql :ge)) (c (eql :any))) (find-class 'matrix-dge)) - -;;; Add classes to the generic matrix creation scheme -#+todo-remove (add-matrix-class 'matrix-base-dge :d :ge :base) -#+todo-remove (add-matrix-class 'matrix-lisp-dge :d :ge :lisp) -#+todo-remove (add-matrix-class 'matrix-blas-dge :d :ge :blas) -#+todo-remove (add-matrix-class 'matrix-dge :d :ge :any) - ;;; All leve1 methods spcialized for dge (defmethod mref ((matrix matrix-base-dge) row col) Modified: trunk/src/matrix/level1-dgt.lisp ============================================================================== --- trunk/src/matrix/level1-dgt.lisp (original) +++ trunk/src/matrix/level1-dgt.lisp Thu May 13 09:46:10 2010 @@ -82,13 +82,6 @@ (defmethod make-matrix-class ((a (eql :d)) (b (eql :gt)) (c (eql :any))) (find-class 'matrix-dgt)) - -;;; Add classes to the generic matrix creation scheme -#+todo-remove (add-matrix-class 'matrix-base-dgt :d :gt :base) -#+todo-remove (add-matrix-class 'matrix-lisp-dgt :d :gt :lisp) -#+todo-remove (add-matrix-class 'matrix-blas-dgt :d :gt :blas) -#+todo-remove (add-matrix-class 'matrix-dgt :d :gt :any) - ;;; Methods spezilied for the tridiagnoal matrices (defmethod mref ((matrix matrix-base-dgt) row col) Modified: trunk/src/matrix/level1-ge.lisp ============================================================================== --- trunk/src/matrix/level1-ge.lisp (original) +++ trunk/src/matrix/level1-ge.lisp Thu May 13 09:46:10 2010 @@ -33,10 +33,6 @@ (defmethod make-matrix-class ((a (eql :any)) (b (eql :ge)) (c (eql :any))) (find-class 'matrix-ge)) -;;; Add class to the generic matrix creation scheme -#+todo-remove (add-matrix-class 'matrix-base-ge :any :ge :base) -#+tod-remove (add-matrix-class 'matrix-ge :any :ge :any) - (defmethod initialize-instance :after ((m matrix-ge) &key dim (value 0)) (with-slots (rows cols size matrix-store) m (setf rows (car dim) Modified: trunk/src/matrix/level1-zge.lisp ============================================================================== --- trunk/src/matrix/level1-zge.lisp (original) +++ trunk/src/matrix/level1-zge.lisp Thu May 13 09:46:10 2010 @@ -64,14 +64,6 @@ (defmethod make-matrix-class ((a (eql :z)) (b (eql :ge)) (c (eql :any))) (find-class 'matrix-zge)) - -;;; Add classes to the generic matrix creation scheme -#+todo-remove (add-matrix-class 'matrix-base-zge :z :ge :base) -#+todo-remove (add-matrix-class 'matrix-lisp-zge :z :ge :lisp) -#+todo-remove (add-matrix-class 'matrix-blas-zge :z :ge :blas) -#+todo-remove (add-matrix-class 'matrix-zge :z :ge :any) - - ;;; Level1 methods specialized for zge (defmethod mref ((matrix matrix-base-zge) row col) Modified: trunk/src/matrix/level2-matrix-zge.lisp ============================================================================== --- trunk/src/matrix/level2-matrix-zge.lisp (original) +++ trunk/src/matrix/level2-matrix-zge.lisp Thu May 13 09:46:10 2010 @@ -171,31 +171,6 @@ ;;;; The cross terms, where one input is a real matrix, the other complex -#| -(defmacro def-cross-complex-real-method (name) - ;; Assumes output type same as input - ;; Note will crash if input is not converted properly!!!!!! - (let ((a (gensym)) - (b (gensym))) - `(defmethod ,name ((,a matrix-base-zge) (,b matrix-base-dge)) - ;; This is not the fastest possible, but rather fast - (,name ,a (.complex ,b 0))))) - -(defmacro def-all-cross-complex-real-methods (name) - `(progn - (def-cross-complex-real-method ,name) - #+nil (def-cross-complex-real-method ,name matrix-base-dge complex) - ;; (def-cross-complex-real-method ,name matrix-base-zge matrix-base-dge) - ;; (def-cross-complex-real-method ,name matrix-base-dge matrix-base-zge) - 'done)) - -(def-all-cross-complex-real-methods .add) -(def-all-cross-complex-real-methods .sub) -(def-all-cross-complex-real-methods .mul) -(def-all-cross-complex-real-methods .div) -(def-all-cross-complex-real-methods .expt) -|# - ;;; Add (defmethod .add ((a matrix-base-dge) (b complex)) From jivestgarden at common-lisp.net Thu May 13 14:18:21 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 10:18:21 -0400 Subject: [lisplab-cvs] r160 - in trunk: . src/matrix Message-ID: Author: jivestgarden Date: Thu May 13 10:18:21 2010 New Revision: 160 Log: vector functions Added: trunk/src/matrix/level2-vector.lisp Modified: trunk/lisplab.asd trunk/package.lisp trunk/src/matrix/level2-interface.lisp Modified: trunk/lisplab.asd ============================================================================== --- trunk/lisplab.asd (original) +++ trunk/lisplab.asd Thu May 13 10:18:21 2010 @@ -104,6 +104,7 @@ ; (:file "level2-array-functions") (:file "level2-view") (:file "level2-list") + (:file "level2-vector") )) ;; Modified: trunk/package.lisp ============================================================================== --- trunk/package.lisp (original) +++ trunk/package.lisp Thu May 13 10:18:21 2010 @@ -203,6 +203,9 @@ "CIRC-SHIFT" "PAD-SHIFT" "MREVERSE" + "VDOT" + "VNORM" + "VCROSS" ;; Matrix level 3 ;; IO Modified: trunk/src/matrix/level2-interface.lisp ============================================================================== --- trunk/src/matrix/level2-interface.lisp (original) +++ trunk/src/matrix/level2-interface.lisp Thu May 13 10:18:21 2010 @@ -154,4 +154,15 @@ (:documentation "Shifts the matrix and pads results")) (defgeneric mreverse (m) - (:documentation "Reverts elements of matrix or vector. Similar to cl:reverse")) \ No newline at end of file + (:documentation "Reverts elements of matrix or vector. Similar to cl:reverse")) + +;; Some vector functions + +(defgeneric vcross (a b) + (:documentation "Cross product. Must be a vecotors of length 3")) + +(defgeneric vdot (a b) + (:documentation "Dot product of vectors")) + +(defgeneric vnorm (a) + (:documentation "The vector norm")) Added: trunk/src/matrix/level2-vector.lisp ============================================================================== --- (empty file) +++ trunk/src/matrix/level2-vector.lisp Thu May 13 10:18:21 2010 @@ -0,0 +1,41 @@ +;;; Lisplab, level2-vector.lisp +;;; A small number of vector functions, general and specialized + +;;; Copyright (C) 2009 Joern Inge Vestgaarden +;;; +;;; This program is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 2 of the License, or +;;; (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License along +;;; with this program; if not, write to the Free Software Foundation, Inc., +;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +(in-package :lisplab) + +;;; For general matrices + +(defmethod vdot ((a matrix-base) (b matrix-base)) + (msum (.* a b))) + +(defmethod vcross :before ((a matrix-base) (b matrix-base)) + (assert (= (size a) (size b) 3))) + +(defmethod vcross ((a matrix-base) (b matrix-base)) + (let ((out (mcreate a))) + (setf (vref out 0) (.- (.* (vref a 1) (vref b 2)) + (.* (vref a 2) (vref b 1))) + (vref out 1) (.- (.* (vref a 2) (vref b 0)) + (.* (vref a 0) (vref b 2))) + (vref out 2) (.- (.* (vref a 0) (vref b 1)) + (.* (vref a 1) (vref b 0)))) + out)) + +(defmethod vnorm ((a matrix-base)) + (.sqrt (vdot (.conj a) a))) \ No newline at end of file From jivestgarden at common-lisp.net Thu May 13 16:02:30 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 12:02:30 -0400 Subject: [lisplab-cvs] r161 - trunk/src/matrix Message-ID: Author: jivestgarden Date: Thu May 13 12:02:30 2010 New Revision: 161 Log: first draft on container Added: trunk/src/matrix/level1-container.lisp Modified: trunk/src/matrix/level1-matrix.lisp Added: trunk/src/matrix/level1-container.lisp ============================================================================== --- (empty file) +++ trunk/src/matrix/level1-container.lisp Thu May 13 12:02:30 2010 @@ -0,0 +1,82 @@ +;;; Lisplab, level1-container.lisp +;;; Container matrices that contains one matrix and passes all operations to this. +;;; This should be the default matrix. + +;;; Copyright (C) 2010 Joern Inge Vestgaarden +;;; +;;; This program is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 2 of the License, or +;;; (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License along +;;; with this program; if not, write to the Free Software Foundation, Inc., +;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +;;; TODO: this will only get useful if also implemented on level 2, including +;;; high level optimizations. This is a lot of work... + +(in-package :lisplab) + +(defclass matrix (matrix-base) + ((matrix-content :initarg :content + :initform nil + :accessor matrix-content + :type matrix-base)) + (:documentation "A meta-matrix that contains wraps another matrix.")) + +(defmethod make-matrix-class ((a (eql :any)) (b (eql :any)) (c (eql :any))) + (find-class 'matrix)) + +(defmethod initialize-instance :after ((m matrix) &key dim (value 0)) + (with-slots (matrix-content) m + (unless matrix-content + (setf matrix-content + (make-matrix-instance (typecase value + (real 'matrix-dge) + (complex 'matrix-zge) + (t 'matrix-ge)) + dim + value))))) + + +;;; Level methods specialized for untyped, general matrices + +(defmethod element-type ((m matrix)) + (element-type (slot-value m 'matrix-content))) + +(defmethod size ((m matrix)) + (size (slot-value m 'matrix-content))) + +(defmethod rows ((m matrix)) + (rows (slot-value m 'matrix-content))) + +(defmethod cols ((m matrix)) + (cols (slot-value m 'matrix-content))) + +(defmethod dim ((m matrix) &optional direction) + (dim (slot-value m 'matrix-content) direction)) + +(defmethod mref ((matrix matrix) row col) + (mref (slot-value matrix 'matrix-content) row col)) + +(defmethod (setf mref) (value (matrix matrix) row col) + (with-slots (matrix-content) matrix + (unless (subtypep (type-of value) (element-type matrix-content)) + (setf matrix-content (convert matrix 'matrix-ge))) ;; could do something more clever here + (setf (mref matrix-content row col) value))) + +(defmethod vref ((matrix matrix) idx) + (vref (slot-value matrix 'matrix-content) idx)) + +(defmethod (setf vref) (value (matrix matrix) idx) + (with-slots (matrix-content) matrix + (unless (subtypep (type-of value) (element-type matrix-content)) + (setf matrix-content (convert matrix 'matrix-ge))) ;; could do something more clever here + (setf (vref matrix-content idx) value))) + Modified: trunk/src/matrix/level1-matrix.lisp ============================================================================== --- trunk/src/matrix/level1-matrix.lisp (original) +++ trunk/src/matrix/level1-matrix.lisp Thu May 13 12:02:30 2010 @@ -42,11 +42,14 @@ rows and columns is limited by *lisplab-print-size*." (print-unreadable-object (matrix stream :type t :identity t) (let ((rows (min (rows matrix) *lisplab-print-size*)) - (cols (min (cols matrix) *lisplab-print-size*))) + (cols (min (cols matrix) *lisplab-print-size*)) + (fmt (if (eql (element-type matrix) 'double-float) + "~0,4g " + "~a "))) (format stream " ~ax~a~&" (rows matrix) (cols matrix)) (dotimes (i rows) (dotimes (j cols) - (format stream "~a " (mref matrix i j))) + (format stream fmt (mref matrix i j))) (when (< cols (cols matrix)) (format stream "...")) (princ #\Newline stream)) From jivestgarden at common-lisp.net Thu May 13 16:12:07 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 12:12:07 -0400 Subject: [lisplab-cvs] r162 - trunk/src/matrix Message-ID: Author: jivestgarden Date: Thu May 13 12:12:07 2010 New Revision: 162 Log: simplfied class hierarchi for dge and zge Modified: trunk/src/matrix/level1-dge.lisp trunk/src/matrix/level1-zge.lisp Modified: trunk/src/matrix/level1-dge.lisp ============================================================================== --- trunk/src/matrix/level1-dge.lisp (original) +++ trunk/src/matrix/level1-dge.lisp Thu May 13 12:12:07 2010 @@ -43,13 +43,9 @@ (:documentation "A full matrix (rows x cols) with double float elements. Executes in lisp only.")) -(defclass matrix-blas-dge (matrix-implementation-blas matrix-lisp-dge) () - (:documentation "A full matrix (rows x cols) with double float elements. -Executes in alien blas/lapack only.")) - -(defclass matrix-dge (matrix-blas-dge) () +(defclass matrix-dge (matrix-implementation-blas matrix-lisp-dge) () (:documentation "A full matrix (rows x cols) with double float matrix elements. -Executes first in alien blas/lapack if possible. If not it executes in lisp.")) +Executes in FFI if possible. If not it executes in lisp.")) (defmethod make-matrix-class ((a (eql :d)) (b (eql :ge)) (c (eql :base))) (find-class 'matrix-base-dge)) @@ -58,10 +54,10 @@ (find-class 'matrix-lisp-dge)) (defmethod make-matrix-class ((a (eql :d)) (b (eql :ge)) (c (eql :ffi))) - (find-class 'matrix-blas-dge)) + (find-class 'matrix-dge)) (defmethod make-matrix-class ((a (eql :d)) (b (eql :ge)) (c (eql :blas))) - (find-class 'matrix-blas-dge)) + (find-class 'matrix-dge)) (defmethod make-matrix-class ((a (eql :d)) (b (eql :ge)) (c (eql :any))) (find-class 'matrix-dge)) Modified: trunk/src/matrix/level1-zge.lisp ============================================================================== --- trunk/src/matrix/level1-zge.lisp (original) +++ trunk/src/matrix/level1-zge.lisp Thu May 13 12:12:07 2010 @@ -41,13 +41,9 @@ (:documentation "A full matrix (rows x cols) with complex double float elements. Executes in lisp only.")) -(defclass matrix-blas-zge (matrix-implementation-blas matrix-lisp-zge) () - (:documentation "A full matrix (rows x cols) with complex double float elements. -Executes in alien blas/lapack only.")) - -(defclass matrix-zge (matrix-blas-zge) () +(defclass matrix-zge (matrix-implementation-blas matrix-lisp-zge) () (:documentation "A full matrix (rows x cols) with complex double float matrix elements. -Executes first in alien blas/lapack if possible. If not it executes in lisp.")) +Executes in FFI if possible. If not it executes in lisp.")) (defmethod make-matrix-class ((a (eql :z)) (b (eql :ge)) (c (eql :base))) (find-class 'matrix-base-zge)) @@ -56,10 +52,10 @@ (find-class 'matrix-lisp-zge)) (defmethod make-matrix-class ((a (eql :z)) (b (eql :ge)) (c (eql :ffi))) - (find-class 'matrix-blas-zge)) + (find-class 'matrix-zge)) (defmethod make-matrix-class ((a (eql :z)) (b (eql :ge)) (c (eql :blas))) - (find-class 'matrix-blas-zge)) + (find-class 'matrix-zge)) (defmethod make-matrix-class ((a (eql :z)) (b (eql :ge)) (c (eql :any))) (find-class 'matrix-zge)) From jivestgarden at common-lisp.net Thu May 13 16:20:55 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 12:20:55 -0400 Subject: [lisplab-cvs] r163 - trunk/src/matrix Message-ID: Author: jivestgarden Date: Thu May 13 12:20:55 2010 New Revision: 163 Log: fixed acosh Modified: trunk/src/matrix/level2-matrix-dge.lisp trunk/src/matrix/store-ordinary-functions.lisp Modified: trunk/src/matrix/level2-matrix-dge.lisp ============================================================================== --- trunk/src/matrix/level2-matrix-dge.lisp (original) +++ trunk/src/matrix/level2-matrix-dge.lisp Thu May 13 12:20:55 2010 @@ -239,7 +239,7 @@ (.cosh . cosh_dfa-to-dfa) (.tanh . tanh_dfa-to-dfa) (.asinh . asinh_dfa-to-dfa) - (.acosh . acosh_dfa-to-dfa) + #+nil (.acosh . acosh_dfa-to-dfa) (.exp . exp_dfa-to-dfa) #+nil (.ln . log_dfa) #+nil (.sqrt . sqrt_dfat) @@ -330,6 +330,15 @@ (atanh_dfa-to-cdfa (matrix-store a) (matrix-store out)) out)))) +(defmethod .acosh ((a matrix-base-dge)) + (if (>= (mmin a) 1d0) + (let ((out (mcreate a))) + (acosh_dfa-to-dfa (matrix-store a) (matrix-store out)) + out) + (let ((out (mcreate* a :element-type :z))) + (acosh_dfa-to-cdfa (matrix-store a) (matrix-store out)) + out))) + ;;; Some special functions with with complex output for real input (defmethod .besh1 (n (x matrix-base-dge)) Modified: trunk/src/matrix/store-ordinary-functions.lisp ============================================================================== --- trunk/src/matrix/store-ordinary-functions.lisp (original) +++ trunk/src/matrix/store-ordinary-functions.lisp Thu May 13 12:20:55 2010 @@ -113,7 +113,9 @@ (acos . acos_dfa-to-cdfa) (atanh . atanh_dfa-to-cdfa) (log . log_dfa-to-cdfa) - (sqrt . sqrt_dfa-to-cdfa))) + (sqrt . sqrt_dfa-to-cdfa) + (acosh . acosh_dfa-to-cdfa) + )) (defmacro defun-dfa-to-cdfa (name op) (let ((a (gensym)) From jivestgarden at common-lisp.net Thu May 13 17:35:24 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 13:35:24 -0400 Subject: [lisplab-cvs] r164 - in trunk/src: fft matrix Message-ID: Author: jivestgarden Date: Thu May 13 13:35:24 2010 New Revision: 164 Log: put classes back in and bugix in fft Modified: trunk/src/fft/fftw-ffi.lisp trunk/src/fft/level3-fft-generic.lisp trunk/src/matrix/level1-dge.lisp trunk/src/matrix/level1-zge.lisp Modified: trunk/src/fft/fftw-ffi.lisp ============================================================================== --- trunk/src/fft/fftw-ffi.lisp (original) +++ trunk/src/fft/fftw-ffi.lisp Thu May 13 13:35:24 2010 @@ -70,8 +70,9 @@ (sap+ (vector-sap b) bstart) direction flag))) - (|fftw_execute| plan) - (|fftw_destroy_plan| plan))) + (unwind-protect + (|fftw_execute| plan) + (|fftw_destroy_plan| plan)))) b)) (defun fftw-fft2 (m n in out direction flag) @@ -85,8 +86,9 @@ (vector-sap out) direction flag))) - (|fftw_execute| plan) - (|fftw_destroy_plan| plan))) + (unwind-protect + (|fftw_execute| plan) + (|fftw_destroy_plan| plan)))) out) Modified: trunk/src/fft/level3-fft-generic.lisp ============================================================================== --- trunk/src/fft/level3-fft-generic.lisp (original) +++ trunk/src/fft/level3-fft-generic.lisp Thu May 13 13:35:24 2010 @@ -20,9 +20,7 @@ (in-package :lisplab) (defun convert-to-matrix-zge (m) - (let ((m-copy (make-matrix-instance (create-matrix-description m :et :z) - (dim m) - 0))) + (let ((m-copy (mcreate* m :element-type :z))) (copy-contents m m-copy) m-copy)) Modified: trunk/src/matrix/level1-dge.lisp ============================================================================== --- trunk/src/matrix/level1-dge.lisp (original) +++ trunk/src/matrix/level1-dge.lisp Thu May 13 13:35:24 2010 @@ -43,7 +43,11 @@ (:documentation "A full matrix (rows x cols) with double float elements. Executes in lisp only.")) -(defclass matrix-dge (matrix-implementation-blas matrix-lisp-dge) () +(defclass matrix-blas-dge (matrix-implementation-blas matrix-lisp-dge) () + (:documentation "A full matrix (rows x cols) with double float matrix elements. +Executes in FFI if possible. If not it executes in lisp.")) + +(defclass matrix-dge ( matrix-blas-dge) () (:documentation "A full matrix (rows x cols) with double float matrix elements. Executes in FFI if possible. If not it executes in lisp.")) Modified: trunk/src/matrix/level1-zge.lisp ============================================================================== --- trunk/src/matrix/level1-zge.lisp (original) +++ trunk/src/matrix/level1-zge.lisp Thu May 13 13:35:24 2010 @@ -41,10 +41,15 @@ (:documentation "A full matrix (rows x cols) with complex double float elements. Executes in lisp only.")) -(defclass matrix-zge (matrix-implementation-blas matrix-lisp-zge) () +(defclass matrix-blas-zge (matrix-implementation-blas matrix-lisp-zge) () (:documentation "A full matrix (rows x cols) with complex double float matrix elements. Executes in FFI if possible. If not it executes in lisp.")) +(defclass matrix-zge (matrix-blas-zge) () + (:documentation "A full matrix (rows x cols) with complex double float matrix elements. +Executes in FFI if possible. If not it executes in lisp.")) + + (defmethod make-matrix-class ((a (eql :z)) (b (eql :ge)) (c (eql :base))) (find-class 'matrix-base-zge)) From jivestgarden at common-lisp.net Thu May 13 18:44:18 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 13 May 2010 14:44:18 -0400 Subject: [lisplab-cvs] r165 - trunk/src/test Message-ID: Author: jivestgarden Date: Thu May 13 14:44:18 2010 New Revision: 165 Log: added new tests Modified: trunk/src/test/scaling-test.lisp Modified: trunk/src/test/scaling-test.lisp ============================================================================== --- trunk/src/test/scaling-test.lisp (original) +++ trunk/src/test/scaling-test.lisp Thu May 13 14:44:18 2010 @@ -18,7 +18,7 @@ (mapcar (lambda (x) (/ (loop for i from 0 below N sum (seconds-of-internal-real-time - (lambda () (funcall fun x)))) + (lambda () (apply fun x)))) N)) inputs)) @@ -55,17 +55,35 @@ .sin .cos .tan .asin .acos .atan .sinh .cosh .tanh - .asinh - ;; .acosh - .atanh + .asinh .acosh .atanh .abs .re .im .conj)) +(defun matrix-functions () + '(mmax mmin mabsmax mabsmin ll::mminmax)) + (defun report-function-times (filename &key (ns '(1 2 3 4 5 10 20 50 100 150 200 300 400 500)) (avg 10) (funs (ordinary-functions)) (titles (mapcar #'symbol-name funs)) (mats (mapcar (lambda (n) (drandom N N)) ns))) - (let* ((times (time-functions funs mats avg))) + (let* ((times (time-functions funs (mapcar #'list mats) avg))) + (write-gnuplot-scaling filename ns times titles) + :end)) + +(defun ordinary-operators () + '(.+ .- .* ./ .^ )) + +(defun ordinary-operators-real () + '(.+ .- .* ./ .^ .max .min .= ./= .< .> .<= .>=)) + +(defun report-operator-times (filename &key + (ns '(1 2 3 4 5 10 20 50 100 150 200 300 400 500)) + (avg 10) + (funs (ordinary-operators-real)) + (titles (mapcar #'symbol-name funs)) + (lmats (mapcar (lambda (n) (drandom N N)) ns)) + (rmats lmats)) + (let* ((times (time-functions funs (mapcar #'list lmats rmats) avg))) (write-gnuplot-scaling filename ns times titles) :end)) From jivestgarden at common-lisp.net Mon May 17 09:23:34 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Mon, 17 May 2010 05:23:34 -0400 Subject: [lisplab-cvs] r166 - in trunk: . src/matrix src/test Message-ID: Author: jivestgarden Date: Mon May 17 05:23:33 2010 New Revision: 166 Log: New matrix creation read macro and printers Modified: trunk/example.lisp trunk/src/matrix/level1-dge.lisp trunk/src/matrix/level1-ge.lisp trunk/src/matrix/level1-interface.lisp trunk/src/matrix/level1-matrix.lisp trunk/src/matrix/level1-zge.lisp trunk/src/matrix/level2-constructors.lisp trunk/src/test/test-methods.lisp Modified: trunk/example.lisp ============================================================================== --- trunk/example.lisp (original) +++ trunk/example.lisp Mon May 17 05:23:33 2010 @@ -12,7 +12,6 @@ (dnew 0 3 5) ; same as (mnew '(:d :ge :any) 0 3 5) - (mnew 'matrix-zge 0 3 5) ; same as (znew 0 3 5) @@ -24,9 +23,18 @@ (zrow 2 %i 1) (zcol 2 %i 1) + ;; Read macro + #md((1 2) (-1 4)) + #mz((1 2) (-1 4)) + #mm((1 2) (-1 4)) + ;; Setting of individual elements - (dmat (0 4 -2) (1 3 -5) (-2 4 0)) - (zmat (0 #C(0 2) -2) (1 3 -5) (-2 %i 0)) + (dmat '((0 4 -2) + (1 3 -5) + (-2 4 0))) + (zmat '((0 #c(0 2) -2) + (1 3 -5) + (-2 #c(0 1) 0))) ;; Setting of structure (funmat '(4 4) (lambda (i j) @@ -35,12 +43,15 @@ (if (< i j) 1 0.5))) ;; From another matrix - (copy (dmat (1 4) (-2 3))) - (mcreate (dmat (1 4) (-2 3))) + (copy #md((1 4) (-2 3))) + + (mcreate #md((1 4) (-2 3))) (convert '((3 2 4) (1 4 2)) 'matrix-dge) (convert (funmat '(3 3) (lambda (i j) (random 1.0))) 'matrix-dge) (mmap '(:z :ge :any) #'random (mnew '(:d :ge :any) 1 3 3)) - (.+ 3 (dmat (2 3) (-2 9))))) + (.+ 3 #md((2 3) (-2 9))) + + )) (mapcar (lambda (x) (mref x 0 0)) *test-matrices*) @@ -48,17 +59,25 @@ ;; Arithmetics -(let ((a (dmat (0 4 -2) (1 3 -5) (-2 4 0))) - (b (zmat (0 #C(0 2) -2) (1 3 -5) (-2 %i 0)))) +(let ((a #md((0 4 -2) + (1 3 -5) + (-2 4 0))) + (b #mz((0 (.* 2 %i) -2) + (1 3 -5) + (-2 %i 0)))) (.+ (.* 3 a) b)) ;; Infix arithmetics -(let ((a (dmat (0 4 -2) (1 3 -5) (-2 4 0))) - (b (zmat (0 #C(0 2) -2) (1 3 -5) (-2 %i 0)))) +(let ((a #md((0 4 -2) + (1 3 -5) + (-2 4 0))) + (b #mz((0 #c(0 2) -2) + (1 3 -5) + (-2 %i 0)))) (w/infix 3 .* a .+ b)) ;; Matrix inversion -(minv (dmat (0 4 -2) (1 3 -5) (-2 4 0))) +(minv #md((0 4 -2) (1 3 -5) (-2 4 0))) Modified: trunk/src/matrix/level1-dge.lisp ============================================================================== --- trunk/src/matrix/level1-dge.lisp (original) +++ trunk/src/matrix/level1-dge.lisp Mon May 17 05:23:33 2010 @@ -68,6 +68,26 @@ ;;; All leve1 methods spcialized for dge +(defmethod print-object ((matrix matrix-base-dge) stream) + (if (not *lisplab-print-size*) + (call-next-method) + (progn + (format stream "~&#md(" ) + (print-matrix-contents matrix + :stream stream + :pr (if *lisplab-element-printer* + *lisplab-element-printer* + (lambda (x stream) (format stream "~10,4g" x))) + :rmax (if (eq *lisplab-print-size* t) + (rows matrix) + *lisplab-print-size*) + :cmax (if (eq *lisplab-print-size* t) + (cols matrix) + *lisplab-print-size*) + :indent 4 + :braket-p t) + (format stream ")" )))) + (defmethod mref ((matrix matrix-base-dge) row col) (ref-blas-real-store (slot-value matrix 'matrix-store) row col (slot-value matrix 'rows))) Modified: trunk/src/matrix/level1-ge.lisp ============================================================================== --- trunk/src/matrix/level1-ge.lisp (original) +++ trunk/src/matrix/level1-ge.lisp Mon May 17 05:23:33 2010 @@ -43,6 +43,26 @@ ;;; Level methods specialized for untyped, general matrices +(defmethod print-object ((matrix matrix-ge) stream) + (if (not *lisplab-print-size*) + (call-next-method) + (progn + (format stream "~&#mm(" ) + (print-matrix-contents matrix + :stream stream + :pr (if *lisplab-element-printer* + *lisplab-element-printer* + (lambda (x stream) (format stream "~a" x))) + :rmax (if (eq *lisplab-print-size* t) + (rows matrix) + *lisplab-print-size*) + :cmax (if (eq *lisplab-print-size* t) + (cols matrix) + *lisplab-print-size*) + :indent 4 + :braket-p t) + (format stream ")" )))) + (defmethod mref ((matrix matrix-ge) row col) (aref (slot-value matrix 'matrix-store) (column-major-idx row col (slot-value matrix 'rows)))) Modified: trunk/src/matrix/level1-interface.lisp ============================================================================== --- trunk/src/matrix/level1-interface.lisp (original) +++ trunk/src/matrix/level1-interface.lisp Mon May 17 05:23:33 2010 @@ -20,7 +20,12 @@ (in-package :lisplab) -(defvar *lisplab-print-size* 10 "Suggested number of rows and columns printed to standard output. Not all matrices, such as ordinary lisp arrays, will care about the value.") +(defvar *lisplab-print-size* 5 + "Suggested number of rows and columns printed to standard output. +Not all matrices will care about the value.") + +(defvar *lisplab-element-printer* nil + "The function used to print matrix elements. For is same as princ and prin1.") (defgeneric make-matrix-instance (type dim value) (:documentation "Creates a new matrix instance")) Modified: trunk/src/matrix/level1-matrix.lisp ============================================================================== --- trunk/src/matrix/level1-matrix.lisp (original) +++ trunk/src/matrix/level1-matrix.lisp Mon May 17 05:23:33 2010 @@ -37,19 +37,71 @@ (1 (cols matrix))) (list (rows matrix) (cols matrix)))) +(defun print-matrix-contents (m + &key + (stream *standard-output*) + (pr #'princ) + (rmax (rows m)) + (cmax (cols m)) + (indent 0) + (braket-p nil)) + "Utility function that prints the matrix elements in a human-friendly way." + ;; TODO move among other utility functions? + (let ((rows (min (rows m) rmax)) + (cols (min (cols m) cmax)) + (indfmt (if (zerop indent) + "" + (format nil "~~~aT" indent)))) + (dotimes (i rows) + (when (> i 0) + (format stream indfmt)) + (when braket-p (princ "(" stream)) + (dotimes (j cols) + (funcall pr (mref m i j) stream) + (when (< j (1- cols)) + (princ " " stream))) + (when (< cols (cols m)) + (format stream " ...")) + (when braket-p (princ ")" stream)) + (when (< i (1- rows)) + (princ #\newline stream))) + (when (< rows (rows m)) + (format stream indfmt) + (format stream "~& ...")))) + +(defmethod print-object ((matrix matrix-base) stream) + "Prints matrix as an unreadable object. The number of printed +rows and columns is limited by *lisplab-print-size* +and format is given by *lisplab-element-printer*." + (print-unreadable-object (matrix stream :type t :identity t) + (format stream " ~ax~a" (rows matrix) (cols matrix)) + (when *lisplab-print-size* + (format stream "~&") + (print-matrix-contents matrix + :stream stream + :pr (if *lisplab-element-printer* + *lisplab-element-printer* + #'princ) + :rmax (if (eq *lisplab-print-size* t) + (rows matrix) + *lisplab-print-size*) + :cmax (if (eq *lisplab-print-size* t) + (cols matrix) + *lisplab-print-size*) + :indent 0) + (format stream "~%")))) + +#+todo-remove (defmethod print-object ((matrix matrix-base) stream) "Prints matrix as an unreadable object. The number of printed rows and columns is limited by *lisplab-print-size*." (print-unreadable-object (matrix stream :type t :identity t) (let ((rows (min (rows matrix) *lisplab-print-size*)) - (cols (min (cols matrix) *lisplab-print-size*)) - (fmt (if (eql (element-type matrix) 'double-float) - "~0,4g " - "~a "))) + (cols (min (cols matrix) *lisplab-print-size*))) (format stream " ~ax~a~&" (rows matrix) (cols matrix)) (dotimes (i rows) (dotimes (j cols) - (format stream fmt (mref matrix i j))) + (format stream "~a " (mref matrix i j))) (when (< cols (cols matrix)) (format stream "...")) (princ #\Newline stream)) Modified: trunk/src/matrix/level1-zge.lisp ============================================================================== --- trunk/src/matrix/level1-zge.lisp (original) +++ trunk/src/matrix/level1-zge.lisp Mon May 17 05:23:33 2010 @@ -67,6 +67,27 @@ ;;; Level1 methods specialized for zge +(defmethod print-object ((matrix matrix-base-zge) stream) + (if (not *lisplab-print-size*) + (call-next-method) + (progn + (format stream "~&#mz(" ) + (print-matrix-contents matrix + :stream stream + :pr (if *lisplab-element-printer* + *lisplab-element-printer* + (lambda (x stream) + (format stream "#c(~8,2g ~8,2g)" (realpart x) (imagpart x)))) + :rmax (if (eq *lisplab-print-size* t) + (rows matrix) + *lisplab-print-size*) + :cmax (if (eq *lisplab-print-size* t) + (cols matrix) + *lisplab-print-size*) + :indent 4 + :braket-p t) + (format stream ")" )))) + (defmethod mref ((matrix matrix-base-zge) row col) (ref-blas-complex-store (slot-value matrix 'matrix-store) row col (slot-value matrix 'rows))) Modified: trunk/src/matrix/level2-constructors.lisp ============================================================================== --- trunk/src/matrix/level2-constructors.lisp (original) +++ trunk/src/matrix/level2-constructors.lisp Mon May 17 05:23:33 2010 @@ -19,9 +19,30 @@ ;;; TODO: needs constructors for diagonal matrices. +;;; TODO: specialize convert for standard-class. + + (in-package :lisplab) + +;;; Creates matrices with general structure, e.g., #md((1 2) (3 4)) + +;;; TODO: error check is important here! + +(set-dispatch-macro-character #\# #\M + (lambda (stream c1 c2) + (let* ((s1 (make-string 1))) + (setf (aref s1 0) (read-char stream)) + (setf s1 (string-capitalize s1)) + (let ((type (cond ((string= s1 "D") :d) + ((string= s1 "Z") :z) + (t :any))) + (cont (read stream t nil t))) + (list 'mmat + (list 'list type :ge :any) + (cons 'list (mapcar (lambda (x) (cons 'list x)) cont))))))) + (defmethod mcreate ((m number) &optional (val 0) dim) (declare (ignore dim)) ;; This is not about matrices at all, but is usefull @@ -80,7 +101,8 @@ ;; Should it be moved to some other file? ;; TODO some better way ... some more general guessing routine ;; like guess-best-element-type - (if (consp (car x)) + (mmat type x) + #+todo-remove (if (consp (car x)) (let* ((cols (length (car x))) (rows (length x)) (m (make-matrix-instance type (list rows cols) 0))) @@ -96,13 +118,16 @@ rows) value)) -(defmacro mmat (type &body args) - "Creates a matrix." - `(convert - ,(cons 'list (mapcar (lambda (x) - (cons 'list x)) - args)) - ,type)) +(defun mmat (type x) + "Creates a matrix from the list of lists. For a macro use #mm((..) (..) ..) instead." + (unless (consp (car x)) + ;; It is a list. Create a column vector. + (setf x (mapcar #'list x))) + (let* ((cols (length (car x))) + (rows (length x)) + (m (make-matrix-instance type (list rows cols) 0))) + (fill-matrix-with-list m x) + m)) (defun mcol (type &rest args) "Creates a column matrix." @@ -118,9 +143,9 @@ "Creates a double matrix with random element between 0 and 1." (mmap t #'random (dnew 1d0 rows cols))) -(defmacro dmat (&body args) - "Creates a matrix-dge matrix." - `(mmat 'matrix-dge , at args)) +(defun dmat (args) + "Creates a matrix-dge from the list of lists. For macro: use #md((..) (..) ..) instead." + (mmat 'matrix-dge args)) (defun dcol (&rest args) "Creates a matrix-dge column matrix." @@ -179,9 +204,9 @@ ;;; Constructors for matrix-zge -(defmacro zmat (&body args) - "Creates a matrix-dge matrix." - `(mmat 'matrix-zge , at args)) +(defun zmat (args) + "Creates a matrix-zge from the list of lists. For macro: use #mz((..) (..) ..) instead." + (mmat 'matrix-zge args)) (defun zcol (&rest args) "Creates a matrix-zge column matrix." Modified: trunk/src/test/test-methods.lisp ============================================================================== --- trunk/src/test/test-methods.lisp (original) +++ trunk/src/test/test-methods.lisp Mon May 17 05:23:33 2010 @@ -22,9 +22,9 @@ (let* ((a 1) (b 1d0) (c %i) - (x (dmat (1 2) (3 4))) - (y (zmat (1 2) (3 4))) - (w (mmat 'matrix-ge (1 2) (3 4))) + (x #md((1 2) (3 4))) + (y #md((1 2) (3 4))) + (w #mm((1 2) (3 4))) (args (list a b c x y w))) (mapc (lambda (fun) (mapc (lambda (x) @@ -64,10 +64,10 @@ (defun test-level3-fft () - (let ((a (dmat (1 2) (3 4))) - (b (zmat (1 2) (3 5))) - (c (dmat (1 2 -1) (3 4 9) (1 1 1))) - (d (zmat (1 2 2.1) (3 5 %i) (-%i -%i -%i)))) + (let ((a #md((1 2) (3 4))) + (b #mz((1 2) (3 5))) + (c #md((1 2 -1) (3 4 9) (1 1 1))) + (d #mz((1 2 2.1) (3 5 %i) (-%i -%i -%i)))) (simple-non-nil-check #'fft1 (list a)) (simple-non-nil-check #'fft1 (list b)) (simple-non-nil-check #'fft2 (list a)) @@ -95,11 +95,11 @@ 'done)) (defun test-level3-linalg () - (let* ((a (dmat (1 2) (3 4))) - (b (zmat (1 2) (3 5))) - (c (dmat (1 2 -1) (3 4 9) (1 1 1))) - (d (zmat (1 2 2.1) (3 5 %i) (-%i %i -%i))) - (x (mmat 'matrix-ge (1 2 2.1) (3 5 %i) (-%i %i -%i))) + (let* ((a #md((1 2) (3 4))) + (b #mz((1 2) (3 5))) + (c #md((1 2 -1) (3 4 9) (1 1 1))) + (d #mz((1 2 2.1) (3 5 %i) (-%i %i -%i))) + (x #mm((1 2 2.1) (3 5 %i) (-%i %i -%i))) (args (list a b c d x))) (mapc (lambda (x) (simple-non-nil-check #'mtp (list x))) args) (mapc (lambda (x) (simple-non-nil-check #'mct (list x))) args) From jivestgarden at common-lisp.net Mon May 17 09:41:51 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Mon, 17 May 2010 05:41:51 -0400 Subject: [lisplab-cvs] r167 - trunk Message-ID: Author: jivestgarden Date: Mon May 17 05:41:51 2010 New Revision: 167 Log: updated doc Modified: trunk/README trunk/start.lisp Modified: trunk/README ============================================================================== --- trunk/README (original) +++ trunk/README Mon May 17 05:41:51 2010 @@ -1,7 +1,7 @@ ============================================================ LISPLAB - a mathematics library for Common Lisp ============================================================ -Lisplab is a mathematics library for common lisp, released +Lisplab is a mathematics/matrix library for common lisp, released under the GNU General Public License (GPL), except files that state something else. @@ -13,16 +13,17 @@ ============================================================ INSTALLING ============================================================ -Lisplab is asdf-installable. It has only been tested on SBCL -on Linux, but should be fairly portable to other platforms. +Lisplab is installed by asdf. It has only been tested on SBCL +on Linux, but it should be fairly portable to other platforms. Lisplab uses BLAS, LAPACK, and FFTW, and the path to these libraries must be set before loading. See file "start.lisp" for how. -Lisplab has only been run with double-floats, so -your ".sbclrc" should include -(setf *READ-DEFAULT-FLOAT-FORMAT* 'double-float) +Builing for the first time requires double-floats, +i.e., compile/load with +% (let ((*READ-DEFAULT-FLOAT-FORMAT* 'double-float)) + (require :lisplab)) ============================================================ @@ -39,7 +40,6 @@ Think of it as late alpha cycle. The Library is rather extensive, the API is fairly stable, and the implementation has OK structure. It also has fairly good documentation and a manual. -But it is poorly tested. +But it is poorly tested. -(In general, Lisplab needs more users and more developers.) Modified: trunk/start.lisp ============================================================================== --- trunk/start.lisp (original) +++ trunk/start.lisp Mon May 17 05:41:51 2010 @@ -2,14 +2,13 @@ (in-package :cl-user) -;; Uncomment or move to .sbslrc +;; Uncomment or move to .sbclrc ;; (defvar *lisplab-libblas-path* #P"/usr/lib/atlas/libblas.so.3.0") ;; (defvar *lisplab-liblapack-path* #P"/usr/lib/atlas/liblapack.so.3.0") ;; (defvar *lisplab-libfftw-path* #P"/usr/lib/libfftw3.so.3") -;; Slatec needs this for compiling. -(setf *read-default-float-format* 'double-float) - -(require :lisplab) +;; Slatec needs double-floats for compiling +(let ((*read-default-float-format* 'double-float)) + (require :lisplab)) (format t "~&Lisplab is loaded.~%") From jivestgarden at common-lisp.net Mon May 17 18:31:01 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Mon, 17 May 2010 14:31:01 -0400 Subject: [lisplab-cvs] r168 - in trunk/src: linalg test Message-ID: Author: jivestgarden Date: Mon May 17 14:31:01 2010 New Revision: 168 Log: bugfix lin-solve Modified: trunk/src/linalg/level3-linalg-dge.lisp trunk/src/linalg/level3-linalg-generic.lisp trunk/src/linalg/level3-linalg-interface.lisp trunk/src/test/test-methods.lisp Modified: trunk/src/linalg/level3-linalg-dge.lisp ============================================================================== --- trunk/src/linalg/level3-linalg-dge.lisp (original) +++ trunk/src/linalg/level3-linalg-dge.lisp Mon May 17 14:31:01 2010 @@ -32,10 +32,10 @@ (setf (mref b i j) (mref a j i)))) b)) -(defmethod mct ((a matrix-lisp-dge)) +(defmethod mct ((a matrix-base-dge)) (mtp a)) -(defmethod m* ((a matrix-lisp-dge) (b matrix-lisp-dge)) +(defmethod m* ((a matrix-base-dge) (b matrix-base-dge)) (let* ((N (rows a)) (M (cols b)) (S (rows b)) @@ -57,7 +57,7 @@ (setf (refc i j) cij)))) c))) -(defmethod LU-factor! ((A matrix-lisp-dge) p) +(defmethod LU-factor! ((A matrix-base-dge) p) ;; Translation from GSL. ;; Destructive LU factorization. The outout is PA=LU, ;; stored in one matrix, where the diagonal elements belong @@ -100,7 +100,7 @@ (defun L-solve!-blas-real (L x col) ;; Solve Lx=b - (declare (matrix-lisp-dge L x)) + (declare (matrix-base-dge L x)) (let ((L2 (matrix-store L)) (x2 (matrix-store x)) (N (rows x))) @@ -117,7 +117,7 @@ x) (defun U-solve!-blas-real (U x col) - (declare (matrix-lisp-dge U x)) + (declare (matrix-base-dge U x)) (let* ((U2 (matrix-store U)) (x2 (matrix-store x)) (N (rows x)) @@ -141,8 +141,9 @@ (U-solve!-blas-real LU x col) x) -(defmethod lin-solve ((A matrix-lisp-dge) (b matrix-lisp-dge)) - (destructuring-bind (LU pvec sign) (LU-factor A) +(defmethod lin-solve ((A matrix-base-dge) (b matrix-base-dge)) + (destructuring-bind (LU pvec sign) + (LU-factor! (copy A) (make-permutation-vector (size b))) (let ((b2 (copy b))) (dotimes (i (rows A)) (setf (vref b2 (vref pvec i)) (vref b i))) @@ -159,10 +160,10 @@ (LU-solve!-blas-real LU A (vref p i))))) A) -(defmethod minv! ((A matrix-lisp-dge)) +(defmethod minv! ((A matrix-base-dge)) (minv!-blas-real A)) -(defmethod minv ((A matrix-lisp-dge)) +(defmethod minv ((A matrix-base-dge)) (minv! (copy A))) Modified: trunk/src/linalg/level3-linalg-generic.lisp ============================================================================== --- trunk/src/linalg/level3-linalg-generic.lisp (original) +++ trunk/src/linalg/level3-linalg-generic.lisp Mon May 17 14:31:01 2010 @@ -160,17 +160,18 @@ (mref U i i))))) x)) -(defun LU-solve! (LU x) +(defmethod LU-solve! ((LU matrix-base) (x matrix-base)) (L-solve! LU x) (U-solve! LU x) x) (defmethod lin-solve ((A matrix-base) (b matrix-base)) - (destructuring-bind (LU pvec sign) (LU-factor A) + (destructuring-bind (LU pvec det) + (LU-factor! (copy A) (make-permutation-vector (rows A))) (let ((b2 (copy b))) - (dotimes (i (rows A)) - (setf (vref b2 (vref pvec i)) (vref b i))) - (LU-solve! LU b2)))) + (dotimes (i (size b)) + (setf (vref b2 i) (vref b (vref pvec i)))) + (LU-solve! LU b2)))) (defmethod mdet ((A matrix-base)) (destructuring-bind (LU pvec det) Modified: trunk/src/linalg/level3-linalg-interface.lisp ============================================================================== --- trunk/src/linalg/level3-linalg-interface.lisp (original) +++ trunk/src/linalg/level3-linalg-interface.lisp Mon May 17 14:31:01 2010 @@ -71,6 +71,10 @@ L is low diagonal with unity at diagnoals, U is upper diagnoal and P is an permutation matrix, so that A = P L U.")) +(defgeneric LU-solve! (LU x) + (:documentation "Solves the linear equation system LUx=b, where LU is an output +from LU-factor!.")) + (defgeneric lin-solve (A b) (:documentation "Solves the linear system of equations Ax=b.")) Modified: trunk/src/test/test-methods.lisp ============================================================================== --- trunk/src/test/test-methods.lisp (original) +++ trunk/src/test/test-methods.lisp Mon May 17 14:31:01 2010 @@ -100,7 +100,11 @@ (c #md((1 2 -1) (3 4 9) (1 1 1))) (d #mz((1 2 2.1) (3 5 %i) (-%i %i -%i))) (x #mm((1 2 2.1) (3 5 %i) (-%i %i -%i))) - (args (list a b c d x))) + (args (list a b c d x)) + (vec1 (mcol 'matrix-ge 1 2 3)) + (vec2 (dcol 1 2 3))) + (simple-non-nil-check #'lin-solve (list x vec1)) + (simple-non-nil-check #'lin-solve (list c vec2)) (mapc (lambda (x) (simple-non-nil-check #'mtp (list x))) args) (mapc (lambda (x) (simple-non-nil-check #'mct (list x))) args) (mapc (lambda (x) (simple-non-nil-check #'minv (list x))) args) From jivestgarden at common-lisp.net Mon May 17 19:23:57 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Mon, 17 May 2010 15:23:57 -0400 Subject: [lisplab-cvs] r169 - trunk/doc/www Message-ID: Author: jivestgarden Date: Mon May 17 15:23:57 2010 New Revision: 169 Log: updated web-page Modified: trunk/doc/www/index.html Modified: trunk/doc/www/index.html ============================================================================== --- trunk/doc/www/index.html (original) +++ trunk/doc/www/index.html Mon May 17 15:23:57 2010 @@ -40,51 +40,50 @@ -LISPLAB project +LISPLAB project - A mathematics/matrix library for Common Lisp

Lisplab

-

A mathematics library for Common Lisp

+

A mathematics/matrix library for Common Lisp

- Lisplab is a mathematics library in Common Lisp + Lisplab is a mathematics and matrix library in Common Lisp released under the GNU General Public License (GPL) and hosted at common-lisp.net. - Lisplab is based on code from Matlisp, - but has now moved quite far from the original code mass. + Lisplab was originally based on code from Matlisp + but it has moved quite far from the original code mass.

- The main purpose of Lisplab is to provide a framwork - for mathematical computations. This means that it should be easy - to create and manipulate mathematical objects and that naming - of classes and functions should be consistent and clear. + The main purpose of Lisplab is to + to integrate all kinds of mathematical capabilities into one framework. Lisplab is heavily based on CLOS.

Lisplab contains
    -
  • Interfaces to BLAS and LAPACK.
  • -
  • Interface to FFTW.
  • -
  • Numerical integration from QUADPACK and F2CL.
  • -
  • Special functions from SLATEC and F2CL.
  • -
  • Routines for linear algebra, +
  • Matlab-like matrix manipulation
  • +
  • Interfaces to BLAS and LAPACK
  • +
  • Interface to FFTW
  • +
  • Numerical integration through QUADPACK
  • +
  • Special functions from SLATEC
  • +
  • Many Lisplab-specific routines for linear algebra, postscript output, PGM output, Fast Fourier Transform (native Common Lisp), infix math, etc.

- The part of Lisplab which is most mature is the matrix and linear algebra, - and these should provide a good basis for matrix based modelling. + The part of Lisplab which is most mature is the matrix and linear algebra, + which should provide a good basis for matrix based modelling.

Installing

Lisplab is installed by asdf. - The external libraries, BLAS, LAPACK, and FFTW must be installed separately. - They make Lisplab more powerful, but it also makes sense to run it - without external libraries. - Lisplab is mainly ANSI compliant and does not depend on any other Common Lisp projects, + BLAS, LAPACK, and FFTW must be installed separately. + The external libraries make Lisplab more powerful, but it has a lot of capabilities + and good performance without them. + Lisplab is mainly ANSI-compliant and does not depend on other Common Lisp projects but it has so far only been tested on SBCL, so for other Lisps you must expect some hacking to make it build. @@ -102,14 +101,16 @@

   > (use-package :ll-user)
When compiling for the first time you must have *read-default-float-format* set to 'double-float because the generated slatec code requires it. - When started, you can do -
  LL-USER> (.^ (dmat (1 2) (3 4)) 2)
-  #<MATRIX-DGE  2x2
-    1.0 4.0 
-    9.0 16.0 
-  {B7E3E71}>
Common operations are + When started, you can for example square the elements: +
  LL-USER> (.^ #md((1 2) (3 4)) 2)
+  #md(( 1.000      4.000    )
+      ( 9.000      16.00    ))
+ The read macro #md creates double-floats matrices, + and #mz create complex double float matrices. + Untyped matrices are created with #mm. + Common operations are
  .+ .- .* ./ .^ 
-  .expt .sqrt .log
+  .expt .sqrt .log .sgn
   .sin .cos .tan .asin .acos .atan
   .sinh .cosh .tanh .asinh .acosh .atanh
   .besj .besy .besi .besk .besh 
@@ -125,6 +126,7 @@
   m* m/ minv mtp mct 
   eivenvalues eigenvectors 
   LU-factor
+  lin-solve
   dlmread dlmwrite pswrite pgmwrite
   export-list import-list
   fftw1 ifftw1 
@@ -205,11 +207,12 @@
    
  • Matlisp
  • Femlisp
  • NLISP +
  • GNU Scientific Library for Lisp

  • Valid XHTML 1.0 Strict From jivestgarden at common-lisp.net Mon May 17 19:59:34 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Mon, 17 May 2010 15:59:34 -0400 Subject: [lisplab-cvs] r170 - trunk/doc/manual Message-ID: Author: jivestgarden Date: Mon May 17 15:59:34 2010 New Revision: 170 Log: Fixing manual. Not finished Modified: trunk/doc/manual/lisplab.texi Modified: trunk/doc/manual/lisplab.texi ============================================================================== --- trunk/doc/manual/lisplab.texi (original) +++ trunk/doc/manual/lisplab.texi Mon May 17 15:59:34 2010 @@ -42,28 +42,30 @@ @node Introduction @chapter Introduction -Lisplab is a mathematics library in Common Lisp. It is -placed under the Gnu general public license and offers +Lisplab is a mathematics/matrix library in Common Lisp. It is +placed under the GNu General Public License (GPL) and offers an easy-to-use and rich programming framework for mathematics, -including linear algebra, +including Matlab-like matrix handling, linear algebra, Fast Fourier Transform, special functions, Runge-Kutta solver, -infix notation, and general matrix utility functions. +infix notation, and interfaces to BLAS, LAPACK, FFTW, SLATEC and +QUADPACK. + The name Lisplab is inspired by Matlab and Lisplab offers -much of the same kind of programming style as Matlab, with high level -manipulation of matrices. Contrary to Matlab, Lisplab can do a -lot more than just matrix manipulation because Lisplab is -based on Common Lisp. Hence, you get all -the benefits of lexical scope, dynamic scope, macros, CLOS, fast execution, +much of the same kind of programming-style as Matlab, with high level +manipulation of matrices, but contrary to Matlab, Lisplab +benefits from being a part of Common Lisp. Hence, you have +lexical scope, dynamic scope, macros, first class +functions, iterations, CLOS, fast execution, and working in an free general purpose programming language. And best of all: you can enjoy you favorite data-types in addition to the matrices: functions, hash tables, structures, classes, arbitrary precision integers, rationals, and lists. Lisplab is not unique in building Matlab-like -syntax on top of Common Lisp. Other Common Lisp matrix libraries -are Matlisp, Femlisp and NLISP. Lisplab itself was -started as a branch of Matlisp, but has now moved -far from the original code mass. +syntax on top of Common Lisp. Other similar framweorks are +Matlisp, Femlisp, NLISP and GSLL. Lisplab itself was +started as a branch of Matlisp, but there is now only +little of the original code left. @node Getting started @@ -78,15 +80,17 @@ @item FFTW -- The fastest Fast Fourier Transform available. @end itemize + at section Portability Lisplab has been developed with SBCL, SLIME and ASDF on Linux, and there are yet unnecessary bindings to these platforms. @itemize @item Some of the optimized lisp code uses the -SBCL macro @code{truly-the}. This must be dealt with. - at item The FFTW FFI is only for SBCL. - at item The Matlisp FFI should be portable to other lisps and -Windows, but it has not been tested. - at item The @code{*READ-DEFAULT-FLOAT-FORMAT*} must be @code{double-float}. +SBCL macro @code{truly-the}. + at item The FFTW FFI works only for SBCL. + at item The Matlisp FFI should in theory be portable to other lisps and +Windows, but it has not yet been tested. + at item The @code{*READ-DEFAULT-FLOAT-FORMAT*} must be @code{double-float} +when compiling Slatec. This is a minor problem. @end itemize Except from this, Lisplab should be self-contained and not depend on @@ -127,9 +131,9 @@ If you have problems loading, first look at @code{start.lisp} and see if you can hack it. Then look at @code{lisplab.asd}. -To install Blas, Lapack, and FFTW, if you are lazy, and lucky -enough to administer a Debian or Ubuntu machine, -you typically do +To install BLAS, LAPACK, and FFTW, if you are too lazy to do a custom build, +and is lucky enough to administer a Debian or Ubuntu machine, +you typically write @example # aptitude install libatlas3gf-base # aptitude install libfftw3-3 @@ -152,7 +156,7 @@ @code{.+}, @code{.-}, @code{.*}, @code{./}, @code{.^}, @code{.sin} @code{.cos}, @code{.tan}, @code{.besj}, @code{.re}, etc. On numbers these functions work as the non-dotted Common Lisp functions -and on matrices they work element-vise. +and on matrices they work elementwise. @item Linear algebra functions tend to start with @i{m}: @code{m*}, @code{minv}, @code{mmax}, @code{mtp}, etc., @@ -167,30 +171,12 @@ @section Status - past and future -Lisplab contains a lot of linear algebra stuff, but -in the future it is hope it can be broad mathematics programming environment, -not just linear algebra. - Lisplab has been developed for physics simulations and data handling. -Lisplab started as a refactoring of Matlisp, but the code -has been to large degree rewritten, except the -interfaces to Blas and Lapack. Currently, -Lisplab and Matlisp have more or less the same functionality. -Lisplab differ from Matlisp in the following ways - at itemize - at item Implementation. - at item Layered structure (@xref{Structure}.) - at item Shorter names. - at item Lisplab uses the standard Lapack and Blas libraries, not a special build. - at item Rich matrix class hierarchy. - at end itemize - -The future I will mainly do minor changes and bug-fixes, -since it now covers my basic needs. I will only add new -modules when I personally needed them. +Lisplab started as a refactoring of Matlisp, but most of the code +has been replaced and a lot new code has been written. +The only Matlisp code that is kept is the interfaces to BLAS and LAPACK. -However, there are many exiting extensions that can be made, -such as +Some large extensions that could be fun to do: @itemize @item Parallel computation, e.g. using MPI. @item More native linear algebra routines, e.g. eigenvalue computation. @@ -201,13 +187,15 @@ @item New matrix optimization for new usage, e.g. integer matrices for image processing or cryptography. @item Interface to new foreign libraries, e.g. GSL. + at item More special functions. @end itemize -So it this sounds interesting, please contact if you want to contribute. +An of course a lot more linear algebra and matrix stuff. + @section Bugs and limitations The purpose of Lisplab is to be a platform for mathematical computations. From this perspective it -is clear it will never be complete. Also, since there is no +is clear that it will never be complete. Also, since there is no spec it is not obvious what is a bug and what is not! Hence, the list in this section must be read as non-systematic gathering @@ -223,25 +211,6 @@ @item Lacks error checks (but these should not be made before a spec!) @end itemize -Missing features: - at itemize - at item There is no way to iterate through the elements of -a general matrix in a fast way. (The map functions are currently the only -thing, but these are structure agnostic and also not fast.) There -should maybe be an macro @code{w/matrix}. - at item There should be linear algebra primitives, like row exchange, -in level 2, so that level 3 can be made entirely without knowledge about -internal structure of matrices. (Structure similar to blas - lapack) - at item Integer matrices. - at item Vectorized execution of operations. - at item Numerical integration. - at item Symbolic math. Should be separate module, only with knowledge -of the dotted algebra generic functions. - at item The dotted algebra should also work on functions -so the one could write @code{(.+ (lambda (x) (+ x 1)) 3)} -and get a new functions as result. It might even -be possible to make beautiful optimizations this way. - at end itemize @node Tutorial @@ -732,16 +701,21 @@ @chapter Discussion @section The foreign function interfaces +The foreign function interface comes from Matlisp and +is mainly on level 3. The elements of Lisplab typed matrices (double-float and complex double-float) are stored as 1D simple arrays, and most Lisps will then have a SAP inside the array pointer which is binary compatible with Fortran. This adds some overhead to matrix element references, -but simplifies the garbage collections. +but simplifies the memory management considerably compared to a bare pointer type. +Also, it is important to avoid pointers from being moved +by the garbage collector. In Matlisp, this was handled by stopping +the garbage collector, but a more smoother and better way would be to +just pin the pointers in action. -Matlisp has an extra layer with Fortran compatibility above +Lisplab has an extra layer with Fortran compatibility above the ordinary C FFI. This layer is mainly unchanged compared -to Matlisp, but only the SBCL FFI is in the code. The -FFIs for other lisps could easily be added, but not without testing. +to Matlisp, but only the SBCL FFI is distributed with Lisplab. The FFI for FFTW is a mock-up for SBCL, and it only is for standard complex transforms and inverse transforms. Of course, a lot more can @@ -759,6 +733,28 @@ in the build. The symbolic code need not know anything about the rest of Lisplab, except for the generic methods of the dotted algebra (The level 0). + + at section Missing features + at itemize + at item There is no way to iterate through the elements of +a general matrix in a fast way. (The map functions are currently the only +thing, but these are structure agnostic and also not fast.) There +should maybe be an macro @code{w/matrix}. + at item There should be linear algebra primitives, like row exchange, +in level 2, so that level 3 can be made entirely without knowledge about +internal structure of matrices. (Structure similar to blas - lapack) + at item Integer matrices. + at item Vectorized execution of operations. + at item Numerical integration. + at item Symbolic math. Should be separate module, only with knowledge +of the dotted algebra generic functions. + at item The dotted algebra should also work on functions +so the one could write @code{(.+ (lambda (x) (+ x 1)) 3)} +and get a new functions as result. It might even +be possible to make beautiful optimizations this way. + at end itemize + + @c End stuff @c @node Index From jivestgarden at common-lisp.net Thu May 20 19:47:07 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Thu, 20 May 2010 15:47:07 -0400 Subject: [lisplab-cvs] r171 - trunk/src/matrix Message-ID: Author: jivestgarden Date: Thu May 20 15:47:06 2010 New Revision: 171 Log: optimized and fixed .expt Modified: trunk/src/matrix/level2-matrix-dge.lisp trunk/src/matrix/store-operators.lisp Modified: trunk/src/matrix/level2-matrix-dge.lisp ============================================================================== --- trunk/src/matrix/level2-matrix-dge.lisp (original) +++ trunk/src/matrix/level2-matrix-dge.lisp Thu May 20 15:47:06 2010 @@ -148,7 +148,7 @@ (.sub . -_dfa-df) (.mul . *_dfa-df) (.div . /_dfa-df) - (.expt . ^_dfa-df) + ;; (.expt . ^_dfa-df) (.max . max_dfa-df) (.min . min_dfa-df))) @@ -176,7 +176,7 @@ (.sub . -_df-dfa) (.mul . *_df-dfa) (.div . /_df-dfa) - (.expt . ^_df-dfa) + ;; (.expt . ^_df-dfa) (.max . max_df-dfa) (.min . min_df-dfa))) @@ -204,7 +204,7 @@ (.sub . -_dfa-dfa) (.mul . *_dfa-dfa) (.div . /_dfa-dfa) - (.expt . ^_dfa-dfa) + ;; (.expt . ^_dfa-dfa) (.max . max_dfa-dfa) (.min . min_dfa-dfa))) @@ -225,6 +225,85 @@ (expand-generic-function-dfa-dfa-map) +;;; The expt is an exception, since negative input can give complex exponent +;;; and since the general case is slow. + +(defun all-integer-elements-p (a) + "Helper function for .expt" + (declare (type-blas-store a)) + (dotimes (i (length a)) + (multiple-value-bind (div mod) (ftruncate (aref a i)) + (declare (ignore div)) + (unless (zerop mod) + (return-from all-integer-elements-p nil)))) + t) + +(defmethod .expt ((a matrix-base-dge) (b matrix-base-dge)) + (cond ((>= (mmin a) 0d0) + (let ((c (mcreate a))) + (^_dfa>=0-dfa (matrix-store a) (matrix-store b) (matrix-store c)) + c)) + ((all-integer-elements-p (matrix-store b)) + (let ((c (mcreate a))) + (^_dfa-dfa (matrix-store a) (matrix-store b) (matrix-store c)) + c)) + (t (let ((c (mcreate* a :element-type :z)) + (a2 (mcreate* a :element-type :z)) + (b2 (mcreate* a :element-type :z))) + ;; There should be some better way to upgrade the element type of a matrix + ;; while keeping the contents. + (copy-contents a a2) + (copy-contents b b2) + ;; This could in theory be a litle more clever since if all exponents + ;; are even, the output is still real. However, recognizing even integers + ;; from float input is risky. + (^_cdfa-cdfa (matrix-store a2) (matrix-store b2) (matrix-store c)) + c)))) + +(defmethod .expt ((a matrix-base-dge) (b real)) + "There is a lot of fuzz going on in here. The reason is because +the important special cases of exponents -3,-2,-1,0,1,2,3 are a factor 10 faster +than the general case on SBCL. Furthermor, output can be complex for non-integer exponent." + (multiple-value-bind (div mod) (truncate b) + (if (= 0 mod) + (let ((c (mcreate a))) + (case div + (-3 (^_dfa--3 (matrix-store a) (matrix-store c))) + (-2 (^_dfa--2 (matrix-store a) (matrix-store c))) + (-1 (^_dfa--1 (matrix-store a) (matrix-store c))) + (0 (mfill c 1)) + (1 (copy-contents a c)) + (2 (^_dfa-+2 (matrix-store a) (matrix-store c))) + (3 (^_dfa-+3 (matrix-store a) (matrix-store c))) + (t (^_dfa-df (matrix-store a) (coerce div 'double-float) (matrix-store c)))) + c) + (let ((min (mmin a))) + (if (>= min 0) + (let ((c (mcreate a))) + (^_dfa>=0-df (matrix-store a) (coerce b 'double-float) (matrix-store c)) + c) + (let ((c (mcreate* a :element-type :z)) + (a2 (mcreate* a :element-type :z))) + (copy-contents a a2) + (^_cdfa-cdf (matrix-store a2) + (coerce b '(complex double-float)) + (matrix-store c)) + c)))))) + +(defmethod .expt ((a real) (b matrix-base-dge) ) + (if (>= a 0) + (let ((c (mcreate b))) + (^_df>=0-dfa (coerce a 'double-float) (matrix-store b) (matrix-store c)) + c) + (if (all-integer-elements-p (matrix-store b)) + (let ((c (mcreate b))) + (^_df-dfa (coerce a 'double-float) (matrix-store b) (matrix-store c)) + c) + (let ((c (mcreate* b :element-type :z)) + (b2 (mcreate* b :element-type :z))) + (copy-contents b b2) + (^_cdf-cdfa (coerce a '(complex double-float)) (matrix-store b2) (matrix-store c)) + c)))) (define-constant +generic-function-dfa-to-dfa-map+ ;really bad name Modified: trunk/src/matrix/store-operators.lisp ============================================================================== --- trunk/src/matrix/store-operators.lisp (original) +++ trunk/src/matrix/store-operators.lisp Thu May 20 15:47:06 2010 @@ -132,6 +132,50 @@ (type double-float a)) (map-into c (lambda (x) (expt a x)) b)) +(defun ^_dfa>=0-dfa (a b c) + (declare (type (simple-array (double-float 0d0) (*)) a b c)) + (map-into c #'expt a b)) + +(defun ^_df>=0-dfa (a b c) + (declare (type type-blas-store b c) + (type (double-float 0d0) a)) + (map-into c (lambda (x) (expt a x)) b)) + +(defun ^_dfa>=0-df (a b c) + (declare (type (simple-array (double-float 0d0) (*)) a c) + (type double-float b)) + (map-into c (lambda (x) (expt x b)) a)) + +(defun ^_dfa-+2 (a c) + (declare (type type-blas-store a c)) + (dotimes (i (length a)) + (setf (aref c i) (expt (aref a i) 2))) + c) + +(defun ^_dfa-+3 (a c) + (declare (type type-blas-store a c)) + (dotimes (i (length a)) + (setf (aref c i) (expt (aref a i) 3))) + c) + +(defun ^_dfa--1 (a c) + (declare (type type-blas-store a c)) + (dotimes (i (length a)) + (setf (aref c i) (expt (aref a i) -1))) + c) + +(defun ^_dfa--2 (a c) + (declare (type type-blas-store a c)) + (dotimes (i (length a)) + (setf (aref c i) (expt (aref a i) -2))) + c) + +(defun ^_dfa--3 (a c) + (declare (type type-blas-store a c)) + (dotimes (i (length a)) + (setf (aref c i) (expt (aref a i) -3))) + c) + (defun max_dfa-dfa (a b c) (declare (type type-blas-store a b c)) (map-into c #'max a b)) From jivestgarden at common-lisp.net Sat May 22 15:17:02 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Sat, 22 May 2010 11:17:02 -0400 Subject: [lisplab-cvs] r172 - trunk/src/matrix Message-ID: Author: jivestgarden Date: Sat May 22 11:17:02 2010 New Revision: 172 Log: bugfix Modified: trunk/src/matrix/level2-constructors.lisp Modified: trunk/src/matrix/level2-constructors.lisp ============================================================================== --- trunk/src/matrix/level2-constructors.lisp (original) +++ trunk/src/matrix/level2-constructors.lisp Sat May 22 11:17:02 2010 @@ -131,11 +131,11 @@ (defun mcol (type &rest args) "Creates a column matrix." - (convert (mapcar 'list args) type)) + (mmat type (mapcar #'list args))) (defun mrow (type &rest args) "Creates a row matrix." - (convert args type)) + (mmat type (list args))) ;;; Constructors for matrix-dge From jivestgarden at common-lisp.net Sat May 22 18:27:33 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Sat, 22 May 2010 14:27:33 -0400 Subject: [lisplab-cvs] r173 - trunk Message-ID: Author: jivestgarden Date: Sat May 22 14:27:33 2010 New Revision: 173 Log: changed version to 0.2 Modified: trunk/version.lisp Modified: trunk/version.lisp ============================================================================== --- trunk/version.lisp (original) +++ trunk/version.lisp Sat May 22 14:27:33 2010 @@ -1,6 +1,6 @@ (in-package :lisplab) -(defparameter lisplab-version "0.1.0" "A rather non-systematic overall version number.") +(defparameter lisplab-version "0.2.0" "A rather non-systematic overall version number.") (defparameter lisplab-svn-version (if (probe-file #P"SVNVERSION") From jivestgarden at common-lisp.net Sat May 22 18:29:41 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Sat, 22 May 2010 14:29:41 -0400 Subject: [lisplab-cvs] r174 - in trunk/doc: manual www Message-ID: Author: jivestgarden Date: Sat May 22 14:29:40 2010 New Revision: 174 Log: updated manual Modified: trunk/doc/manual/lisplab.texi trunk/doc/www/index.html Modified: trunk/doc/manual/lisplab.texi ============================================================================== --- trunk/doc/manual/lisplab.texi (original) +++ trunk/doc/manual/lisplab.texi Sat May 22 14:29:40 2010 @@ -3,7 +3,7 @@ @settitle Lisplab manual @copying -This manual is for Lisplab version 0.1, updated 10. September 2009. +This manual is for Lisplab version 0.2, updated 10. May 2010. Copyright @copyright{} 2009 Joern Inge Vestgaarden @end copying @@ -43,7 +43,7 @@ @node Introduction @chapter Introduction Lisplab is a mathematics/matrix library in Common Lisp. It is -placed under the GNu General Public License (GPL) and offers +placed under the GNU General Public License (GPL) and offers an easy-to-use and rich programming framework for mathematics, including Matlab-like matrix handling, linear algebra, Fast Fourier Transform, special functions, Runge-Kutta solver, @@ -216,12 +216,13 @@ @node Tutorial @chapter Tutorial - @section Starting -Currently Lisplab only runs on SBCL, and there is a small porting +Currently Lisplab only runs on SBCL and there is a small porting job (mainly the FFIs and a few uses of SB-EXT package) to -get it run on other platforms. If you have SBCL you must -make sure that @code{lisplab.asd} is (or pointed to) in @code{asdf:*centeral-registry*}. +get it run on other platforms. On SBCL +make sure that @code{lisplab.asd} is in @code{asdf:*centeral-registry*} +and that @code{*read-default-float-format*} is @code{double-float}, as is +requrieed when compiling Slatec. Then type @example CL-USER> (require :lisplab) @@ -240,31 +241,29 @@ to the stream example in Object-Oriented Programming in Common Lisp, by Sonya E. Keene. -The most common classes are @code{matrix-dge} which -is a general, double-float matrix with any implementation -and @code{matrix-zge} which is a -general, complex double-float matrix with any implementation. - -The best way to inspect the class structure is to play -with the low level constructor @code{make-matrix-instance}, -for example, - at example -LL> (make-matrix-instance '(:z :ge :any) '(2 2) 1) -# - at end example -where types are :d, :z, or :any, structure is :ge or :d, -and implementation is :any, :lisp, :blas. Not all combinations -have a class, since not all combinations are usefull. More types -and structures will be added in the future. - -Note that with these three lines of inheritance there -are potentially incredibly many potential class. Let's -say we have 10 structures, 10 types and 4 implementations, giving -400 classes. Not all of these are useful and only few are created -by default. To add new classes in a structured way, +Objects of the most important classes can be created by +read macros. For double-float matrices, @code{matrix-dge}, + at example +LL-USER> #md((1 2) (3 4)) +#md(( 1.000 2.000 ) + ( 3.000 4.000 )) + at end example +For complex double-float matrices, @code{matrix-zge}, + at example +LL-USER> #mz((1 2) (#c(1 2) #c(3 4))) +#mz((#c( 1.0 0.0 ) #c( 2.0 0.0 )) + (#c( 1.0 2.0 ) #c( 3.0 4.0 ))) + at end example +Untyped matrices, @code{matrix-ge}, + at example +LL-USER> #mm(('a 'b) ('c 'd)) +#mm((A B) + (C D)) + at end example + +There are more matrix classes, but these are not exported. +Even more matric classes can be created dynamically, +but these capabilities are not yet fully in use. @xref{Structure}. @@ -273,47 +272,36 @@ the primary choice to create a matrix. Its better to use a special constructor. Try @example -LL> (dnew 0 2 2) -# - -LL>(drow 1 2) -# - -LL> (dcol 1 2) -# - -LL> (dmat (1 2) (3 4)) -# - at end example -where @code{dnew}, @code{dcol}, and @code{drow} are functions, -while @code{dmat} is a macro. Similarly, there are - at code{znew}, @code{zcol}, @code{zrow}, and @code{zmat} +LL-USER> (dnew 0 2 2) +#md(( 0.000 0.000 ) + ( 0.000 0.000 )) + +LL-USER> (drow 1 2) +#md(( 1.000 2.000 )) + +LL-USER> (dcol 1 2) +#md(( 1.000 ) + ( 2.000 )) + +LL-USER> (dmat '((1 2) (3 4))) +#md(( 1.000 2.000 ) + ( 3.000 4.000 )) + at end example +Similarly, there are @code{znew}, @code{zcol}, @code{zrow}, and @code{zmat} for double float matrices and @code{mnew}, @code{mcol}, @code{mrow}, and @code{mmat} for any matrices. The latter take matrix class as first argument. Often you want to create a matrix of the same type as a input -matrix. Then you can use @code{mcreate}. It's mainly useful when +matrix. Then you can use @code{mcreate} and @code{mcreate*} for +extended syntax. They are useful when creating methods that should operate on many matrix types. To create matrices from something else, use @code{convert} @example -LL> (convert '((1 2) (3 4)) '(:d :ge :any)) -# +LL-USER> (convert '((1 2) (3 4)) '(:d :ge :any)) +#md(( 1.000 2.000 ) + ( 3.000 4.000 )) @end example @code{Convert} also converts between matrix types. If the matrix contents cannot be converted directly @@ -321,159 +309,130 @@ use @code{copy-contents} instead. - at section Matrix element reference (mref and vref) -To access a matrix element use the generic function @code{mref} + at section Matrix element reference +Lisplab matrices are zero-based and in column major order. +Matrix reference is with the settable generic function @code{mref} @example -LL> (mref (dmat (1 2) (3 4)) 0 1) +LL-USER> (mref #md((1 2) (3 4)) 0 1) 2.0 @end example -Matrix references are zero based. The @code{mref} is settable. - -Furthermore, all matrices can also list their elements as vectors -(similar to row-major-aref for arrays). To access a matrix as vector -use the generic function @code{vref} +Matrices can also list their elements as vectors +(similar to @code{row-major-aref} for arrays). Vector access is with +the generic function @code{vref} @example -LL> (vref (dmat (1 2) (3 4)) 1) +LL-USER> (vref #md((1 2) (3 4)) 1) 3.0 @end example -which is also settable. Note that the matrices are column major order. +which is also settable. - at section The dotted algebra (.+, .*, .sin, ...) -Central in Lisplab is an algebra (in the widest possible sense of the word) -with the functions + at section Elementwise operators and functions +Lisplab introduces general mathematical operators @code{.+}, @code{.-}, @code{.*}, @code{./}, and @code{.^}. These are generalization of @code{+}, @code{-}, @code{*}, @code{/}, and @code{^}. For numbers they work the same, @example -LL> (.+ 1 2) +LL-USER> (.+ 1 2) 3 @end example -The functions @code{.+}, @code{.-}, @code{.*}, @code{./}, and @code{.^} -are mainly wrappers that call @code{reduce} on its arguments with the -generic functions +But the lisplab functions have a much wider functionality since +they are based on the binary generic functions @code{.add}, @code{.sub}, @code{.mul}, @code{.div}, and @code{.expt}. -If you want to extend the algebra, e.g. with polynomials, -you should add specializing methods to these generic functions. -The element-vise functions by conventions have names starting -with a dot (period). The dotted algebra works on the single elements and -is structure agnostic. The functions of the dotted algebra -introduce a programming style much the same as for Matlab, -and combined with the linear algebra -functions, you can write compact programs, without the slow -single element references. - at example -LL> (.sin (drow 0 1)) -# +On matrices the all functions starting with a dot works elementwise. +Hence + at example +LL-USER> (.sin (drow 0 1)) +#md(( 0.000 0.8415 )) @end example -And so also for the algebraic operations +The dotted operators ignores the internal structure of the matrices @example -LL> (let ((a (drow 0 1)) - (b (dcol 0.1 0.2))) - (.+ a (.* b 2))) -# - at end example -Note here that the @code{.+}, @code{.*}, etc. ignore the structure -so that it is completely valid to add a row and a column matrix. Note -also that the scalar is multiplied element-vise. - -The dotted algebra is to some extent also implemented for -general element matrices, so that you can work with fractions and -integers rather than floats - at example -LL> (.+ (row 'matrix-ge 1/2 3/2) 1) -# +LL-USER> (let ((a (drow 0 1)) + (b (dcol 0.1 0.2))) + (.+ a (.* b 2))) +#md((0.2000 1.400 )) + at end example +The output need not have same type as the input + at example +LL-USER> (.asin #md((1 2))) +#mz((#c( 1.6 0.0 ) #c( 1.6 1.3 ))) + at end example +The dotted functions and operators are optimized and very fast +for the double-float matrices, but slow for the matrices with +arbitrary element-types. + at example +LL-USER> (.+ #mm((1/2 3/2)) 1) +#mm((3/2 5/2)) @end example @section Linear algebra -The linear algebra functions (unlike the dotted algebra) +The linear algebra functions feel and maybe also change the matrix structure. The linear algebra functions often start with @i{m}, although this -conventions is not strictly enforced. Currently there is no a wide -spectrum of linear algebra function, but you find matrix multiplication, -matrix inversion, transpose, conjugate transpose and eigenvalues. +conventions is not strictly followed. The number of linear algebra functions +is small compared with LAPACK, but you will find matrix multiplication, +matrix inversion, transpose, conjugate transpose, LU-decomposition and eigenvalues. Matrix multiplication @example -LL>(let ((a (dmat (1 0) (0 -1))) - (b (dcol 0.1 0.2))) - (m* a b)) -# +LL-USER> (let ((a #md((1 0) (0 -1))) + (b #md((0.1) (0.2)))) + (m* a b)) +#md((0.1000 ) + (-.2000 )) @end example Matrix inversion @example -LL> (minv (dmat (1 2) (-2 1))) -# +LL-USER> (minv #md((1 2) + (-2 1))) +#md((0.2000 -.4000 ) + (0.4000 0.2000 )) @end example Transpose @example -LL> (mtp (dmat (1 2) (-2 1))) -# +LL-USER> (mtp #md((1 2) + (-2 1))) +#md(( 1.000 -2.000 ) + ( 2.000 1.000 )) @end example Conjugate transpose @example -LL> (mct (zmat (1 (* 2 %i)) (-2 1))) -# +LL-USER> (mct #mz((1 (* 2 %i)) (-2 1))) +#mz((#c( 1.0 -0.0 ) #c(-2.0 -0.0 )) + (#c( 0.0 -2.0 ) #c( 1.0 -0.0 ))) @end example Eigenvalues @example -LL> (eigenvalues (dmat (1 2) (0 0.5))) -# +LL-USER> (eigenvalues #md((1 2) (0 0.5))) +#md(( 1.000 ) + (0.5000 )) @end example Eigenvectors @example -LL> (eigenvectors (dmat (1 2) (0 0.5))) -(# - #) +LL-USER> (eigenvectors #md((1 2) (0 0.5))) +( +#md(( 1.000 ) + (0.5000 )) + +#md(( 1.000 -.9701 ) + ( 0.000 0.2425 ))) @end example Some of the linear algebra functions also work for general element matrices @example -LL> (let ((a (mat 'matrix-ge (1 0) (0 -1))) - (b (col 'matrix-ge 1/2 2/3))) - (m* a b)) -# - -LL> (minv (mat 'matrix-ge (1 2)(-2 1))) -# +LL-USER> (let ((a #mm((1 0) (0 -1))) + (b #mm((1/2) (2/3)))) + (m* a b)) +#mm((1/2) + (-2/3)) + +LL-USER> (minv #mm((1 2)(-2 1))) +#mm((1/5 -2/5) + (2/5 1/5)) @end example @@ -488,19 +447,18 @@ @section Matrices without store The class @code{function-matrix} implements matrices with -functions and has no store. - -The contents can for example be given directly by a rule, -using the macro funmat +functions and has no store, but where the elements are given by a function @example -LL> (funmat '(2 2) (i j) (if (= i j) 1 0)) +LL-USER> (funmat '(2 2) (lambda (i j) + (if (= i j) + 1 + 0))) # @end example -The funmat (and its generalization @code{fmat} that creates any matrix type) -it also useful to create grids. +The similar macro @code{fmat} creates functions of any type by a function. Function matrices are also used to view a part or restructured other matrix with @code{view-matrix}, @code{view-col}, or @code{view-row}. @@ -510,11 +468,9 @@ There are two methods for mapping of matrices: @code{mmap} and @code{mmap-into}. For example @example -LL> (mmap 'matrix-dge #'realpart (zmat (1 %i) (-%i 2))) -# +LL-USER> (mmap 'matrix-dge #'.re #mz((1 %i) (-%i 2))) +#md(( 1.000 0.000 ) + ( 0.000 2.000 )) @end example The output matrix takes the structure from the first arguments, but ignores in general matrix structure. If first argument @code{t} output @@ -522,7 +478,6 @@ @section Ordinary functions -These are: @code{.sin}, @code{.cos}, @code{.sin}, @code{.tan}, @code{.sinh}, @code{.cosh}, @code{.sinh}, @code{.tanh}, @code{.asin}, @code{.acos}, @code{.asin}, @code{.atan}, @@ -532,7 +487,6 @@ @section Special functions -These are: @code{.besj}, @code{.besy}, @code{.besi}, @code{.besk}, @code{.besh1}, @code{.besh2}, @@ -540,54 +494,46 @@ @section Infix notation -Infix input is with the macro @code{w/infix}, -where you must have spaces before and after -the operators - at example -LL> (w/infix - (let ((x 3)) - (1 .+ 2 .* x))) +Infix input is with the macro @code{w/infix} + at example +LL-USER> (w/infix + (let ((x 3)) + (1 .+ 2 .* x))) 7 @end example -The @code{w/infix} messes as little as possible with the Lisp -semantics, so that if you have a lot of formulas just wrap all -of it inside the macro. The infix math also works with the +The @code{w/infix} is compatible with the Lisp +semantics. The infix math also works with the functions @code{+, -, *, /} and @code{^}. @node Structure @chapter Structure - @section Design principles -Design principles for the full library +High level principles @itemize + at item Lisplab will be a @i{homogeneous platform} for mathematics. @item Lisplab is free software. - at item It makes a @i{homogeneous platform} for all -kinds of mathematical calculations. (So it's a lot more -than just a matrix library) @item User applications should need to stay only in Common Lisp. (There should be no need for optimized math in FFIs or special languages like Maxima) + at item Lisplab will steal as much code as possible from as many as possible. + at end itemize + +General design principles + at itemize @item Every common mathematical operator and function is represented by a @i{CLOS generic function}. -This is called the dotted algebra. @item Modular structure (Inspired by GSL). - at item Trust the Lisp system and use foreign code as little as possible. - at item Avoid programming mathematical algorithms in macros. Despite the -advantages (fast and generic at the same time) it is hard to -understand and debug. - at item Error checks is primarily callers responsibility, not Lisplab's! - at item To steal as much code as possible from as many as possible -(I love free software). + at item Trust the Lisp virtual machine (Avoid use of FFIs and destructive functions). + at item Avoid mathematical algorithms in macros. + at item Error checks is primarily caller's responsibility. @end itemize -Design principles for the matrix part +Design principles for the matrix code @itemize @item Layered structure where dependencies are -primarily on the layer below -- not vertical within the layer. - at item Layer 0 is mainly interfaces and generic functions, not implementations. -Level 1 and 2 are small. This structure should encourage modularity. +primarily to the layer below -- not vertical within the layer. @end itemize @@ -604,23 +550,22 @@ where @itemize @item @b{Level 0} is matrix independent and contains -the dotted algebra generic functions, -the dotted algebra methods specialized for numbers, and -helper functions and macros. - at item @b{Level 1} defines matrices and defines and implements +generic functions for mathematics. +In this level only specialization for numbers and non-matrix objects. + at item @b{Level 1} defines matrices and implements @code{mref}, @code{vref}, at code{cols}, @code{rows}, @code{size} and @code{make-matrix-instance}. - at item @b{Level 2} defines and core functionality related -to matrices, such as the dotted algebra methods, -matrix constructors (@code{dnew}, @code{dcol}, etc.) + at item @b{Level 2} Implements level 0 for matrices and +defines core functionality related to matrices such as +matrix constructors @code{dnew}, @code{dcol}, etc. and other matrix helper functions, such as @code{mmax}, @code{mmin}, @code{circ-shift}, etc. +Optimizations are mainly in level 2. @item @b{Level 3} is everything else that uses matrices, including linear algebra, FFTs, solvers, etc. @end itemize -The levels are unequal in size: level 0 is fairly large, -level 1 is extremely small, level 2 is fairly small, and -level 3 is large and I hope it will never stop to grow. +The levels are unequal in size: level 0 is potentially large, +level 1 is small, level 2 and 3 are large. The intention with the structure are the following @itemize Modified: trunk/doc/www/index.html ============================================================================== --- trunk/doc/www/index.html (original) +++ trunk/doc/www/index.html Sat May 22 14:29:40 2010 @@ -102,9 +102,9 @@ When compiling for the first time you must have *read-default-float-format* set to 'double-float because the generated slatec code requires it. When started, you can for example square the elements: -
      LL-USER> (.^ #md((1 2) (3 4)) 2)
    -  #md(( 1.000      4.000    )
    -      ( 9.000      16.00    ))
    +
    LL-USER> (.^ #md((1 2) (3 4)) 2)
    +#md(( 1.000      4.000    )
    +    ( 9.000      16.00    ))
    The read macro #md creates double-floats matrices, and #mz create complex double float matrices. Untyped matrices are created with #mm. From jivestgarden at common-lisp.net Sat May 22 18:54:07 2010 From: jivestgarden at common-lisp.net (=?UTF-8?Q?J=C3=B8rn_Inge_Vestg=C3=A5rden?=) Date: Sat, 22 May 2010 14:54:07 -0400 Subject: [lisplab-cvs] r175 - trunk/doc/manual Message-ID: Author: jivestgarden Date: Sat May 22 14:54:07 2010 New Revision: 175 Log: updated manual Modified: trunk/doc/manual/lisplab.texi Modified: trunk/doc/manual/lisplab.texi ============================================================================== --- trunk/doc/manual/lisplab.texi (original) +++ trunk/doc/manual/lisplab.texi Sat May 22 14:54:07 2010 @@ -217,27 +217,22 @@ @chapter Tutorial @section Starting -Currently Lisplab only runs on SBCL and there is a small porting -job (mainly the FFIs and a few uses of SB-EXT package) to -get it run on other platforms. On SBCL -make sure that @code{lisplab.asd} is in @code{asdf:*centeral-registry*} -and that @code{*read-default-float-format*} is @code{double-float}, as is -requrieed when compiling Slatec. -Then type - at example -CL-USER> (require :lisplab) -CL-USER> (in-package :ll) - at end example -The main package of Lisplab is @i{lisplab}, with nickname @i{ll}. -The tutorial assues that you are in the @i{lisplab} package or -use it. There is also a package @i{lisplab-user}, with nickname @i{ll-user} -that uses @i{lisplab}. +On SBCL, make sure that @code{asdf:*centeral-registry*} contains + at code{lisplab.asd} and type + at example +CL-USER> (let ((*read-default-float-format* 'double-float)) + (require :lisplab)) +CL-USER> (in-package :ll)) + at end example +The @code{*read-default-float-format*} is only needed when requiring +for first time. The main package of Lisplab is @i{lisplab}, with nickname @i{ll}, +and the package @i{lisplab-user}, with nickname @i{ll-user}. @section Matrix classes -The matrix classes hierarchy has three lines of inheritance. The -first is on structure, the second is on element type, and -the third is on implementation. This hierarchy is similar +The matrix classes hierarchy has three lines of inheritance: +on structure, on element type and +on implementation. This hierarchy is similar to the stream example in Object-Oriented Programming in Common Lisp, by Sonya E. Keene. @@ -262,15 +257,13 @@ @end example There are more matrix classes, but these are not exported. -Even more matric classes can be created dynamically, +Even more matrix classes can be created dynamically, but these capabilities are not yet fully in use. @xref{Structure}. @section Matrix construction -The constructor @code{make-matrix-instance} is not -the primary choice to create a matrix. Its better to use a special -constructor. Try +There are many ways to create a matrix, such as @example LL-USER> (dnew 0 2 2) #md(( 0.000 0.000 ) @@ -288,7 +281,7 @@ ( 3.000 4.000 )) @end example Similarly, there are @code{znew}, @code{zcol}, @code{zrow}, and @code{zmat} -for double float matrices and +for complex double float matrices and @code{mnew}, @code{mcol}, @code{mrow}, and @code{mmat} for any matrices. The latter take matrix class as first argument. @@ -308,6 +301,9 @@ (e.g., conversion from complex to real), use @code{copy-contents} instead. +Other matrix constructors are @code{mcreate}, @code{mcreate*}, + at code{drange}, @code{dgrid}, @code{fmat}, @code{funmat}. +The most fundamental constructor is @code{make-matrix-instance}. @section Matrix element reference Lisplab matrices are zero-based and in column major order. @@ -442,17 +438,15 @@ as images with @code{pgmwrite} and @code{pswrite}, writing portable graymap and postscript respectively. -Note that the IO functions are currently in a poor state. - @section Matrices without store The class @code{function-matrix} implements matrices with functions and has no store, but where the elements are given by a function @example LL-USER> (funmat '(2 2) (lambda (i j) - (if (= i j) - 1 - 0))) + (if (= i j) + 1 + 0))) # Author: jivestgarden Date: Mon May 24 10:02:40 2010 New Revision: 176 Log: bugfix in fft + new destructive optimized methods for real to complex transforms Modified: trunk/src/draft/level0-expression.lisp trunk/src/fft/fftw-ffi-package.lisp trunk/src/fft/fftw-ffi.lisp trunk/src/fft/level3-fft-fftw.lisp Modified: trunk/src/draft/level0-expression.lisp ============================================================================== --- trunk/src/draft/level0-expression.lisp (original) +++ trunk/src/draft/level0-expression.lisp Mon May 24 10:02:40 2010 @@ -19,6 +19,229 @@ (in-package :lisplab) +(defclass expression-base () + () + (:documentation "Represents symbolic expressions.")) + +(defclass whatever (expression-base) + () + (:documentation "Matches anything.")) + +(defclass symbol-expression (expression-base) + ((symbol :initarg :symbol :accessor expression-symbol :initform nil)) + (:documentation "Matches the same symbol. ")) + + + +(defclass list-expression (expression-base) + ((list :accessor expression-list :initform nil :initarg :list)) + (:documentation "A collection of expressions.")) + +(defclass rule-base () + ((name :accessor rule-name :initarg :name :initform nil))) + +(defclass function-rule (rule-base) + ((arg :accessor rule-arg :initarg :arg :initform nil) + (val :accessor rule-val :initarg :val :initform nil))) + + +(defclass relation-rule (rule-base) + ((a :accessor rule-a :initarg :a :initform nil) + (b :accessor rule-b :initarg :b :initform nil) + (val :accessor rule-val :initarg :val :initform nil))) + +(defvar *rules* nil) + +(defun add-rule (rule) + (push rule *rules*)) + +(defgeneric applicable-p (rule expr)) + +(defgeneric apply-rule (rule expr)) + +(defgeneric match-p (expr pat)) + +(defmethod match-p (expr pat) + nil) + +(defmethod match-p (expr (pat whatever)) + t) + +(defmethod match-p ((expr symbol-expression) (pat symbol-expression)) + (eql (expression-symbol expr) + (expression-symbol pat))) + +(defmethod match-p ((expr list-expression) (pat list-expression)) + (every #'match-p + (expression-list expr) + (expression-list pat))) + + + +(defmethod applicable-p (rule expr) nil) + +(defmethod applicable-p ((rule function-rule) (expr list-expression)) + (let ((elms (expression-list expr))) + (if (< (length elms) 2) + nil + (and (match-p (rule-name rule) (car elms)) + (match-p (rule-arg rule) (cadr elms)))))) + + +;;; Just simple integration with lisplab + +(defmethod print-object ((ex symbol-expression) stream) + (prin1 (expression-symbol ex) stream)) + +(defmethod print-object ((ex list-expression) stream) + (prin1 (expression-list ex) stream)) + + +;;; Bellow is just cut and paste code to simplify debugging. Must do it properly later + +(defmethod .= ((a symbol) (b symbol) &optional acc) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.=) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .= ((a symbol) (b number) &optional acc) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.=) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .= ((a number) (b symbol) &optional acc) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.=) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .= ((a expression-base) (b symbol) &optional acc) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.=) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .= ((a symbol) (b expression-base) &optional acc) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.=) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .= ((a expression-base) (b number) &optional acc) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.=) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .= ((a number) (b expression-base) &optional acc) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.=) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .add ((a symbol) (b symbol)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.+) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .add ((a symbol) (b number)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.+) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .add ((a number) (b symbol)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.+) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .add ((a expression-base) (b symbol)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.+) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .add ((a symbol) (b expression-base)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.+) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .add ((a expression-base) (b number)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.+) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .add ((a number) (b expression-base)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.+) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + + + + +(defmethod .mul ((a symbol) (b symbol)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.*) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .mul ((a symbol) (b number)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.*) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .mul ((a number) (b symbol)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.*) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .mul ((a expression-base) (b symbol)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.*) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .mul ((a symbol) (b expression-base)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.*) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .mul ((a expression-base) (b number)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.*) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + +(defmethod .mul ((a number) (b expression-base)) + (make-instance 'list-expression + :list (list (make-instance 'symbol-expression :symbol '.*) + (make-instance 'symbol-expression :symbol a) + (make-instance 'symbol-expression :symbol b)))) + + + + + + + + + + + + +#| + + (defclass expression () ((list :accessor expression-list :initform nil :initarg :list))) @@ -274,4 +497,6 @@ (case b (0 0) (1 a) - (t (call-next-method)))) \ No newline at end of file + (t (call-next-method)))) + +|# \ No newline at end of file Modified: trunk/src/fft/fftw-ffi-package.lisp ============================================================================== --- trunk/src/fft/fftw-ffi-package.lisp (original) +++ trunk/src/fft/fftw-ffi-package.lisp Mon May 24 10:02:40 2010 @@ -22,6 +22,10 @@ "+FFTW-BACKWARD+" "FFTW-FFT1" "FFTW-FFT2" + "FFTW-FFT1-R2C" + "FFTW-FFT1-C2R" + "FFTW-FFT2-R2C" + "FFTW-FFT2-C2R" "FFTW-INIT-THREADS" "FFTW-CLEANUP-THREADS") (:documentation "Simple ffi for fftw.")) Modified: trunk/src/fft/fftw-ffi.lisp ============================================================================== --- trunk/src/fft/fftw-ffi.lisp (original) +++ trunk/src/fft/fftw-ffi.lisp Mon May 24 10:02:40 2010 @@ -16,8 +16,6 @@ ;;; with this program; if not, write to the Free Software Foundation, Inc., ;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -;;; TODO: the calls should be wrapped in unwind protect -;;; to avoid memory leaks (in-package :fftw-ffi) @@ -29,38 +27,10 @@ (defconstant +FFTW-BACKWARD+ 1) -(declaim (inline |fftw_plan_dft_1d|)) -(define-alien-routine |fftw_plan_dft_1d| - (* t) - (n int) - (in (* double-float)) - (out (* double-float)) - (sign int) - (flags int)) - -(declaim (inline |fftw_plan_dft_2d|)) -(define-alien-routine |fftw_plan_dft_2d| - (* t) - (n0 int) - (n1 int) - (in (* double-float)) - (out (* double-float)) - (sign int) - (flags int)) - -(declaim (inline |fftw_execute|)) -(define-alien-routine |fftw_execute| - void - (plan (* t))) - -(declaim (inline |fftw_destroy_plan|)) -(define-alien-routine |fftw_destroy_plan| - void - (plan (* t))) +;;; The interface functions (defun fftw-fft1 (n a astart b bstart direction flag) "One dimensional fft by forign call to fftw." - ;; TODO we should handle conditions to avoid mem-leaks (let ((astart (* astart +double-float-bytes+)) (bstart (* bstart +double-float-bytes+))) (with-pinned-objects (a b) @@ -77,7 +47,6 @@ (defun fftw-fft2 (m n in out direction flag) "Two dimensional fft by forign call to fftw." - ;; TODO we should handle conditions to avoid mem-leaks (with-pinned-objects (in out) (let ((plan (|fftw_plan_dft_2d| n ; swap n and m due to row major order @@ -91,6 +60,100 @@ (|fftw_destroy_plan| plan)))) out) +(defun fftw-fft1-r2c (n a astart b bstart flag) + "One dimensional real fft by forign call to fftw. +The length of b must at least be n/2+1." + (let ((astart (* astart +double-float-bytes+)) + (bstart (* bstart +double-float-bytes+))) + (with-pinned-objects (a b) + (let ((plan (|fftw_plan_dft_r2c_1d| + n + (sap+ (vector-sap a) astart) + (sap+ (vector-sap b) bstart) + flag))) + (unwind-protect + (|fftw_execute| plan) + (|fftw_destroy_plan| plan)))) + b)) + +(defun fftw-fft1-c2r (n a astart b bstart flag) + "One dimensional reverse fft transform by forign call to fftw." + (let ((astart (* astart +double-float-bytes+)) + (bstart (* bstart +double-float-bytes+))) + (with-pinned-objects (a b) + (let ((plan (|fftw_plan_dft_c2r_1d| + n + (sap+ (vector-sap a) astart) + (sap+ (vector-sap b) bstart) + flag))) + (unwind-protect + (|fftw_execute| plan) + (|fftw_destroy_plan| plan)))) + b)) + +(defun fftw-fft2-r2c (m n in out flag) + "Two dimensional fft by forign call to fftw. Real to complex. Length of complex must +at least be n/2+1." + (with-pinned-objects (in out) + (let ((plan (|fftw_plan_dft_r2c_2d| + n ; swap n and m due to row major order + m + (vector-sap in) + (vector-sap out) + flag))) + (unwind-protect + (|fftw_execute| plan) + (|fftw_destroy_plan| plan)))) + out) + +(defun fftw-fft2-c2r (m n in out flag) + "Two dimensional inverse fft by forign call to fftw. Real to complex. +Length of complex must at least be n/2+1." + (with-pinned-objects (in out) + (let ((plan (|fftw_plan_dft_c2r_2d| + n ; swap n and m due to row major order + m + (vector-sap in) + (vector-sap out) + flag))) + (unwind-protect + (|fftw_execute| plan) + (|fftw_destroy_plan| plan)))) + out) + + + + +;;; The FFI definitions + +(declaim (inline |fftw_plan_dft_1d|)) +(define-alien-routine |fftw_plan_dft_1d| + (* t) + (n int) + (in (* double-float)) + (out (* double-float)) + (sign int) + (flags int)) + +(declaim (inline |fftw_plan_dft_2d|)) +(define-alien-routine |fftw_plan_dft_2d| + (* t) + (n0 int) + (n1 int) + (in (* double-float)) + (out (* double-float)) + (sign int) + (flags int)) + +(declaim (inline |fftw_execute|)) +(define-alien-routine |fftw_execute| + void + (plan (* t))) + +(declaim (inline |fftw_destroy_plan|)) +(define-alien-routine |fftw_destroy_plan| + void + (plan (* t))) ;;;; Now multi-thread code @@ -114,3 +177,38 @@ (defun fftw-cleanup-threads () (|fftw_cleanup_threads|)) +;;; Now real to complex transforms + +(declaim (inline |fftw_plan_dft_r2c_1d|)) +(define-alien-routine |fftw_plan_dft_r2c_1d| + (* t) + (n int) + (in (* double-float)) + (out (* double-float)) + (flags int)) + +(declaim (inline |fftw_plan_dft_c2r_1d|)) +(define-alien-routine |fftw_plan_dft_c2r_1d| + (* t) + (n int) + (in (* double-float)) + (out (* double-float)) + (flags int)) + +(declaim (inline |fftw_plan_dft_r2c_2d|)) +(define-alien-routine |fftw_plan_dft_r2c_2d| + (* t) + (n0 int) + (n1 int) + (in (* double-float)) + (out (* double-float)) + (flags int)) + +(declaim (inline |fftw_plan_dft_c2r_2d|)) +(define-alien-routine |fftw_plan_dft_c2r_2d| + (* t) + (n0 int) + (n1 int) + (in (* double-float)) + (out (* double-float)) + (flags int)) \ No newline at end of file Modified: trunk/src/fft/level3-fft-fftw.lisp ============================================================================== --- trunk/src/fft/level3-fft-fftw.lisp (original) +++ trunk/src/fft/level3-fft-fftw.lisp Mon May 24 10:02:40 2010 @@ -58,13 +58,12 @@ (y (mcreate x)) (store-y (matrix-store y))) (dotimes (i cols) - ;; Could be made in parallel (fftw-ffi:fftw-fft1 rows store-x - (* i cols) + (* 2 i rows) store-y - (* i cols) + (* 2 i rows) fftw-ffi:+FFTW-FORWARD+ fftw-ffi:+FFTW-ESTIMATE+)) y))) @@ -78,13 +77,12 @@ (y (mcreate x)) (store-y (matrix-store y))) (dotimes (i cols) - ;; Could be made in parallel (fftw-ffi:fftw-fft1 rows store-x - (* i cols) + (* 2 i rows) store-y - (* i cols) + (* 2 i rows) fftw-ffi:+FFTW-BACKWARD+ fftw-ffi:+FFTW-ESTIMATE+)) y))) @@ -115,7 +113,12 @@ fftw-ffi:+FFTW-ESTIMATE+) y))) -;;; TODO: remove the destructive mothods below. They only mess things up +;;; The below methods and functions with optimizations, such +;;; as destructive transforms and real to complex transforms. Note +;;; that these are less tested than the other and more likly to have bugs. + +;;; TODO: I should change the destructive methods so that they have explicite +;;; output also. (defun fft1!-forward-or-backward (x direction) (let* ((rows (rows x)) @@ -125,25 +128,27 @@ (fftw-ffi:fftw-fft1 rows store - (* i cols) + (* 2 i rows) store - (* i cols) + (* 2 i rows) direction fftw-ffi:+FFTW-ESTIMATE+))) x) (defmethod fft1! ((x matrix-blas-zge) &key) - (if cl-user::*lisplab-libfftw-path* - (fft1!-forward-or-backward x fftw-ffi:+fftw-forward+) - (call-next-method))) + (if (not (use-fftw-p)) + (call-next-method) + (fft1!-forward-or-backward x fftw-ffi:+fftw-forward+))) + (defmethod ifft1! ((x matrix-blas-zge) &key) - (if cl-user::*lisplab-libfftw-path* - (fft1!-forward-or-backward x fftw-ffi:+fftw-backward+) - (call-next-method))) + (if (not (use-fftw-p)) + (call-next-method) + (fft1!-forward-or-backward x fftw-ffi:+fftw-backward+))) (defmethod fft2! ((x matrix-blas-zge) &key) - (if cl-user::*lisplab-libfftw-path* + (if (not (use-fftw-p)) + (call-next-method) (progn (fftw-ffi:fftw-fft2 (rows x) @@ -152,11 +157,11 @@ (matrix-store x) fftw-ffi:+fftw-forward+ fftw-ffi:+FFTW-ESTIMATE+) - x) - (call-next-method))) + x))) (defmethod ifft2! ((x matrix-blas-zge) &key) - (if cl-user::*lisplab-libfftw-path* + (if (not (use-fftw-p)) + (call-next-method) (progn (fftw-ffi:fftw-fft2 (rows x) @@ -165,5 +170,58 @@ (matrix-store x) fftw-ffi:+fftw-backward+ fftw-ffi:+FFTW-ESTIMATE+) - x) - (call-next-method))) + x))) + +(defmethod fftw1-r2c! ((x matrix-blas-dge) (y matrix-blas-zge)) + "Real to complex transform. y must have dimensions 1+(rows x)/2 X (cols x)." + (let* ((rows-x (rows x)) + (cols-x (cols x)) + (rows-y (rows y)) + (store-x (matrix-store x)) + (store-y (matrix-store y))) + (dotimes (i cols-x) + (fftw-ffi:fftw-fft1-r2c + rows-x + store-x + (* i rows-x) + store-y + (* 2 i rows-y) + fftw-ffi:+FFTW-ESTIMATE+))) + y) + +(defmethod fftw1-c2r! ((x matrix-blas-zge) (y matrix-blas-dge)) + "Complx to real inverse transform. x must have dimensions 1+(rows y)/2 X (cols y)." + (let* ((rows-y (rows y)) + (cols-y (cols y)) + (rows-x (rows x)) + (store-x (matrix-store x)) + (store-y (matrix-store y))) + (dotimes (i cols-y) + (fftw-ffi:fftw-fft1-c2r + rows-y + store-x + (* 2 i rows-x) + store-y + (* i rows-y) + fftw-ffi:+FFTW-ESTIMATE+))) + y) + +(defmethod fftw2-r2c! ((x matrix-blas-dge) (y matrix-blas-zge)) + "Real to complex transform. y must have dimensions 1+(rows x)/2 X (cols x)." + (fftw-ffi:fftw-fft2-r2c + (rows x) + (cols x) + (matrix-store x) + (matrix-store y) + fftw-ffi:+FFTW-ESTIMATE+) + y) + +(defmethod fftw2-c2r! ((x matrix-blas-zge) (y matrix-blas-dge)) + "Complx to real inverse transform. x must have dimensions 1+(rows y)/2 X (cols y)." + (fftw-ffi:fftw-fft2-c2r + (rows y) + (cols y) + (matrix-store x) + (matrix-store y) + fftw-ffi:+FFTW-ESTIMATE+) + y) \ No newline at end of file