Skip to content
Snippets Groups Projects
Commit 19434887 authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

added linear interpolate

parent 11f859cd
No related branches found
Tags v2.14.14
No related merge requests found
# v2.14.14
* added `linear_interpolate`
Rudimentary data transforms and algorithms
==========================================
.. autofunction:: satella.coding.transforms.linear_interpolate
.. autofunction:: satella.coding.transforms.intify
......
__version__ = '2.14.14_a1'
__version__ = '2.14.14'
......@@ -8,10 +8,11 @@ from .jsonify import jsonify
from .merger import merge_series
from .percentile import percentile
from .base64 import b64encode
from .interpol import linear_interpolate
__all__ = ['stringify', 'split_shuffle_and_join', 'one_tuple',
'merge_series', 'pad_to_multiple_of_length', 'clip',
'jsonify', 'intify', 'percentile', 'b64encode']
'jsonify', 'intify', 'percentile', 'b64encode', 'linear_interpolate']
from satella.coding.typing import T, NoArgCallable, Appendable, Number, Predicate
......
import typing as tp
from satella.coding.typing import U, K
import bisect
def linear_interpolate(series: tp.Sequence[tp.Tuple[K, U]], t: K) -> U:
"""
Given a sorted (ascending) series of (t_value, y_value) interpolating linearly a function of
y=f(t) compute a linear approximation of f at t
of two closest values.
t must be larger or equal to t_min and smaller or equal to t_max
:param series: series of (t, y) sorted by t ascending
:param t: t to compute the value for
:return: return value
:raise ValueError: t was smaller than t_min or greater than t_max
"""
if t < series[0][0]:
raise ValueError('t smaller than t_min')
if t > series[-1][0]:
raise ValueError('t greater than t_max')
if t == series[0][0]:
return series[0][1]
i = bisect.bisect_left([y[0] for y in series], t) - 1
if i == len(series)-1:
return series[-1][1]
t1, v1 = series[i]
t2, v2 = series[i+1]
assert t1 <= t <= t2, 'Series not sorted!'
return (v2 - v1) / (t2 - t1) * (t - t1) + v1
......@@ -3,11 +3,20 @@ import unittest
import base64
from satella.coding.transforms import stringify, split_shuffle_and_join, one_tuple, \
merge_series, pad_to_multiple_of_length, clip, b64encode
merge_series, pad_to_multiple_of_length, clip, b64encode, linear_interpolate
class TestTransforms(unittest.TestCase):
def test_linear_interpolate(self):
self.assertEqual( linear_interpolate([(0, 10), (10, 20)], 5), 15)
self.assertEqual( linear_interpolate([(0, 10), (10, 20)], 2.5), 12.5)
self.assertEqual( linear_interpolate([(0, 10), (10, 20)], 0), 10)
self.assertEqual( linear_interpolate([(0, 10), (10, 20)], 10), 20)
self.assertEqual( linear_interpolate([(0, 10), (10, 20), (20, 10)], 15), 15)
self.assertRaises(ValueError, lambda: linear_interpolate([(0, 10), (10, 20)], 30))
self.assertRaises(ValueError, lambda: linear_interpolate([(0, 10), (10, 20)], -2))
def test_base64(self):
a = b64encode(b'test')
self.assertEqual(base64.b64decode(a), b'test')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment