- 类型参数:
-
E
-ETYPE
的装箱版本,向量的元素类型
VectorShuffle
表示一个有序的不可变序列,其中包含称为源索引的int
值,每个源索引在兼容的Vector
中选择一个源通道。
VectorShuffle
和具有相同元素类型(ETYPE
)和shape
的Vector
具有相同数量的通道,因此它们是兼容的(具体来说,它们的vector species
是兼容的)。
使用rearrange
方法将洗牌应用于(兼容的)源向量。
洗牌具有从其向量种类派生的通道结构,但它存储通道索引,作为int
,而不是通道值。
此方法通过随机访问源向量来收集通道值,通过查询源索引来选择通道。如果一个源索引在洗牌中出现多次,则所选通道的值将多次复制到结果中。如果某个通道从未被源索引选择,则该通道的值将被忽略。结果向量包含由洗牌的源索引选择的所有源通道值。结果通道值根据洗牌的源索引排序,而不是根据原始向量的通道顺序排序。
每个洗牌都有一个vectorSpecies()
属性,用于确定洗牌操作的向量的兼容性。这确保了洗牌的length()
始终等于它操作的任何向量的VLENGTH。洗牌的种类的元素类型和形状与洗牌的行为无直接关系。洗牌可以轻松地转换为其他通道类型,只要通道计数保持恒定即可。
在其内部状态中,洗牌始终保持从[-VLENGTH..VLENGTH-1]
的窄范围内的整数值。正数是不言自明的;它们是应用于任何源向量的通道号。负数在出现时表示洗牌是从一个不是有效通道索引的原始整数值创建的。
在洗牌中表示的无效源索引(负数)称为异常索引。
异常索引以各种方式进行处理:
- 除非另有说明,使用洗牌的方法在通过异常索引处理通道时将抛出
ArrayIndexOutOfBoundsException
。 - 当无效的源索引(负数或非负数)首次加载到洗牌中时,它将部分归一化为
[-VLENGTH..-1]
的负范围,就好像通过wrapIndex()
。这种对异常索引的部分包装称为部分包装,因为它保留了正常和异常索引之间的区别,同时将它们包装成相邻的正数和非正数范围。部分包装的索引可以稍后通过添加最终偏移量VLENGTH
完全包装到正范围中。 - 在某些应用中,异常索引用于“引导”访问第二个源向量。在这些情况下,异常索引值(在范围
[-VLENGTH..-1]
内)被循环到有效范围[0..VLENGTH-1]
并用于第二个源向量。 - 当从具有较小
VLENGTH
的另一个洗牌种类转换洗牌时,所有索引都会根据新的VLENGTH
重新验证,并且一些可能会转换为异常索引。无论如何,洗牌转换永远不会将异常索引转换为正常索引。
基于值的类和标识操作
VectorShuffle
,以及Vector
是基于值的类。诸如==
之类的标识敏感操作可能会产生不可预测的结果,或者性能降低。此外,向量洗牌对象可以存储在局部变量和参数中,以及作为static final
常量,但将它们存储在其他Java字段或数组元素中,虽然在语义上有效,但可能会导致性能损失。最后,尽可能避免在循环中计算向量洗牌,而应将其存储在循环不变的局部变量或作为static final
常量。
-
Method Summary
Modifier and TypeMethodDescriptionabstract <F> VectorShuffle
<F> cast
(VectorSpecies<F> species) 将此洗牌转换为给定元素类型F
的种类的洗牌。abstract <F> VectorShuffle
<F> check
(VectorSpecies<F> species) 检查此洗牌是否具有给定种类,并返回此洗牌不变。abstract int
checkIndex
(int index) 用于可能超出[0..VLENGTH-1]
有效范围的通道索引的验证函数。abstract VectorShuffle
<E> 对所有通道应用checkIndex()
验证函数,如果此洗牌中存在任何异常索引,则抛出IndexOutOfBoundsException
。final boolean
指示此洗牌是否与其他对象相同。static <E> VectorShuffle
<E> fromArray
(VectorSpecies<E> species, int[] sourceIndexes, int offset) 从偏移量开始,从int
数组创建给定种类的洗牌。static <E> VectorShuffle
<E> fromOp
(VectorSpecies<E> species, IntUnaryOperator fn) 从应用于范围[0..VLENGTH-1]
的连续值的运算符创建给定种类的洗牌。static <E> VectorShuffle
<E> fromValues
(VectorSpecies<E> species, int... sourceIndexes) 从一系列源索引创建给定种类的洗牌。protected final Object
final int
hashCode()
基于通道源索引和向量种类返回此洗牌的哈希码值。abstract void
intoArray
(int[] a, int offset) 从偏移量开始将此洗牌存储到int
数组中。static <E> VectorShuffle
<E> iota
(VectorSpecies<E> species, int start, int step, boolean wrap) 使用从start
开始并按给定step
步进的顺序值创建洗牌。abstract VectorMask
<E> 查找包含有效索引(非负值)的所有通道,并返回一个掩码,其中仅设置了这些通道。int
laneSource
(int i) 获取通道索引i
处的int
通道元素。final int
length()
返回此洗牌处理的通道数量。static <E> VectorShuffle
<E> makeUnzip
(VectorSpecies<E> species, int part) 创建一个洗牌,将两个向量的串联解压缩,交替将输入通道存储到一个或另一个输出向量中。static <E> VectorShuffle
<E> makeZip
(VectorSpecies<E> species, int part) 创建一个洗牌,将两个向量合并在一起,交替从一个或另一个中选择通道。abstract VectorShuffle
<E> rearrange
(VectorShuffle<E> s) 重新排列此洗牌的通道元素,选择由另一个洗牌控制的通道索引。abstract int[]
toArray()
返回包含此洗牌的通道源索引的int
数组。final String
toString()
返回此洗牌的字符串表示形式,形式为"Shuffle[0,1,2...]"
,按通道顺序报告源索引。toVector()
将此洗牌转换为向量,创建与洗牌的通道源索引对应的整数值向量。abstract VectorSpecies
<E> 返回此洗牌的种类。abstract int
wrapIndex
(int index) 用于可能超出[0..VLENGTH-1]
有效范围的通道索引的验证函数。abstract VectorShuffle
<E> 对所有通道应用wrapIndex()
验证函数,将任何异常索引替换为包装的正常索引。
-
Method Details
-
vectorSpecies
返回此洗牌的种类。- 返回:
- 此洗牌的种类
-
length
public final int length()返回此洗牌处理的通道数量。这与它操作的任何向量的VLENGTH
相同。- 返回:
- 洗牌通道的数量
-
cast
将此洗牌转换为给定元素类型F
的种类的洗牌。各种通道源索引保持不变。异常源索引保持异常,有效索引保持有效。- 类型参数:
-
F
- 种类的装箱元素类型 - 参数:
-
species
- 所需洗牌的种类 - 返回:
- 通过形状和元素类型转换的洗牌
- 抛出:
-
IllegalArgumentException
- 如果此洗牌长度与种类长度不同
-
check
检查此洗牌是否具有给定种类,并返回此洗牌不变。效果类似于此伪代码:species == vectorSpecies() ? this : throw new ClassCastException()
。- 类型参数:
-
F
- 所需种类的装箱元素类型 - 参数:
-
species
- 所需种类 - 返回:
- 相同的洗牌
- 抛出:
-
ClassCastException
- 如果洗牌种类错误 - 参见:
-
checkIndex
public abstract int checkIndex(int index) 对可能超出[0..VLENGTH-1]
有效范围的通道索引应用验证函数。如果index
在此范围内,则返回不变。否则,抛出IndexOutOfBoundsException
。- 参数:
-
index
- 通道索引 - 返回:
-
index
- 抛出:
-
IndexOutOfBoundsException
- 如果index
不小于VLENGTH
,或为负数 - 参见:
-
wrapIndex
public abstract int wrapIndex(int index) 对可能超出[0..VLENGTH-1]
有效范围的通道索引应用验证函数。通过添加或减去适当的VLENGTH
的倍数,将index
强制为此范围。具体地,通过计算length-floor
的值将索引减少到所需范围,其中floor=vectorSpecies().loopBound(length)
是VLENGTH
的下一个较低倍数。只要VLENGTH
是2的幂,那么减少后的索引也等于index & (VLENGTH - 1)
。- 参数:
-
index
- 轨道索引 - 返回:
-
index
,通过适当倍数的VLENGTH
调整到范围[0..VLENGTH-1
} - 参见:
-
checkIndexes
对所有轨道应用checkIndex()
验证函数,如果此洗牌中存在任何异常索引,则抛出IndexOutOfBoundsException
。- 返回:
- 当前洗牌,不变
- 抛出:
-
IndexOutOfBoundsException
- 如果此洗牌中的任何轨道包含异常索引 - 参见:
-
wrapIndexes
对所有轨道应用wrapIndex()
验证函数,将任何异常索引替换为包装的正常索引。- 返回:
- 当前洗牌,所有异常索引都被包装
- 参见:
-
laneIsValid
查找所有包含有效索引(非负值)的轨道,并返回一个掩码,其中确切设置了这些轨道。- 返回:
- 包含有效源索引的轨道掩码
- 参见:
-
fromValues
从一系列源索引为给定种类创建一个洗牌。对于每个洗牌轨道,其中
N
是洗牌轨道索引,第N
个索引值根据种类VLENGTH
进行验证,并且(如果无效)部分包装为范围[-VLENGTH..-1]
中的异常索引。- 类型参数:
-
E
- 装箱元素类型 - 参数:
-
species
- 洗牌种类 -
sourceIndexes
- 洗牌将从中提取的源索引 - 返回:
-
每个轨道的源索引设置为给定的
int
值的洗牌,如果异常则部分包装 - 抛出:
-
IndexOutOfBoundsException
- 如果sourceIndexes.length != VLENGTH
- 参见:
-
fromArray
public static <E> VectorShuffle<E> fromArray(VectorSpecies<E> species, int[] sourceIndexes, int offset) 从偏移开始的int
数组为给定种类创建一个洗牌。对于每个洗牌轨道,其中
N
是洗牌轨道索引,位于索引offset + N
处的数组元素根据种类VLENGTH
进行验证,并且(如果无效)部分包装为范围[-VLENGTH..-1]
中的异常索引。- 类型参数:
-
E
- 装箱元素类型 - 参数:
-
species
- 洗牌种类 -
sourceIndexes
- 洗牌将从中提取的源索引 -
offset
- 数组中的偏移量 - 返回:
-
每个轨道的源索引设置为给定的
int
值的洗牌,如果异常则部分包装 - 抛出:
-
IndexOutOfBoundsException
- 如果offset < 0
,或者offset > sourceIndexes.length - VLENGTH
- 参见:
-
fromOp
从应用于范围[0..VLENGTH-1]
的连续值的操作符创建一个给定种类的洗牌。对于每个洗牌轨道,其中
N
是洗牌轨道索引,第N
个索引值根据种类VLENGTH
进行验证,并且(如果无效)部分包装为范围[-VLENGTH..-1]
中的异常索引。应注意确保从此方法生成的
VectorShuffle
值作为常量消耗,以确保代码的最佳生成。例如,洗牌值可以保存在static final
字段或循环不变的局部变量中。此方法的行为就好像从映射索引数组创建一个洗牌一样:
int[] a = new int[species.length()]; for (int i = 0; i < a.length; i++) { a[i] = fn.applyAsInt(i); } return VectorShuffle.fromArray(a, 0);
- 类型参数:
-
E
- 装箱元素类型 - 参数:
-
species
- 洗牌种类 -
fn
- 轨道索引映射函数 - 返回:
- 映射索引的洗牌
- 参见:
-
iota
public static <E> VectorShuffle<E> iota(VectorSpecies<E> species, int start, int step, boolean wrap) 使用从start
开始并按给定step
步长递增的顺序值设置源索引创建一个洗牌。此方法返回表达式
VectorShuffle.fromOp(species, i -> R(start + i * step))
的值,其中R
是wrapIndex
(如果wrap
为 true),否则为恒等函数。如果
wrap
为 false,则每个索引都将根据种类VLENGTH
进行验证,并且(如果无效)部分包装为范围[-VLENGTH..-1]
中的异常索引。否则,如果wrap
为 true,则还将每个索引减少,就像通过wrapIndex
,将其减少到有效范围[0..VLENGTH-1]
。- API 注释:
-
如果应该包装无效源索引,则应将
wrap
参数设置为true
。否则,将其设置为false
允许后续操作(如unary rearrange
)对无效源索引进行范围检查。 - 类型参数:
-
E
- 装箱元素类型 - 参数:
-
species
- 洗牌种类 -
start
- 源索引序列的起始值 -
step
- 相邻源索引之间的差异 -
wrap
- 是否包装结果索引 - 返回:
- 顺序轨道索引的洗牌,可能被包装
- 参见:
-
makeZip
创建一个洗牌,将两个向量一起压缩,交替从其中一个或另一个选择轨道。压缩的逻辑结果是任一输入的两倍大小,因此 扩展结果 被分为两个物理部分,由部分编号选择。例如,压缩两个向量[a,b,c,d]
和[1,2,3,4]
将产生扩展的逻辑结果[a,1,b,2,c,3,d,4]
,必须以两部分获取,[a,1,b,2]
和[c,3,d,4]
。此方法返回表达式
VectorShuffle.fromOp(species, i -> i/2 + (i%2)*VLENGTH + P
的值,其中P
是part*VLENGTH/2
。请注意,洗牌的奇数轨道中的源索引将是无效索引(
>= VLENGTH
,或者在部分归一化后为< 0
),这将从第二个向量中选择。- 类型参数:
-
E
- 装箱元素类型 - 参数:
-
species
- 洗牌种类 -
part
- 结果的部分编号(零或一) - 返回:
-
将两个向量压缩为
2*VLENGTH
轨道的洗牌,返回所选部分 - 抛出:
-
ArrayIndexOutOfBoundsException
- 如果part
不是零或一 - 参见:
-
makeUnzip
创建一个洗牌,将两个向量的连接解压缩,交替将输入轨道存储到一个或另一个输出向量中。由于解压缩的逻辑结果是任一输入的两倍大小,因此 扩展结果 被分为两个物理部分,由部分编号选择。例如,解压缩两个向量[a,1,b,2][c,3,d,4]
将在两部分中产生结果,[a,b,c,d]
和[1,2,3,4]
。此方法返回表达式
VectorShuffle.fromOp(species, i -> i*2+part
的值。请注意,洗牌的上半部分中的源索引将是无效索引(
>= VLENGTH
,或者在部分归一化后为< 0
),这将从第二个向量中选择。- 类型参数:
-
E
- 装箱后的元素类型 - 参数:
-
species
- 洗牌种类 -
part
- 结果的部分编号(为零或一) - 返回:
-
一个洗牌,将
2*VLENGTH
个通道解压成两个向量,返回所选部分 - 抛出:
-
ArrayIndexOutOfBoundsException
- 如果part
不是零或一 - 参见:
-
toArray
public abstract int[] toArray()返回一个包含此洗牌的通道源索引的int
数组。此方法的行为就好像将此洗牌存储到一个分配的数组中(使用
intoArray
),并将该数组返回如下:int[] a = new int[this.length()]; VectorShuffle.intoArray(a, 0); return a;
- API 注意:
-
洗牌源索引始终在
-VLENGTH
到VLENGTH-1
的范围内。只有当源索引为负时,源索引才是异常的。 - 返回:
- 包含此洗牌的通道源索引的数组
-
intoArray
public abstract void intoArray(int[] a, int offset) 将此洗牌存储到从偏移量开始的int
数组中。对于每个洗牌通道
N
,存储为该通道元素的源索引将存储到数组元素a[offset+N]
中。- API 注意:
-
洗牌源索引始终在
-VLENGTH
到VLENGTH-1
的范围内。 - 参数:
-
a
- 数组,类型为int[]
-
offset
- 数组中的偏移量 - 抛出:
-
IndexOutOfBoundsException
- 如果offset < 0
或offset > a.length - this.length()
-
toVector
将此洗牌转换为一个向量,创建一个包含洗牌的通道源索引的整数值向量。此方法的行为就好像返回从此洗牌的通道元素获取的
int
数组的结果,如下:int[] sa = this.toArray(); $type$[] va = new $type$[a.length]; for (int i = 0; i < a.length; i++) { va[i] = ($type$) sa[i]; } return IntVector.fromArray(va, 0);
- API 注意:
-
洗牌源索引始终在
-VLENGTH
到VLENGTH-1
的范围内。这些值将转换为结果向量的ETYPE
,即使它是浮点类型。 - 返回:
- 此洗牌的向量表示
-
laneSource
public int laneSource(int i) 获取在通道索引i
处的int
通道元素- 参数:
-
i
- 通道索引 - 返回:
-
在通道索引
i
处的int
通道元素
-
rearrange
重新排列此洗牌的通道元素,选择由另一个洗牌控制的通道索引。对于指定洗牌的每个通道,在通道索引
N
处具有通道元素I
,从此洗牌中选择I
处的通道元素,并将其放入结果洗牌中的N
处。- 参数:
-
s
- 控制通道索引选择的洗牌 - 返回:
- 此洗牌的通道元素重新排列
-
toString
返回此洗牌的字符串表示形式,形式为"Shuffle[0,1,2...]"
,按通道顺序报告源索引。 -
equals
指示此洗牌是否与另一个对象相同。只有当两个洗牌具有相同的种类和相同的源索引,且顺序相同时,它们才是相同的。 -
hashCode
public final int hashCode()返回此洗牌的哈希码值,基于通道源索引和向量种类。 -
getPayload
-