Интерполяция по n-мерной сетке невозможна с помощью scipy.interpolate.griddata. - PullRequest
0 голосов
/ 22 апреля 2019

У меня есть массив наблюдений, называемых значениями, который приходит из функции, определенной следующим образом:

values = np.array([oscillatory(i) for i in range(points.shape[0])])

значения имеют форму (65,1), точки - это массив, в котором оценивается осциллирующая функция, он имеет форму (65,7), 7 - это некоторые элементы, действующие как измерения в 7-мерном пространстве (7 - просто произвольное число).

Я пытаюсь интерполировать некоторые произвольные точки, определенные в этом пространстве,Я попытался определить эти точки с помощью:

grid_x = np.random.uniform(0,10, (100,7))

Но это не сработало.Видимо, потому что сетка не определена правильно, поэтому я попытался:

grid_x= np.mgrid[-2:2, 5:99 , 4:5, 5:6, 5:7, 6:67, 7:67]

, который не работает снова.Я вызываю функцию интерполяции следующим образом:

grid_z1 = gdd(points, values, tuple(grid_x))

Но я всегда получаю огромную ошибку, которую мне трудно понять.

Любопытно, что если я определяю точки и значения случайным образом, код работает:

points = np.random.uniform(0,10, (65,3))
values = np.random.uniform(0,10,(points.shape[0],1))

grid_x= np.mgrid[0:2, 5:9 , 4:5]
grid_z1 = gdd(points, values, tuple(grid_x))

Здесь я просто попробовал 3 вместо 7, потому что это быстрее, но принцип остаетсятот же самый.Если я определю это в 7 измерениях, код также работает.Итак, мои вопросы: 1) Как я могу получить исходный код в 7 измерениях?2) Почему случайное объявление работает по сравнению с другим, если массивы имеют одинаковую форму?

Любая помощь будет принята с благодарностью.Большое спасибо.

Я получаю следующую ошибку:

    Traceback (most recent call last):
  File "/usr/lib/python3.6/code.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 2, in <module>
  File "/usr/local/lib/python3.6/dist-packages/scipy/interpolate/ndgriddata.py", line 222, in griddata
    rescale=rescale)
  File "interpnd.pyx", line 248, in scipy.interpolate.interpnd.LinearNDInterpolator.__init__
  File "qhull.pyx", line 1828, in scipy.spatial.qhull.Delaunay.__init__
  File "qhull.pyx", line 354, in scipy.spatial.qhull._Qhull.__init__
scipy.spatial.qhull.QhullError: QH6154 Qhull precision error: Initial simplex is flat (facet 1 is coplanar with the interior point)
While executing:  | qhull d Qbb Qt Qz Q12 Qc
Options selected for Qhull 2015.2.r 2016/01/18:
  run-id 526315618  delaunay  Qbbound-last  Qtriangulate  Qz-infinity-point
  Q12-no-wide-dup  Qcoplanar-keep  _pre-merge  _zero-centrum  Qinterior-keep
  Pgood  _max-width  4  Error-roundoff 1.2e-14  _one-merge 1.1e-13
  Visible-distance 7.3e-14  U-coplanar-distance 7.3e-14  Width-outside 1.5e-13
  _wide-facet 4.4e-13
precision problems (corrected unless 'Q0' or an error)
      2 flipped facets
      6 degenerate hyperplanes recomputed with gaussian elimination
     12 nearly singular or axis-parallel hyperplanes
      6 zero divisors during back substitute
    126 zero divisors during gaussian elimination
The input to qhull appears to be less than 4 dimensional, or a
computation has overflowed.
Qhull could not construct a clearly convex simplex from points:
- p2(v4):  -1.9     5     4 0.012
- p1(v3):  -1.9     5     4 0.0054
- p65(v2):     0   5.5   4.5     4
- p64(v1):     2     6     5     3
- p0(v0):    -2     5     4 -8.9e-16
The center point is coplanar with a facet, or a vertex is coplanar
with a neighboring facet.  The maximum round off error for
computing distances is 1.2e-14.  The center point, facets and distances
to the center point are as follows:
center point  -0.7625    5.309    4.309    1.407
facet p1 p65 p64 p0 distance=    0
facet p2 p65 p64 p0 distance= -8.9e-16
facet p2 p1 p64 p0 distance= -8.9e-16
facet p2 p1 p65 p0 distance= -8.9e-16
facet p2 p1 p65 p64 distance= -8.9e-16
These points either have a maximum or minimum x-coordinate, or
they maximize the determinant for k coordinates.  Trial points
are first selected from points that maximize a coordinate.
The min and max coordinates for each dimension are:
  0:        -2         2  difference=    4
  1:         5         6  difference=    1
  2:         4         5  difference=    1
  3:  -8.882e-16         4  difference=    4
If the input should be full dimensional, you have several options that
may determine an initial simplex:
  - use 'QJ'  to joggle the input and make it full dimensional
  - use 'QbB' to scale the points to the unit cube
  - use 'QR0' to randomly rotate the input for different maximum points
  - use 'Qs'  to search all points for the initial simplex
  - use 'En'  to specify a maximum roundoff error less than 1.2e-14.
  - trace execution with 'T3' to see the determinant for each point.
If the input is lower dimensional:
  - use 'QJ' to joggle the input and make it full dimensional
  - use 'Qbk:0Bk:0' to delete coordinate k from the input.  You should
    pick the coordinate with the least range.  The hull will have the
    correct topology.
  - determine the flat containing the points, rotate the points
    into a coordinate plane, and delete the other coordinates.
  - add one or more points to make the input full dimensional.

1 Ответ

1 голос
/ 22 апреля 2019

Думаю, проблема в том, что вам нужно убедиться, что вы согласны с количеством измерений и «доменами» этих измерений.Вы не получите хороших результатов при интерполяции в места, которые вы не выбрали.Я думаю, что ошибки, которые вы получаете, связаны с попытками вычислить вещи в этих местах.

Вот как можно сделать что-то вроде примера в документах scipy.interpolate.griddata для 7-мерного примера.Я использую гораздо более простую функцию, которая просто суммирует «особенности» в данных points:

import numpy as np

def func(data):
    return np.sum(data, axis=1)

grid = np.mgrid[0:1:5j, 0:1:5j, 0:1:5j, 0:1:5j, 0:1:5j, 0:1:5j, 0:1:5j]

points = np.random.rand(100, 7)
values = func(points)

Обратите внимание, что сетка охватывает весь диапазон координат points.То есть, поскольку каждый столбец в points имеет значения в диапазоне от 0 до 1, я должен убедиться, что я делаю сетку по тем же координатам.

from scipy.interpolate import griddata
grid_z = griddata(points, values, tuple(grid), method='linear')

Теперь у меня есть это:

>>> grid_z[2, 2, 2, 2, 2, :, :]
array([[ nan,  nan,  nan,  nan,  nan],
       [ nan, 3.  , 3.25, 3.5 ,  nan],
       [ nan, 3.25, 3.5 , 3.75,  nan],
       [ nan, 3.5 , 3.75, 4.  ,  nan],
       [ nan,  nan,  nan,  nan,  nan]])

Обратите внимание, что существует много NaN.Если вы используете nearest в качестве метода, вы всегда получите решение, но, конечно, linear интерполяция требует две вещи для интерполяции, так что «края» гиперкуба недопустимы (и 7-D пространство имеетмного преимуществ!).

...