Matlab double sum over vectors
조회 수: 3 (최근 30일)
이전 댓글 표시
I want to calculate
, in which k and k' are vectors with x and y components. Both k and k' lie in the 1st Brillouin zone: -pi<kx<pi, -pi<ky<pi, -pi<kx'<pi, -pi<ky'<pi. How to write Matlab code to perform the sum over k and k'? My code doesn't work:
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1484997/image.png)
sum = 0;
kvec = linspace(-pi,pi,N);
for j1=1:1:length(kvec)
kx = kvec(j1);
for j2=1:1:length(kvec)
ky = kvec(j2);
for j3=1:1:length(kvec)
kxprime = kvec(j3);
for j4=1:1:length(kvec)
kyprime = kvec(j4);
sum = sum + f(kx,ky,kxprime,kyprime)
end
end
end
end
댓글 수: 4
채택된 답변
Walter Roberson
2023년 9월 17일
Different versions, and their timings.
Except... in different runs, the timings especially for the first version varied by more than a factor of 10, so the values shown here for a single run might not be representative of real use.
format long g
tic
N = 10;
kvec = linspace(-pi,pi,N);
ck = cos(kvec);
ca = reshape(ck, [], 1);
cb = reshape(ck, 1, []);
cc = reshape(ck, 1, 1, []);
cd = reshape(ck, 1, 1, 1, []);
f = (ca + cb)*2 - (cc + cd)/2;
out1 = sum(f,'all')
toc
tic
f = @(a,b,c,d) 2*(cos(a) + cos(b)) - 0.5*(cos(c) + cos(d));
%Random value for N for example
N = 10;
kvec = linspace(-pi,pi,N);
[kx,ky,kxprime,kyprime] = ndgrid(kvec);
arr = f(kx,ky,kxprime,kyprime);
out2 = sum(arr,'all')
toc
tic
out3 = 0;
N = 10;
kvec = linspace(-pi,pi,N);
f = @(k,kprime) 2* (cos(k(1)) + cos(k(2))) - 0.5* (cos(kprime(1)) + cos(kprime(2)));
for j1=1:1:length(kvec)
kx = kvec(j1);
for j2=1:1:length(kvec)
ky = kvec(j2);
for j3=1:1:length(kvec)
kxprime = kvec(j3);
for j4=1:1:length(kvec)
kyprime = kvec(j4);
out3 = out3 + f([kx,ky],[kxprime,kyprime]);
end
end
end
end
out3
toc
tic
N = 10;
kvec = linspace(-pi,pi,N);
ck = cos(kvec);
ca = reshape(ck, [], 1);
cb = reshape(ck, 1, []);
cc = reshape(ck, 1, 1, []);
cd = reshape(ck, 1, 1, 1, []);
f = bsxfun(@plus, bsxfun(@plus, ca, cb), bsxfun(@plus, cc, cd));
out4 = sum(f(:))
toc
댓글 수: 0
추가 답변 (2개)
Torsten
2023년 9월 17일
편집: Torsten
2023년 9월 17일
Note that -pi<=kx<=pi, -pi<=ky<=pi, -pi<=kx'<=pi, -pi<=ky'<=pi because of your linspace choice.
And most probably you need to normalize the sum somehow because at the moment, it depends strongly on N.
sum = 0;
N = 10;
kvec = linspace(-pi,pi,N);
f = @(k,kprime) 2* (cos(k(1)) + cos(k(2))) - 0.5* (cos(kprime(1)) + cos(kprime(2)));
for j1=1:1:length(kvec)
kx = kvec(j1);
for j2=1:1:length(kvec)
ky = kvec(j2);
for j3=1:1:length(kvec)
kxprime = kvec(j3);
for j4=1:1:length(kvec)
kyprime = kvec(j4);
sum = sum + f([kx,ky],[kxprime,kyprime]);
end
end
end
end
sum
댓글 수: 0
Dyuman Joshi
2023년 9월 17일
Using 4 nested for loops will be take quite a good amount of time to run, specially if N is a comparetively big value.
You can vectorize your code -
f = @(a,b,c,d) 2*(cos(a) + cos(b)) - 0.5*(cos(c) + cos(d));
%Random value for N for example
N = 10;
kvec = linspace(-pi,pi,N);
[kx,ky,kxprime,kyprime] = ndgrid(kvec);
arr = f(kx,ky,kxprime,kyprime);
Also, it's not a good idea to use inbuilt function names as variables, in your case - sum
out = sum(arr,'all')
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Introduction to Installation and Licensing에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!