tlinalg_abstract.py - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
 (HTM) git clone git://src.adamsgaard.dk/pism
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
       tlinalg_abstract.py (4590B)
       ---
            1 ############################################################################
            2 #
            3 #  This file is a part of siple.
            4 #
            5 #  Copyright 2010 David Maxwell
            6 #
            7 #  siple is free software: you can redistribute it and/or modify
            8 #  it under the terms of the GNU General Public License as published by
            9 #  the Free Software Foundation, either version 2 of the License, or
           10 #  (at your option) any later version.
           11 # 
           12 ############################################################################
           13 
           14 class AbstractVector:
           15   """
           16   Defines the interface that a vector is required to implement for use in the
           17   inverse problem routines.  Typically a subclass will have a member variable
           18   that contains a class that is the concrete representation of the vector (e.g. 
           19   a FEniCS Function or a PETSc Vec) and translates the AbstractVector methods
           20   to operations on its concrete data.
           21   
           22   An abstract vector does not have a notion of of an assoiciated basis, so
           23   it does not make sense to access the 'coefficients' of an abstract vector.
           24   Hence there is no operator[] associated with an AbstractVector.
           25   
           26   When the underlying vector is needed, use the core() method to access it.
           27   """
           28   
           29   def set(self,rhs):
           30     """Sets the value of the vector to the value of 'rhs'. If 'rhs' is not of the same
           31     class as the current vector, an exception may be thrown.
           32     """
           33     if isinstance(rhs,AbstractVector):
           34       self._set_from_abstract(rhs)
           35     else:
           36       self._set_from_array(rhs)
           37 
           38   def _set_from_abstract(self,rhs):
           39     raise NotImplementedError()
           40 
           41   def _set_from_array(self,rhs):
           42     """Sets the vector from anything array-like. The interpretation of this
           43     operation is implementation dependent."""
           44     raise NotImplementedError()
           45 
           46 
           47   def acc(self,rhs):
           48     """Adds the vector 'rhs' to the current vector (i.e. accumulates rhs)."""
           49     raise NotImplementedError()
           50 
           51   def sum(self,rhs,storage=None):
           52     """Returns a vector that is the sum of the current vector and 'rhs'.  Uses 'storage'
           53     for the return value if it is specified."""
           54     if storage is None:
           55       storage = self.copy()
           56     else:
           57       storage.set(self)
           58     storage.acc(rhs)
           59     return storage
           60 
           61   def diff(self,rhs,storage=None):
           62     """Returns a vector that is the difference of the current vector and 'rhs'.  Uses 'storage'
           63     for the return value if it is specified."""
           64     if storage is None:
           65       storage = self.copy()
           66     else:
           67       storage.set(self)
           68     storage.axpy(-1,rhs)
           69     return storage
           70 
           71   def mul(self,t,storage=None):
           72     """Returns a vector that is the current vector, using 'storage' for the return value if given."""
           73     if storage is None:
           74       storage = self.copy()
           75     else:
           76       storage.set(self)
           77     storage.scale(t)
           78     return storage
           79 
           80   def lincomb(self,t0,t1,v,storage=None):
           81     """Returns the vector t0*u+t1*v where u is the current vector.  Uses 'storage'
           82     for the return value if it is specified"""
           83     if storage is None:
           84       storage = self.copy()
           85     else:
           86       storage.set(self)
           87     storage.scale(t0)
           88     storage.axpy(t1,v)
           89     return storage
           90 
           91   def dim(self):
           92     """Returns the dimension of the ambient vector space"""
           93     raise NotImplementedError()
           94 
           95   def size(self):
           96     return self.dim()
           97 
           98   def core(self):
           99     """Returns the underlying concrete vector."""
          100     raise NotImplementedError()
          101 
          102   def scale(self,t):
          103     """Multiplies the current vector by the scalar 't'."""
          104     raise NotImplementedError()
          105 
          106   def axpy(self,t,v):
          107     """Adds t*v to the current vector."""
          108     raise NotImplementedError()
          109 
          110   def copy(self):
          111     """Returns a new vector with the same contents as sthe current one."""
          112     raise NotImplementedError()
          113     
          114   def vector_like(self):
          115     """Returns a new vector in the same vector space as the current vector.  The value
          116     of the vector is not specified."""
          117     raise NotImplementedError()
          118     
          119   def zero_like(self):
          120     """Returns a zero vector in the same vector space as the current vector."""
          121     raise NotImplementedError()
          122 
          123   def norm(self,name):
          124     """Returns a norm of the vector.  The string name describes the desired
          125     norm (e.g. 'l1', 'l2', 'linf').  There is no guarantee that an AbstractVector
          126     has a notion of any particular norm. Use with caution."""
          127     raise NotImplementedError()
          128 
          129   def __imul__(self,t):
          130     self.scale(t)
          131     return self
          132 
          133   def __iadd__(self,v):
          134     self.acc(v)
          135     return self
          136 
          137   def __isub__(self,v):
          138     self.axpy(-1,v)
          139     return self
          140   
          141   def __idiv__(self,t):
          142     self.scale(1./t)
          143     return self
          144     
          145   def __sub__(self,other):
          146     return self.diff(other)
          147     
          148   def __add__(self,other):
          149