# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE', which is part of this source code package.
#
#
import os
import numpy as np
import bisect
[docs]
def BinarySearch(orderedList, item):
"""
Inspects the sorted list "ordered_list" and returns:
- 0 if item <= orderedList[0]
- the rank of the largest element smaller or equal than item otherwise
Parameters
----------
ordered_list: list or one-dimensional np.ndarray
the data sorted in increasing order from which the previous rank is\
searched
item : float or int
the item for which the previous rank is searched
Returns
-------
int
0 or the rank of the largest element smaller or equal than item in\
"orderedList"
"""
return max(bisect.bisect_right(orderedList, item) - 1, 0)
[docs]
def BinarySearchVectorized(orderedList, items):
"""
BinarySearch for more than one call (items is now a list or one-dimensional np.ndarray)
"""
return np.fromiter(map(lambda item: BinarySearch(orderedList, item), items), dtype = int)
[docs]
def PieceWiseLinearInterpolation(item, itemIndices, vectors, tolerance = 1e-4):
"""
Computes a item interpolation for temporal vectors defined either by
itemIndices and vectors at these indices
Parameters
----------
item : float
the input item at which the interpolation is required
itemIndices : np.ndarray
the items where the available data is defined, of size
(numberOfTimeIndices)
vectors : np.ndarray or dict
the available data, of size (numberOfVectors, numberOfDofs)
tolerance : float
tolerance for deciding when using the closest timestep value instead of carrying out the linear interpolation
Returns
-------
np.ndarray
interpolated vector, of size (numberOfDofs)
"""
if item <= itemIndices[0]:
return vectors[0]
if item >= itemIndices[-1]:
return vectors[-1]
prev = BinarySearch(itemIndices, item)
coef = (item - itemIndices[prev]) / (itemIndices[prev+1] - itemIndices[prev])
if 0.5 - abs(coef - 0.5) < tolerance:
coef = round(coef)
return (
coef * vectors[prev+1]
+ (1 - coef) * vectors[prev]
)
[docs]
def PieceWiseLinearInterpolationWithMap(item, itemIndices, vectors, vectorsMap, tolerance = 1e-4):
"""
Computes a item interpolation for temporal vectors defined either by
itemIndices, some tags at these item indices (vectorsMap), and vectors at those tags.
Parameters
----------
item : float
the input item at which the interpolation is required
itemIndices : np.ndarray
the items where the available data is defined, of size
(numberOfTimeIndices)
vectors : np.ndarray or dict
the available data, of size (numberOfVectors, numberOfDofs)
vectorsMap : list
list containing the mapping from the numberOfTimeIndices items indices to the numberOfVectors vectors, of size (numberOfTimeIndices,). Default is None, in which case numberOfVectors = numberOfTimeIndices.
tolerance : float
tolerance for deciding when using the closest timestep value instead of carrying out the linear interpolation
Returns
-------
np.ndarray
interpolated vector, of size (numberOfDofs)
"""
if item <= itemIndices[0]:
return vectors[vectorsMap[0]]
if item >= itemIndices[-1]:
return vectors[vectorsMap[-1]]
prev = BinarySearch(itemIndices, item)
coef = (item - itemIndices[prev]) / (itemIndices[prev+1] - itemIndices[prev])
if 0.5 - abs(coef - 0.5) < tolerance:
coef = round(coef)
return (
coef * vectors[vectorsMap[prev+1]]
+ (1 - coef) * vectors[vectorsMap[prev]]
)
[docs]
def PieceWiseLinearInterpolationVectorized(items, itemIndices, vectors):
"""
PieceWiseLinearInterpolation for more than one call (items is now a list or one-dimensional np.ndarray)
"""
return [PieceWiseLinearInterpolation(item, itemIndices, vectors) for item in items]
#return np.fromiter(map(lambda item: PieceWiseLinearInterpolation(item, itemIndices, vectors), items), dtype = type(vectors[0]))
[docs]
def PieceWiseLinearInterpolationVectorizedWithMap(items, itemIndices, vectors, vectorsMap):
"""
PieceWiseLinearInterpolation for more than one call (items is now a list or one-dimensional np.ndarray)
"""
return [PieceWiseLinearInterpolationWithMap(item, itemIndices, vectors, vectorsMap) for item in items]
#return np.fromiter(map(lambda item: PieceWiseLinearInterpolationWithMap(item, itemIndices, vectors, vectorsMap), items), dtype = np.float)
if __name__ == "__main__":# pragma: no cover
from Mordicus import RunTestFile
RunTestFile(__file__)