我想以double[][]
最紧凑和最有效的表达方式转置矩阵。现在我有这个:
public static Function<double[][], double[][]> transpose() {
return (m) -> {
final int rows = m.length;
final int columns = m[0].length;
double[][] transpose = new double[columns][rows];
range(0, rows).forEach(r -> {
range(0, columns).forEach(c -> {
transpose[c][r] = m[r][c];
});
});
return transpose;
};
}
有什么想法吗?
你可以有:
public static UnaryOperator<double[][]> transpose() {
return m -> {
return range(0, m[0].length).mapToObj(r ->
range(0, m.length).mapToDouble(c -> m[c][r]).toArray()
).toArray(double[][]::new);
};
}
此代码不使用,forEach
而是使用mapToObj
并将mapToDouble
每行映射到它们的转置。由于返回类型相同,因此我也更改Function<double[][], double[][]>
为UnaryOperator<double[][]>
。
但是,像assylias的答案中那样具有简单的for循环可能不会更有效。
样例代码:
public static void main(String[] args) {
double[][] m = { { 2, 3 }, { 1, 2 }, { -1, 1 } };
double[][] tm = transpose().apply(m);
System.out.println(Arrays.deepToString(tm)); // prints [[2.0, 1.0, -1.0], [3.0, 2.0, 1.0]]
}
我已经实现了一个JMH基准测试,可以比较上面的代码,for循环版本和上面的代码并行运行。使用大小分别为100、1000和3000的随机平方矩阵调用这三种方法。结果是,对于较小的矩阵,for
循环版本更快,但是对于较大的矩阵,并行Stream解决方案的性能确实更好(
Windows 10,JDK 1.8.0_66,i5-3230M @ 2.60 GHz ):
Benchmark (matrixSize) Mode Cnt Score Error Units
StreamTest.forLoopTranspose 100 avgt 30 0,026 ± 0,001 ms/op
StreamTest.forLoopTranspose 1000 avgt 30 14,653 ± 0,205 ms/op
StreamTest.forLoopTranspose 3000 avgt 30 222,212 ± 11,449 ms/op
StreamTest.parallelStreamTranspose 100 avgt 30 0,113 ± 0,007 ms/op
StreamTest.parallelStreamTranspose 1000 avgt 30 7,960 ± 0,207 ms/op
StreamTest.parallelStreamTranspose 3000 avgt 30 122,587 ± 7,100 ms/op
StreamTest.streamTranspose 100 avgt 30 0,040 ± 0,003 ms/op
StreamTest.streamTranspose 1000 avgt 30 14,059 ± 0,444 ms/op
StreamTest.streamTranspose 3000 avgt 30 216,741 ± 5,738 ms/op
基准代码:
@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(3)
public class StreamTest {
private static final UnaryOperator<double[][]> streamTranspose() {
return m -> {
return range(0, m[0].length).mapToObj(r ->
range(0, m.length).mapToDouble(c -> m[c][r]).toArray()
).toArray(double[][]::new);
};
}
private static final UnaryOperator<double[][]> parallelStreamTranspose() {
return m -> {
return range(0, m[0].length).parallel().mapToObj(r ->
range(0, m.length).parallel().mapToDouble(c -> m[c][r]).toArray()
).toArray(double[][]::new);
};
}
private static final Function<double[][], double[][]> forLoopTranspose() {
return m -> {
final int rows = m.length;
final int columns = m[0].length;
double[][] transpose = new double[columns][rows];
for (int r = 0; r < rows; r++)
for (int c = 0; c < columns; c++++)
transpose[c][r] = m[r][c];
return transpose;
};
}
@State(Scope.Benchmark)
public static class MatrixContainer {
@Param({ "100", "1000", "3000" })
private int matrixSize;
private double[][] matrix;
@Setup(Level.Iteration)
public void setUp() {
ThreadLocalRandom random = ThreadLocalRandom.current();
matrix = random.doubles(matrixSize).mapToObj(i -> random.doubles(matrixSize).toArray()).toArray(double[][]::new);
}
}
@Benchmark
public double[][] streamTranspose(MatrixContainer c) {
return streamTranspose().apply(c.matrix);
}
@Benchmark
public double[][] parallelStreamTranspose(MatrixContainer c) {
return parallelStreamTranspose().apply(c.matrix);
}
@Benchmark
public double[][] forLoopTranspose(MatrixContainer c) {
return forLoopTranspose().apply(c.matrix);
}
}
问题内容: 任何人都具有可以用以下形式在Java中转置Matrix的功能: 我有这样的功能: 但是在某处是错误的。 问题答案:
我尝试创建一个使用压缩和删除的Kafka主题配置,以实现以下目标: 在保留期限内,保留密钥的最新版本 在保留期之后,要删除的任何早于时间戳的消息 当我在测试中将其设置为较小的量时,例如20mins、1hr等,我可以正确地看到数据在保留期后被修剪,只需调整主题上的。 我可以看到数据正按照预期的那样被正确压缩,但是如果我从一开始就阅读主题,那么在10天的保留期之后,比10天早得多的数据仍然存在。这么长
问题内容: 我想将图像的颜色基础从RGB更改为其他颜色。我有一个要应用于每个像素的RGB的矩阵M,我们可以将其定义为x ij。 我目前正在迭代NumPy图像的每个像素并手动计算Mx ij。我什至无法对它们进行矢量化处理,因为RGB是1x3而不是3x1数组。 有一个更好的方法吗?也许是OpenCV或NumPy中的函数? 问题答案: 记不清执行此操作的规范方法(可能避免了转置),但这应该可行: 如果是
变换矩阵 之前三节所说的坐标变换的三种方式——平移translate(),缩放scale(),以及旋转rotate()都可以通过transform()做到。 在介绍矩阵变换transform()前,我们来说一说什么是变换矩阵。 以上是Canvas中transform()方法所对应的变换矩阵。而此方法正是传入图中所示的六个参数,具体为context.transform(a,b,c,d,e,f)。 各
本文向大家介绍如何使用HTML5创建转换矩阵?,包括了如何使用HTML5创建转换矩阵?的使用技巧和注意事项,需要的朋友参考一下 HTML5 canvas提供了允许直接修改转换矩阵的方法。转换矩阵最初必须是身份转换。然后可以使用转换方法对其进行调整。 S号 方法和说明 1 变换(m11,m12,m21,m22,dx,dy) 此方法更改转换矩阵以应用参数指定的矩阵。 2 setTransform(m1
我目前正在将原始矩阵转换为光栅以使用焦距函数,然后我想将光栅转换回矩阵。但是,当我尝试将光栅函数用作时,出现了一条错误消息。矩阵()。即使有这个非常简单的例子: 以下是我得到的: 如果(!is.null(names(x)))列表(names(x),,则数组(x,c(length(x),1L)中出错: “dimnames”[1]的长度不等于数组范围 我正在使用RstuIO、R版本3.4.0和、和库。