interpolate_wrapper.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. """ helper_funcs.py.
  2. scavenged from enthought,interpolate
  3. """
  4. from __future__ import division, print_function, absolute_import
  5. import numpy as np
  6. from . import _interpolate # C extension. Does all the real work.
  7. def atleast_1d_and_contiguous(ary, dtype=np.float64):
  8. return np.atleast_1d(np.ascontiguousarray(ary, dtype))
  9. @np.deprecate(message="'nearest' is deprecated in SciPy 1.0.0")
  10. def nearest(x, y, new_x):
  11. """
  12. Rounds each new x to nearest input x and returns corresponding input y.
  13. Parameters
  14. ----------
  15. x : array_like
  16. Independent values.
  17. y : array_like
  18. Dependent values.
  19. new_x : array_like
  20. The x values to return the interpolate y values.
  21. Returns
  22. -------
  23. nearest : ndarray
  24. Rounds each `new_x` to nearest `x` and returns the corresponding `y`.
  25. """
  26. shifted_x = np.concatenate((np.array([x[0]-1]), x[0:-1]))
  27. midpoints_of_x = atleast_1d_and_contiguous(.5*(x + shifted_x))
  28. new_x = atleast_1d_and_contiguous(new_x)
  29. TINY = 1e-10
  30. indices = np.searchsorted(midpoints_of_x, new_x+TINY)-1
  31. indices = np.atleast_1d(np.clip(indices, 0, np.Inf).astype(int))
  32. new_y = np.take(y, indices, axis=-1)
  33. return new_y
  34. @np.deprecate(message="'linear' is deprecated in SciPy 1.0.0")
  35. def linear(x, y, new_x):
  36. """
  37. Linearly interpolates values in new_x based on the values in x and y
  38. Parameters
  39. ----------
  40. x : array_like
  41. Independent values
  42. y : array_like
  43. Dependent values
  44. new_x : array_like
  45. The x values to return the interpolated y values.
  46. """
  47. x = atleast_1d_and_contiguous(x, np.float64)
  48. y = atleast_1d_and_contiguous(y, np.float64)
  49. new_x = atleast_1d_and_contiguous(new_x, np.float64)
  50. if y.ndim > 2:
  51. raise ValueError("`linear` only works with 1-D or 2-D arrays.")
  52. if len(y.shape) == 2:
  53. new_y = np.zeros((y.shape[0], len(new_x)), np.float64)
  54. for i in range(len(new_y)): # for each row
  55. _interpolate.linear_dddd(x, y[i], new_x, new_y[i])
  56. else:
  57. new_y = np.zeros(len(new_x), np.float64)
  58. _interpolate.linear_dddd(x, y, new_x, new_y)
  59. return new_y
  60. @np.deprecate(message="'logarithmic' is deprecated in SciPy 1.0.0")
  61. def logarithmic(x, y, new_x):
  62. """
  63. Linearly interpolates values in new_x based in the log space of y.
  64. Parameters
  65. ----------
  66. x : array_like
  67. Independent values.
  68. y : array_like
  69. Dependent values.
  70. new_x : array_like
  71. The x values to return interpolated y values at.
  72. """
  73. x = atleast_1d_and_contiguous(x, np.float64)
  74. y = atleast_1d_and_contiguous(y, np.float64)
  75. new_x = atleast_1d_and_contiguous(new_x, np.float64)
  76. if y.ndim > 2:
  77. raise ValueError("`linear` only works with 1-D or 2-D arrays.")
  78. if len(y.shape) == 2:
  79. new_y = np.zeros((y.shape[0], len(new_x)), np.float64)
  80. for i in range(len(new_y)):
  81. _interpolate.loginterp_dddd(x, y[i], new_x, new_y[i])
  82. else:
  83. new_y = np.zeros(len(new_x), np.float64)
  84. _interpolate.loginterp_dddd(x, y, new_x, new_y)
  85. return new_y
  86. @np.deprecate(message="'block_average_above' is deprecated in SciPy 1.0.0")
  87. def block_average_above(x, y, new_x):
  88. """
  89. Linearly interpolates values in new_x based on the values in x and y.
  90. Parameters
  91. ----------
  92. x : array_like
  93. Independent values.
  94. y : array_like
  95. Dependent values.
  96. new_x : array_like
  97. The x values to interpolate y values.
  98. """
  99. bad_index = None
  100. x = atleast_1d_and_contiguous(x, np.float64)
  101. y = atleast_1d_and_contiguous(y, np.float64)
  102. new_x = atleast_1d_and_contiguous(new_x, np.float64)
  103. if y.ndim > 2:
  104. raise ValueError("`linear` only works with 1-D or 2-D arrays.")
  105. if len(y.shape) == 2:
  106. new_y = np.zeros((y.shape[0], len(new_x)), np.float64)
  107. for i in range(len(new_y)):
  108. bad_index = _interpolate.block_averave_above_dddd(x, y[i],
  109. new_x, new_y[i])
  110. if bad_index is not None:
  111. break
  112. else:
  113. new_y = np.zeros(len(new_x), np.float64)
  114. bad_index = _interpolate.block_average_above_dddd(x, y, new_x, new_y)
  115. if bad_index is not None:
  116. msg = "block_average_above cannot extrapolate and new_x[%d]=%f "\
  117. "is out of the x range (%f, %f)" % \
  118. (bad_index, new_x[bad_index], x[0], x[-1])
  119. raise ValueError(msg)
  120. return new_y
  121. @np.deprecate(message="'block' is deprecated in SciPy 1.0.0")
  122. def block(x, y, new_x):
  123. """
  124. Essentially a step function.
  125. For each `new_x`, finds largest j such that``x[j] < new_x[j]`` and
  126. returns ``y[j]``.
  127. Parameters
  128. ----------
  129. x : array_like
  130. Independent values.
  131. y : array_like
  132. Dependent values.
  133. new_x : array_like
  134. The x values used to calculate the interpolated y.
  135. Returns
  136. -------
  137. block : ndarray
  138. Return array, of same length as `x_new`.
  139. """
  140. # find index of values in x that precede values in x
  141. # This code is a little strange -- we really want a routine that
  142. # returns the index of values where x[j] < x[index]
  143. TINY = 1e-10
  144. indices = np.searchsorted(x, new_x+TINY)-1
  145. # If the value is at the front of the list, it'll have -1.
  146. # In this case, we will use the first (0), element in the array.
  147. # take requires the index array to be an Int
  148. indices = np.atleast_1d(np.clip(indices, 0, np.Inf).astype(int))
  149. new_y = np.take(y, indices, axis=-1)
  150. return new_y