diffpy.srfit.equation package

The core equation evaluator for diffpy.srfit.

This package contains modules and subpackages that are used to create Equation objects. The Equation class is an encapsulation of a lazy evaluation network that is used throughout SrFit. The EquationsFactory class is used to create Equation objects from strings and can incorporate user-defined functions as well as default operations.

The subpackages define various pieces of the evaluation network.

class diffpy.srfit.equation.Equation(name=None, root=None)[source]

Bases: Operator

Class for holding and evaluating a Literal tree.

Instances have attributes that are the non-const Arguments of the tree (accessed by name) and a __call__ method that evaluates the tree. It is assumed, but not enforced that Arguments have unique names. If this is not the case, then one should keep its own list of Arguments.

The tree is scanned for errors when it is added. Thus, the tree should be complete before putting it inside an Equation.

Equations can act as Operator nodes within a literal tree. In this context, they evaluate as the root node, but provide a calling interface that accepts new argument values for the literal tree.

Parameters:
  • name (str, optional) – The name of the Equation. If None (default) and root is given, the name is “eq_<root name>”.

  • root (Literal, optional) – The root node of the Literal tree. If None (default), call set_root to set it.

root

The root Literal of the equation tree.

Type:

Literal or None

argdict

The non-constant Arguments of the tree, indexed by name.

Type:

OrderedDict

args

The values of argdict, in the same order.

Type:

list

name

The name of the Equation.

Type:

str

nin

The number of non-constant Arguments.

Type:

int

nout

The number of outputs, which is always 1.

Type:

int

symbol

The symbolic representation, which is the same as name.

Type:

str

value

The value of the Equation, read with get_value.

Type:

object

add_literal(literal)[source]

Raise a RuntimeError, because an Equation takes its literals from its root.

Parameters:

literal (Literal) – The literal that cannot be added.

Raises:

RuntimeError – Always.

property args

Arguments of the operator.

identify(visitor)[source]

Identify this Equation to a visitor.

Parameters:

visitor (Visitor) – The visitor to identify to.

Returns:

The result of visitor.on_equation(self).

Return type:

object

nin = None
nout = 1
operation(*args, **kw)[source]

Evaluate this Equation object.

Same as the __call__ method. This method is used via the Operator interface.

Parameters:
  • *args – The new values of the arguments, in the order of args.

  • **kw – The new values of the arguments, by name.

Returns:

The value of the Equation.

Return type:

object

setRoot(root)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.Equation.set_root instead.

set_root(root)[source]

Set the root of the Literal tree.

Parameters:

root (Literal) – The new root of the Literal tree.

Raises:

ValueError – If errors are found in the Literal tree.

swap(oldlit, newlit)[source]

Swap a literal in the equation for another.

Note that this may change the root and the operation interface.

Parameters:
  • oldlit (Literal) – The literal to replace.

  • newlit (Literal) – The literal to put in its place.

Raises:

ValueError – If newlit causes a self-reference.

property symbol

Symbol representing the operator.

Subpackages

Submodules

diffpy.srfit.equation.builder module

Classes and utilities for creating equations.

The EquationFactory class is used to create an equation (an Equation instance) from a string equation. User-defined Literals can be registered with the factory so that they are used in the equation. Registered Literals are referenced by name, and when a new Literal of the same name is registered, the factory will swap out the old Literal for the new one in all equations built by the factory.

An example using the EquationFactory: The make_equation method turns the string-representation of an equation into a callable object. > factory = EquationFactory() > eq = factory.make_equation(“A*sin(a*x)”) will create an equation that evaluates as “A*sin(a*x)”. The equation takes no arguments.

Custom Arguments and constants can be included in the equation: > factory.register_constant(“offset”, 3) > A = Argument(name = “A”, value = 1.0) > factory.register_argument(“A”, A) > eq = factory.make_equation(“A*sin(a*x) + offset”) This includes a constant offset in the equation and makes sure that the user-defined Argument is in the equation. This can be used to assure that the same instance of an Argument appears in multiple equations. Other literals can be registered in a similar fashion.

The BaseBuilder class does the hard work of making an equation from a string in EquationFactory.make_equation. BaseBuilder can be used directly to create equations. BaseBuilder is specified in the ArgumentBuilder and OperatorBuilder classes. You can create builders from Literals or equations by using the “wrap” functions within this module or by using the builder classes directly.

With a collection of BaseBuilder objects, one can simply write the equation using normal python syntax: > A = ArgumentBuilder(name = “A”) > a = ArgumentBuilder(name = “a”) > x = ArgumentBuilder(name = “x”) > # sin is defined in this module as an OperatorBuilder > sin = get_builder(“sin”) > beq = A*sin(a*x) > eq = beq.get_equation()

The equation builder can also handle scalar constants. Staring with the above setup: > beq2 = A*sin(a*x) + 3 > eq2 = beq2.get_equation() Here, we didn’t have to wrap ‘3’ in an ArgumentBuilder. Non scalars, constant or otherwise, must be wrapped as ArgumentBuilders in order to be used in this way.

BaseBuilder can make use of user-defined functions. Any callable python object can be wrapped as an OperatorBuilder with the wrap_function function. For example. > _f = lambda a, b : (a-b)/(a+b) > f = wrap_function(“f”, _f) > # Using BaseBuilder > a = ArgumentBuilder(name = “a”) > b = ArgumentBuilder(name = “b”) > c = ArgumentBuilder(name = “c”) > beq = c*f(a,b) > eq = beq.get_equation()

class diffpy.srfit.equation.builder.ArgumentBuilder(value=None, name=None, const=False, arg=None)[source]

Bases: BaseBuilder

BaseBuilder wrapper around an Argument literal.

Equation builder objects can be composed like a normal function where the arguments can be other BaseBuilder instances or constants.

Parameters:
  • value (object, optional) – The value of the new Argument. Default is None.

  • name (str, optional) – The name of the new Argument. Default is None.

  • const (bool, optional) – The flag that is True if the new Argument is constant. Default is False.

  • arg (Argument, optional) – The existing Argument to wrap. If None (default), a new Argument is created from value, name and const.

literal

The Argument wrapped by this instance.

Type:

Argument

class diffpy.srfit.equation.builder.BaseBuilder[source]

Bases: object

Class for building equations.

Equation builder objects can be composed like a normal function where the arguments can be other BaseBuilder instances or constants.

literal

The equation Literal being built by this instance.

Type:

Literal or None

getEquation()

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.BaseBuilder.get_equation instead.

get_equation()[source]

Get the equation built by this object.

The equation will given the name “_eq_<root>” where “<root>” is the name of the root node.

Returns:

The equation whose root is this builder’s literal.

Return type:

Equation

class diffpy.srfit.equation.builder.EquationFactory[source]

Bases: object

A Factory for equations.

builders

The BaseBuilders registered with the factory, indexed by name.

Type:

dict

newargs

The new arguments created by the last call to make_equation.

Type:

set

equations

The equations that have been built by the factory.

Type:

set

deRegisterBuilder(name)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.EquationFactory.deregister_builder instead.

deregister_builder(name)[source]

Deregister a builder by name.

This does not change the equations that use the Literal wrapped by the builder. Nothing happens if no builder has this name.

Parameters:

name (str) – The name of the builder to deregister.

ignore = ('(', ',', ')')
makeEquation(eqstr, buildargs=True, argclass=<class 'diffpy.srfit.equation.literals.argument.Argument'>, argkw={})

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.EquationFactory.make_equation instead.

make_equation(eqstr, buildargs=True, argclass=<class 'diffpy.srfit.equation.literals.argument.Argument'>, argkw={})[source]

Make an equation from an equation string.

Parameters:
  • eqstr (str) – The equation in string form using standard python syntax. The equation string can use any registered literal or function, including the numpy ufuncs that are registered automatically.

  • buildargs (bool, optional) – The flag that is True (default) to let the factory create missing arguments. If False, undefined names in eqstr raise a ValueError.

  • argclass (type, optional) – The class used to create new arguments. Its constructor must accept the name keyword. Default is diffpy.srfit.equation.literals.Argument.

  • argkw (dict, optional) – The keyword arguments passed to the argclass constructor. Default is an empty dict.

Returns:

The callable equation built from eqstr.

Return type:

Equation

Raises:
  • ValueError – If buildargs is False and eqstr uses undefined names.

  • SyntaxError – If eqstr is not valid python syntax.

registerArgument(name, arg)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.EquationFactory.register_argument instead.

registerBuilder(name, builder)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.EquationFactory.register_builder instead.

registerConstant(name, value)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.EquationFactory.register_constant instead.

registerFunction(name, func, argnames)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.EquationFactory.register_function instead.

registerOperator(name, op)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.EquationFactory.register_operator instead.

register_argument(name, arg)[source]

Register a named Argument with the factory.

Parameters:
  • name (str) – The name to register the argument under.

  • arg (Argument) – The argument to register.

Returns:

The registered builder.

Return type:

ArgumentBuilder

register_builder(name, builder)[source]

Register a builder so it can be used in make_equation.

If an extant builder with the given name is already registered, this will replace all instances of the old builder’s literal in the factory’s equation set with the new builder’s literal. Note that this may lead to errors if one of the replacements causes a self-reference.

Parameters:
  • name (str) – The name to register the builder under.

  • builder (BaseBuilder) – The builder to register.

Returns:

The registered builder.

Return type:

BaseBuilder

Raises:
  • TypeError – If name is not a string or builder is not a BaseBuilder.

  • ValueError – If the new builder’s literal causes a self-reference in an existing equation.

register_constant(name, value)[source]

Register a named constant with the factory.

Parameters:
  • name (str) – The name of the constant.

  • value (object) – The value of the constant.

Returns:

The registered builder.

Return type:

ArgumentBuilder

register_function(name, func, argnames)[source]

Register a named function with the factory.

This will register a builder for the function.

Parameters:
  • name (str) – The name of the function.

  • func (callable) – The callable python object.

  • argnames (list of str) – The argument names for func. If these names do not correspond to builders, then new constants with value 0 will be created for each name.

Returns:

registered_builder – The registered builder.

Return type:

OperatorBuilder

register_operator(name, op)[source]

Register an Operator literal with the factory.

Operators can be used with or without arguments (or parentheses) in an equation string. If used with arguments, then the Operator will use the passed arguments as arguments for the operation. If used without arguments, it is assumed that the operator is already populated with arguments, and those will be used.

Parameters:
  • name (str) – The name to register the operator under.

  • op (Operator) – The operator to register.

Returns:

The registered builder.

Return type:

OperatorBuilder

symbols = ('+', '-', '*', '/', '**', '%', '|')
wipeout(eq)[source]

Invalidate the specified equation and remove it from the factory.

This will remove the equation from the purview of the factory and also change its formula to return NaN. This ensures that eq does not observe any object in the factory and thus prevents its indirect pickling with the factory because of observer callback function.

Parameters:

eq (Equation or None) – The equation to invalidate. Nothing happens if this is None.

class diffpy.srfit.equation.builder.OperatorBuilder(name, op=None)[source]

Bases: BaseBuilder

BaseBuilder wrapper around an Operator literal.

Parameters:
  • name (str) – The name of the wrapped Operator.

  • op (Operator, optional) – The Operator to wrap. If None (default), name is taken to be the name of a numpy ufunc, which defines the Operator when the builder is called.

literal

The Operator wrapped by this instance.

Type:

Operator or None

name

The name of the wrapped Operator.

Type:

str

diffpy.srfit.equation.builder.getBuilder(name)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.get_builder instead.

diffpy.srfit.equation.builder.get_builder(name)[source]

Get an operator builder from the global builders dictionary.

Parameters:

name (str) – The name of the builder, such as “sin” or “add”.

Returns:

The global builder registered under name.

Return type:

OperatorBuilder

Raises:

KeyError – If no global builder has this name.

diffpy.srfit.equation.builder.wrapArgument(name, arg)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.wrap_argument instead.

diffpy.srfit.equation.builder.wrapFunction(name, func, nin=2, nout=1)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.wrap_function instead.

diffpy.srfit.equation.builder.wrapOperator(name, op)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.builder.wrap_operator instead.

diffpy.srfit.equation.builder.wrap_argument(name, arg)[source]

Wrap an Argument as a builder.

Parameters:
  • name (str) – The name of the argument. It is not used, because the builder takes its name from arg.

  • arg (Argument) – The argument to wrap.

Returns:

The builder that wraps arg.

Return type:

ArgumentBuilder

diffpy.srfit.equation.builder.wrap_function(name, func, nin=2, nout=1)[source]

Wrap a function in an OperatorBuilder instance.

Parameters:
  • name (str) – The name of the function.

  • func (callable) – The callable python object.

  • nin (int, optional) – The number of input arguments. Default is 2.

  • nout (int, optional) – The number of return values. Default is 1.

Returns:

The builder that wraps the function.

Return type:

OperatorBuilder

diffpy.srfit.equation.builder.wrap_operator(name, op)[source]

Wrap an Operator as a builder.

Parameters:
  • name (str) – The name of the builder.

  • op (Operator) – The operator to wrap.

Returns:

The builder that wraps op.

Return type:

OperatorBuilder

diffpy.srfit.equation.equationmod module

The Equation class for holding and evaluating an equation.

Equation is a functor that holds a Literal tree that defines an equation. Its __call__ method evaluates the equation at the most recent value of its Arguments. The non-constant arguments are accessible as attributes of the Equation instance and can be passed as arguments to __call__.

Example:

# make a Literal tree. Here's a simple one
add = AdditionOperator()
a = Argument(name="a")  # Don't forget to name these!
b = Argument(name="b")
add.add_literal(a)
add.add_literal(b)
# make an Equation instance and pass the root
eq = Equation(root=add)
eq(a=3, b=4)  # returns 7
eq(a=2)  # remembers b=4, returns 6
eq.a.set_value(-3)
eq.b.set_value(3)
eq()  # uses last assignment of a and b, returns 0

See the class documentation for more information.

class diffpy.srfit.equation.equationmod.Equation(name=None, root=None)[source]

Bases: Operator

Class for holding and evaluating a Literal tree.

Instances have attributes that are the non-const Arguments of the tree (accessed by name) and a __call__ method that evaluates the tree. It is assumed, but not enforced that Arguments have unique names. If this is not the case, then one should keep its own list of Arguments.

The tree is scanned for errors when it is added. Thus, the tree should be complete before putting it inside an Equation.

Equations can act as Operator nodes within a literal tree. In this context, they evaluate as the root node, but provide a calling interface that accepts new argument values for the literal tree.

Parameters:
  • name (str, optional) – The name of the Equation. If None (default) and root is given, the name is “eq_<root name>”.

  • root (Literal, optional) – The root node of the Literal tree. If None (default), call set_root to set it.

root

The root Literal of the equation tree.

Type:

Literal or None

argdict

The non-constant Arguments of the tree, indexed by name.

Type:

OrderedDict

args

The values of argdict, in the same order.

Type:

list

name

The name of the Equation.

Type:

str

nin

The number of non-constant Arguments.

Type:

int

nout

The number of outputs, which is always 1.

Type:

int

symbol

The symbolic representation, which is the same as name.

Type:

str

value

The value of the Equation, read with get_value.

Type:

object

add_literal(literal)[source]

Raise a RuntimeError, because an Equation takes its literals from its root.

Parameters:

literal (Literal) – The literal that cannot be added.

Raises:

RuntimeError – Always.

property args

Arguments of the operator.

identify(visitor)[source]

Identify this Equation to a visitor.

Parameters:

visitor (Visitor) – The visitor to identify to.

Returns:

The result of visitor.on_equation(self).

Return type:

object

nin = None
nout = 1
operation(*args, **kw)[source]

Evaluate this Equation object.

Same as the __call__ method. This method is used via the Operator interface.

Parameters:
  • *args – The new values of the arguments, in the order of args.

  • **kw – The new values of the arguments, by name.

Returns:

The value of the Equation.

Return type:

object

setRoot(root)

This function has been deprecated and will be removed in version 4.0.0.

Please use diffpy.srfit.equation.Equation.set_root instead.

set_root(root)[source]

Set the root of the Literal tree.

Parameters:

root (Literal) – The new root of the Literal tree.

Raises:

ValueError – If errors are found in the Literal tree.

swap(oldlit, newlit)[source]

Swap a literal in the equation for another.

Note that this may change the root and the operation interface.

Parameters:
  • oldlit (Literal) – The literal to replace.

  • newlit (Literal) – The literal to put in its place.

Raises:

ValueError – If newlit causes a self-reference.

property symbol

Symbol representing the operator.