Задача Джулии - решатель Рунге-Кутты модели ФитцХью – Нагумо в частных производных

Я новичок в языке программирования Julia, поэтому не знаю, как оптимизировать код. Я слышал, что Julia должна быть быстрее по сравнению с Python, но я написал простой код Julia для решения задачи ФитцХью– Модель Нагумо, и, похоже, она не быстрее Python.

Уравнения модели ФитцХью – Нагумо:

function FHN_equation(u,v,a0,a1,d,eps,dx)
  u_t = u - u.^3 - v + laplacian(u,dx)
  v_t = eps.*(u - a1 * v - a0) + d*laplacian(v,dx)
  return u_t, v_t
end

где u и v - переменные, которые представляют собой двумерные поля (то есть двумерные массивы), а a0,a1,d,eps - параметры модели. И параметры, и переменные относятся к типу Float. dx - это параметр, который управляет разделением между точками сетки для использования функции Лапласа, которая является реализацией конечных разностей с периодическими граничными условиями.

Если один из вас, опытных программистов, Джулия, подскажет, как улучшить работу Джулии, я буду рад услышать.

Пошаговая функция Рунге-Кутте:

function uv_rk4_step(Vs,Ps, dt)
  u = Vs.u
  v = Vs.v
  a0=Ps.a0
  a1=Ps.a1
  d=Ps.d
  eps=Ps.eps
  dx=Ps.dx
  du_k1, dv_k1 =    FHN_equation(u,v,a0,a1,d,eps,dx)
  u_k1 = dt*du_k1י
  v_k1 = dt*dv_k1
  du_k2, dv_k2 =    FHN_equation((u+(1/2)*u_k1),(v+(1/2)*v_k1),a0,a1,d,eps,dx)
  u_k2 = dt*du_k2
  v_k2 = dt*dv_k2
  du_k3, dv_k3 =    FHN_equation((u+(1/2)*u_k2),(v+(1/2)*v_k2),a0,a1,d,eps,dx)
  u_k3 = dt*du_k3
  v_k3 = dt*dv_k3
  du_k4, dv_k4 =    FHN_equation((u+u_k3),(v+v_k3),a0,a1,d,eps,dx)
  u_k4 = dt*du_k4
  v_k4 = dt*dv_k4
  u_next    =   u+(1/6)*u_k1+(1/3)*u_k2+(1/3)*u_k3+(1/6)*u_k4
  v_next    =   v+(1/6)*v_k1+(1/3)*v_k2+(1/3)*v_k3+(1/6)*v_k4
  return u_next, v_next
end

И я использовал imshow () из пакета PyPlot для построения поля u.


person Ohm    schedule 30.06.2016    source источник
comment
Приведите минимальный рабочий пример, который можно запустить. Вам нужно указать лапласовскую функцию и пример вызова.   -  person David P. Sanders    schedule 30.06.2016
comment
На первый взгляд вам следует удалить векторизованные операции и записать их в виде явных циклов.   -  person David P. Sanders    schedule 30.06.2016
comment
@ DavidP.Sanders, код можно скачать по ссылке, которую я дал на GitHub, а в README я написал строки для запуска кода.   -  person Ohm    schedule 30.06.2016
comment
@ DavidP.Sanders, вы имеете в виду, что в функции FHN_equation я должен писать все уравнения как для циклов?   -  person Ohm    schedule 30.06.2016
comment
Извините, я не понял, что у вас есть ссылка на код. Да, я имею в виду, что вам следует попробовать переписать все на лапласианском языке и fhn, что касается циклов.   -  person David P. Sanders    schedule 30.06.2016
comment
Вам также следует избегать создания новой матрицы для лапласиана на каждом этапе.   -  person David P. Sanders    schedule 30.06.2016
comment
Хотя в этом нет необходимости для повышения скорости (при условии наличия хорошо сформированного кода), для подобных вопросов часто бывает полезно включить информацию о типе в аргумент функции. Благодаря этому людям, не знакомым с ФитцХью-Нагумо, намного легче предлагать предложения по вашему коду.   -  person Colin T Bowers    schedule 01.07.2016
comment
Еще лучше было бы предоставить автономную подпрограмму, которая имитирует ввод и время вашей функции, которую мы можем скопировать и вставить в REPL, а затем попытаться улучшить ... это уловки, которые обычно приводят к получению наилучшего возможного ответа из StackOverflow.   -  person Colin T Bowers    schedule 01.07.2016
comment
Поддерживая комментарии @ColinTBowers, почти всегда стоит добавлять информацию о типе, касающуюся размеров (а не типов элементов) векторов, матриц. Поскольку функции действительно не будут работать для типов с другими интерфейсами. Это также дает лучший интерфейс для людей, читающих функции. Типы можно сделать как можно более абстрактными, чтобы в дальнейшем функции оставались как можно более общими.   -  person Dan Getz    schedule 01.07.2016
comment
Последний комментарий, который может сэкономить ваше время. Я готов сделать крупную ставку, что вы пришли из среды Matlab (как и я). Ваш связанный github, похоже, имеет одну функцию для каждого файла (или один тип для каждого файла). Классический Матлаб. Вам не нужно беспокоиться об этом с Джулией (или большинством других языков). Вы можете поместить несколько функций и типов в один файл и сделать его модулем. Это способ удобнее, когда вы к нему привыкнете.   -  person Colin T Bowers    schedule 01.07.2016
comment
@ColinTBowers На самом деле я обычно использую Python, но я подумал, что Джулия должна быть больше похожа на Matlab, чем на Python в том, как организовать программу ..   -  person Ohm    schedule 02.07.2016
comment
@ Ом Ха. Так что пари я проиграл :-) Нет, стандартный способ организации кода в Julia - это модули. Часто весь модуль представляет собой один файл, хотя для более крупных модулей код будет разделен на несколько разных файлов, которые все собираются вместе с помощью include. Я всегда думал, что пакет Distances - отличный пример того, как структурировать код Julia.   -  person Colin T Bowers    schedule 04.07.2016


Ответы (1)


Это не полный ответ, а попытка оптимизации функции laplacian. Исходный laplacian на матрице 10x10 дал мне @time:

0.000038 seconds (51 allocations: 12.531 KB)

Пока эта версия:

function laplacian2(a,dx)
          # Computes Laplacian of a matrix
          # Usage: al=laplacian(a,dx)
          # where  dx is the grid interval
          ns=size(a,1)
          ns != size(a,2) && error("Input matrix must be square")
          aa=zeros(ns+2,ns+2)

          for i=1:ns
              aa[i+1,1]=a[i,end]
              aa[i+1,end]=a[i,1]
              aa[1,i+1]=a[end,i]
              aa[end,i+1]=a[1,i]
          end
          for i=1:ns,j=1:ns
              aa[i+1,j+1]=a[i,j]
          end
          lap = Array{eltype(a),2}(ns,ns)
          scale = inv(dx*dx)
          for i=1:ns,j=1:ns
              lap[i,j]=(aa[i,j+1]+aa[i+2,j+1]+aa[i+1,j]+aa[i+1,j+2]-4*aa[i+1,j+1])*scale
          end
          return lap
end

Дает @time:

0.000010 seconds (6 allocations: 2.250 KB)

Обратите внимание на сокращение распределения. Дополнительные выделения обычно указывают на возможность оптимизации.

person Dan Getz    schedule 01.07.2016