API Reference
=============
The package contains two modules to model and solve problems.
The :py:mod:`eut.peerless.model` is used to model the problem
and :py:mod:`eut.peerless.solver` is used to solve it.
Step by step
------------
Lets model the following problem taken from
`here `_
.. math::
\begin{eqnarray}
\min\; & \sin(y)e^{(1-\cos(x))^2} + \cos(x)e^{(1-\sin(y))^2} + (x-y)^2 \\
s.t.\; & (x+5)^2+(y+5)^2\le 25 \\
& -10 \le x \le 0 \\
& -6.5 \le y \le 0
\end{eqnarray}
Create the model
^^^^^^^^^^^^^^^^
All the variables, constraints, objective and expressions must belong to a
model. It will hold the representation of the problem to be solved.
.. code-block:: python
model = eut.peerless.model.Model("Townsend")
Create the variables
^^^^^^^^^^^^^^^^^^^^
In this example we only have two variables. Notice that the first argument
in the constructor is the model. The variables are added to the model
at construction, you don't have to add them yourself.\
At construction time we specify the lower and upper bound too. These are
extremely important and the tighter the bounds of the variables, the
better the performance of most of the algorithms in *Peerless*.
.. code-block:: python
x = eut.peerless.model.Variable(model, "x", -10, 0)
y = eut.peerless.model.Variable(model, "y", -6.5, 0)
Add constraints
^^^^^^^^^^^^^^^
Constraints are created and **must be added to the model**, they are not
added at construction time as variables or the objective function.
Variables and expression have the comparison operators,
``<=``, ``>=`` and ``==``, overriden to facilitate the creation of constraints.
.. code-block:: python
model.add_constraint((x + 5)**2 + (y + 5)**2 <= 25, "ct1")
Add the objective
^^^^^^^^^^^^^^^^^
The objective function is created using an expression at construction.
Like variables, the model is the first argument and the objetive is set
in the model once it is constructed.
.. code-block:: python
eut.peerless.model.Minimize(model, "objective",
mdl.sin(y) * mdl.exp((1-mdl.cos(x))**2) +
mdl.cos(x) * mdl.exp((1-mdl.sin(y))**2) + (x - y)**2)
Solve the model
^^^^^^^^^^^^^^^
In order to solve the model we must create the parameters, and optionaly,
the environment. If the environment is ommitted, *Peerless* will send
the problem to Eve Utils public servers.
Notice that the
size of the problems that can be solved in the public service is limited and
that you might encounter delays because your problem might be queued.
In case of requiring more performance, contact Eve Utils
to get a dedicated server dimensioned to your needs, or maybe to discuss an
on premises solution.
.. code-block:: python
parameters = mdl.Parameters()
environment = solver.Environment("your@email.com", "password")
ans = solver.solve(model, parameters, environment)
# Print the solution
print(ans.solution)
Solution and output
^^^^^^^^^^^^^^^^^^^
The value returned by the solver is an instance of
:py:class:`eut.peerless.solver.OptimizationResult`. The possible statuses are
defined in :py:class:`eut.abba.processor.statuses.Statuses`.
In this case the output is
.. highlight:: none
::
$ python tests/test_townsend.py
INFO:eut.peerless.solver:Sending problem to the jobstore
INFO:eut.peerless.solver:..job's key is 159534646712651717ed83179cb1fcbd8aa2bb4eff7338b
INFO:eut.peerless.solver:..pooling every 2 seconds
INFO:eut.peerless.solver:..|159534646712651717ed83179cb1fcbd8aa2bb4eff7338b|20200721T11:47:47|created: ''
INFO:eut.peerless.solver:..|159534646712651717ed83179cb1fcbd8aa2bb4eff7338b|20200721T11:47:48|processing: ''
INFO:eut.peerless.solver:..|159534646712651717ed83179cb1fcbd8aa2bb4eff7338b|20200721T11:47:50|executed: 'Objective: -106.76453674926478. Feasibility: 0.0. Iterations: 57. Elapsed: 0.150143996'
{x: -3.130246801712496, y: -1.5821421805049385}
Complete program
^^^^^^^^^^^^^^^^
.. code-block:: python
import logging
logging.basicConfig(level=logging.DEBUG)
import eut.peerless.model as mdl
import eut.peerless.solver as solver
# Create the model
model = mdl.Model("Townsend")
# Add the variables
x = mdl.Variable(model, "x", -10, 0)
y = mdl.Variable(model, "y", -6.5, 0)
# Add the objective function
mdl.Minimize(model, "objective",
mdl.sin(y) * mdl.exp((1-mdl.cos(x))**2) +
mdl.cos(x) * mdl.exp((1-mdl.sin(y))**2) + (x - y)**2)
# Add the constraints
model.add_constraint((x + 5)**2 + (y + 5)**2 <= 25, "ct1")
# Configure the parameters
parameters = mdl.Parameters()
# Solve the model
ans = solver.solve(model, parameters)
# Print the solution
print(ans.solution)
:mod:`eut.peerless`
-------------------
.. automodule:: eut.peerless
:mod:`eut.peerless.model`
-------------------------
.. automodule:: eut.peerless.model
.. autofunction:: eut.peerless.model.Expression
.. autoclass:: eut.peerless.model.Function
:members:
:special-members:
:exclude-members: serialize, deserialize, __init__
The following are the available functions in the library:
.. autoclass:: eut.peerless.model.add
.. autoclass:: eut.peerless.model.sub
.. autoclass:: eut.peerless.model.mul
.. autoclass:: eut.peerless.model.truediv
.. autoclass:: eut.peerless.model.pow
.. autoclass:: eut.peerless.model.abs
.. autoclass:: eut.peerless.model.remainder
.. autoclass:: eut.peerless.model.mod
.. autoclass:: eut.peerless.model.sign
.. autoclass:: eut.peerless.model.min
.. autoclass:: eut.peerless.model.max
.. autoclass:: eut.peerless.model.sin
.. autoclass:: eut.peerless.model.cos
.. autoclass:: eut.peerless.model.tan
.. autoclass:: eut.peerless.model.sqrt
.. autoclass:: eut.peerless.model.exp
.. autoclass:: eut.peerless.model.log
.. autoclass:: eut.peerless.model.round
.. autoclass:: eut.peerless.model.ceil
.. autoclass:: eut.peerless.model.floor
.. autoclass:: eut.peerless.model.Model
:members:
:special-members:
:exclude-members: __init__, __str__
.. autoclass:: eut.peerless.model.ModelMeasures
.. autofunction:: eut.peerless.model.Variable
.. autofunction:: eut.peerless.model.IntegerVariable
.. autofunction:: eut.peerless.model.BinaryVariable
.. autoclass:: eut.peerless.model.Constraint
:members:
:special-members:
:exclude-members: serialize, deserialize, __init__, __str__
.. autofunction:: Maximize
.. autofunction:: Minimize
.. autoclass:: eut.peerless.model.Solution
:members:
:special-members:
:exclude-members: serialize, deserialize, __init__, __str__
.. autoclass:: eut.peerless.model.Parameters
:mod:`eut.peerless.solver`
--------------------------
.. automodule:: eut.peerless.solver
:members:
The job service
---------------
The jobs are stored in a :class:`eut.abba.processor.jobstore.JobStore`.
A JobStore is registered in a :class:`eut.abba.rpc.Server`, with
the server extending
`xmlrpc.server.DocXMLRPCServer `_.
The jobstore is self-documenting and is located at
`http://eveutils.services/peerless/ `_
A `xmlrpc.client.ServerProxy `_ can be used to query the JobStore, it
must be created using ``allow_none=True``.
:class:`eut.abba.processor.jobstore.JobStore`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: eut.abba.processor.jobstore.JobStore
:members: get_partials, get_result, get_statuses, cancelled, cancel
:mod:`eut.abba.processor.statuses`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: eut.abba.processor.statuses
:members:
:class:`eut.abba.rpc.Server`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: eut.abba.rpc.Server
:members: