#TODO: Remove old functions
import numpy as np
from collections.abc import Iterable
from . import utils as netu
from ddg.datastructures.nets.domain import (DiscreteRectangularDomain,
SmoothRectangularDomain,
EmptyDomain)
from ddg.datastructures.nets.net import (DiscreteNet, EmptyNet, PointNet,
SamplingNet)
from ddg.datastructures.nets.utils import sample_interval
[docs]def sampling_decomposer(sampling, atol, anchor, dimension):
"""
Helper function for sample_smooth_domain.
Given parameters of a sampling, this function returns
a list of usable length for the sampling process of domains.
Parameters
----------
sampling : list, int or float
Stepsize/Amount of samples and additional options. To default pass an
int/float. If not pass a list of the form [stepsize/samples, option].
atol : list, int or float
Tolerance(s) used in the sampling process. To default pass an
int/float. If not pass a list of tolerances for each direction.
anchor : list, tuple or None
Anchor point used in the sampling process.
dimension : int
Dimension of the domain you want to sample.
Returns
-------
list
| List of the decomposed sampling.
| [0] stepsize/samples
| [1] options
| [2] tolerances
| [3] anchor
See also
--------
sample_smooth_domain
"""
if not isinstance(sampling, Iterable):
samples = [[sampling] * dimension, [''] * dimension]
elif len(sampling) == 1 and isinstance(sampling[0], Iterable):
samples = [sampling[0][:-1]] * dimension
if len(sampling[0]) == 2:
options = [sampling[0][-1]] * dimension
else:
options = ['']*dimension
samples = [samples, options]
elif len(sampling) == 1:
samples = [[sampling[0]] * dimension, [''] * dimension]
elif len(sampling) in [2,3] and type(sampling[-1]) == str:
samples = [[sampling[:-1]] * dimension, [sampling[-1]] * dimension]
else:
samples = [s[:-1] if isinstance(s, Iterable) else [s] for s in sampling]
options = [s[-1] if isinstance(s, Iterable) and len(s) in [2,3] else ''
for s in sampling]
samples = [samples, options]
if isinstance(atol, Iterable):
if len(atol) == 1:
samples.append([atol[0]] * dimension)
else:
samples.append(atol)
else:
samples.append([atol] * dimension)
if anchor is not None:
anchor = np.array(anchor)
samples.append(anchor)
else:
samples.append([None] * dimension)
return samples
[docs]def sample_smooth_domain(domain, sampling, anchor=None, atol=1e-8):
"""
Samples a smooth domain.
Parameters
----------
domain : ddg.datastructures.nets.domain.SmoothDomain
SmoothDomain to sample.
sampling : list, int or float
| Determines how the domain is sampled.
| If a default stepsize/sample amount and option
| should be used for all directions, either pass an int/float (will be
| regarded as stepsize), or a list of length 2 where the first entry is
| the stepsize/sample amount and the second is the option to use.
| Else pass a list of length of the dimension of the domain where each
| entry can be either an int/float or a list of length two (same rules as
| above).
|
| Options:
| 't' : use the number as total amount of samples. Will raise a
| warning, if the number is a float
| 's' : symmetric sampling.
|
| WARNING! Not compatible with anchor and 't' yet.
| 'p' : direction is periodic. Only needs to be set manually, if the
| direction in the domain was not marked as periodic.
| 'c' : compound sampling. Sampling given as a list
| [stepsize, amount of samples, 'c']
anchor : list, tuple or None
Anchor point to use for the sampling process.
atol : list, int or float
Tolerance(s) used in the sampling process. Either pass a single value
to use for all directions, or a list of length of the dimension of the
domain of floats/ints.
Returns
-------
ddg.datastructures.nets.net.DiscreteNet
See also
--------
sampling_decomposer
"""
if isinstance(domain, EmptyDomain):
return DiscreteNet(lambda : None,domain)
if not isinstance(domain, SmoothRectangularDomain):
raise TypeError(
'Domain does not support given type: {}'.format(
domain.__class__.__name__))
if domain.dimension == 0:
return DiscreteNet(lambda : None, domain)
def fct(*args, **kwargs):
sample, option, atols, anc = sampling_decomposer(sampling, atol,
anchor,
domain.dimension)
sampfcts = []
for idx, el in enumerate(domain):
if idx in domain.periodicity:
option[idx] += 'p'
temp = sample_interval(el, sample[idx], option=option[idx],
atol=atols[idx], anchor=anc[idx])[2]
sampfcts.append(temp)
return sampfcts
sample, option, atols, anc = sampling_decomposer(sampling, atol,
anchor,
domain.dimension)
intervals = []
for idx, el in enumerate(domain):
periodic = idx in domain.periodicity
if periodic:
option[idx] += 'p'
temp = sample_interval(el, sample[idx], option=option[idx],
atol=atols[idx], anchor=anc[idx])
if temp[0][0] == -np.inf and temp[0][1] == np.inf:
intervals.append([-np.inf, np.inf])
elif temp[0][0] == -np.inf:
intervals.append([-np.inf, 0])
elif temp[0][1] == np.inf:
intervals.append([0, np.inf])
else:
intervals.append([0, temp[1] - 1])
if periodic and all(np.isclose(temp[0], el, atol=atols[idx])):
intervals[-1].append(True)
sampledomain = DiscreteRectangularDomain(intervals)
samplingnet = SamplingNet(fct, sampledomain, name='SamplingNet')
return samplingnet
[docs]@netu.applicable_to_netcollection
def sample_smooth_net(net, sampling, anchor=None, atol=1e-8, name=None,
outsnet=False):
"""
Samples a smooth net.
Parameters
----------
net : ddg.datastructures.nets.net.SmoothNet
Smooth net to sample.
sampling : list, int or float
See sample_smooth_domain.
anchor : list or None
Anchor point for sampling process.
atol : list, int or float
Tolerance(s) for sampling process.
name : string
Name of the sampled net. If None, uses net.name instead.
outsnet : bool
Set to true, the function returns a tuple of the sampled net and the
sampling net instead.
Returns
-------
ddg.datastructures.nets.net.DiscreteNet or
tuple
See Also
--------
sample_smooth_domain
"""
samplingnet = sample_smooth_domain(net.domain, sampling, anchor=anchor,
atol=atol)
def discrete_fct(*args, **kwargs):
return net(*samplingnet(*args))
if name == None:
name = net.name
if isinstance(net, EmptyNet) or isinstance(net, PointNet):
return net
dnet = DiscreteNet(discrete_fct, samplingnet.domain, name=name)
if not outsnet:
return dnet
else:
return (dnet, samplingnet)