diff --git a/README.md b/README.md index f982022ad8050b2d8f54a134fd999773a3bb9ea5..f14d95ab6f4e36755c758d87e98bdd6e8f9a7a10 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,9 @@ take its neighbours into account and let you return a custom value. By default, it will assumes that values can be added, subbed, multed and dived, and will do classical linear interpolation. +They can either utilize an existing discrete series, or be created just as +any other discrete series would be. + ## Ranges Can be imported from _sai.ranges_. diff --git a/firanka/ranges.py b/firanka/ranges.py index b0b57fb48ea6eaf9c52bb5518141019956ef539a..3e06c1e886ef5b47446ea54a9f15618c18a93f22 100644 --- a/firanka/ranges.py +++ b/firanka/ranges.py @@ -1,9 +1,11 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division -import six + import functools import math +import six + __all__ = [ 'Range', 'REAL_SET', @@ -59,7 +61,8 @@ class Range(object): args = float(start), float(stop), rs[0] == '<', rs[-1] == '>' elif len(args) == 2: - args = args[0], args[1], not math.isinf(args[0]), not math.isinf(args[1]) + args = args[0], args[1], not math.isinf(args[0]), not math.isinf( + args[1]) q = lambda a, b, args: args[a] and math.isinf(args[b]) @@ -78,7 +81,7 @@ class Range(object): if isinstance(x, Range): if ((x.start == self.start) and (x.left_inc ^ self.left_inc)) \ or ((x.stop == self.stop) and ( - x.right_inc ^ self.right_inc)): + x.right_inc ^ self.right_inc)): return False return (x.start >= self.start) and (x.stop <= self.stop) @@ -93,15 +96,15 @@ class Range(object): def is_empty(self): return (self.start == self.stop) and not ( - self.left_inc or self.right_inc) + self.left_inc or self.right_inc) def length(self): return self.stop - self.start def __repr__(self): return 'Range(%s, %s, %s, %s)' % ( - repr(self.start), repr(self.stop), repr(self.left_inc), - repr(self.right_inc)) + repr(self.start), repr(self.stop), repr(self.left_inc), + repr(self.right_inc)) def __getitem__(self, item): if not isinstance(item, slice): diff --git a/firanka/series/__init__.py b/firanka/series/__init__.py index 59a5abc47844b6908fbd8c71d2603dc019c6c702..f73801128dd02f06c00af1719db8c1623be0a171 100644 --- a/firanka/series/__init__.py +++ b/firanka/series/__init__.py @@ -1,7 +1,9 @@ # coding=UTF-8 from __future__ import absolute_import + from .base import FunctionSeries, DiscreteSeries, Series -from .interpolations import LinearInterpolationSeries, SCALAR_LINEAR_INTERPOLATOR +from .interpolations import LinearInterpolationSeries, \ + SCALAR_LINEAR_INTERPOLATOR from .modulo import ModuloSeries __all__ = [ diff --git a/firanka/series/base.py b/firanka/series/base.py index 52a6d16bdcf121a983b4949bf942a6ec572e7502..6182ce09a2b5197069655a9ef284cd3b957407c4 100644 --- a/firanka/series/base.py +++ b/firanka/series/base.py @@ -1,14 +1,10 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division -import math - import six from firanka.exceptions import NotInDomainError -from firanka.ranges import Range, REAL_SET, EMPTY_SET - - +from firanka.ranges import Range, EMPTY_SET class Series(object): @@ -281,4 +277,3 @@ class JoinedSeries(Series): def _get_for(self, item): return self.op(self.ser1._get_for(item), self.ser2._get_for(item)) - diff --git a/firanka/series/interpolations.py b/firanka/series/interpolations.py index 5814bcb698b489617b952a54dacae5395ee9e51f..178c0ff901855be5a9240244d8c71d5dbda3ff75 100644 --- a/firanka/series/interpolations.py +++ b/firanka/series/interpolations.py @@ -1,32 +1,36 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division + import six -from .base import DiscreteSeries +from .base import DiscreteSeries, Series def SCALAR_LINEAR_INTERPOLATOR(t0, v0, t1, v1, tt): """ Good intepolator if our values can be added, subtracted, multiplied and divided """ - return v0 + (tt-t0) * (t1-t0)/(v1-v0) + return v0 + (tt - t0) * (t1 - t0) / (v1 - v0) class LinearInterpolationSeries(DiscreteSeries): - - def __init__(self, data, domain=None, interpolator=SCALAR_LINEAR_INTERPOLATOR, + def __init__(self, data, domain=None, + interpolator=SCALAR_LINEAR_INTERPOLATOR, *args, **kwargs): """ :param interpolator: callable(t0: float, v0: any, t1: float, v1: any, tt: float) -> any This, given intepolation points (t0, v0) and (t1, v1) such that t0 <= tt <= t1, return a value for index tt + :raise TypeError: a non-discrete series was passed as data """ self.interpolator = interpolator if isinstance(data, DiscreteSeries): - self.data = data.data - self.domain = domain or data.domain - else: - super(LinearInterpolationSeries, self).__init__(data, domain, *args, **kwargs) + data, domain = data.data, data.domain + elif isinstance(data, Series): + raise TypeError('non-discrete series not supported!') + + super(LinearInterpolationSeries, self).__init__(data, domain, *args, + **kwargs) def _get_for(self, item): if item == self.domain.start: @@ -35,9 +39,9 @@ class LinearInterpolationSeries(DiscreteSeries): if len(self.data) == 1: return super(LinearInterpolationSeries, self).__getitem__(item) - for i in six.moves.range(0, len(self.data)-1): + for i in six.moves.range(0, len(self.data) - 1): cur_i, cur_v = self.data[i] - next_i, next_v = self.data[i+1] + next_i, next_v = self.data[i + 1] if cur_i <= item <= next_i: return self.interpolator(cur_i, cur_v, next_i, next_v, item) diff --git a/firanka/series/modulo.py b/firanka/series/modulo.py index 665ea720e9167a4017eb5b1f086cb0975791be5b..ed728086214a840ea39286448302e1994d4afd06 100644 --- a/firanka/series/modulo.py +++ b/firanka/series/modulo.py @@ -1,7 +1,6 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division -import six -import logging + import math from .base import Series @@ -34,6 +33,3 @@ class ModuloSeries(Series): item = 0 return self.series._get_for(self.series.domain.start + item) - - - diff --git a/firanka/timeproviders.py b/firanka/timeproviders.py index 2cca5f445727763f15fe355218f8806290311fb8..47dbd0cfe6507a6d0b5cb47e7dc66d2b5441516b 100644 --- a/firanka/timeproviders.py +++ b/firanka/timeproviders.py @@ -1,10 +1,8 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division -import six -import logging -from .series import Series from .ranges import Range +from .series import Series class BijectionMapping(object): diff --git a/tests/test_range.py b/tests/test_range.py index f95cb6f87be4ef26798cca987d9d7a0762fcd349..c8bc9353b508d85f803932cbaf644565ff33a667 100644 --- a/tests/test_range.py +++ b/tests/test_range.py @@ -1,6 +1,8 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division + import unittest + from firanka.ranges import Range diff --git a/tests/test_series.py b/tests/test_series.py index c5396638282e8557832ba5d2ab07222363dcf1b0..94d73bc27346f091801e279cb44aca457b0d6840 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1,12 +1,13 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division -import six + import math import unittest -from firanka.series import DiscreteSeries, FunctionSeries, ModuloSeries, \ - LinearInterpolationSeries, SCALAR_LINEAR_INTERPOLATOR -from firanka.ranges import Range + from firanka.exceptions import NotInDomainError +from firanka.ranges import Range +from firanka.series import DiscreteSeries, FunctionSeries, ModuloSeries, \ + LinearInterpolationSeries NOOP = lambda x: x @@ -180,11 +181,13 @@ class TestModuloSeries(unittest.TestCase): class TestLinearInterpolation(unittest.TestCase): def test_lin(self): series = LinearInterpolationSeries( - DiscreteSeries([(0, 1), (1, 2), (2, 3)], '<0;3)'), - None, SCALAR_LINEAR_INTERPOLATOR) + DiscreteSeries([(0, 1), (1, 2), (2, 3)], '<0;3)')) self.assertEqual(series[0], 1) self.assertEqual(series[0.5], 1.5) self.assertEqual(series[1], 2) self.assertEqual(series[2.3], 3) + def test_conf(self): + self.assertRaises(TypeError, lambda: LinearInterpolationSeries( + FunctionSeries(NOOP, '<0;3)'))) diff --git a/tests/test_timeproviders.py b/tests/test_timeproviders.py index d6d0d78c56f0aec503e4eab6090eb045d964e10e..87bc595feb1fa122891fa837b6a5095613599536 100644 --- a/tests/test_timeproviders.py +++ b/tests/test_timeproviders.py @@ -1,6 +1,6 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division -import six + import unittest from firanka.series import DiscreteSeries