# Trying to figure out the behavior of numpy.interp.
import math
import bisect
def to_float(iterable):
return list(map(float, iterable))
def lerp(a, b, t):
return (1 - t) * a + b * t
def invlerp(x, a, b):
if math.isclose(a, b):
return 0.5
return (x - a) / (b - a)
def interp(x, xp, fp, left=None, right=None):
"""
Linear interpolation for monotonically increasing sample points.
"""
n = len(xp)
if n != len(fp):
raise ValueError('fp and xp are not of the same length.')
if n == 0:
return
xp = to_float(xp)
fp = to_float(fp)
if left is None:
left = fp[0]
else:
left = float(left)
if right is None:
right = fp[-1]
else:
right = float(right)
last = xp[-1]
for y in x:
if y > last:
yield right; continue
i = bisect.bisect(xp, y)
if i == 0:
yield left; continue
j = i-1
k = min(i, n-1)
yield lerp(fp[j], fp[k], invlerp(y, xp[j], xp[k]))
# Main.
xp = [1, 2, 3]
fp = [3, 2, 0]
x = [0, 0.99, 1, 1.5, 2.73, 3, 3.01, 3.14]
print(list(interp([2.5], xp, fp)))
print(list(interp(x, xp, fp)))
print(list(interp(x, xp, fp, left=-99, right=99)))
import numpy as np
print(list(np.interp([2.5], xp, fp)))
print(list(np.interp(x, xp, fp)))
print(list(np.interp(x, xp, fp, left=-99, right=99)))
IyBUcnlpbmcgdG8gZmlndXJlIG91dCB0aGUgYmVoYXZpb3Igb2YgbnVtcHkuaW50ZXJwLgoKaW1wb3J0IG1hdGgKaW1wb3J0IGJpc2VjdAoKZGVmIHRvX2Zsb2F0KGl0ZXJhYmxlKToKICAgIHJldHVybiBsaXN0KG1hcChmbG9hdCwgaXRlcmFibGUpKQoKZGVmIGxlcnAoYSwgYiwgdCk6CiAgICByZXR1cm4gKDEgLSB0KSAqIGEgKyBiICogdAoKZGVmIGludmxlcnAoeCwgYSwgYik6CiAgICBpZiBtYXRoLmlzY2xvc2UoYSwgYik6CiAgICAgICAgcmV0dXJuIDAuNQogICAgcmV0dXJuICh4IC0gYSkgLyAoYiAtIGEpCgpkZWYgaW50ZXJwKHgsIHhwLCBmcCwgbGVmdD1Ob25lLCByaWdodD1Ob25lKToKICAgICIiIgogICAgTGluZWFyIGludGVycG9sYXRpb24gZm9yIG1vbm90b25pY2FsbHkgaW5jcmVhc2luZyBzYW1wbGUgcG9pbnRzLgogICAgIiIiCiAgICBuID0gbGVuKHhwKQoKICAgIGlmIG4gIT0gbGVuKGZwKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdmcCBhbmQgeHAgYXJlIG5vdCBvZiB0aGUgc2FtZSBsZW5ndGguJykKICAgIGlmIG4gPT0gMDoKICAgICAgICByZXR1cm4KCiAgICB4cCA9IHRvX2Zsb2F0KHhwKQogICAgZnAgPSB0b19mbG9hdChmcCkKCiAgICBpZiBsZWZ0IGlzIE5vbmU6CiAgICAgICAgbGVmdCA9IGZwWzBdCiAgICBlbHNlOgogICAgICAgIGxlZnQgPSBmbG9hdChsZWZ0KQogICAgaWYgcmlnaHQgaXMgTm9uZToKICAgICAgICByaWdodCA9IGZwWy0xXQogICAgZWxzZToKICAgICAgICByaWdodCA9IGZsb2F0KHJpZ2h0KQoKICAgIGxhc3QgPSB4cFstMV0KCiAgICBmb3IgeSBpbiB4OgogICAgICAgIGlmIHkgPiBsYXN0OgogICAgICAgICAgICB5aWVsZCByaWdodDsgY29udGludWUKICAgICAgICBpID0gYmlzZWN0LmJpc2VjdCh4cCwgeSkKICAgICAgICBpZiBpID09IDA6CiAgICAgICAgICAgIHlpZWxkIGxlZnQ7IGNvbnRpbnVlCiAgICAgICAgaiA9IGktMQogICAgICAgIGsgPSBtaW4oaSwgbi0xKQogICAgICAgIHlpZWxkIGxlcnAoZnBbal0sIGZwW2tdLCBpbnZsZXJwKHksIHhwW2pdLCB4cFtrXSkpCgojIE1haW4uCgp4cCA9IFsxLCAyLCAzXQpmcCA9IFszLCAyLCAwXQp4ICA9IFswLCAwLjk5LCAxLCAxLjUsIDIuNzMsIDMsIDMuMDEsIDMuMTRdCgpwcmludChsaXN0KGludGVycChbMi41XSwgeHAsIGZwKSkpCnByaW50KGxpc3QoaW50ZXJwKHgsIHhwLCBmcCkpKQpwcmludChsaXN0KGludGVycCh4LCB4cCwgZnAsIGxlZnQ9LTk5LCByaWdodD05OSkpKQoKaW1wb3J0IG51bXB5IGFzIG5wCnByaW50KGxpc3QobnAuaW50ZXJwKFsyLjVdLCB4cCwgZnApKSkKcHJpbnQobGlzdChucC5pbnRlcnAoeCwgeHAsIGZwKSkpCnByaW50KGxpc3QobnAuaW50ZXJwKHgsIHhwLCBmcCwgbGVmdD0tOTksIHJpZ2h0PTk5KSkp
[1.0]
[3.0, 3.0, 3.0, 2.5, 0.54, 0.0, 0.0, 0.0]
[-99.0, -99.0, 3.0, 2.5, 0.54, 0.0, 99.0, 99.0]
[1.0]
[3.0, 3.0, 3.0, 2.5, 0.54, 0.0, 0.0, 0.0]
[-99.0, -99.0, 3.0, 2.5, 0.54, 0.0, 99.0, 99.0]