Как записать значение переменной в odeint? - PullRequest
0 голосов
/ 27 марта 2019

Хотелось бы узнать, есть ли способ записать значение определенной переменной в функции интегрирования, без необходимости печатать его в определении функции, что во многих случаях из-за алгоритма прогнозирования-коррекция, привести к большему или меньшему количеству значений, чем конечный вектор, возвращаемый функцией?


Пример, давайте попробуем с этим кодом:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt


def essai(y, t):

    a = y[0]

    c1 = a
    a = c1 / a**2

    return [a]


# Solving
essai0 = [10]
t = np.linspace(0, 2000, 10)
y = odeint(essai, essai0, t)

a = y[:, 0]

# Graphs
fig, ax = plt.subplots()
ax.plot(t, a, 'k--', label='a')
legend = ax.legend(loc='lower right', shadow=True, fontsize='x-large')
legend.get_frame().set_facecolor('#FFFCCC')  # 00FFCC
plt.xlabel('x')
plt.ylabel('y')
plt.title('y vs x')
plt.show()

Я хотел бы записать значенияc1, который зависит от a.Что мне делать?

Если я распечатаю, то получаю (из-за алгоритма pre-corr):

10.0
10.001203411814794
10.00120326701222
10.002406534059283
10.00240638930896
10.031168251789499
10.03116843523562
10.059847893733858
10.059848247411573
10.088446178306066
10.088446526968276
10.178981333917179
10.1789826635142
10.26872274187664
10.268720875457465
10.251795853148066
10.251794757670828
10.324093402400061
10.324093338929458
10.395889284010963
10.395889126663482
10.467192620394076
10.467192470562162
10.60836217080531
10.608361512785885
10.747675991273601
10.747676529983982
10.885208084361661
10.88520861500753
11.021024408838219
11.021024559158226
11.15518691385528
11.15518704871583
11.389028983440005
11.389029612664437
11.618166387462095
11.618166372845774
11.842871925632974
11.842870666797078
12.063390475531826
12.0633901508557
12.279950446401756
12.279950250452782
12.492757035192547
12.492756877414479
12.790475076345272
12.79047467718475
13.081418818481728
13.081418595295522
13.366029970579808
13.366030900758636
13.644707388512776
13.644707798536366
13.917805722870085
13.917805853240296
14.185647189512732
14.185647276304193
14.448524340486092
14.44852440612534
14.849045554474056
14.849045812160185
15.239043242348172
15.239044113472564
15.619306858637934
15.619307570817467
15.990530200625596
15.990530706701604
16.353328829257094
16.35332918566708
16.70825155213741
16.708251810028536
17.055790075751844
17.055790265472186
17.52054793291328
17.520548366986496
17.97329155702487
17.97329263337524
18.414908470097206
18.41490919183692
18.84617978510828
18.846180323693773
19.26780035288661
19.26780072790131
19.68039039537204
19.680390669145883
20.084506483562638
20.084506685872917
20.63204921728682
20.632049705019547
21.165431430483114
21.16543268212929
21.685699626883885
21.685700483180575
22.193774842932424
22.193775478119036
22.69047628806277
22.69047673120133
23.176535191516802
23.1765355148269
23.652607704971896
23.652607943862492
24.296731084127696
24.296731656936466
24.92421316694978
24.924214631653445
25.536282592848192
25.536283593100098
26.134020839947766
26.134021582629195
26.718389929663125
26.718390447872228
27.290248649274574
27.290249027491374
27.8503676838429
27.85036796338048
28.60821935477876
28.608220025227006
29.346505899333515
29.346507613905608
30.066670806260635
30.066671977520553
30.769984796557875
30.769985666417984
31.457578314647648
31.457578921761066
32.13046057231114
32.13046101551341
32.78953730742519
32.789537635058444
33.68118868621462
33.68118947182226
34.54983545122736
34.549837459883506
35.39717380841791
35.397175180698845
36.22469707822626
36.224698097642104
37.033733817898586
37.03373452954837
37.82547018189015
37.82547070150822
38.60097077071101
38.60097115490064
39.65004988104156
39.650050802111195
40.67207751401193
40.67207986867377
41.669047220267416
41.66904882908885
42.64271422854618
42.64271542393563
43.594640193459966
43.59464102811222
44.52621945824691
44.52622006777859
45.43870353935591
45.438703990091476
46.67300975177773
46.673010832232926
47.87550305124021
47.87550581301012
49.04852683447106
49.04852872160157
50.194144483083306
50.19414588551954
51.3141919066777
51.31419288605143
52.41030839692969
52.41030911225109
53.48396538985435
53.483965918885744
54.9362075454971
54.93620881348237
56.35103457439806
56.35103781516747
57.73120149400896
57.731203708595864
59.07913425147381
59.07913589751868
60.39699143853227
60.39699258818307
61.68670054765226
61.68670138744394
62.94999176730058
62.949992388453296
64.65865496068966
64.65865644932029

Что гораздо больше значений, чем можно ожидать при t = np.linspace(0, 2000, 10), чторазделите интервал времени на десятую из 200.

Я долго думал над этой проблемой, не находя действительно хорошего способа сделать это, и я был бы рад узнать, как обойти эту проблему.

1 Ответ

1 голос
/ 27 марта 2019

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

Самый простой способ сделать то, что вы хотите в структурированном виде, - это определить функцию c1 как отдельную функцию, а затем вызвать ее по результатам

def c1_func(y): return y[0]

def essai(y, t):

    a = y[0]

    c1 = c1_func(y)
    a = c1 / a**2

    return [a]

...
y = odeint(...
c1_val = c1_func(y.T)
plt.plot(x, c1_val)

или около того.

...