Source code for ddg.datastructures.nets.conversion

#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)