Skip to content

Commit

Permalink
rename pacakge to pyrandvec; add environment.yml for (Ana)conda
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobbossek committed Mar 24, 2023
1 parent 2b9ecba commit 8fa6372
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 59 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ exclude visualise.py
exclude setup.cfg
exclude Makefile
exclude publish.sh
exclude environment.yml
exclude pyproject.toml_bck
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ test:
flake8:
flake8

conda:
conda env create -f environment.yml
conda activate pyrandvec
21 changes: 21 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: pyrandvec
channels:
- conda-forge
- defaults
dependencies:
# Basic conda install
- python=3.9
- matplotlib
- codecov
- pip
- pip:
- --editable . # install locally
# Testing
- pytest
# Linting
- flake8==5.0.4
- flake8-quotes==3.3.1
- flake8-bandit==4.1.1
- pep8-naming==0.13.2
- flake8-docstrings==1.6.0
- flake8-use-fstring==1.4.0
62 changes: 34 additions & 28 deletions randvec.py → pyrandvec.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""Module with methods for the generation of random vectors with a fixed sum of one."""
import random
import math


def sample(n: int, d: int, method: str = "normalisation", shuffle: bool = False) -> list[list[float]]:
'''
Generates a list of n d-dimensional random vectors whose elements sum up to one
with different methods.
def sample(n: int, d: int, method: str = 'normalisation', shuffle: bool = False) -> list[list[float]]:
"""
Generate a list of n d-dimensional random vectors whose elements sum up to one.
Args:
n (int): desired number of vectors.
Expand All @@ -14,7 +14,7 @@ def sample(n: int, d: int, method: str = "normalisation", shuffle: bool = False)
shuffle (bool): shall each vector be randomly shuffled? Default is False.
Returns:
List of length n of d-dimensional lists.
'''
"""
assert n >= 1
assert d >= 2

Expand All @@ -37,30 +37,33 @@ def sample(n: int, d: int, method: str = "normalisation", shuffle: bool = False)


def normalise(x: list[float]) -> list[float]:
'''
Utility function to normalise a list of floating point numbers.
I.e., the function divides each component of the list by its sum.
"""
Normalise a list of floating point numbers.
I.e., the function divides each component of the list by its sum such that
the resulting list has sum one.
Args:
x (list[float]): Input list.
Returns:
Normalised list.
'''
"""
return list(map(lambda e: e / sum(x), x))


def sample_normalisation(n: int, d: int) -> list[list[float]]:
'''
Generates a list of random vectors via normalisation.
I.e., (1) each component is sampled from a U(0,1) distribution and subsequently
(2) each component is divided by the components' sum.
"""
Generate a list of random vectors via normalisation.
The process works as follows: (1) each component is sampled from a U(0,1) distribution
and subsequently (2) each component is divided by the components' sum.
Args:
n (int): desired number of vectors.
d (int): dimension.
Returns:
List of length n of d-dimensional lists.
'''
"""
assert n >= 1
assert d >= 2

Expand All @@ -74,9 +77,10 @@ def sample_normalisation(n: int, d: int) -> list[list[float]]:


def sample_iterative(n: int, d: int) -> list[list[float]]:
'''
Generates a list of random vectors via an iterative approach:
I.e., the i-th component of the rpv is sampled uniformly at random from [0, s] where s is
"""
Generate a list of random vectors via an iterative approach.
More precisely, the i-th component of the rpv is sampled uniformly at random from [0, s] where s is
the sum of the 0, ..., (i-1)st components. The last component is finally (1-s). This
way it is unsured that the vectors are normalised.
Expand All @@ -85,7 +89,7 @@ def sample_iterative(n: int, d: int) -> list[list[float]]:
d (int): dimension.
Returns:
List of length n of d-dimensional lists.
'''
"""
assert n >= 1
assert d >= 2

Expand All @@ -103,8 +107,9 @@ def sample_sample_iterative(d):


def sample_trigonometric(n: int, d: int) -> list[list[float]]:
'''
Generates a list of random vectors via a trigonometric method.
"""
Generate a list of random vectors via a trigonometric method.
Section 5 in the following paper contains the details: Maziero, J. Generating Pseudo-Random
Discrete Probability Distributions. Brazilian Journal of Physics 45, 377–382 (2015).
https://doi.org/10.1007/s13538-015-0337-8)
Expand All @@ -114,7 +119,7 @@ def sample_trigonometric(n: int, d: int) -> list[list[float]]:
d (int): dimension.
Returns:
List of length n of d-dimensional lists.
'''
"""
assert n >= 1
assert d >= 2

Expand All @@ -141,9 +146,10 @@ def sample_sample_trigonometric(d):


def sample_exponential(n: int, d: int) -> list[list[float]]:
'''
Generates a list of random vectors by means of the inverse
exponential distribution function: I.e., the i-th component of the rpv is sampled
"""
Generate a list of random vectors by means of the inverse exponential distribution function.
More precisely, the i-th component of the rpv is sampled
uniformly at random from [0, s] where s is the sum of the 0, ..., (i-1)st
components. The last component is finally (1-s). This way it is unsured that
the vectors are normalised.
Expand All @@ -153,7 +159,7 @@ def sample_exponential(n: int, d: int) -> list[list[float]]:
d (int): dimension.
Returns:
List of length n of d-dimensional lists.
'''
"""
assert n >= 1
assert d >= 2

Expand All @@ -166,8 +172,8 @@ def sample_exponential(n: int, d: int) -> list[list[float]]:


def sample_simplex(n: int, d: int) -> list[list[float]]:
'''
Generates a list of random vectors via simplex sampling.
"""
Generate a list of random vectors via simplex sampling.
See the following paper for details on this method:
Grimme, C. Picking a Uniformly Random Point from an Arbitrary Simplex.
Expand All @@ -178,7 +184,7 @@ def sample_simplex(n: int, d: int) -> list[list[float]]:
d (int): dimension.
Returns:
List of length n of d-dimensional lists.
'''
"""
assert n >= 1
assert d >= 2

Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ exclude =
.pytest_cache,
.mypy_cache,
docs,
tests
ignore =
# unexpected spaces around keyword / parameter equal
# Allows for param = value instead of enforcing param=value
Expand Down
52 changes: 26 additions & 26 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
import setuptools

with open("README.md", "r") as fh:
with open('README.md', 'r') as fh:
long_description = fh.read()

setuptools.setup(
name = "randvec",
version = "1.0.2",
author = "Jakob Bossek",
author_email = "j.bossek@gmail.com",
description = "Generate random and uniform vectors whose components sum up to one",
name = 'pyrandvec',
version = '1.0.2',
author = 'Jakob Bossek',
author_email = 'j.bossek@gmail.com',
description = 'Generate random vectors whose components sum up to one',
long_description = long_description,
url = "https://github.com/jakobbossek/randvec/",
url = 'https://github.com/jakobbossek/pyrandvec/',
# tell PyPi that we use markdown and not RestructuredText
long_description_content_type = "text/markdown",
packages = setuptools.find_packages(exclude = ["tests"]),
long_description_content_type = 'text/markdown',
packages = setuptools.find_packages(exclude = ['tests']),
python_requires = '>=3.7',
py_modules = ["randvec"],
py_modules = ['pyrandvec'],
package_dir = {},
# make it easy for users to find the package
# (see https://pypi.org/classifiers/)
classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"License :: OSI Approved :: MIT License",
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Mathematics",
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'License :: OSI Approved :: MIT License',
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Intended Audience :: Science/Research',
'Topic :: Scientific/Engineering',
'Topic :: Scientific/Engineering :: Mathematics',
],
# for production dependencies
install_requires = [],
# for optional (development) requirements
extras_require = {
"dev": [
"pytest >=3.7",
'dev': [
'pytest >=3.7',
]
},
)
4 changes: 2 additions & 2 deletions tests/test_sample.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import itertools
from randvec import sample
from pyrandvec import sample


def test_that_vector_sum_is_one():
n = 5
ds = [2, 4]
methods = ["normalisation", "iterative", "exponential", "simplex", "trigonometric"]
methods = ['normalisation', 'iterative', 'exponential', 'simplex', 'trigonometric']
shuffling = [True, False]

for d, method, shuffle in list(itertools.product(ds, methods, shuffling)):
Expand Down
6 changes: 3 additions & 3 deletions visualise.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import matplotlib.pyplot as plt
from randvec import sample
from pyrandvec import sample

# parameters
n, d = 1000, 3

# plot
fig = plt.figure()

methods = ["normalisation", "iterative", "exponential", "simplex", "trigonometric"]
methods = ['normalisation', 'iterative', 'exponential', 'simplex', 'trigonometric']
k = 1
for i, method in enumerate(methods):
for j, shuffle in enumerate([True, False]):
Expand All @@ -28,7 +28,7 @@
sp.set_zlabel('z')
title = method
if shuffle:
title += " (shuffled)"
title += ' (shuffled)'
sp.set_title(title)
sp.scatter(xs, ys, zs, marker = 'o')

Expand Down

0 comments on commit 8fa6372

Please sign in to comment.