Package: optool
Optool - Optimization toolsGenerally usable utilities related to optimization problems.Optool is a comprehensive Python package that simplifies the formulation of numerical optimization problems by
supporting the use of units of measurements and parallel execution of optimizations.
In addition, the package includes advanced data validation capabilities and provides out of the box serialization of a
variety of well-known data types.HighlightsEasy to use optimization framework built aroundCasADi, allowing to specify the problem with units of measurements.Integrated data validation usingPydantic.Additional Pydantic-compatible fields for a variety of well-known data types such asNumpyarrays,PandasSeries
and DataFrame objects, unit and quantity objects ofPint.Out of the box serialization to JSON of a variety of well-known data types within data models.Parallelization of optimizations with convenient redirection of logging statements.Installationoptoolcan be installed from PyPI:python-mpipinstalloptoolGetting StartedThe main purpose of this package is to simplify the formulation of optimization problems.
Following anexample applicationofCasADi, which aims to find the lowest
fuel consumption of a rocket in order to reach a certain target height, the corresponding optimization problem can be
formulated as follows:importnumpyasnpfromoptool.optimization.odeimportOrdinaryDifferentialEquation,ForwardEulerfromoptool.optimization.problemimportOptimizationProblemfromoptool.uomimportQuantity# Define general parameterstime=Quantity(np.arange(0,101,1),"s")gravitational_acceleration=Quantity(9.81,"m/s²")fuel_consumption=Quantity(0.3,"g/(N*s)")target_height=Quantity(100.0,"km")initial_mass=Quantity(500.0,"t")# Setup problemprb=OptimizationProblem.casadi("Rocket launch")integration_method=ForwardEuler# Decision variablesheight=prb.new_variable("height",len(time),"m")height.lower_bounds=Quantity(np.hstack([np.zeros(len(time)-1),target_height.m]),target_height.u)height.upper_bounds=Quantity(np.hstack([0.0,np.full(len(time)-2,np.inf),target_height.m]),target_height.u)height.nominal_values=target_heightspeed=prb.new_variable("speed",len(time),"m/s")speed.lower_bounds=Quantity(np.hstack([0.0,np.full(len(time)-1,-np.inf)]),"m/s")speed.upper_bounds=Quantity(np.hstack([0.0,np.full(len(time)-1,np.inf)]),"m/s")speed.nominal_values=Quantity(1500.0,"m/s")mass=prb.new_variable("mass",len(time),"kg")mass.lower_bounds=Quantity(np.hstack([initial_mass.m,np.zeros(len(time)-1)]),initial_mass.u)mass.upper_bounds=Quantity(np.hstack([initial_mass.m,np.full(len(time)-1,np.inf)]),initial_mass.u)mass.initial_guess=initial_massmass.nominal_values=initial_massthrust=prb.new_variable("control",len(time)-1,"N")thrust.lower_bounds=Quantity(0.0,"N")thrust.nominal_values=Quantity(1.5e8,"N")# Dynamic constraintsode=OrdinaryDifferentialEquation(name="height_dynamics",state_variable=height.regular,input_variable=speed.regular[:-1],function=lambdax,u:u)prb.add_equation(integration_method.integrate(ode,time))ode=OrdinaryDifferentialEquation(name="velocity_dynamics",state_variable=speed.regular,input_variable=thrust.regular/mass.regular[:-1],function=lambdax,u:u-gravitational_acceleration)prb.add_equation(integration_method.integrate(ode,time))ode=OrdinaryDifferentialEquation(name="mass_dynamics",state_variable=mass.regular,input_variable=thrust.regular,function=lambdax,u:-fuel_consumption*u)prb.add_equation(integration_method.integrate(ode,time))# Objectiveprb.objective=mass.regular[0]-mass.regular[-1]# Solveprb.parse('ipopt')response=prb.solve()forvalinresponse.debug_info.get_details():print(val)response.guarantee_success()As a result, the optimal control strategy is to get the rocket to a high speed as quickly as possible, using a lot of
fuel, so that it is lighter and requires less thrust.
The propulsion is cut off after less than 10 seconds so that the rocket reaches the desired altitude in glide flight.The complete code is availablehere.DependenciesThe following libraries are necessary to run the program code.CasADiis a symbolic framework for numeric optimization implementing automatic differentiation.Humanizeprovides various common string-related utilities like turning a number into a fuzzy human-readable
duration (e.g.3 minutes ago).Loguruintends to make Python logging less painful by adding a bunch of useful functionalities that solve caveats of
the standard loggers.Numpyis the fundamental package for scientific computing with Python.Pandasprovides fast, powerful, flexible and easy to use features for data analysis and manipulation.Pintallows to define, operate and manipulate physical quantities.
It allows arithmetic operations between them and conversions from and to different units.Pint-pandasprovides an extension to Pandas, which allows Pandas to recognize the quantities and store them in
Pandas data frames and series.Pydanticprovides extensive data validation features and serialization capabilities using Python type hints.Extra dependencies are needed for development, which can all be installed viapipinstall-rrequirements.txtHowever, all processes are automated usingTox, which automatically installs the
required dependencies.
Hence,Toxis the only Python package stringently necessary.