;;; Lisplab, level1-classes.lisp ;;; Level1, abstract matrix classes ;;; 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. ;;; The class structure is inspired by the stream example ;;; in Object-Oriented programming in Common Lisp, by Sonja E. Keene. ;;; There are three class hierarchies: ;;; 1) The element-types ;;; 2) The strucure ;;; 3) The preffered implmentation of the methods ;;; ;;; Only the builing blocks are in this file. ;;; The classes for implmentations are somwhere else. (in-package :lisplab) (defgeneric find-element-type-class (element-type)) (defgeneric find-structure-class (structure)) (defgeneric find-implementation-class (implementation)) (defgeneric element-type-class-name (obj)) (defgeneric implementation-class-name (obj)) (defgeneric structure-class-name (obj)) (defgeneric element-type-spec (obj)) (defgeneric implementation-spec (obj)) (defgeneric structure-specs (obj)) (defgeneric make-matrix-class (element-type structure implementation) (:documentation "Creates a class from the three input classes.")) (defmethod make-matrix-class ((element-type standard-class) (structure standard-class) (implementation standard-class)) (let* ((args (list element-type structure implementation))) (make-instance 'standard-class :direct-superclasses args))) (defmethod make-matrix-class ((element-type symbol) (structure symbol) (implementation symbol)) (make-matrix-class (find-element-type-class element-type) (find-structure-class structure) (find-implementation-class implementation))) ;;; The matrix element tells the element type of the matrix ;; TOOD remove (defgeneric find-element-mixin (spec)) ;;; The implementation is a mixin intended to solve conflicts ;;; when there is one foreign and one native implementation (defclass implementation-base () ((implementation-class-name :allocation :class :initform 'implementation-base :reader implementation-class-name) (implementation-spec :allocation :class :initform :base :reader implementation-spec))) (defclass implementation-lisp (implementation-base) ((implementation-class-name :allocation :class :initform 'implementation-lisp :reader implementation-class-name) (implementation-spec :allocation :class :initform :lisp :reader implementation-spec))) (defclass implementation-foreign (implementation-lisp) ((implementation-class-name :allocation :class :initform 'implementation-foreign :reader implementation-class-name) (implementation-spec :allocation :class :initform :foreign :reader implementation-spec))) ;;; The matrix structure tells the structure of the matrix (defclass matrix-base () ()) (defclass structure-base (matrix-base) ((structure-class-name :allocation :class :initform 'structure-base :reader structure-class-name) (structure-spec :allocation :class :initform :base :reader structure-spec))) (defclass structure-general (structure-base) ((structure-class-name :allocation :class :initform 'structure-general :reader structure-class-name) (structure-spec :allocation :class :initform :ge :reader structure-spec) (rows :initarg :rows :initform 0 :reader rows :type type-blas-idx) (cols :initarg :cols :initform 0 :reader cols :type type-blas-idx))) (defclass structure-square (structure-base) ((structure-class-name :allocation :class :initform 'structure-square :reader structure-class-name) (structure-spec :allocation :class :initform :square ; Or is it something else in lapack? :reader structure-spec) (rowcols :initarg :rowcols :initform 0 :reader rowcols :type type-blas-idx))) (defclass structure-diagonal (structure-square) ((structure-class-name :allocation :class :initform 'structure-diagonal :reader structure-class-name) (structure-spec :allocation :class :initform :di :reader structure-spec))) (defclass structure-bidiagonal (structure-square) ((structure-class-name :allocation :class :initform 'structure-bidiagonal :reader structure-class-name) (structure-spec :allocation :class :initform :bi ;; Is this the same as lapack? If not change it :reader structure-spec))) (defclass structure-tridiagonal (structure-square) ((structure-class-name :allocation :class :initform 'structure-tridiaonal :reader structure-class-name) (structure-spec :allocation :class :initform :gt :reader structure-spec))) ;;; Search methods ;;; ... these are not complete (defmethod find-element-type-class ((spec (eql :any))) (find-class 'element-base)) (defmethod find-element-type-class ((spec (eql :d))) (find-class 'element-double-float)) (defmethod find-element-type-class ((spec (eql :z))) (find-class 'element-complex-double-float)) (defmethod find-element-type-class ((spec (eql :ub8))) (find-class 'element-ub8)) (defmethod find-element-type-class ((spec (eql :sb8))) (find-class 'element-sb8)) (defmethod find-structure-class ((spec (eql :ge))) (find-class 'structure-general)) (defmethod find-structure-class ((spec (eql :gt))) (find-class 'structure-tridiagonal)) (defmethod find-structure-class ((spec (eql :di))) (find-class 'structure-diagonal)) (defmethod find-implementation-class ((spec (eql :lisp))) (find-class 'implementation-lisp)) (defmethod find-implementation-class ((spec (eql :foreign))) (find-class 'implementation-foreign))