Фортран, а также множество других языков программирования, имеют операторы jump, которые позволяют манипулировать итерацией l oop сверх стандартного элемента управления l oop. В Фортране это операторы CYCLE и EXIT:
оператор CYCLE: Выполнение итераций al oop может быть сокращено путем выполнения оператора CYCLE, принадлежащего конструкции Оператор EXIT: Оператор EXIT предоставляет один из способов завершения al oop или завершения выполнения другой конструкции.
Используя эти конструкции, теперь можно быстро циклически проходить циклы когда конкретный индекс не имеет отношения к вычислению. В случае OP можно сделать что-то вроде:
do i=1,n
s=0
do l=1,n
do m=1,n
if (a(i,l,m) == 0) cycle
s=s-a(i,l,m)*q0(l)*q0(m)
end do
end do
f0(i)=s-g(i)*q0(i)
end do
Конечно, вы всегда должны учитывать, что это останется проблемой O (n ^ 3).
Там Тем не менее, больше информации о том, как вы строите свой 3d-массив a
. Поскольку a(i,l,m) = a1 - b1
и a1
и b1
могут иметь значения 0
или 1
только в зависимости от условия, элемент a(i,l,m)
отличается от 0, если выполняется только 1 из условий. Теперь очень легко проверить, что если первое условие выполнено:
i == l+m .or. i == -l+m .or. i == l-m
, второе условие никогда выполнено:
i+l+m == 2*n+2 .or. i-l+m == 2*n+2 .or. i+l-m == 2*n+2 .or. i-l-m == 2*n+2
Таким образом, только одно из условия могут быть выполнены одновременно. Это дает вам дополнительные рычаги для ускорения процесса и удаления внутреннего l oop, делая это O (n ^ 2):
do i=1,n
s=0
do l=1,n
m=i-l
if (m > 0 .and. m <= n) s=s-a(i,l,m)*q0(l)*q0(m)
m=i+l
if (m > 0 .and. m <= n) s=s-a(i,l,m)*q0(l)*q0(m)
m=l-i
if (m > 0 .and. m <= n) s=s-a(i,l,m)*q0(l)*q0(m)
m=2*n+2-i-l
if (m > 0 .and. m <= n) s=s-a(i,l,m)*q0(l)*q0(m)
m=2*n+2-i+l
if (m > 0 .and. m <= n) s=s-a(i,l,m)*q0(l)*q0(m)
m=-(2*n+2-i-l)
if (m > 0 .and. m <= n) s=s-a(i,l,m)*q0(l)*q0(m)
m=-(2*n+2-i+l)
if (m > 0 .and. m <= n) s=s-a(i,l,m)*q0(l)*q0(m)
end do
f0(i)=s-g(i)*q0(i)
end do
Дальнейшие улучшения наверняка еще возможны.