Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes implementation to SymPy #26

Merged
merged 2 commits into from
Jul 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 7 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ language: python

python:
- '2.7'
- '3.6'

sudo: true

Expand All @@ -38,25 +39,21 @@ env:
- secure: KwansI0JAlS1EZe0yPP16mLf16tdy3uT6thiFral7VLA+PsfiEYJbjnkaDBKu/ICB70KK46EA7rJ4bpof0RKDyadTKY1nixDrIVPhFIQaqAuUILmsPmFcS7xzh0DPCz8C1SK01jqJgzutztFCQkQfYjHUL6pHM9x46mImsJLyqmKjT74GGGt29iINkO2jK54WmJWb79G9eWNCGtNCepEXEwQvReD7Bs9oR/ErZULugfZTCsPGMQa40rOt+tW6rYg32hJkGZBU52dUk5VqopLV4eQopkrEvk+5mURewUj+QR59i92jhtHtGqpcl4gGlSRKteII0dNF2KFHLGViOEsSjbKfdcjCnvRawypeEJVvtTizBL2N5zL4Zku56QRZhDSOia/ZyCgXBLQJpxUM/9OxI7c7X87qQGCwvTTg3UqBbYw8NLcuz4UTn0eNXTkguW3w6v9QXpMyiJDIthvSAAuj5JhKKeNrrqCQazSfozjj10YJeZxoMXtm6cjbGhAOJVBBLFEEre33cqv52CrS5aK3Pr5mHIXpNkMVBZpCfzF0e/OHPliSqSsOPeoeKxqLYnJQf/EmGnEPf9LSYSxIxiIdSMrCdlkZf2ysRVSp73BM1w9vOO0vpp2KOQYT58XNc/ex1XE2uh77I48F6SFwYnsTutzyNMKzCqnyTp2STeD/aE=

before_install:
- >
if [ ! -f SageMath/sage ] ; then
wget -O - http://mirror.switch.ch/mirror/sagemath/linux/64bit/sage-7.6-Ubuntu_12.04-x86_64.tar.bz2 | tar xjf -;
SageMath/sage -pip install -U pip setuptools;
fi
- travis_retry SageMath/sage -pip install twine wheel coveralls
- travis_retry pip install twine wheel coveralls
- travis_retry pip install check-manifest pydocstyle
- travis_retry pip install https://github.com/sympy/sympy/archive/1.1.zip

install:
- SageMath/sage -pip install -e .[all]
- pip install -e .[all]

script:
- SageMath/sage setup.py test
- SageMath/sage setup.py build_sphinx
- python setup.py test
- python setup.py build_sphinx
- pydocstyle essm
- check-manifest

after_script:
- SageMath/sage -sh -c coveralls
- coveralls

after_success:
- ./gh-pages.sh
Expand Down
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def get_attr(obj, value, *args, **kwargs):
extensions = ['matplotlib.sphinxext.plot_directive',
'sphinxcontrib.bibtex',
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
Expand Down
5 changes: 2 additions & 3 deletions essm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,5 @@

from __future__ import absolute_import

from .bases import convert, expand_units

__all__ = ('convert', 'expand_units')
from sympy import E as e
from sympy import Eq, solve, sqrt
16 changes: 8 additions & 8 deletions essm/_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
from collections import defaultdict

import pkg_resources
from isort import SortImports
from yapf.yapflib.yapf_api import FormatCode

from isort import SortImports
from sage import all as sage_all
import essm

from .variables import Variable

Expand Down Expand Up @@ -78,9 +78,9 @@ class {name}(Variable):
"""

# CONSTANTS = re.compile(r'\b(e|pi)\b')
SAGE_IMPORTS = re.compile(
_IMPORTS = re.compile(
r'\b({0})\b'.format(
'|'.join(name for name in dir(sage_all) if not name.startswith('_'))))
'|'.join(name for name in dir(essm) if not name.startswith('_'))))
"""Regular expression to find sage-specific constants and functions."""


Expand Down Expand Up @@ -197,7 +197,7 @@ def var(
# register all imports of units
if units:
if units != 1:
for arg in units.args():
for arg in units.args:
self._imports['essm.variables.units'].add(str(arg))

def write(self, filename):
Expand Down Expand Up @@ -313,14 +313,14 @@ def eq(self, name, expr, doc='', parents=None, variables=None):
self.eqs.append(context)

# register all imports
for arg in expr.args():
for arg in expr.args:
if str(arg) not in internal_variables and\
arg in Variable.__registry__:
self._imports[Variable.__registry__[arg].__module__].add(
str(arg))

for match in re.finditer(SAGE_IMPORTS, str(expr)) or []:
self._imports['sage.all'].add(match.group())
for match in re.finditer(_IMPORTS, str(expr)) or []:
self._imports['essm'].add(match.group())

def write(self, filename):
"""Serialize itself to a filename."""
Expand Down
76 changes: 18 additions & 58 deletions essm/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,68 +23,28 @@

import warnings

from sage.all import SR, Expression

class RegistryType(type):
"""Base registry operations."""

def expand_units(expr, units=None, simplify_full=True):
"""Expand units of all arguments in expression."""
from .variables._core import Variable

units = units or Variable.__units__
used_units = {}
# Need to multiply units with variable,
# so that we can devide by the symbolic equation later:
for variable in expr.arguments():
used_units[variable] = variable * units[variable]

result = convert(Expression(SR, expr.subs(used_units) / expr))
if simplify_full:
result = result.simplify_full()
return result


def convert(expr):
"""Convert a given expression."""
op = expr.operator()
ops = expr.operands()
if op:
return op(*(convert(o) for o in ops))
return expr.convert() if hasattr(expr, 'convert') else expr


class BaseExpression(Expression):
"""Add definition and instance documentation."""

def __init__(self, expr, definition, units=None):
"""Initialize expression."""
super(BaseExpression, self).__init__(SR, expr)
self.definition = definition
self.__units__ = units or getattr(definition, '__units__', None)

def register(self):
def __setitem__(cls, expr, definition):
"""Register expression in registry."""
if self in self.definition.__registry__:
if expr in cls.__registry__:
warnings.warn(
'"{0}" will be overridden by "{1}"'.format(
self.definition.__registry__[self].__module__ + ':' +
self.definition.name,
self.definition.__module__ + ':' + str(self), ),
cls.__registry__[expr].__module__ + ':' +
cls.__registry__[expr].name,
definition.__module__ + ':' + str(cls), ),
stacklevel=2)
self.definition.__registry__[self] = self.definition
return self

def expand_units(self, simplify_full=True):
"""Expand units of all arguments in expression."""
return expand_units(self, self.__units__, simplify_full=simplify_full)

def short_units(self):
"""Return short units of equation."""
from .variables.units import SHORT_UNIT_SYMBOLS
return self.expand_units().subs(SHORT_UNIT_SYMBOLS)

def convert(self):
"""Convert itself using custom ``convert`` function."""
return convert(self)
cls.__registry__[expr] = definition


__all__ = ('BaseExpression', 'convert', 'expand_units')
def __delitem__(cls, expr):
"""Remove a expr from the registry."""
if expr in cls.__registry__:
warnings.warn(
'"{0}" will be unregistered.'.format(
cls.__registry__[expr].__module__),
stacklevel=2)
del cls.__registry__[expr]
else:
raise KeyError(expr)
38 changes: 22 additions & 16 deletions essm/equations/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@

from __future__ import absolute_import

from sage.all import SR
from sage.misc.latex import latex
import warnings

from ..bases import BaseExpression, convert
import six
from sympy.core.relational import Eq

from ..bases import RegistryType
from ..transformer import build_instance_expression
from ..variables import Variable
from ..variables._core import BaseVariable
from ..variables.units import derive_quantity, unit_symbols


class EquationMeta(type):
class EquationMeta(RegistryType):
r"""Equation interface.

Defines an equation with a docstring and internal variables,
Expand Down Expand Up @@ -97,36 +100,39 @@ def __new__(cls, name, parents, dct):

instance = super(EquationMeta, cls).__new__(
cls, name, parents, dct)
instance.expr = expr = BaseEquation(
build_instance_expression(instance, expr),
instance,
units=Variable.__units__, ).register()

expanded_units = expr.expand_units()
if not expanded_units:
raise ValueError(
'Invalid expression units: {0}'.format(expanded_units))
expr = build_instance_expression(instance, expr)
instance.expr = expr = BaseEquation(instance, expr)
instance[expr] = instance

return expr

return super(EquationMeta, cls).__new__(cls, name, parents, dct)


@six.add_metaclass(EquationMeta)
class Equation(object):
"""Base type for all equations."""

__metaclass__ = EquationMeta
__registry__ = {}

@classmethod
def args(cls):
"""Return equation arguments from registry if exist."""
return tuple(
Variable.__registry__.get(arg, arg) for arg in cls.expr.args())
Variable.__registry__.get(arg, arg)
for arg in cls.expr.atoms(BaseVariable))


class BaseEquation(BaseExpression):
class BaseEquation(Eq):
"""Add definition and short unit."""

def __new__(cls, definition, expr):
if not isinstance(expr, Eq):
return expr
self = super(BaseEquation, cls).__new__(cls, *expr.args)
self.definition = definition
return self

@property
def __doc__(self):
return self.definition.__doc__
Expand Down
4 changes: 3 additions & 1 deletion essm/equations/chamber/insulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

from __future__ import absolute_import

from essm import Eq

from ...variables.chamber.insulation import A_i, L_i, Q_i, dT_i, lambda_i
from .._core import Equation

Expand All @@ -31,7 +33,7 @@ class eq_Qi(Equation):
:cite:`schymanski_leaf-scale_2017`
"""

expr = Q_i == dT_i * lambda_i * A_i / L_i
expr = Eq(Q_i, dT_i * lambda_i * A_i / L_i)
"""Describe how you got the equation."""


Expand Down