Ограничьте решения положительным значением, используя JiTCDDE - PullRequest
0 голосов
/ 12 ноября 2018

Я использую JiTCDDE для решения DDE на модифицированной модели Oregantor. Проблема, которая у меня возникла, близка к точке бифуркации, она будет возвращать отрицательные значения. Хотя я знаю, что это математически обоснованные решения, Oregantor представляет собой химическую систему. Следовательно, отрицательные ответы не являются реалистичными для реальной системы. Есть ли способ настроить код, чтобы он возвращал минимальное значение для переменной, когда оно <= 0. Ниже приведена основная часть кода, который у меня есть. </p>

def P1(k):
        return(
            ((H*y(k))/(k01+H*y(k)+kl*H*H*A))*phi
        )

def C(i,j):

    return(
        M1 * ( y(j,t-tau1)-y(i) ) 
      + M2 * ( y(j,t-tau2)-y(i) ) 
    )




MO4 = [
 k1*A*y(1)-k2*y(0)*y(1)+ k3*A*y(0)-2.0*k4*y(0)*y(0)-(y(0)-xsur)*kf,           #HBrO2
 -k1*A*y(1)-k2*y(0)*y(1)+f1*k5*y(2)-(y(1)-ysur)*kf+P1(3)+C(2,6),              #Bromide
 2*k3*A*y(0)-k5*y(2)+P1(3)+C(2,6),                                            #Cataylst
 k1*A*y(1)+2*k2*y(0)*y(1)+k4*y(0)*y(0)-k6*y(3)-(y(3)-vsur)*kf-P1(3)-C(2,6),   #BrMa
 k1*A*y(5)-k2*y(4)*y(5)+ k3*A*y(4)-2.0*k4*y(4)*y(4)-(y(4)-xsur)*kf,           #HBrO2
 -k1*A*y(5)-k2*y(4)*y(5)+f2*k5*y(6)-(y(5)-ysur)*kf+P1(7)+C(6,2),              #Bromide
 2*k3*A*y(4)-k5*y(6)+P1(7)+C(6,2),                                            #Cataylst
 k1*A*y(5)+2*k2*y(4)*y(5)+k4*y(4)*y(4)-k6*y(7)-(y(7)-vsur)*kf-P1(7)-C(6,2),   #BrMa
]

I = jitcdde(MO4)
I.set_integration_parameters(rtol=1e-7,atol=1e-7)
I.constant_past ([0,1.0e-6,0,0,1.0e-6,1.0e-6,1.0e-6,1.0e-6], time=0.0)
I.step_on_discontinuities(max_step=.00001)


data=[]
for time in times:
    data.append( I.integrate(time))
np.savetxt('peaks_%d.dat'%(i), data,)

data1=np.loadtxt('peaks_%d.dat'%(i),dtype = float,delimiter=' ',skiprows=200,usecols=(2,6)).T #,skiprows=80
plt.plot(data1[0],'r')
plt.plot(data1[1],'-.b')
plt.title( 'Catalyst ' )
plt.xlabel('time(sec)')
plt.ylabel('Amplitude')
plt.show()
print('DONE')

1 Ответ

0 голосов
/ 12 ноября 2018

Не существует прямого способа ограничить знаки решений в JiTCDDE. (Источник: я автор; я бы знал.)

Что вам нужно сделать, это выяснить, почему ваши решения становятся отрицательными. Пока я могу думать о трех возможных причинах (и я не могу сказать вам больше, не зная ваших точных настроек):

  • Численный шум превращает решение из математически правильного положительного в математически правильное отрицательное (но переход между решениями не является математически корректным). В этом случае вы сможете избежать этого, уменьшив абсолютный допуск (atol) или, возможно, максимальный размер шага (max_step). Альтернативой является работа в логарифмической области (см. Также этот ответ на аналогичный вопрос ), т. Е. Вы делаете ноль недостижимым по построению (также вы более сильно взвешиваете ошибки, близкие к нулю).

  • Ваша модель позволяет этому случиться, когда этого не должно быть. В этом случае, и если вам действительно нужно избегать отрицательных значений, избегайте отрицательной производной динамических переменных, которые уже довольно близки к нулю, оборачивая вокруг себя функцию, которая делает именно это - используя сигмоиды для реализации этой логики (см. Также это мой ответ на другой вопрос ). Не поддавайтесь искушению использовать для этого пошаговые функции, потому что интеграторам это не нравится ( дальнейшее чтение ).

  • Ваши начальные условия положительные, но не правдоподобные. В этом случае используйте разные начальные условия. Если не существует простого способа определить, какие начальные условия являются правдоподобными, может быть целесообразно выбирать случайные, пока вы не найдете подходящее.

Наконец, я рекомендую вам принять решение о том, что вы хотите сделать, если решение станет отрицательным и действительно ли это будет лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...