2014-10-01 1 views
3

Я реализовал функцию в Julia для создания матрицы Римана размера N. Это матрица N-на-N, связанная с гипотезой Римана, которая истинна тогда и только тогда, когда:Оптимизация матричной функции Римана в Julia

DET(A) = O(N! N^(-1/2+epsilon)) за каждые epsilon > 0, DET() обозначает детерминанту, ! обозначает факторный.

Где, А = матрица Римана с

A = B(2:N+1, 2:N+1), где

B(i,j) = i-1 if i divides j, and 
      -1 otherwise. 

Вот мой код, который работает отлично, но нуждается в оптимизации:

function riemann(x::Int32) 
    R = zeros(Int32,x+1,x+1) 
    for i=1:x+1, j=1:x+1 
     if j%i == 0 
      R[i,j] = i-1 
     else 
      R[i,j] = -1 
     end 
    end 
    return R[2:x+1,2:x+1] 
end 

Будем надеяться, что мне нужно напишите его в более эффективной форме:

function riemann!{T}(R::AbstractMatrix{T}, x::T) 
. 
. 
. 

Любые предложения приветствуются.

EDIT:

Ну, это другая форма я предложил выше. Я приурочил его к исходному коду и не нашел прироста скорости.

function calc_riemann!{T}(R::AbstractMatrix{T}, x::T) 
    for i=1:x+1, j=1:x+1 
     if j%i == 0 
      R[i,j] = i-1 
     else 
      R[i,j] = -1 
     end 
    end 
end 
function riemann(x::Int) 
    R = Array(Int, x+1,x+1) 
    calc_riemann!(R, x) 
    y = R[2:x+1,2:x+1] 
end 
+0

Непонятно, в чем вопрос. – StefanKarpinski

+0

Вопрос в том, как оптимизировать вышеуказанную функцию для эффективного использования памяти и максимальной скорости. –

+0

Если вы внесли 'Int32' в 'Int', я сомневаюсь, что вы могли бы получить это намного быстрее. Похоже, что с версией 'riemann! 'Вы предлагаете выделить матрицу вне функции, но это не изменит общее время. – IainDunning

ответ

3

Это работает намного быстрее, вырезая все тесты (мы можем просто перейти к кратным).

function my_riemann(x::Int) 
    R = Array(Int,x+1,x+1) 
    fill!(R,-1) 
    for i=2:x+1 
     for j=i:i:x+1 
      R[i,j] = i - 1 
     end 
    end 
    return R[2:x+1,2:x+1] 
end 

EDIT

Да, выделяя нужный размер Array и не копировать это ускоряет вещи значительно. Посмотрите, значительно ли сокращено ваше время для этой версии.

function my_riemann2(x::Int) 
    R = Array(Int,x,x) 
    fill!(R,-1) 
    for i=1:x 
     for j=i:i+1:x 
      R[i,j] = i 
     end 
    end 
    return R 
end 
+0

Наверное, не нужно выделять 'Array', который больше, чем возвращаемое значение Я оставлю это вам, чтобы узнать, сильно ли это ускорилось. – rickhg12hs

+0

Большое спасибо, это примерно в 4,4 раза быстрее, чем у меня. Мне непонятно, что вы имеете в виду, выделив массив, который больше, чем возвращаемое значение Я вижу, что R больше, чем возвращаемое значение только одной строкой и одним столбцом. В чем же разница между значениями «Int» и «Int32» в производительности? –

+0

В настоящее время 'R [2: x + 1, 2: x + 1] 'будет делать копию, поэтому избежать этого может быть действительно.' Int 'будет 'typealias' для' Int32' или 'Int64' в зависимости от того, используете ли вы 32-битные или 64-битные julia. –