Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

units tests

I just stumbled over a problem again that I reported years ago in sage-devel, but perhaps someone here can help. I am still after the quick and dirty way for using the existing units package in sage to test symbolic equations for consistent units. This is currently not possible because units are treated as conventional variables, meaning that:

units.x.y - units.x.y

0

The only thing that really stops me right now is that I don't know how to get it to return:

units.x.y + units.x.y

units.x.y

units.x.y - units.x.y

units.x.y

Is there an easy way to write a function or create a subclass that would do that while keeping the rest (multiplication, division, exponents etc.) the way it is?

Thanks already for your help!

units tests

I just stumbled over a problem again that I reported years ago in sage-devel, but perhaps someone here can help. I am still after the quick and dirty way for using the existing units package in sage to test symbolic equations for consistent units. This is currently not possible because units are treated as conventional variables, meaning that:

units.x.y - units.x.y

0

The only thing that really stops me right now is that I don't know how to get it to return:

units.x.y + units.x.y

units.x.y

units.x.y - units.x.y

units.x.y

Is there an easy way to write a function or create a subclass that would do that while keeping the rest (multiplication, division, exponents etc.) the way it is?

Thanks already A modification of the first answer by tmonteil does part of the job:

class MYExp(sage.symbolic.expression.Expression):
def __sub__(self,other):
    if self.convert() == other.convert():
        return self
    else:
        raise TypeError('Subtraction of non-matching units')

def __add__(self,other):
    if self.convert() == other.convert():
        return self
    else:
        raise TypeError('Sum of non-matching units')
def __mul__(self,other):
        return MYExp(SR, super(MYExp, self).__mul__(other))
def __div__(self,other):
    return MYExp(SR, super(MYExp, self).__div__(other))
def __pow__(self,other):
    return MYExp(SR, super(MYExp, self).__pow__(other))

U = lambda x: MYExp(SR,x)
for your help! s in units.length.trait_names():
    globals()[s] = U(getattr(units.length,s))

Now this works:

type(meter*2)

class '__main__.MYExp'

But this does not:

type(2*meter)

type 'sage.symbolic.expression.Expression'

Similar for division. Is there a way to somehow modify the above to make any expressions involving MYExp return a MYExp, rather than just those expressions that start with MYExp? Sorry for expressing my ignorance about the organisation of classes, parents, elements etc. in sage...

units tests

I just stumbled over a problem again that I reported years ago in sage-devel, but perhaps someone here can help. I am still after the quick and dirty way for using the existing units package in sage to test symbolic equations for consistent units. This is currently not possible because units are treated as conventional variables, meaning that:

units.x.y - units.x.y

0

The only thing that really stops me right now is that I don't know how to get it to return:

units.x.y + units.x.y

units.x.y

units.x.y - units.x.y

units.x.y

Is there an easy way to write a function or create a subclass that would do that while keeping the rest (multiplication, division, exponents etc.) the way it is?

UPDATE: A modification of the first answer by tmonteil does part of the job:

class MYExp(sage.symbolic.expression.Expression):
def __sub__(self,other):
    if self.convert() == other.convert():
        return self
    else:
        raise TypeError('Subtraction of non-matching units')

def __add__(self,other):
    if self.convert() == other.convert():
        return self
    else:
        raise TypeError('Sum of non-matching units')
def __mul__(self,other):
        return MYExp(SR, super(MYExp, self).__mul__(other))
def __div__(self,other):
    return MYExp(SR, super(MYExp, self).__div__(other))
def __pow__(self,other):
    return MYExp(SR, super(MYExp, self).__pow__(other))

U = lambda x: MYExp(SR,x)
for s in units.length.trait_names():
    globals()[s] = U(getattr(units.length,s))

Now this works:

type(meter*2)

class '__main__.MYExp'

But this does not:

type(2*meter)

type 'sage.symbolic.expression.Expression'

Similar for division. Is there a way to somehow modify the above to make any expressions involving MYExp return a MYExp, rather than just those expressions that start with MYExp? Sorry for expressing my ignorance about the organisation of classes, parents, elements etc. in sage...