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

Fix documentation #51

Merged
merged 7 commits into from
Dec 14, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ name: Deploy docs
# build the documentation whenever there are new commits on main
on:
push:
branches:
- main
# branches:
# - main
# Alternative: only build for tags.
# tags:
# - '*'
Expand Down
20 changes: 18 additions & 2 deletions docs/dev_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ Many python libraries use `sphinx` to generate docs via `readthedocs` (also host
This setup is too powerful (and therefore complicated) for our purposes.
Instead, we use [pdoc](https://github.com/mitmproxy/pdoc), run via **GitHub Actions**,
as configured [here](./.github/workflows/deploy-docs.yml).
The resulting `html` is hosted with **Github Pages**.

.. warning:: dirs must contain `__init__.py` file to be recognized by `pdoc`.

`pdoc` grabs the docstrings of modules/classes/functions,
and renders them into pretty html.
The docstrings should be written using markdown syntax.
The resulting `html` is hosted with **Github Pages**.

The docstrings should be written using **markdown** syntax.
In general, you should also try to [reference other objects](https://pdoc.dev/docs/pdoc.html#link-to-other-identifiers)
(if appropriate) by using backticks.
And if you want to do it really well, you should follow
Expand All @@ -23,6 +25,20 @@ To *live preview* your changes, do
pdoc -t docs/templates --docformat=numpy --math pipt popt misc ensemble simulator input_output docs/dev_guide.py
```

This will probably open a browser window with the rendered html.
You can also ctrl/cmd-cick the printed localhost link, or simply copy-paste it into your browser.

If you want to reproduce errors that occur in **CI**, you'll want to include the option `-o docs-generated `.
Since this actually generates html *files*, it will processes **all** of the files by default
(without which you might not pick up on the error).

.. note:: PS: it seems that the upstream `pdoc` does not report where parsing errors occur
(it simply quits with a traceback).
We therefore use my (`patnr`) fork which

- skips the markdown conversion,
- prints the specific docstring that causes issues.

## Tests

Th test suite is orchestrated using `pytest`. Both in **CI** and locally.
Expand Down
Empty file added popt/cost_functions/__init__.py
Empty file.
12 changes: 6 additions & 6 deletions popt/cost_functions/ecalc_npv.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@
from pathlib import Path
import pandas as pd

from libecalc.core.ecalc import EnergyCalculator
from libecalc.common.time_utils import Frequency
from libecalc.input.model import YamlModel


HERE = Path().cwd() # fallback for ipynb's
HERE = HERE.resolve()

Expand All @@ -34,6 +29,11 @@ def ecalc_npv(pred_data, keys_opt, report):
Objective function values (NPV) for all ensemble members.
"""

from libecalc.core.ecalc import EnergyCalculator
from libecalc.common.time_utils import Frequency
from libecalc.input.model import YamlModel


# Economic values
npv_const = {}
for name, value in keys_opt['npv_const']:
Expand Down Expand Up @@ -124,4 +124,4 @@ def results_as_df(yaml_model, results, getter) -> pd.DataFrame:
df = pd.DataFrame(df, index=res.timesteps)
df.index.name = "dates"
df.attrs = attrs
return df
return df
117 changes: 58 additions & 59 deletions popt/loop/dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,21 @@ def __init__(self, x, cov, theta0=[20.0, 20.0], func=None, ne=None):
'''
Parameters
----------
x : array_like, shape (d,)
Initial control vector. Used initally to get the dimensionality of the problem.

cov : array_like, shape (d,d)
Initial covaraince matrix. Used to construct the correlation matrix and
epsilon parameter of GenOpt

theta0 : list, of length 2 ([alpha, beta])
Initial alpha and beta parameter of the marginal Beta distributions.

func : callable (optional)
An objective function that can be used later for the gradeint.
Can also be passed directly to the gradeint fucntion.

ne : int

x : array_like, shape (d,)
Initial control vector. Used initally to get the dimensionality of the problem.

cov : array_like, shape (d,d)
Initial covaraince matrix. Used to construct the correlation matrix and
epsilon parameter of GenOpt

theta0 : list, of length 2 ([alpha, beta])
Initial alpha and beta parameter of the marginal Beta distributions.

func : callable (optional)
An objective function that can be used later for the gradeint.
Can also be passed directly to the gradeint fucntion.

ne : int
'''
self.dim = x.size # dimension of state
self.corr = ot.cov2corr(cov) # initial correlation
Expand All @@ -46,12 +45,12 @@ def update_distribution(self, theta, corr):

Parameters
----------
theta : array_like, shape (d,2)
Contains the alpha (first column) and beta (second column)
of the marginal distirbutions.
theta : array_like, shape (d,2)
Contains the alpha (first column) and beta (second column)
of the marginal distirbutions.

corr : array_like, shape (d,d)
Correlation matrix
corr : array_like, shape (d,d)
Correlation matrix
'''
self.theta = theta
self.corr = corr
Expand All @@ -77,8 +76,8 @@ def sample(self, size):

Parameters
----------
size: int
Ensemble size (ne). Size of the sample to be drawn.
size: int
Ensemble size (ne). Size of the sample to be drawn.

Returns
-------
Expand Down Expand Up @@ -115,16 +114,16 @@ def epsilon_transformation(self, x, enX):

Parameters
----------
x : array_like, shape (d,)
Current state vector.
enX : array_like, shape (ne,d)
Ensemble matrix X sampled from GenOpt distribution
x : array_like, shape (d,)
Current state vector.

enX : array_like, shape (ne,d)
Ensemble matrix X sampled from GenOpt distribution

Returns
-------
out : array_like, shape (ne,d)
Epsilon transfromed ensemble matrix, Y
out : array_like, shape (ne,d)
Epsilon transfromed ensemble matrix, Y
'''
enY = np.zeros_like(enX) # tranfomred ensemble

Expand All @@ -151,21 +150,21 @@ def gradient(self, x, *args, **kwargs):

Parameters
----------
x : array_like, shape (d,)
Current state vector.

args : (theta, corr)
theta (parameters of distribution), shape (d,2)
corr (correlation matrix), shape (d,d)

kwargs :
func : callable objectvie function
ne : ensemble size
x : array_like, shape (d,)
Current state vector.

args : (theta, corr)
theta (parameters of distribution), shape (d,2)
corr (correlation matrix), shape (d,d)

kwargs :
func : callable objectvie function
ne : ensemble size

Returns
-------
out : array_like, shape (d,)
The average gradient.
out : array_like, shape (d,)
The average gradient.
'''
# check for objective fucntion
if 'func' in kwargs:
Expand Down Expand Up @@ -236,16 +235,16 @@ def mutation_gradient(self, x=None, *args, **kwargs):

Parameters
----------
kwargs:
return_ensemble : bool
If True, all the ensemble matrices are also returned in a dictionary.
kwargs:
return_ensemble : bool
If True, all the ensemble matrices are also returned in a dictionary.

Returns
-------
out : array_like, shape (d,2)
Mutation gradeint of theta
NB! If return_ensembles=True, the ensmebles are also returned!
out : array_like, shape (d,2)
Mutation gradeint of theta

NB! If return_ensembles=True, the ensmebles are also returned!
'''
if 'return_ensembles' in kwargs:
ensembles = {'gaussian' : self.enZ,
Expand Down Expand Up @@ -279,16 +278,16 @@ def fisher_matrix(self, alpha, beta):

Parameters
----------------------------------------------
alpha : float
alpha parameter in Beta distribution
alpha : float
alpha parameter in Beta distribution

beta : float
beta parameter in Beta distribution
beta : float
beta parameter in Beta distribution

Returns
----------------------------------------------
out : array_like, of shape (2, 2)
Fisher matrix
out : array_like, of shape (2, 2)
Fisher matrix
'''
a = alpha
b = beta
Expand All @@ -315,13 +314,13 @@ def delA(theta):

Parameters
--------------------------------------------
a : float
b : float
a : float
b : float

Returns
--------------------------------------------
out : float
out : float
'''
a = theta[0]
b = theta[1]
return digamma(a)-digamma(a+b)
return digamma(a)-digamma(a+b)
56 changes: 28 additions & 28 deletions popt/loop/ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ class Ensemble(PETEnsemble):

Methods
-------
get_state()
Returns control vector as ndarray
get_state()
Returns control vector as ndarray

get_cov()
Returns the ensemble covariance matrix
get_cov()
Returns the ensemble covariance matrix

function(x,*args)
Objective function called during optimization
function(x,*args)
Objective function called during optimization

gradient(x,*args)
Ensemble gradient
gradient(x,*args)
Ensemble gradient

hessian(x,*args)
Ensemble hessian
hessian(x,*args)
Ensemble hessian

"""

Expand Down Expand Up @@ -176,13 +176,13 @@ def function(self, x, *args):

Parameters
----------
x : ndarray
Control vector, shape (number of controls, number of perturbations)
x : ndarray
Control vector, shape (number of controls, number of perturbations)

Returns
-------
obj_func_values : numpy.ndarray
Objective function values, shape (number of perturbations, )
obj_func_values : numpy.ndarray
Objective function values, shape (number of perturbations, )
"""
self._aux_input()

Expand Down Expand Up @@ -229,15 +229,15 @@ def gradient(self, x, *args):

Parameters
----------
x : ndarray
Control vector, shape (number of controls, )
x : ndarray
Control vector, shape (number of controls, )

args : tuple
Covarice (:math:`C_x`), shape (number of controls, number of controls)
args : tuple
Covarice (:math:`C_x`), shape (number of controls, number of controls)

Returns
-------
gradient : numpy.ndarray
gradient : numpy.ndarray
The gradient evaluated at x, shape (number of controls, )
"""

Expand Down Expand Up @@ -297,13 +297,13 @@ def hessian(self, x=None, *args):

Parameters
----------
x : ndarray
Control vector, shape (number of controls, number of perturbations)
x : ndarray
Control vector, shape (number of controls, number of perturbations)

Returns
-------
hessian: numpy.ndarray
The hessian evaluated at x, shape (number of controls, number of controls)
hessian: numpy.ndarray
The hessian evaluated at x, shape (number of controls, number of controls)

References
----------
Expand Down Expand Up @@ -344,15 +344,15 @@ def calc_ensemble_weights(self, x, *args):

Parameters
----------
x : ndarray
Control vector, shape (number of controls, )
x : ndarray
Control vector, shape (number of controls, )

args : tuple
Inflation factor and covarice (:math:`C_x`), shape (number of controls, number of controls)
args : tuple
Inflation factor and covarice (:math:`C_x`), shape (number of controls, number of controls)

Returns
-------
sens_matrix, best_ens, best_func : tuple
sens_matrix, best_ens, best_func : tuple
The weighted ensemble, the best ensemble member, and the best objective function value
"""

Expand Down
Loading
Loading