Matlab double sum over vectors
3 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
CC SS
il 17 Set 2023
Risposto: Walter Roberson
il 17 Set 2023
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 Commenti
Risposta accettata
Walter Roberson
il 17 Set 2023
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 Commenti
Più risposte (2)
Torsten
il 17 Set 2023
Modificato: Torsten
il 17 Set 2023
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 Commenti
Dyuman Joshi
il 17 Set 2023
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 Commenti
Vedere anche
Categorie
Scopri di più su Introduction to Installation and Licensing in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!