Skip to content

Commit

Permalink
v0.4.0 Release Prep (#17)
Browse files Browse the repository at this point in the history
* Changed SigmaSq to its own class type. APIs no longer allow directly setting sigma_sq values, and instead only indicate whether to train them.

* Update README.md

missed dropping a reference to old sigma_sq api pattern

* Hotfix/learn-sigma (#5)

* Fixed a bug causing sigma_sqs to always go unlearned.

* Changed default behavior throughout to automatically scale variance by sigma_sq (assuming it is trained). Overridable with the apply_sigma_sq kwarg. (#6)

* Added option to all high-level apis to return crosswise_dists and pairwise_dists. (#7)

* Added make_regress_tensors and make_train_tensors helper functions and dispersed them throughout the code. Simplified optimization API. Cleaned up some documentation. (#8)

* Added CONTRIBUTING.md document. (#9)

* Refactored BenchmarkGP to share new gp API. Added _sq_rel_err test function. Explored bug in rbf computation of sigma_sq, and turned off related test cases. See issue #1. (#11)

* Feature/notebooks (#12)

* First pass on a univariate regression tutorial, describing the basics of MuyGPyS.

* Cleaned up some comments and documentation.

* Linked tutorial notebook into docs and inserted links.

* bugfix: changed return distances semantics and documentation to work correctly.

* some miscellaneous cleanup.

* Added regression API tutorial.

* Edited readme to remove code and added links to notebooks.

* Added matplotlib to docs/requirements.txt. (#13)

* hopefully fixed rtd.yml (#14)

* Docs (#15)

* formatting fix to get readthedocs to build the project for notebooks

* Hotfix/sigma sq approx (#16)

* Addresses sigma_sq inference bug in issue #10 

* Fixed test chassis to avoid overly smooth curves for to guarantee well-behaved estimators.

* Fixed a bug in the sigma_sq testing chassis. (#18)

* incremented minor version number.
  • Loading branch information
bwpriest authored Dec 9, 2021
1 parent 0ad3cdd commit f60e671
Show file tree
Hide file tree
Showing 27 changed files with 3,223 additions and 1,281 deletions.
6 changes: 5 additions & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ sphinx:
formats:
- pdf



# Optionally set the version of Python and requirements required to build your docs
python:
version: 3.7
install:
- requirements: docs/requirements.txt
- method: pip
path: .
- requirements: docs/requirements.txt
320 changes: 320 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,320 @@
# How to Contribute

`MuyGPyS` is an open source project.
Our team welcomes contributions from collaborators in the form of raising issues
as well as code contributions including hotfixes, code improvements, and new
features.

`MuyGPyS` is distributed under the terms of the
[MIT license](https://github.com/LLNL/MuyGPyS/blob/develop/LICENSE-MIT).
All new contributions must be made under this license.

If you identify a problem such as a bug or awkward or confusing code, or require
a new feature, please feel free to start a thread on our
[issue tracker](https://github.com/LLNL/MuyGPyS/issues).
Please first review the existing issues to avoid duplicates.

If you plan on contributing to `MuyGPyS`, please review the
[issue tracker](https://github.com/LLNL/MuyGPyS/issues) to check for threads
related to your desired contribution.
We recommend creating an issue prior to issuing a pull request if you are
planning significant code changes or have questions.

# Contribution Workflow

These guidelines assume that the reader is familiar with the basics of
collaborative development using git and GitHub.
This section will walk through our preferred pull request workflow for
contributing code to `MuyGPyS`.
The tl;dr guidance is:
- Fork the [LLNL MuyGPyS repository](https://github.com/LLNL/MuyGPyS)
- Create a descriptively named branch
(`feature/myfeature`, `iss/##`, `hotfix/bugname`, etc) in your fork off of
the `develop` branch
- Commit code, following our [guidelines](#formatting-guidelines)
- Create a [pull request](https://github.com/LLNL/MuyGPyS/compare/) from your
branch targeting the LLNL `develop` branch

## Forking MuyGPyS

If you are not a `MuyGPyS` developer at LLNL, you will not have permissions to
push new branches to the repository.
Even `MuyGPyS` developers at LLNL will want to use forks for most contributions.
This will create a clean copy of the repository that you own, and will allow for
exploration and experimentation without muddying the history of the central
repository.

If you intend to maintain a persistent fork of `MuyGPyS`, it is a best practice
to set the LLNL repository as the `upstream` remote in your fork.
```
$ git clone [email protected]:your_name/MuyGPyS.git
$ cd MuyGPyS
$ git remote add upstream [email protected]:LLNL/MuyGPyS.git
```
This will allow you to incorporate changes to the `main` and `develop`
branches as they evolve.
For example, to your fork's develop branch perform the following commands:
```
$ git fetch upstream
$ git checkout develop
$ git pull upstream develop
$ git push origin develop
```
It is important to keep your develop branch up-to-date to reduce merge conflicts
resulting from future PRs.

## Contribution Types

Most contributions will fit into one of the follow categories, which by
convention should be committed to branches with descriptive names.
Here are some examples:
- A new feature (`feature/<feature-name>`)
- A bug or hotfix (`hotfix/<bug-name>` or `hotfix/<issue-number>`)
- A response to a [tracked issue](https://github.com/LLNL/MuyGPyS/issues)
(`iss/<issue-number>`)
- A work in progress, not to be merged for some time (`wip/<change-name>`)

### Developing a new feature

New features should be based on the develop branch:
```
$ git checkout develop
$ git pull upstream develop
```
You can then create new local and remote branches on which to develop your
feature.
```
$ git checkout -b feature/<feature-name>
$ git push --set-upstream origin feature/<feature-name>
```
Commit code changes to this branch, and add tests to the `tests` directory that
validate the correctness of your code, modifying existing tests if need be.
Be sure that your test runs successfully.

Make sure that you follow our [formatting guidelines](#formatting-guidlines) for
any changes to the source code or build system.
If you create new methods or classes, please add ReStructuredText documentation.

Once your feature is complete and your tests are passing, ensure that your
remote fork is up-to-date and
[create a PR](https://github.com/LLNL/MuyGPyS/compare).

### Developing a hotfix

Firstly, please check to ensure that the bug you have found has not already been
fixed in `develop`.
If it has, we suggest that you either temporarily swap to the `develop` branch.

If you have identified an unsolved bug, you can document the problem and create
an [issue](https://github.com/LLNL/MuyGPyS/issues).
If you would like to solve the bug yourself, follow a similar protocol to
feature development.
First, ensure that your fork's `develop` branch is up-to-date.
```
$ git checkout develop
$ git pull upstream develop
```
You can then create new local and remote branches on which to write your bug
fix.
```
$ git checkout -b hotfix/<bug-name>
$ git push --set-upstream origin hotfix/<bug-name>
```

Firstly, create a test added to the `tests` directory that reproduces the bug or
modify an existing test to catch the bug if that is more appropriate.
Then, modify the code to fix the bug and ensure that your new or modified test
case(s) pass.

Please update function and class documentation to reflect any changes as
appropriate, and follow our [formatting guidlines](#formatting-guidelines) with
any new code.

Once your are satisfied that the bug is fixed, ensure that your remote fork is
up-to-date and [create a PR](https://github.com/LLNL/MuyGPyS/compare).

# Tests

<!-- `MuyGPyS` uses GitHub actions for continuous integration tests.
Our tests run automatically against every new commit and pull request, and pull
requests must pass all tests prior to being considered for merging into the main
project. -->
Pull requests must pass all tests prior to being considered for merging into the
main project.
If you are developing a new feature or fixing a bug, please add a test or modify
existing tests that will ensure the correctness of the new code.

`MuyGPyS`'s tests are contained in the `test` directory, and make use of the
`absl` library.

# Formatting Guidelines

## Naming Style

In general, all names in `MuyGPyS` should be as succinct as possible while
remaining descriptive.

MuyGPyS methods and variables should all be `snake_case`, i.e. one or more
lowercase words separated by underscores.
Mathy variable names like `x` and `y` should be avoided in favor of descriptive
names such as `train_features`.
The few exceptions to this rule are canonical kernel hyperparameters such as
`nu` and `sigma_sq`.

Here are some example function and variable names
```
def my_cool_function() -> int
magic_number = 14
return magic_number
def my_other_cool_function(fun_array: np.array) -> np.array
return 2.5 * fun_array
```

MuyGPyS classes should be `PascalCase`, one or more words that start with
uppercase letters with no separator.
Classes are to be avoided where possible, as MuyGPyS is a "soft" functional
package.
What classes do exist are predominantly functors (classes organized around a
`__call__()` method) or near-functors (classes organized around two or more
related named functions, such as `MuyGPS` and its methods `MuyGPS.regress()`
and `MuyGPS.regress_from_indices()`).
Class members (variables and functions) that are intended for internal use
should be prepended with an underscore.
Think carefully as to whether what you are trying to do really requires the
statefulness of a functor, or whether it can be alternatively accomplished via a
function or set of functions.

Here is an example functor class:
```
class NeatMultiplier:
def __init__(self, coefficient: float) -> None:
self._coefficient = coefficient
def __call__(self, val: float) -> float:
return val * self._coefficient
```

## Python type hints

`MuyGPyS` uses [type hints](https://www.python.org/dev/peps/pep-0484/) for all
function arguments and return values.
These type hints are useful for documentation, debugging, and for linting using,
e.g. [mygpy](http://mypy-lang.org/).

The examples in [the prior section](#naming-style) include some simple examples.
Here is a slightly more sophisticated example of a functor that can return
either a `float` or `np.ndarray` object:
```
from typing import Union
class VariableMultiplier:
def __init__(self, coefficient: float) -> None:
self._coefficient = coefficient
def __call__(
self, val: Union[float, np.ndarray]
) -> Union[float, np.ndarray]:
return val * self._coefficient
```

## Documentation Style

All API methods and classes that are called by users must include a
[ReStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html)
docstring.
This docstring must include the following components:
- A single sentence summarizing its use.
- Formatted descriptions of any arguments
- Formatted descriptions of any returned objects
- Formatted descriptions of any `Error`s the could be raised and the conditions
that trigger them.

Additional components might include:
- Paragraph(s) following the single sentence summary expanding upon detail
- RST links to other sections of the package
- Hyperlinks to external references
- Inline LaTeX formatted strings illustrating the math
- Formatted code example(s) demonstrating the functor or function's use.

*Important Detail* MuyGPyS deals with many vectors, matrices, and tensors.
For clarity, functions and functors operating on such objects should record in
their docstrings the expected shape of their arguments, if they are known.
Most vectors, matrices, and tensors throughout the codebase have dimensions
definded in terms of the scalar quantities `train_count`, `test_count`,
`batch_count`, or `nn_count`.

*Important Detail* The formatting required for functions with multiple return
values (i.e. functions that return a tuple of objects) differs from that of
functions with a single return object.
Here is an example function with a single return value:
```
def array_multiplier(fun_array: np.array, coeff: float = 2.5) -> np.array
"""
Multiplies an array by a scalar.
.. math::
Y = cX
Example:
>>> import numpy as np
>>> X = np.random.randn(10, 5)
>>> c = 2.5
>>> Y = array_multiplier(X, coeff=c)
Args:
fun_array:
A tensor of shape `(shape_1, shape_2, shape_3)`
coeff:
A floating point coefficient.
Returns:
A tensor of shape `(shape_1, shape_2, shape_3)`, elementwise multiplied
by the provided scalar coefficient.
"""
return coeff * fun_array
```
Meanwhile, here is a similar function with multiple return values.
Note the different formating of the returns.
```
from typing import Tuple
def verbose_array_multiplier(
fun_array: np.array, coeff: float = 2.5
) -> Tuple[np.array, float]
"""
Multiplies an array by a scalar, and also returns the scalar + 1.
.. math::
Y = cX
Example:
>>> import numpy as np
>>> X = np.random.randn(10, 5)
>>> c = 2.5
>>> Y, c_prime = array_multiplier(X, coeff=c)
Args:
fun_array:
A tensor of shape `(shape_1, shape_2, shape_3)`
coeff:
A floating point coefficient.
Returns
-------
ret_array:
A tensor of shape `(shape_1, shape_2, shape_3)`, elementwise
multiplied by the provided scalar coefficient.
ret_coeff:
The provided scalar coefficient incremented by one.
"""
ret_array = coeff * fun_array
ret_coeff = coeff + 1
return ret_array, ret_coeff
```
See the codebase for more sophisticated examples.

## Code Style

`MuyGPyS` uses the [black](https://pypi.org/project/black/) formatter to
guarantee a consistent format for python code.
`black` is easy to use, and can be easily instrumented to auto-format
code using most modern editors.

8 changes: 3 additions & 5 deletions COPYRIGHT
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
Intellectual Property Notice
------------------------------

MuyGPyS is the Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or
the MIT license, (LICENSE-MIT or http://opensource.org/licenses/MIT), at your option.
MuyGPyS uses the MIT license, (LICENSE-MIT or http://opensource.org/licenses/MIT).

Copyrights and patents in the MuyGPyS project are retained by contributors.
No copyright assignment is required to contribute to MuyGPyS.
Expand All @@ -15,7 +14,6 @@ Individual files contain SPDX tags instead of the full license text.
This enables machine processing of license information based on the SPDX
License Identifiers that are available here: https://spdx.org/licenses/

Files that are dual-licensed as Apache-2.0 OR MIT contain the following
text in the license header:
Files that are licensed under MIT contain the following text in the license header:

SPDX-License-Identifier: (Apache-2.0 OR MIT)
SPDX-License-Identifier: MIT
2 changes: 1 addition & 1 deletion MuyGPyS/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

"""Public MuyGPyS modules and functions."""

__version__ = '0.3.0'
__version__ = '0.4.0'

from MuyGPyS import neighbors

Expand Down
Loading

0 comments on commit f60e671

Please sign in to comment.