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

Add How-to-develop guide #191

Merged
merged 1 commit into from
May 6, 2024
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 docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
Distributions = "^0.25"
Documenter = "0.27.24"
COSMO = "^0.8.9"
Documenter = "^1.4.1"
Literate = "2.8"
Plots = "^1.3.3"
StatsFuns = "^1.3"
116 changes: 110 additions & 6 deletions docs/src/contributing.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,118 @@
# Contributing

Contributions are always welcome:
This package is currently in maintenance mode.

* If you want to contribute features, bug fixes, etc, please take a look at our __Code Style Guide__ below
* Please report any issues and bugs that you encounter in [Issues](https://github.com/oxfordcontrol/ossdp/issues)
* As an open source project we are also interested in any projects and applications that use COSMO. Please let us know via email to: michael.garstka[at]eng.ox.ac.uk
We are trying to keep it compatible with new releases of JuMP/MOI. Contributions for bug fixes or new features are always welcome. Enhancement ideas are tagged as such in the [Issues](https://github.com/oxfordcontrol/ossdp/issues) section. If you are unsure how to develop, continue with the section below.

## Code Style Guide

The code in this repository follows the naming and style conventions of [Julia Base](https://docs.julialang.org/en/v1.0/manual/style-guide/#Style-Guide-1) with a few modifications. This style guide is heavily "inspired" by the guides of [John Myles White](https://github.com/johnmyleswhite/Style.jl) and [JuMP](http://www.juliaopt.org/JuMP.jl/latest/style).
# How-to develop
Let's assume you found a bug that you want to fix or develop a new feature. You have already downloaded the latest julia version as well as git. Follow these steps to make changes, test the changes, and open your first PR. This assumes that you don't yet have push access to the repository and need to fork.

- Create a new fork in Github by clicking on `Fork` at the top right of the repository page and name it e.g. `migarstka/COSMO.jl`. (If you have repository push rights, you don't need to fork and can clone the repository directly.)

- Clone the forked repository to your machine with:
```bash
$ git clone [email protected]:migarstka/COSMO.jl.git
```

- Navigate into the new folder and create a new branch:
```bash
$ git checkout -b mg/bug_fix
```

- Make your code changes by modifying the files in the repository.

- As a first sanity check that nothing obvious is broken, you can run one of the examples in the `examples/` folder. Open julia and navigate into the git repository. Next, we want to activate and instantiate the repositories virtual environment. In the julia REPL type `]`, then to activate the current environment (i.e. current `Project.toml` file):

```julia
(@v1.8) pkg> activate .
```
Next, instantiate the environment, i.e. install the solver's dependencies defined in `Project.toml`:

```julia
(COSMO) pkg> instantiate
```

- Since we instantiated the local envrionment, `COSMO` now refers to the local version that includes your changes. You can solve an example problem using the modified code:
```julia
julia> include("examples/qp.jl")
```

Let's assume you have made some changes and want to check whether the bug is fixed or the new feature broke anything. In both cases you should add some new tests for the change to `/test/UnitTest` and `/test/run_cosmo_tests.jl`. If you want to run existing tests follow the steps below.

### How-to run tests
You can run all package-native tests with the main test file:
```julia
julia> include("test/run_cosmo_tests.jl")
```
The full test suite also includes several MathOptInterface test problems that you can run with:
```julia
julia> include("test/runtests.jl")
```
These take longer to complete, so I recommend using `test/run_cosmo_tests.jl` during iterative development and then switch to
`test/runtests.jl` once the previous tests pass.

### Open a PR
Once all tests pass, you have added additional tests for your changes, and used docstrings to describe any new functionality in the code, you can open a PR. Commit your changes with a detailed commit message, and push your branch to the (fork) remote.
```bash
$ git add .
$ git commit
[Write commit message]
$ git push
```
Then navigate to [https://github.com/oxfordcontrol/COSMO.jl/compare](https://github.com/oxfordcontrol/COSMO.jl/compare) and create a new PR with `base repository: oxfordcontrol/COSMO.jl` `base: master` and `head repository: [your-fork-repo]` `base:mg/bug_fix`.
Ask me or other collaborators to review it, before it can get merged.

## Making a new release
Changes to `master` are periodically bundled in a new release version of the package. If you have permissions, you can make a new release by following these steps:

1. Ensure all tests pass (locally and in Github Actions)
2. Locally run `bumpversion patch` (or `bumpversion minor` or `bumpversion major` depending on [semver](https://semver.org/) convention) to increment the version number across the repository (most importantly in `Project.toml`).
3. Check and commit the changes and use the commit message `Bump version to X`.
4. Push changes to remote with `git push`.
5. Let the julia package registry know about the new release by commenting `@JuliaRegistrator register` on the bump commit (like [here](https://github.com/oxfordcontrol/COSMO.jl/commit/20764ba075e1f598ec17990fb1721dcb5a3b418b#commitcomment-141674207)).
6. This will open a PR in the `JuliaRegistries` repository and a new release will typically be approved within hours.
7. Update the [CHANGELOG](https://github.com/oxfordcontrol/COSMO.jl/blob/master/CHANGELOG.md) and describe the changes bundled in the new release.

## Updating COSMO's documentation
The code for COSMO's documentation resides in the `/docs` folder of the repository and is created with the [Documenter.jl package](https://documenter.juliadocs.org/stable/). There are two main versions of this documentation. **Stable** is based on the committed changes of the latest tagged release. **Dev** is based on the latest commit of `master`.

The documentation has its own environment defined inside `/docs` (see `docs/Project.toml` file). To edit the documentation, edit the files in `/docs`. It's advised to run the documentation generation process locally do ensure the layout is as expected and that `Literate` code examples are built without errors. To generate the documentation locally, follow these steps:

- Clone the repository and make your changes (as described in the section above).
- Navigate into the `/docs` folder and start julia.
- Activate and instantiate the (docs) environment, after `]`, type:

```julia
(@v1.8) pkg> activate .
```

```julia
(docs) pkg> instantiate
```

- Build the documentation locally into the `/build` folder with

```julia
include("make.jl")
```

(The first build will take several minutes. Subsequent changes will take ~30s.)

- After the new documentation has been built, you can serve the files in `/build` in your browser, e.g. using a python webserver. Navigate into `/build` and run:
```bash
python3 -m http.server --bind localhost
```

- View the local documentation in your browser of choice at `http://127.0.0.1:8000/`

- If you are satisfied with the results, open a PR for the changes as described in the section above.



# Code Style Guide

The code in this repository follows the naming and style conventions of [Julia Base](https://docs.julialang.org/en/v1.0/manual/style-guide/#Style-Guide-1) with a few modifications. This style guide is heavily "inspired" by the guides of [John Myles White](https://github.com/johnmyleswhite/Style.jl) and [JuMP](https://jump.dev/JuMP.jl/stable/developers/style/).

### Formatting
* Use one tab when indenting a new block (except `module`)
Expand Down
26 changes: 13 additions & 13 deletions docs/src/examples/closest_correlation_matrix.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The source files for all examples can be found in [/examples](https://github.com/oxfordcontrol/COSMO.jl/tree/master/examples/).
```@meta
EditURL = "<unknown>/../examples/closest_correlation_matrix.jl"
EditURL = "../../../examples/closest_correlation_matrix.jl"
```

# Closest Correlation Matrix
Expand All @@ -17,22 +17,22 @@ The problem is given by:
Notice that we use `JuMP` to model the problem. `COSMO` is chosen as the backend solver. And COSMO-specific settings are passed using
the `optimizer_with_attributes()` function.

```@example closest_correlation_matrix
````@example closest_correlation_matrix
using COSMO, JuMP, LinearAlgebra, SparseArrays, Test, Random
```
````

```@example closest_correlation_matrix
````@example closest_correlation_matrix
rng = Random.MersenneTwister(12345);
# create a random test matrix C
n = 8;
C = -1 .+ rand(rng, n, n) .* 2;
c = vec(C);
nothing #hide
```
````

Define problem in `JuMP`:

```@example closest_correlation_matrix
````@example closest_correlation_matrix
q = -vec(C);
r = 0.5 * vec(C)' * vec(C);
m = JuMP.Model(optimizer_with_attributes(COSMO.Optimizer, "verbose" => true));
Expand All @@ -42,20 +42,20 @@ x = vec(X);
for i = 1:n
@constraint(m, X[i, i] == 1.);
end
```
````

Solve the `JuMP` model with `COSMO` and query the solution `X_sol`:

```@example closest_correlation_matrix
````@example closest_correlation_matrix
status = JuMP.optimize!(m);
obj_val = JuMP.objective_value(m);
X_sol = JuMP.value.(X);
nothing #hide
```
````

Double check result against known solution:

```@example closest_correlation_matrix
````@example closest_correlation_matrix
known_opt_val = 12.5406
known_solution = [
1.0 0.732562 -0.319491 -0.359985 -0.287543 -0.15578 0.0264044 -0.271438;
Expand All @@ -67,11 +67,11 @@ known_solution = [
0.0264044 0.126612 -0.248641 0.141151 0.137518 -0.731556 1.0 -0.436274;
-0.271438 -0.187489 -0.395299 0.286088 0.0262425 0.0841783 -0.436274 1.0 ];
@test isapprox(obj_val, known_opt_val , atol=1e-3)
```
````

```@example closest_correlation_matrix
````@example closest_correlation_matrix
@test norm(X_sol - known_solution, Inf) < 1e-3
```
````

---

Expand Down
30 changes: 15 additions & 15 deletions docs/src/examples/lp.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The source files for all examples can be found in [/examples](https://github.com/oxfordcontrol/COSMO.jl/tree/master/examples/).
```@meta
EditURL = "<unknown>/../examples/lp.jl"
EditURL = "../../../examples/lp.jl"
```

# Linear Program
Expand All @@ -16,22 +16,22 @@ We want to solve the following linear program with decision variable `x`:
```
The problem can be solved with `COSMO` in the following way:

```@example lp
````@example lp
using COSMO, LinearAlgebra, SparseArrays, Test
```
````

```@example lp
````@example lp
##Define problem data:
c = [1; 2; 3; 4.];
A = Matrix(1.0I, 4, 4);
b = [10.; 10; 10; 10];
n = 4;
nothing #hide
```
````

Create the constraints $Ax + b \in \mathcal{K}$:

```@example lp
````@example lp
# Ax <= b
c1 = COSMO.Constraint(-A, b, COSMO.Nonnegatives);
# x >= 1
Expand All @@ -41,34 +41,34 @@ c3 = COSMO.Constraint(1, -5, COSMO.Nonnegatives, n, 2:2);
# x1 + x3 >= 4
c4 = COSMO.Constraint([1 0 1 0], -4, COSMO.Nonnegatives);
nothing #hide
```
````

Define matrix $P$ and vector $q$ for the objective function:

```@example lp
````@example lp
P = spzeros(4, 4);
q = c;
nothing #hide
```
````

Create, assemble and solve the model:

```@example lp
````@example lp
settings = COSMO.Settings(verbose=true, eps_abs = 1e-4, eps_rel = 1e-5);
model = COSMO.Model();
assemble!(model, P, q, [c1; c2; c3; c4], settings = settings);
res = COSMO.optimize!(model)
```
````

Compare the result to the known solution:

```@example lp
````@example lp
@test isapprox(res.x[1:4], [3; 5; 1; 1], atol=1e-2, norm = (x -> norm(x, Inf)))
```
````

```@example lp
````@example lp
@test isapprox(res.obj_val, 20.0, atol=1e-2)
```
````

---

Expand Down
22 changes: 11 additions & 11 deletions docs/src/examples/qp.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The source files for all examples can be found in [/examples](https://github.com/oxfordcontrol/COSMO.jl/tree/master/examples/).
```@meta
EditURL = "<unknown>/../examples/qp.jl"
EditURL = "../../../examples/qp.jl"
```

# Quadratic Program
Expand All @@ -13,7 +13,7 @@ We want to solve the following quadratic program with decision variable `x`:
```
The problem can be solved with `COSMO` in the following way. Start by defining the problem data

```@example qp
````@example qp
using COSMO, SparseArrays, LinearAlgebra, Test

q = [1; 1.];
Expand All @@ -22,49 +22,49 @@ A = [1. 1; 1 0; 0 1];
l = [1.; 0; 0];
u = [1; 0.7; 0.7];
nothing #hide
```
````

First, we decide to solve the problem with two one-sided constraints using `COSMO.Nonnegatives` as the convex set:

```@example qp
````@example qp
Aa = [-A; A]
ba = [u; -l]
constraint1 = COSMO.Constraint(Aa, ba, COSMO.Nonnegatives);
nothing #hide
```
````

Next, we define the settings object, the model and then assemble everything:

```@example qp
````@example qp
settings = COSMO.Settings(verbose=true);
model = COSMO.Model();
assemble!(model, P, q, constraint1, settings = settings);
res = COSMO.optimize!(model);
nothing #hide
```
````

Alternatively, we can also use two-sided constraints with `COSMO.Box`:

```@example qp
````@example qp
constraint1 = COSMO.Constraint(A, zeros(3), COSMO.Box(l, u));

model = COSMO.Model();
assemble!(model, P, q, constraint1, settings = settings);
res_box = COSMO.optimize!(model);
nothing #hide
```
````

Let's check that the solution is correct:

```@example qp
````@example qp
@testset "QP Problem" begin
@test norm(res.x[1:2] - [0.3; 0.7], Inf) < 1e-3
@test norm(res_box.x[1:2] - [0.3; 0.7], Inf) < 1e-3
@test abs(res.obj_val - 1.88) < 1e-3
@test abs(res_box.obj_val - 1.88) < 1e-3
end
nothing
```
````

---

Expand Down
Loading
Loading