python 如何在考虑点的权重的同时插值点?

pprl5pva  于 2023-01-01  发布在  Python
关注(0)|答案(2)|浏览(187)

我试着写一个Python函数,它可以完成以下任务:

  • 取一个点数组,其中每个点具有:
  • 从0到1的位置(x)
  • 重量(w)
  • 以考虑点权重的方式在它们之间平滑插值。

为了更清楚地说明这一点,下面是一个例子:

请注意带有权重的点是如何“推动”其他点的。

t3psigkw

t3psigkw1#

一种可能性是制定一个规则,例如:
两个相邻点之间的距离应该与它们的权重之和成比例。
这个规则似乎与你的例子并不完全一致。在你的例子中,看起来每个点都排斥其他每个点,而不仅仅是相邻的点。
但它的优点是规则简单。
下面是这个规则在python中的实现:

from itertools import pairwise, accumulate

def place_points(weights):
    if all(w == 0 for w in weights):
        return [p / (len(weights)-1) for p in range(0, len(weights))]
    else:
        dists = [w1+w2 for w1,w2 in pairwise(weights)]
        positions = list(accumulate(dists, initial=0))
        total_dist = positions[-1]
        normalised_positions = [p / total_dist for p in positions]
        return normalised_positions

for weights in ([0,0,0,0,0], [1,0,0,0,2], [1,0,10,0,2]):
    print('weights: ', weights)
    print('points:  ', place_points(weights))
    print()

# weights:  [0, 0, 0, 0, 0]
# points:   [0.0, 0.25, 0.5, 0.75, 1.0]

# weights:  [1, 0, 0, 0, 2]
# points:   [0.0, 0.333, 0.333, 0.333, 1.0]

# weights:  [1, 0, 10, 0, 2]
# points:   [0.0, 0.043, 0.478, 0.913, 1.0]
nnsrf1az

nnsrf1az2#

这是一个物理模型,它缓慢地移动这些点,就像它们是滑动的磁铁一样。
在每次迭代中,计算施加在每个磁体上的力,并且磁体相应地移动。
一个磁铁对另一个磁铁的排斥力,正比于两个磁铁间距离平方的倒数,因为实际的磁铁就是这样工作的.

import numpy as np
#import matplotlib.pyplot as plt  ## uncomment those lines for graphics output

def move_points(weights, points=None, left=0, right=1, n_iter = 1000, learning_rate = 0.0001):
    n = weights.shape[0]
    if not points:
        points = np.linspace(0, 1, n)
    assert(points.shape == weights.shape == (n,))
    #plt.scatter(points, [0]*n)
    for t in range(1, n_iter+1):
        dists = (points - points.reshape((n,1)))
        coeffs = np.sign(dists) / dists**2
        forces = np.nansum(weights*coeffs, axis=1)
        points = points - learning_rate * forces
        points[0] = max(left, points[0])
        points[-1] = min(points[-1], right)
        #plt.scatter(points, [t]*n)
    #plt.show()
    return points

测试:

for weights in map(np.array, ([0,0,0,0,0], [1,0,0,0,2], [1,0,10,0,2])):
    print('weights: ', weights)
    print('points:  ', move_points(weights, n_iter=100))
    print()

# weights:  [0 0 0 0 0]
# points:   [0.   0.25 0.5  0.75 1.  ]

# weights:  [1 0 0 0 2]
# points:   [0.         0.32732937 0.46804381 0.59336546 1.        ]

# weights:  [ 1  0 10  0  2]
# points:   [0.         0.11141358 0.46804381 0.83729092 1.        ]

轨迹的图形输出:


权重= [0 0 0 0 0]


权重= [1 0 0 0 2]


权重= [1 0 10 0 2]

相关问题