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

Remove duplicate methods #6291

Merged
merged 5 commits into from
Nov 14, 2022
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
99 changes: 34 additions & 65 deletions pymc/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@

from pymc.aesaraf import (
PointFunc,
SeedSequenceSeed,
compile_pymc,
convert_observed_data,
gradient,
Expand Down Expand Up @@ -986,43 +987,6 @@ def dim_lengths(self) -> Dict[str, Variable]:
"""
return self._dim_lengths

@property
def test_point(self) -> Dict[str, np.ndarray]:
"""Deprecated alias for `Model.initial_point(seed=None)`."""
warnings.warn(
"`Model.test_point` has been deprecated. Use `Model.initial_point(seed=None)`.",
FutureWarning,
)
return self.initial_point()

def initial_point(self, seed=None) -> Dict[str, np.ndarray]:
"""Computes the initial point of the model.

Returns
-------
ip : dict
Maps names of transformed variables to numeric initial values in the transformed space.
"""
fn = make_initial_point_fn(model=self, return_transformed=True)
return Point(fn(seed), model=self)

@property
def initial_values(self) -> Dict[TensorVariable, Optional[Union[np.ndarray, Variable, str]]]:
"""Maps transformed variables to initial value placeholders.

Keys are the random variables (as returned by e.g. ``pm.Uniform()``) and
values are the numeric/symbolic initial values, strings denoting the strategy to get them, or None.
"""
return self._initial_values

def set_initval(self, rv_var, initval):
"""Sets an initial value (strategy) for a random variable."""
if initval is not None and not isinstance(initval, (Variable, str)):
# Convert scalars or array-like inputs to ndarrays
initval = rv_var.type.filter(initval)

self.initial_values[rv_var] = initval

def shape_from_dims(self, dims):
shape = []
if len(set(dims)) != len(dims):
Expand Down Expand Up @@ -1137,6 +1101,39 @@ def set_dim(self, name: str, new_length: int, coord_values: Optional[Sequence] =
self.dim_lengths[name].set_value(new_length)
return

def initial_point(self, random_seed: SeedSequenceSeed = None) -> Dict[str, np.ndarray]:
"""Computes the initial point of the model.

Parameters
----------
random_seed : SeedSequenceSeed, default None
Seed(s) for generating initial point from the model. Passed into :func:`pymc.aesaraf.reseed_rngs`

Returns
-------
ip : dict of {str : array_like}
Maps names of transformed variables to numeric initial values in the transformed space.
"""
fn = make_initial_point_fn(model=self, return_transformed=True)
return Point(fn(random_seed), model=self)

@property
def initial_values(self) -> Dict[TensorVariable, Optional[Union[np.ndarray, Variable, str]]]:
"""Maps transformed variables to initial value placeholders.

Keys are the random variables (as returned by e.g. ``pm.Uniform()``) and
values are the numeric/symbolic initial values, strings denoting the strategy to get them, or None.
"""
return self._initial_values

def set_initval(self, rv_var, initval):
"""Sets an initial value (strategy) for a random variable."""
if initval is not None and not isinstance(initval, (Variable, str)):
# Convert scalars or array-like inputs to ndarrays
initval = rv_var.type.filter(initval)

self.initial_values[rv_var] = initval

def set_data(
self,
name: str,
Expand Down Expand Up @@ -1259,34 +1256,6 @@ def set_data(

shared_object.set_value(values)

def initial_point(self, seed=None) -> Dict[str, np.ndarray]:
Copy link
Member

@ricardoV94 ricardoV94 Nov 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I probably caused this when trying to reorder the methods a bit more logically. There is a shape_from_dims below the initial point related methods which makes more sense above, close to the other coord/dims related methods.

I would therefore delete the repeated methods above and not these below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright. I will reorder

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put after the dim/coords methods but before set_data. Thought that made enough sense

"""Computes the initial point of the model.

Returns
-------
ip : dict
Maps names of transformed variables to numeric initial values in the transformed space.
"""
fn = make_initial_point_fn(model=self, return_transformed=True)
return Point(fn(seed), model=self)

@property
def initial_values(self) -> Dict[TensorVariable, Optional[Union[np.ndarray, Variable, str]]]:
"""Maps transformed variables to initial value placeholders.

Keys are the random variables (as returned by e.g. ``pm.Uniform()``) and
values are the numeric/symbolic initial values, strings denoting the strategy to get them, or None.
"""
return self._initial_values

def set_initval(self, rv_var, initval):
"""Sets an initial value (strategy) for a random variable."""
if initval is not None and not isinstance(initval, (Variable, str)):
# Convert scalars or array-like inputs to ndarrays
initval = rv_var.type.filter(initval)

self.initial_values[rv_var] = initval

def register_rv(
self, rv_var, name, data=None, total_size=None, dims=None, transform=UNSET, initval=None
):
Expand Down
2 changes: 1 addition & 1 deletion pymc/smc/kernels.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def _initialize_kernel(self):

"""
# Create dictionary that stores original variables shape and size
initial_point = self.model.initial_point(seed=self.rng.integers(2**30))
initial_point = self.model.initial_point(random_seed=self.rng.integers(2**30))
for v in self.variables:
self.var_info[v.name] = (initial_point[v.name].shape, initial_point[v.name].size)
# Create particles bijection map
Expand Down
22 changes: 11 additions & 11 deletions pymc/tests/test_initial_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def test_new_warnings(self):
with pm.Model() as pmodel:
with pytest.warns(FutureWarning, match="`testval` argument is deprecated"):
rv = pm.Uniform("u", 0, 1, testval=0.75)
initial_point = pmodel.initial_point(seed=0)
initial_point = pmodel.initial_point(random_seed=0)
assert initial_point["u_interval__"] == transform_fwd(rv, 0.75, model=pmodel)
assert not hasattr(rv.tag, "test_value")
pass
Expand All @@ -56,7 +56,7 @@ def test_valid_string_strategy(self):
with pm.Model() as pmodel:
pm.Uniform("x", 0, 1, size=2, initval="unknown")
with pytest.raises(ValueError, match="Invalid string strategy: unknown"):
pmodel.initial_point(seed=0)
pmodel.initial_point(random_seed=0)


class TestInitvalEvaluation:
Expand All @@ -79,15 +79,15 @@ def test_dependent_initvals(self):
U = pm.Uniform("U", lower=9, upper=10, initval=9.5)
B1 = pm.Uniform("B1", lower=L, upper=U, initval=5)
B2 = pm.Uniform("B2", lower=L, upper=U, initval=(L + U) / 2)
ip = pmodel.initial_point(seed=0)
ip = pmodel.initial_point(random_seed=0)
assert ip["L_interval__"] == 0
assert ip["U_interval__"] == 0
assert ip["B1_interval__"] == 0
assert ip["B2_interval__"] == 0

# Modify initval of L and re-evaluate
pmodel.initial_values[U] = 9.9
ip = pmodel.initial_point(seed=0)
ip = pmodel.initial_point(random_seed=0)
assert ip["B1_interval__"] < 0
assert ip["B2_interval__"] == 0
pass
Expand Down Expand Up @@ -121,11 +121,11 @@ def test_initval_resizing(self):
data = aesara.shared(np.arange(4))
rv = pm.Uniform("u", lower=data, upper=10, initval="prior")

ip = pmodel.initial_point(seed=0)
ip = pmodel.initial_point(random_seed=0)
assert np.shape(ip["u_interval__"]) == (4,)

data.set_value(np.arange(5))
ip = pmodel.initial_point(seed=0)
ip = pmodel.initial_point(random_seed=0)
assert np.shape(ip["u_interval__"]) == (5,)
pass

Expand All @@ -134,9 +134,9 @@ def test_seeding(self):
pm.Normal("A", initval="prior")
pm.Uniform("B", initval="prior")
pm.Normal("C", initval="moment")
ip1 = pmodel.initial_point(seed=42)
ip2 = pmodel.initial_point(seed=42)
ip3 = pmodel.initial_point(seed=15)
ip1 = pmodel.initial_point(random_seed=42)
ip2 = pmodel.initial_point(random_seed=42)
ip3 = pmodel.initial_point(random_seed=15)
assert ip1 == ip2
assert ip3 != ip2
pass
Expand Down Expand Up @@ -285,7 +285,7 @@ class MyNormalDistribution(pm.Normal):
def test_pickling_issue_5090():
with pm.Model() as model:
pm.Normal("x", initval="prior")
ip_before = model.initial_point(seed=5090)
ip_before = model.initial_point(random_seed=5090)
model = cloudpickle.loads(cloudpickle.dumps(model))
ip_after = model.initial_point(seed=5090)
ip_after = model.initial_point(random_seed=5090)
assert ip_before["x"] == ip_after["x"]
7 changes: 1 addition & 6 deletions pymc/tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ def test_missing_data(self):

assert m["x2_missing"].type == gf._extra_vars_shared["x2_missing"].type

pnt = m.initial_point(seed=None).copy()
pnt = m.initial_point(random_seed=None).copy()
del pnt["x2_missing"]

res = [gf(DictToArrayBijection.map(Point(pnt, model=m))) for i in range(5)]
Expand Down Expand Up @@ -573,11 +573,6 @@ def test_initial_point():
a = pm.Uniform("a")
x = pm.Normal("x", a)

with pytest.warns(FutureWarning):
initial_point = model.test_point

assert all(var.name in initial_point for var in model.value_vars)

b_initval = np.array(0.3, dtype=aesara.config.floatX)

with pytest.warns(FutureWarning), model:
Expand Down