反转(小)排列
Invert a (small) permutation
我正在使用 OpenCL 的随机播放功能对 float3 向量进行排序,如下所示(忽略实际 4d 向量的最后一个分量):
uint4 mask = (uint4)(0,1,2,3);
mask.xyz = res.x < res.y ? (res.x >= res.z ? mask.yxz : mask.yzx) : (res.y >= res.z ? mask.xyz : mask.xzy);
float4 abcd = shuffle(res,mask);
然后我操作vector的每个分量abcd
,想反转排序排列,如下:
uint4 inv_mask = ... // ???
res = shuffle(abcd,inv_mask); // Inverse the sorting permutation
如何有效地计算逆掩码?
你是说
uint4 invmask = (uint4)(3,3,3,3) - mask;
?
对于掩码 (0,3,1,2) 这给你 (3-0, 3-3, 3-1, 3-2) = (3,0,2,1)
可能性非常有限:
- x >= y >= z => mask.xyz = (0,1,2), inv_mask = (0,1,2)
- x >= z >= y => mask.xyz = (0,2,1), inv_mask = (0,2,1)
- y >= x >= z => mask.xyz = (1,0,2), inv_mask = (1,0,2)
- y >= z >= x => mask.xyz = (1,2,0), inv_mask = (2,0,1)
- z >= x >= y => mask.xyz = (2,0,1), inv_mask = (1,2,0)
- z >= y >= x => mask.xyz = (2,1,0), inv_mask = (2,1,0)
请注意,六个可能的排列中只有两个包含不止一个交换,因此其余 4 个排列自行反转。
计算出 mask
后,您可以使用以下代码获得 inv_mask
:
inv_mask.xyz = mask.xyz == (int3)(1,2,0) ? (int3)(2,0,1) : (mask.xyz == (int3)(2,0,1) ? (int3)(1,2,0) : mask.xyz);
我正在使用 OpenCL 的随机播放功能对 float3 向量进行排序,如下所示(忽略实际 4d 向量的最后一个分量):
uint4 mask = (uint4)(0,1,2,3);
mask.xyz = res.x < res.y ? (res.x >= res.z ? mask.yxz : mask.yzx) : (res.y >= res.z ? mask.xyz : mask.xzy);
float4 abcd = shuffle(res,mask);
然后我操作vector的每个分量abcd
,想反转排序排列,如下:
uint4 inv_mask = ... // ???
res = shuffle(abcd,inv_mask); // Inverse the sorting permutation
如何有效地计算逆掩码?
你是说
uint4 invmask = (uint4)(3,3,3,3) - mask;
?
对于掩码 (0,3,1,2) 这给你 (3-0, 3-3, 3-1, 3-2) = (3,0,2,1)
可能性非常有限:
- x >= y >= z => mask.xyz = (0,1,2), inv_mask = (0,1,2)
- x >= z >= y => mask.xyz = (0,2,1), inv_mask = (0,2,1)
- y >= x >= z => mask.xyz = (1,0,2), inv_mask = (1,0,2)
- y >= z >= x => mask.xyz = (1,2,0), inv_mask = (2,0,1)
- z >= x >= y => mask.xyz = (2,0,1), inv_mask = (1,2,0)
- z >= y >= x => mask.xyz = (2,1,0), inv_mask = (2,1,0)
请注意,六个可能的排列中只有两个包含不止一个交换,因此其余 4 个排列自行反转。
计算出 mask
后,您可以使用以下代码获得 inv_mask
:
inv_mask.xyz = mask.xyz == (int3)(1,2,0) ? (int3)(2,0,1) : (mask.xyz == (int3)(2,0,1) ? (int3)(1,2,0) : mask.xyz);