мне нужно численно оценить некоторые интегралы, которые все форм, показанных на этом изображении: Векторизация двойного цикла, включая синус два переменных
Этих интегралов являются матричными элементами N x N
матрицы, так что мне нужно для их оценки для всех возможных комбинаций n
и m
в диапазоне от 1
до N
. Интегралы симметричны n
и m
, которые я реализовал в моем текущем вложенной подходе for
петли:
function [V] = coulomb3(N, l, R, R0, c, x)
r1 = 0.01:x:R;
r2 = R:x:R0;
r = [r1 r2];
rl1 = r1.^(2*l);
rl2 = r2.^(2*l);
sines = zeros(N, length(r));
V = zeros(N, N);
for i = 1:N;
sines(i, :) = sin(i*pi*r/R0);
end
x1 = length(r1);
x2 = length(r);
for nn = 1:N
for mm = 1:nn
f1 = (1/6)*rl1.*r1.^2.*sines(nn, 1:x1).*sines(mm, 1:x1);
f2 = ((R^2/2)*rl2 - (R^3/3)*rl2.*r2.^(-1)).*sines(nn, x1+1:x2).*sines(mm, x1+1:x2);
value = 4*pi*c*x*trapz([f1 f2]);
V(nn, mm) = value;
V(mm, nn) = value;
end
end
Я понял, что вызов sin(x)
в петле была плохая идея, так что я вычислить все необходимые значения и хранить их , Чтобы оценить интегралы, я использовал trapz
, но поскольку первый и второй/третий интегралы имеют разные диапазоны, значения функций нужно вычислять отдельно и затем объединяться.
Я пробовал пару различных способов векторизации, но единственный, который дает правильные результаты, занимает намного больше времени, чем приведенный выше цикл (используется gmultiply
, но созданные массивы являются излишними). Я также сделал аналитическое решение (что можно предположить, что m
и n
являются целыми числами и R0 > R > 0
), но эти решения включают интеграл косинуса (cosint
в MATLAB), который чрезвычайно мал для больших N
.
Я не уверен, что вся вещь может быть векторизована без создания очень больших массивов, но по крайней мере должна быть внутренняя петля. Любые идеи были бы очень признательны!
входы, которые я использую в настоящее время являются:
R0 = 1000;
R = 8.4691;
c = 0.393*10^(-2);
x = 0.01;
l = 0 # Can reasonably be 0-6;
N = 20; # Increasing the value will give the same results,
# but I would like to be able to do at least N = 600;
Используя эти значения
V(1, 1:3) = 873,379900963549 -5,80688363271849 -3,38139152472590
Хотя диагональные значения никогда не сходятся с увеличением R0 поэтому они менее интересны.
Предоставляет ли код, который вы опубликовали, правильный результат для вычисления? –
С шагом 0,01 значения очень близки к двум образцам, которые я вычислил аналитически в Maple, поэтому я верю, что он дает правильные результаты. –
Хорошо. Не могли бы вы привести пример некоторых разумных материалов? –