Chapel 中矩阵的自定义 rowSums
Custom rowSums of a Matrix in Chapel
跟进 。我有一个大而稀疏的矩阵(是的,我有)。
A = [
[0, 0, 0, 1.2, 0]
[0, 0, 0, 0, 0]
[3.5, 0, 0, 0, 0]
[0 7, 0, 0, 0]
]
我想创建一个向量 v
,其中 A
中每一行的总和为 v[j] = v[j,] * log(v[j,])
我相信有一个像 [x * log(x) for x in row] do...
这样的迭代器,但我很难找到语法。一个特别的错误是避免使用 log(0)
,所以迭代器中可能有一个 if
语句?
I believe there is an iterator like [x * log(x) for x in row] do... but I'm having a hard time finding the syntax.
我们可以创建一个函数来计算 x * log(x)
并只将一个数组(或数组切片)传递给它,而不是创建一个迭代器,让 promotion 处理其余的事情。
不像我们之前那样对数组切片进行 + reduce
,
forall i in indices {
rowsums[i] = + reduce(A[i, ..]);
}
我们可以对数组切片的提升操作执行 + reduce
,如下所示:
forall i in indices {
rowsums[i] = + reduce(logProduct(A[i, ..]));
}
其中 logProduct(x)
可以包含一个 if 语句来处理 0
的特殊情况,如上所述。
把这些放在一起看起来像这样:
config const n = 10;
proc main() {
const indices = 1..n;
const Adom = {indices, indices};
var A: [Adom] real;
populate(A);
var v = rowSums(A);
writeln('matrix:');
writeln(A);
writeln('row sums:');
writeln(v);
}
/* Populate A, leaving many zeros */
proc populate(A: [?Adom]) {
forall i in Adom.dim(1) by 2 do // every other row
forall j in Adom.dim(2) by 3 do // every third column
A[i, j] = i*j;
}
/* Compute row sums with custom function (logProduct) */
proc rowSums(A: [?Adom] ?t) {
var v: [Adom.dim(1)] t;
[i in v.domain] v[i] = + reduce(logProduct(A[i, ..]));
return v;
}
/* Custom function to handle log(0) case */
proc logProduct(x: real) {
if x == 0 then return 0;
return x * log(x);
}
跟进
A = [
[0, 0, 0, 1.2, 0]
[0, 0, 0, 0, 0]
[3.5, 0, 0, 0, 0]
[0 7, 0, 0, 0]
]
我想创建一个向量 v
,其中 A
v[j] = v[j,] * log(v[j,])
我相信有一个像 [x * log(x) for x in row] do...
这样的迭代器,但我很难找到语法。一个特别的错误是避免使用 log(0)
,所以迭代器中可能有一个 if
语句?
I believe there is an iterator like [x * log(x) for x in row] do... but I'm having a hard time finding the syntax.
我们可以创建一个函数来计算 x * log(x)
并只将一个数组(或数组切片)传递给它,而不是创建一个迭代器,让 promotion 处理其余的事情。
不像我们之前那样对数组切片进行 + reduce
,
forall i in indices {
rowsums[i] = + reduce(A[i, ..]);
}
我们可以对数组切片的提升操作执行 + reduce
,如下所示:
forall i in indices {
rowsums[i] = + reduce(logProduct(A[i, ..]));
}
其中 logProduct(x)
可以包含一个 if 语句来处理 0
的特殊情况,如上所述。
把这些放在一起看起来像这样:
config const n = 10;
proc main() {
const indices = 1..n;
const Adom = {indices, indices};
var A: [Adom] real;
populate(A);
var v = rowSums(A);
writeln('matrix:');
writeln(A);
writeln('row sums:');
writeln(v);
}
/* Populate A, leaving many zeros */
proc populate(A: [?Adom]) {
forall i in Adom.dim(1) by 2 do // every other row
forall j in Adom.dim(2) by 3 do // every third column
A[i, j] = i*j;
}
/* Compute row sums with custom function (logProduct) */
proc rowSums(A: [?Adom] ?t) {
var v: [Adom.dim(1)] t;
[i in v.domain] v[i] = + reduce(logProduct(A[i, ..]));
return v;
}
/* Custom function to handle log(0) case */
proc logProduct(x: real) {
if x == 0 then return 0;
return x * log(x);
}