Changeset 1754


Ignore:
Timestamp:
Aug 24, 2005, 5:37:45 PM (19 years ago)
Author:
ole
Message:

Implemented operator overloading for quantities
Implemented set_values with quantity as input
+ testing

Location:
inundation/pyvolution
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • inundation/pyvolution/quantity.py

    r1753 r1754  
    5454        self.interpolate()
    5555
     56
     57
     58    #Methods for operator overloading   
    5659    def __len__(self):
    5760        return self.centroid_values.shape[0]
     61
     62
     63    def __neg__(self):
     64        """Negate all values in this quantity giving meaning to the
     65        expression -Q where Q is an instance of class Quantity
     66        """
     67
     68        Q = Quantity(self.domain)
     69        Q.set_values(-self.vertex_values)
     70        return Q
     71   
     72
     73    def __add__(self, other):
     74        """Add to self anything that could populate a quantity:
     75        E.g other can be a constant, an array, a function, another quantity
     76        (except for a filename or points, attributes (for now))
     77        - see set_values for details
     78        """
     79
     80        Q = Quantity(self.domain)
     81        Q.set_values(other)       
     82
     83        result = Quantity(self.domain)
     84        result.set_values(self.vertex_values + Q.vertex_values)
     85        return result
     86
     87    def __radd__(self, other):
     88        """Handle cases like 7+Q, where Q is an instance of class Quantity
     89        """
     90        return self + other
     91   
     92   
     93    def __sub__(self, other):   
     94        return self + -other  #Invoke __neg__
     95
     96    def __mul__(self, other):
     97        """Multiply self with anything that could populate a quantity:
     98        E.g other can be a constant, an array, a function, another quantity
     99        (except for a filename or points, attributes (for now))
     100        - see set_values for details
     101
     102        Note that if two quantitites q1 and q2 are multiplied,
     103        vertex values are multiplied entry by entry
     104        while centroid and edge values are re-interpolated.
     105        Hence they won't be the product of centroid or edge values
     106        from q1 and q2.
     107        """
     108
     109        Q = Quantity(self.domain)
     110        Q.set_values(other)
     111       
     112        result = Quantity(self.domain)
     113        result.set_values(self.vertex_values * Q.vertex_values)
     114        return result
     115       
     116    def __rmul__(self, other):
     117        """Handle cases like 3*Q, where Q is an instance of class Quantity
     118        """
     119        return self * other
     120   
    58121
    59122    def interpolate(self):
     
    97160       
    98161        numeric:
    99        
    100162          Compatible list, Numeric array (see below) or constant.
    101           If callable it will treated as a function for convenience and
    102           backwards compatibility
     163          If callable it will treated as a function
     164          If instance of another Quantity it will be treated as such.
    103165
    104166        quantity:
    105 
    106167          Another quantity (compatible quantity, e.g. obtained as a
    107168          linear combination of quantities)
     
    124185          If attribute_name is specified, any array matching that name
    125186          will be used. Otherwise the first available one will be used.
    126          
     187
    127188        alpha:
    128189          Smoothing parameter to be used with least squares fits.
     
    173234
    174235        #General input checks
     236        L = [numeric, quantity, function, points, filename]       
    175237        msg = 'Exactly one of the arguments '+\
    176238              'numeric, quantity, function, points, or filename '+\
    177               'must be present.'
    178         L = [numeric, quantity, function, points, filename]
    179 
     239              'must be present. L = %s' %str(L)
    180240        assert L.count(None) == len(L)-1, msg
    181241
     
    204264                self.set_values_from_function(numeric,
    205265                                              location, indices, verbose)
     266            elif isinstance(numeric, Quantity):
     267                self.set_values_from_quantity(numeric,
     268                                              location, indices, verbose)
    206269            else:
    207270                msg = 'Illegal type for argument numeric: %s' %str(numeric)
    208271                raise msg
     272           
    209273        elif quantity is not None:
    210274            self.set_values_from_quantity(quantity,
     
    302366        location: Where values are to be stored.
    303367        Permissible options are: vertices, edges, centroid, unique vertices
    304         Default is "vertices"
     368        Default is 'vertices'
    305369
    306370        indices - if this action is carried out on a subset of
     
    396460                                 location, indices, verbose):
    397461        """Set quantity values from specified quantity instance q
    398         """
    399 
    400 
    401         raise 'not yet implemented'
     462
     463        Location is ignored
     464        """
     465       
     466       
     467        A = q.vertex_values
     468
     469        from Numeric import allclose
     470        msg = 'Quantities are defined on different meshes. '+\
     471              'This might be a case for implementing interpolation '+\
     472              'between different meshes.'
     473        assert allclose(A.shape, self.vertex_values.shape), msg
     474
     475        self.set_values(A, location='vertices',
     476                        indices=indices,
     477                        verbose=verbose)
     478
    402479
    403480    def set_values_from_function(self, f,
  • inundation/pyvolution/test_quantity.py

    r1753 r1754  
    278278       
    279279
    280     def test_set_vertex_values_using_least_squares(self):
     280    def test_set_values_using_least_squares(self):
    281281
    282282       
     
    379379       
    380380
     381
     382    def test_set_values_from_quantity(self):
     383
     384        quantity1 = Quantity(self.mesh4)
     385        quantity1.set_vertex_values([0,1,2,3,4,5])
     386
     387        assert allclose(quantity1.vertex_values,
     388                        [[1,0,2], [1,2,4], [4,2,5], [3,1,4]])
     389
     390       
     391        quantity2 = Quantity(self.mesh4)
     392        quantity2.set_values(quantity = quantity1)
     393        assert allclose(quantity2.vertex_values,
     394                        [[1,0,2], [1,2,4], [4,2,5], [3,1,4]])
     395
     396        quantity2.set_values(quantity = 2*quantity1)
     397        assert allclose(quantity2.vertex_values,
     398                        [[2,0,4], [2,4,8], [8,4,10], [6,2,8]])
     399       
     400        quantity2.set_values(quantity = 2*quantity1 + 3)
     401        assert allclose(quantity2.vertex_values,
     402                        [[5,3,7], [5,7,11], [11,7,13], [9,5,11]])
     403
     404
     405        #Check detection of quantity as first orgument
     406        quantity2.set_values(2*quantity1 + 3)
     407        assert allclose(quantity2.vertex_values,
     408                        [[5,3,7], [5,7,11], [11,7,13], [9,5,11]])             
     409
     410
     411
     412
     413
     414    def test_overloading(self):
     415
     416        quantity1 = Quantity(self.mesh4)
     417        quantity1.set_vertex_values([0,1,2,3,4,5])
     418
     419        assert allclose(quantity1.vertex_values,
     420                        [[1,0,2], [1,2,4], [4,2,5], [3,1,4]])
     421
     422       
     423        quantity2 = Quantity(self.mesh4)
     424        quantity2.set_values([[1,2,3], [5,5,5], [0,0,9], [-6, 3, 3]],
     425                             location = 'vertices')
     426
     427
     428
     429        quantity3 = Quantity(self.mesh4)
     430        quantity3.set_values([[2,2,2], [7,8,9], [7,6,3], [3, 8, -8]],
     431                             location = 'vertices')       
     432
     433
     434        #Negation
     435        Q = -quantity1
     436        assert allclose(Q.vertex_values, -quantity1.vertex_values)
     437        assert allclose(Q.centroid_values, -quantity1.centroid_values)
     438        assert allclose(Q.edge_values, -quantity1.edge_values)               
     439       
     440        #Addition
     441        Q = quantity1 + 7
     442        assert allclose(Q.vertex_values, quantity1.vertex_values + 7)
     443        assert allclose(Q.centroid_values, quantity1.centroid_values + 7)
     444        assert allclose(Q.edge_values, quantity1.edge_values + 7)       
     445       
     446        Q = 7 + quantity1
     447        assert allclose(Q.vertex_values, quantity1.vertex_values + 7)       
     448        assert allclose(Q.centroid_values, quantity1.centroid_values + 7)
     449        assert allclose(Q.edge_values, quantity1.edge_values + 7)       
     450       
     451        Q = quantity1 + quantity2
     452        assert allclose(Q.vertex_values,
     453                        quantity1.vertex_values + quantity2.vertex_values)
     454        assert allclose(Q.centroid_values,
     455                        quantity1.centroid_values + quantity2.centroid_values)
     456        assert allclose(Q.edge_values,
     457                        quantity1.edge_values + quantity2.edge_values)       
     458       
     459
     460        Q = quantity1 + quantity2 - 3
     461        assert allclose(Q.vertex_values,
     462                        quantity1.vertex_values + quantity2.vertex_values - 3)
     463
     464        Q = quantity1 - quantity2
     465        assert allclose(Q.vertex_values,
     466                        quantity1.vertex_values - quantity2.vertex_values)   
     467
     468        #Scaling
     469        Q = quantity1*3
     470        assert allclose(Q.vertex_values, quantity1.vertex_values*3)
     471        assert allclose(Q.centroid_values, quantity1.centroid_values*3)
     472        assert allclose(Q.edge_values, quantity1.edge_values*3)               
     473        Q = 3*quantity1
     474        assert allclose(Q.vertex_values, quantity1.vertex_values*3)
     475
     476        #Multiplication
     477        Q = quantity1 * quantity2
     478        #print Q.vertex_values
     479        #print Q.centroid_values
     480        #print quantity1.centroid_values
     481        #print quantity2.centroid_values
     482       
     483        assert allclose(Q.vertex_values,
     484                        quantity1.vertex_values * quantity2.vertex_values)
     485
     486        #Linear combinations
     487        Q = 4*quantity1 + 2
     488        assert allclose(Q.vertex_values,
     489                        4*quantity1.vertex_values + 2)
     490       
     491        Q = quantity1*quantity2 + 2
     492        assert allclose(Q.vertex_values,
     493                        quantity1.vertex_values * quantity2.vertex_values + 2)
     494       
     495        Q = quantity1*quantity2 + quantity3
     496        assert allclose(Q.vertex_values,
     497                        quantity1.vertex_values * quantity2.vertex_values +
     498                        quantity3.vertex_values)       
     499        Q = quantity1*quantity2 + 3*quantity3
     500        assert allclose(Q.vertex_values,
     501                        quantity1.vertex_values * quantity2.vertex_values +
     502                        3*quantity3.vertex_values)               
     503        Q = quantity1*quantity2 + 3*quantity3 + 5.0
     504        assert allclose(Q.vertex_values,
     505                        quantity1.vertex_values * quantity2.vertex_values +
     506                        3*quantity3.vertex_values + 5)                       
     507       
     508        Q = quantity1*quantity2 - quantity3
     509        assert allclose(Q.vertex_values,
     510                        quantity1.vertex_values * quantity2.vertex_values -
     511                        quantity3.vertex_values)                               
     512        Q = 1.5*quantity1*quantity2 - 3*quantity3 + 5.0
     513        assert allclose(Q.vertex_values,
     514                        1.5*quantity1.vertex_values * quantity2.vertex_values -
     515                        3*quantity3.vertex_values + 5)                               
     516
     517        #Try combining quantities and arrays and scalars
     518        Q = 1.5*quantity1*quantity2.vertex_values -\
     519            3*quantity3.vertex_values + 5.0
     520        assert allclose(Q.vertex_values,
     521                        1.5*quantity1.vertex_values * quantity2.vertex_values -
     522                        3*quantity3.vertex_values + 5)                                       
     523       
     524   
    381525
    382526    def test_gradient(self):
Note: See TracChangeset for help on using the changeset viewer.