[英]Vectorized computation of 3-point correlation functions in Matlab?
I would like to compute the 2- and 3-point correlation functions R2, R3 of samples of a vector by appropriate histogramming of the elements of a vector (num_samples samples of length system_size), and the corresponding cluster functions T2, T3. 我想通过向量元素的适当直方图(长度为system_size的num_samples个样本)和相应的聚类函数T2,T3来计算向量样本的2点和3点相关函数R2,R3。 For simplicity I am considering histogramming across uniform bins.
为简单起见,我考虑对统一容器进行直方图处理。
What is a good way to vectorize and/or speed up the following code? 向量化和/或加速以下代码的好方法是什么?
n = length(mesh);
R2 = zeros(n, n);
R3 = zeros(n, n, n);
for sample_id=1:num_samples
s = samples(:, sample_id);
d = mesh(2) - mesh(1);
% Which bin does the ith sample s belong to?
bins = ceil((s - mesh(1))/d);
% Compute two-point correlation function
for i = 1:system_size
for j = 1:system_size
if i ~= j
R2(bins(i), bins(j))=R2(bins(i), bins(j))+1;
end
end
end
% Compute three-point correlation function
for i = 1:system_size
for j = 1:system_size
if i ~= j
for k = 1:system_size
if k ~= j && k ~= i
R3(bins(i), bins(j), bins(k))=R3(bins(i), bins(j), bins(k))+1;
T3(x1, x2, x3) = R3(x1,x2,x3)-R1(x1)*R2(x2,x3)-R1(x2)*R2(x1,x3)...
-R1(x3)*R2(x1,x2)+2*R1(x1)*R1(x2)*R1(x3);
end
end
end
end
end
end
R2 = R2/sum(R2(:));
R3 = R3/sum(R3(:));
T3 = zeros(n, n, n);
% Compute three-point cluster function
for i = 1:n
for j = 1:n
if i ~= j
for k = 1:n
if k ~= j && k ~= i
T3(x1, x2, x3) = R3(x1,x2,x3)-R1(x1)*R2(x2,x3)-R1(x2)*R2(x1,x3)...
-R1(x3)*R2(x1,x2)+2*R1(x1)*R1(x2)*R1(x3);
end
end
end
end
end
Naively I thought hist3(bins, bins...) or crosstab(bins, bins) would almost do what I want, which is to look for correlated occurrences of elements of the vector, but it doesn't. 我天真地认为hist3(bins,bins ...)或crosstab(bins,bins)几乎可以满足我的要求,即查找向量元素的相关出现,但事实并非如此。
Example: 例:
If my inputs within the outermost loop are 如果我在最外层循环中的输入是
s = [1.2 3.1 4.6 4.7 5.1]
mesh = 0:0.5:6
then the quantized data should be 那么量化的数据应该是
bins = [3 7 10 10 11]
and R2 should be 和R2应该是
>> R2
R2 =
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 2 1 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 2 1 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 2 0 0 0 2 0 0 2 2 0
0 0 1 0 0 0 1 0 0 2 0 0
0 0 0 0 0 0 0 0 0 0 0 0
'R2 and
R3` are easy: “ R2
and
R3”很简单:
R2 = R2 + 1 - diag(ones(size(R2, 1), 1); % you can replace the loop with this
eye3 = zeros(n, n, n);
eye3(linspace(1, numel(eye3), n)) = 1;
R3 = R3 + 1 - eye3; % can move R3 computation outside the loop
For T3
: 对于
T3
:
temp = repmat(R2, [1 1 n]).*permute(repmat(R1, [n, 1, n]), [1, 3, 2]);
T3 = R3 - temp - permute(temp, [2 3 1]) - permute(temp, [3 1 2]);
temp2 = repmat(R1'*R1, [1 1 n]).*permute(repmat(R1, [n, 1, n]), [1, 3, 2]);
T3 = T3 + temp2;
assuming R1
is a row vector. 假设
R1
是行向量。
You may have to play with this a little since there are some things still unclear from your code, but this should be pretty close to what you will eventually need. 你可能有,因为有一些事情还是从您的代码不清楚这个有点玩,但是这应该是非常接近你最终将需要。
EDIT after clarification: 澄清后编辑 :
For R2
: 对于
R2
:
ubins = unique(bins);
bincounts = histc(bins, ubins);
for i=1:max(bincounts)
indices = find(bincounts == i);
R2(indices, indices) = R2(indices, indices) + i
end
This will only be useful for large vectors and arrays. 这仅对大型向量和数组有用。 In effect you are vectorizing the computation of chunks of the matrix, not the entire matrix (because of potential repetition in
bins
). 实际上,您是在矢量化矩阵块的计算,而不是整个矩阵的计算(由于
bins
中可能的重复)。
You can write something similar for R3
. 您可以为
R3
编写类似的内容。 The T3
should still look similar to my earlier answer. T3
仍应与我之前的答案相似。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.