Я пытаюсь растянуть точки сетки, используя функции плотности. Например, учитывая следующее распределение точек (равномерно распределенное):
Приведенный ниже код изменит распределение на что-то вроде этого:
import numpy as np
from scipy.integrate import quad
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
from scipy.special import erf
# the x interval limits
a = 0.0
b = 3.0
# The density function, normalize it
_density_func = lambda x: 5*x
density_func = lambda x: _density_func(x) / quad(_density_func, a, b)[0]*(b-a)
# The xarr and yarr
Npts = 50
xarr = np.linspace(a, b, Npts)
yarr = np.zeros_like(xarr)
# Calculate the primitive function F = integral of density_func, from a, to t normalized by the int(density_func, a, b)
# F = np.vectorize(lambda t: quad(density_func, a, t)[0] / quad(density_func, a, b)[0])
F = np.vectorize(lambda t: quad(density_func, a, t)[0])
# if debug is true, print some info
debug = True
if debug:
print('The range of xarr is: [', a, b, ']')
print('The range of F(xarr) is: [', F(xarr).min(), F(xarr).max(), ']')
# Calculate the new x distribution of points using the inverse function of F.
# Use the trick of interpolation to calculate the inverse function,i.e: interp1d(y, x)(x)
xnew = interp1d(F(xarr), xarr)(xarr)
# plot the result
plt.scatter(xnew, yarr, facecolors='none', edgecolors='black')
plt.show()
Когда я запускаю этот скрипт, я получаю следующую ошибку:
The range of xarr is: [ 0.0 3.0 ]
The range of F(xarr) is: [ 0.0 2.9999999999999996 ]
Traceback (most recent call last):
File "meshDensity.py", line 38, in <module>
xnew = interp1d(F(xarr), xarr)(xarr)
File "C:\Users\navaro\Anaconda3\lib\site-packages\scipy\interpolate\polyint.py", line 79, in __call__
y = self._evaluate(x)
File "C:\Users\navaro\Anaconda3\lib\site-packages\scipy\interpolate\interpolate.py", line 664, in _evaluate
below_bounds, above_bounds = self._check_bounds(x_new)
File "C:\Users\navaro\Anaconda3\lib\site-packages\scipy\interpolate\interpolate.py", line 696, in _check_bounds
raise ValueError("A value in x_new is above the interpolation "
ValueError: A value in x_new is above the interpolation range.
Как видите, проблема в правильном ограничении F(xarr)
вместо точного значения 2.9999999999999996
3.0
.
Не могли бы вы предложить какое-либо решение этой проблемы с ошибками округления? Я ценю любую помощь.
Редактировать : временное решение - использовать функцию mpmath.quad
с mpmath.mp.dps = 20
, но это делает скрипт относительно медленным.