varius

View Source
from typing import Any, Dict

VARIABLE_STORAGE: Dict[str, Dict[str, float]] = {"default": dict()}
EXPRESSION_STORAGE: Dict[str, Dict[str, float]] = {"default": dict()}


class MagicGlobals:
    latex: bool = True  # use latex
    cv: str = "default"  # current version
    float_digit: int = 5
    repr_indent: int = 2


def reset_version(version: str):
    if version not in VARIABLE_STORAGE:
        raise KeyError(f"The version `{version}` does not exist.")
    VARIABLE_STORAGE[version] = dict()
    EXPRESSION_STORAGE[version] = dict()
    if MagicGlobals.cv == version:
        MagicGlobals.cv == "default"


def reset_all():
    VARIABLE_STORAGE.clear()
    EXPRESSION_STORAGE.clear()
    VARIABLE_STORAGE["default"] = dict()
    EXPRESSION_STORAGE["default"] = dict()
    MagicGlobals.cv == "default"


from .printer import *
from .scope import Scope as note
from .variable import Expression, Variable


def set_latex(use: bool = True):
    MagicGlobals.latex = use
    if use:
        latex_use_cdot()


set_latex(use=is_ipython())


vr = Variable
ex = Expression

__all__ = ["note", "vr", "ex", "show"]

__version__ = "0.1.10"
#   class note:
View Source
class Scope:
    "Scope: alias `note`"

    def __init__(self, version: str = "default", copy: Optional[str] = None):
        self.prev = G.cv
        self.version = version
        if version not in VS:
            new_version(version)
        if copy is not None:
            self.load(copy)

    @property
    def variables(self) -> Dict:
        return {latex_to_plain(k.name): v for k, v in VS[self.version].items()}

    @property
    def expressions(self) -> Dict:
        return {latex_to_plain(k): v for k, v in ES[self.version].items()}

    def load(self, other_version):
        duplicate(self.version, other_version)

    def __enter__(self):
        G.cv = self.version
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        G.cv = self.prev

    def __repr__(self) -> str:
        INDENT = G.repr_indent
        lines = []
        lines.append(f"Version: {self.version}")

        lines.append(" " * INDENT + "Variables:")

        for k, v in self.variables.items():
            v = latex_to_plain(str(v))
            lines.append(" " * INDENT * 2 + f"{k} = {v}")
        lines.append(" " * INDENT + "Expressions:")
        for k, v in self.expressions.items():
            v = latex_to_plain(str(v))
            lines.append(" " * INDENT * 2 + f"{k} = {v}")

        return "\n".join(lines)

Scope: alias note

#   note(version: str = 'default', copy: Optional[str] = None)
View Source
    def __init__(self, version: str = "default", copy: Optional[str] = None):
        self.prev = G.cv
        self.version = version
        if version not in VS:
            new_version(version)
        if copy is not None:
            self.load(copy)
#   variables: Dict
#   expressions: Dict
#   def load(self, other_version):
View Source
    def load(self, other_version):
        duplicate(self.version, other_version)
#   class vr(sympy.core.symbol.Symbol):
View Source
class Variable(sympy.Symbol):
    """An abstract variable that represents a numerical quantity."""

    _registry: Dict = dict()

    @classmethod
    def ls(cls) -> List:
        return list(cls._registry.values())

    def __new__(
        cls,
        name: str,
        value: Optional[Union[float, int]] = None,
        is_text: bool = True,
        **assumptions: Any,
    ):
        if is_text:
            name = r"\text{" + name + r"}"
        instance = super(Variable, cls).__new__(cls, name, **assumptions)

        if G.cv is not None and value is not None:
            instance._set_value(G.cv, value)

        cls._registry[instance.plain_name] = instance

        return instance

    @property
    def plain_name(self):
        return latex_to_plain(self.name)

    @property
    def value(self) -> Union[float, int]:
        if G.cv is not None:
            return self.get(G.cv)
        else:
            raise RuntimeError("Current version is `None`.")

    @value.setter
    def value(self, value: Union[float, int]):

        if G.cv is not None:
            self._set_value(G.cv, value)
        else:
            raise RuntimeError("Current version is `None`.")

    def __call__(self, value: Union[float, int]):
        self.value = value

    def get(self, version: str) -> Optional[Union[float, int]]:

        assert isinstance(version, str)

        if version in VS:
            if self in VS[version]:
                return sympy.Float(VS[version][self], G.float_digit)
            else:
                return None
        else:
            raise KeyError(f"Version `{version}` does not exist.")

    def _set_value(self, version: str, value: Union[float, int]):
        if not isinstance(value, (float, int)):
            raise TypeError(
                f"Assigned value should be float or int but get {type(value)}"
            )
        if version not in VS:
            VS[version] = dict()
            ES[version] = dict()

        VS[version][self] = sympy.Float(value, G.float_digit)

    def __repr__(self) -> str:
        return self.plain_name

    __str__ = __repr__

    @property
    def latex_repr(self):
        try:
            v = sympy.latex(self.value)
            return sympy.latex(self) + f"= {v}"
        except KeyError:
            return sympy.latex(self)

An abstract variable that represents a numerical quantity.

#   vr()
#  
@classmethod
def ls(cls) -> List:
View Source
    @classmethod
    def ls(cls) -> List:
        return list(cls._registry.values())
#   plain_name
#   value: Union[float, int]
#   def get(self, version: str) -> Union[float, int, NoneType]:
View Source
    def get(self, version: str) -> Optional[Union[float, int]]:

        assert isinstance(version, str)

        if version in VS:
            if self in VS[version]:
                return sympy.Float(VS[version][self], G.float_digit)
            else:
                return None
        else:
            raise KeyError(f"Version `{version}` does not exist.")
#   latex_repr
#   default_assumptions = {}
Inherited Members
sympy.core.symbol.Symbol
is_comparable
is_Symbol
is_symbol
kind
assumptions0
sort_key
as_dummy
as_real_imag
is_constant
free_symbols
binary_symbols
as_set
name
sympy.core.expr.AtomicExpr
is_number
is_Atom
expr_free_symbols
sympy.core.basic.Atom
matches
xreplace
doit
class_key
sympy.core.expr.Expr
is_scalar
equals
conjugate
dir
transpose
adjoint
as_ordered_factors
as_poly
as_ordered_terms
as_terms
removeO
getO
getn
count_ops
args_cnc
coeff
as_expr
as_coefficient
as_independent
as_powers_dict
as_coefficients_dict
as_base_exp
as_coeff_mul
as_coeff_add
primitive
as_content_primitive
as_numer_denom
normal
extract_multiplicatively
extract_additively
could_extract_minus_sign
extract_branch_factor
is_polynomial
is_rational_function
is_meromorphic
is_algebraic_expr
series
aseries
taylor_term
lseries
nseries
limit
compute_leading_term
as_leading_term
as_coeff_exponent
leadterm
as_coeff_Mul
as_coeff_Add
fps
fourier_series
diff
expand
integrate
nsimplify
separate
collect
together
apart
ratsimp
trigsimp
radsimp
powsimp
combsimp
gammasimp
factor
cancel
invert
round
sympy.logic.boolalg.Boolean
to_nnf
sympy.core.basic.Basic
is_Indexed
is_Dummy
is_Wild
is_Function
is_Add
is_Mul
is_Pow
is_Number
is_Float
is_Rational
is_Integer
is_NumberSymbol
is_Order
is_Derivative
is_Piecewise
is_Poly
is_AlgebraicNumber
is_Relational
is_Equality
is_Boolean
is_Not
is_Matrix
is_Vector
is_Point
is_MatAdd
is_MatMul
copy
compare
fromiter
dummy_eq
atoms
canonical_variables
rcall
is_hypergeometric
func
args
subs
has
replace
find
count
match
simplify
refine
rewrite
is_hermitian
is_rational
is_extended_positive
is_extended_nonpositive
is_odd
is_transcendental
is_composite
is_polar
is_real
is_integer
is_infinite
is_prime
is_algebraic
is_commutative
is_antihermitian
is_extended_negative
is_imaginary
is_irrational
is_positive
is_nonpositive
is_complex
is_nonnegative
is_negative
is_even
is_zero
is_extended_nonnegative
is_finite
is_extended_nonzero
is_noninteger
is_extended_real
is_nonzero
sympy.core.evalf.EvalfMixin
evalf
n
#   class ex(numbers.Number):
View Source
class Expression(numbers.Number):
    """Expression in symbolic variables."""

    _registry: Dict = dict()

    @classmethod
    def ls(cls) -> List:
        return list(cls._registry.values())

    def __init__(self, name: str, expr, is_text: bool = True):
        if is_text:
            name = r"\text{" + name + r"}"
        self.name = name
        self.expr = expr

        self._registry[self.plain_name] = self

    @property
    def plain_name(self):
        return latex_to_plain(self.name)

    @property
    def plain_expr(self):
        return latex_to_plain(r"{}".format(self.expr))

    def __call__(self, version: Optional[str] = None):
        if version is None:
            version = G.cv
        res = eval_expr(self.expr, version)
        ES[version][self.plain_name] = res

        return res

    def __add__(self, other):
        if isinstance(other, Expression):
            return self.expr + other.expr
        else:
            return self.expr + other

    def __sub__(self, other):
        if isinstance(other, Expression):
            return self.expr - other.expr
        else:
            return self.expr - other

    def __mul__(self, other):
        if isinstance(other, Expression):
            return self.expr * other.expr
        else:
            return self.expr * other

    def __truediv__(self, other):
        if isinstance(other, Expression):
            return self.expr / other.expr
        else:
            return self.expr / other

    def __floordiv__(self, other):
        if isinstance(other, Expression):
            return self.expr // other.expr
        else:
            return self.expr // other

    def __pow__(self, other):
        if isinstance(other, Expression):
            return self.expr ** other.expr
        else:
            return self.expr ** other

    __div__ = __truediv__

    def grad(
        self, *args: Variable, evaluate: bool = True, version: Optional[str] = None
    ) -> Dict:
        if len(args) > 0:
            grads = {x: Gradient(self, x) for x in args}
        else:
            grads = {x: Gradient(self, x) for x in Variable._registry.values()}

        if evaluate:
            grads = {v: g(version) for v, g in grads.items()}

        return grads

    def diff(self, variable: Variable):
        return self.expr.diff(variable)

    @property
    def value(self):
        return self.__call__()

    def __repr__(self):
        return f"{self.plain_name} = {self.plain_expr}"

    __str__ = __repr__

    @property
    def latex_repr(self, evaluate: bool = True, version: Optional[str] = None):
        lhs = self.name
        rhs = sympy.latex(self.expr)
        eq = lhs + " = " + rhs
        if not evaluate:
            return eq

        res = self.__call__(version)

        res = sympy.latex(res)
        if res == rhs:
            return eq
        eq += " = " + res
        return eq

Expression in symbolic variables.

#   ex(name: str, expr, is_text: bool = True)
View Source
    def __init__(self, name: str, expr, is_text: bool = True):
        if is_text:
            name = r"\text{" + name + r"}"
        self.name = name
        self.expr = expr

        self._registry[self.plain_name] = self
#  
@classmethod
def ls(cls) -> List:
View Source
    @classmethod
    def ls(cls) -> List:
        return list(cls._registry.values())
#   plain_name
#   plain_expr
#   def grad( self, *args: varius.variable.Variable, evaluate: bool = True, version: Optional[str] = None ) -> Dict:
View Source
    def grad(
        self, *args: Variable, evaluate: bool = True, version: Optional[str] = None
    ) -> Dict:
        if len(args) > 0:
            grads = {x: Gradient(self, x) for x in args}
        else:
            grads = {x: Gradient(self, x) for x in Variable._registry.values()}

        if evaluate:
            grads = {v: g(version) for v, g in grads.items()}

        return grads
#   def diff(self, variable: varius.variable.Variable):
View Source
    def diff(self, variable: Variable):
        return self.expr.diff(variable)
#   value
#   latex_repr
#   def show(*args):
View Source
def show(*args):

    for x in args:

        if G.latex:
            if hasattr(x, "latex_repr"):
                display(Math(x.latex_repr))
            else:
                display(x)
        else:
            if hasattr(x, "latex_repr"):
                print(latex_to_plain(x.latex_repr))
            else:
                print(x)