如果您将所需的索引绘制成三角形函数,就可以得到与输入索引相对应的图形。结果表明,在您的
n
=10情况下,它是这样的。
9.5 - abs(2 (x - 4.75))
因此,对于一般的n
,它将是
n-0.5 - abs(2*(x - n/2-0.25))
或者以整数形式表示,
(2*n-1 - abs(4*x - 2*n + 1)) / 2
这是完全基于分支的思想,在输出索引方面,只需使用单个数学函数即可生成。我认为一般的方法是绘制所需的索引图,并寻找一种表示它的模式和数学函数的方式。
显然,如果你所需的最终索引形成一条直线,则变换很简单。如果你的映射中有一个折点,那么你想要使用绝对值函数来引入弯曲,并且你可以调节缩放来改变弯曲的角度。你可以通过偏置来倾斜这个拐点(例如abs(x)+x/2
)。如果你需要在最终索引函数中出现跳跃间断点,则使用符号函数(希望内置或使用abs(x)/x
)。你需要创造性地利用常见函数的图形来发挥优势。
附录
如果您的索引函数是分段线性的,则有一种简单的算法。假设所需的索引函数表示为一系列线段。
{(sx1,sy1)-(ex1,ey1), (sx2,sy2)-(ex2,ey2), ... , (sxN,syN)-(exN,eyN)}
segment 1 segment 2 segment N
对于所有的K,exK > sxK,并且对于所有的K,sxK > sx(K-1)(从左到右排列)。
k = 1
f(x) = Make affine model of segment k
g(x) = f(x)
Do:
k = k + 1
h(x) = Makeaffine model of segment k
If g(x) and h(x) intersect between ex(k-1) and ex(k)
f(x) = f(x) + [slope difference of g(x) and h(x)] * ramp(x)
Else
f(x) = f(x) + (h(ex(k-1)) - f(ex(k-1))) * step(x)
f(x) = f(x) + [slope difference of g(x) and h(x)] * ramp(x)
ramp(x) = (abs(x)+x)/2
,step(x) = (sign(x)+1)/2
。f(x)代表所需函数,g(x)
是上一个段落的仿射模型,h(x)
是当前段落的仿射模型。仿射模型只是斜率偏移形式的一条线:a*x+b
,而斜率差就是斜率的差异。该算法从左到右简单地进行,随着其前进,添加适当的函数片段。它添加的函数对于x <= 0
总是为零,因此不会影响到目前已经建立起来的f(x)
。
当然,以上内容可能存在一些错误/打字错误。我真的要去开会了,所以不能再写了。
J = A[I]
如果你想对整个数组进行操作而不仅仅是单个数字,你可以展开循环或使用达夫设备来减少分支成本。 - Mike Dunlavey