Обработка решений
Доступ к значениям
Тип решения имеет множество встроенных функций, помогающих проводить анализ. Например, у него есть интерфейс массива для доступа к значениям. Внутренне тип решения содержит два важных поля:
-
u
, в котором находится вектор значений по каждому временному шагу. -
t
, в котором находятся значения времени каждого временного шага.
Различные типы решений могут при необходимости добавлять дополнительную информацию, например производную на каждом временном шаге du
или пространственную дискретизацию x
, y
и т. д.
Интерфейс массива
Вместо работы с Vector{uType}
напрямую можно использовать предоставленный интерфейс массива.
sol[j]
для доступа к значению на временном шаге j
(если временной ряд был сохранен), и
sol.t[j]
для доступа к значению t
на временном шаге j
. Для многомерных систем этот вопрос будет решаться сначала по компонентам и, наконец, по времени, и, таким образом
sol[i, j]
будет i
-м компонентом на временном шаге j
. Следовательно, sol[j][i] == sol[i, j]
. Это делается потому, что в Julia выполняется развертывание по столбцам, поэтому ведущая размерность должна быть непрерывной в памяти. Если бы независимые переменные имели форму (например, представляли собой матрицу), i
являлся бы линейным индексом. Можно также получить доступ к решениям, имеющим форму:
sol[i, k, j]
дает компонент [i,k]
системы на временном шаге j
. Поддерживается оператор двоеточия, то есть
sol[i, :]
дает временной ряд для i
-го компонента.
Использование интерфейса AbstractArray
Интерфейс AbstractArray
можно использовать напрямую. Например, для векторной системы переменных sol[i,j]
— это матрица, строки которой являются переменными, а столбцы — временными точками. Операции типа sol'
транспонируют тип решения. Функционал, написанный для AbstractArray
, может напрямую использовать эту возможность. Например, функция Base cov
вычисляет корреляции между столбцами, а значит:
cov(sol)
вычисляет корреляцию состояния системы во времени, тогда как
cov(sol, 2)
вычисляет корреляцию между переменными. Аналогично, mean(sol,2)
--это среднее значение переменной во времени, а var(sol,2)
— дисперсия. Другие статистические функции и пакеты, работающие с типами AbstractArray
, будут работать и с типом решения.
В любой момент с помощью Array(sol)
можно создать истинный массив (Array
).
Интерполяции и вычисление производных
Если решатель допускает плотный вывод и dense=true
было задано для решения (используется по умолчанию), можно получить доступ к приближенному значению в момент времени t
с помощью команды
sol(t)
Заметим, что интерполирующая функция позволяет t
быть вектором и использует это для ускорения вычислений интерполяции. Полный API для интерполяций выглядит следующим образом.
sol(t, deriv = Val{0}; idxs = nothing, continuity = :left)
Необязательный аргумент deriv
позволяет выбрать номер n
производной, для которой будет решаться интерполяция. По умолчанию используется n=0
. Заметим, что большинство производных пока не реализовано (хотя это несложно, но для каждого алгоритма это нужно делать вручную). Откройте проблему, если вам нужна конкретная производная). continuity
описывает, удовлетворять ли левой или правой непрерывности при сохранении прерывания. По умолчанию используется значение :left
, т. е. захватывается значение до изменения обратного вызова, но оно может быть изменено на :right
. idxs
позволяет выбрать индексы, для которых должна решаться интерполяция. Например,
sol(t, idxs = 1:2:5)
возвратит вектор (Vector
) длины 3, который представляет собой интерполированные значения в t
для компонентов 1
, 3
и 5
. idxs=nothing
(по умолчанию) означает, что будет возвращен каждый компонент. Кроме того, можно выполнить
sol(t, idxs = 1)
и будет возвращено Number
для интерполяции единственного значения. Следует отметить, что эта интерполяция вычисляет только запрашиваемые значения, и поэтому в больших системах она действует значительно быстрее, чем вычисление полной интерполяции и использование только нескольких значений.
Кроме того, имеется действующая на месте форма:
sol(out, t, deriv = Val{0}; idxs = nothing, continuity = :left)
которая запишет вывод в out
. Это позволяет использовать для вывода заранее выделенные векторы, что еще больше повышает скорость.
Включения
Интерфейс решателя также предоставляет средства, используемые для осмысления решения. Используя функцию tuples(sol)
, мы можем получить кортеж для вывода на каждом временном шаге. Это позволяет сделать следующее.
[t + 2u for (u, t) in tuples(sol)]
Можно использовать дополнительные компоненты объекта решения, а также zip
. Например, допустим, что тип решения содержит du
, производную на каждом временном шаге. Можно осмыслить эти значения, используя:
[t + 3u - du for (t, u, du) in zip(sol.t, sol.u, sol.du)]
Обратите внимание, что объект решения выступает как вектор во времени и поэтому его длина равна количеству сохраненных временных точек.
Специальные поля
Интерфейс решения также содержит некоторые специальные поля. В решение включены объект задачи prob
и алгоритм, используемый для решения задачи alg
. Кроме того, поле dense
является логическим, определяющим доступность функции интерполяции. Далее, поле destats
содержит внутреннюю статистику процесса решения, такую как количество линейных решений и сбоев сходимости. Наконец, имеется изменяемое состояние tslocation
, которое управляет поведением шаблона графика. По умолчанию tslocation=0
. Его значения имеют различный смысл для дифференциальных уравнений в частных производных обыкновенных дифференциальных уравнений:
-
tslocation=0
для непространственных задач (ODE) означает, что с помощью шаблона графика будет построено полное решение.tslocation=i
означает, что будет построена только временная точкаi
. -
tslocation=0
для пространственных задач (PDE) означает, что с помощью шаблона графика будет построена конечная временная точка.tslocation=i
означает, что с помощью шаблона графика будет построенаi
-я временная точка.
Это означает, что для уравнений ODE графики будут строиться по умолчанию в виде полного графика, а для уравнений PDE — в виде графика поверхности в конечной точке времени. Интерфейс итератора просто итерирует значение tslocation
, а функция animate
итерирует решение, вызывая функцию solve на каждом шаге.
Статистика решателя дифференциальных уравнений (destats)
#
DiffEqBase.DEStats
— Type
mutable struct Stats
Статистика, получаемая от решателя дифференциальных уравнений о процессе решения.
Поля
-
nf: количество вычислений функции. Если дифференциальное уравнение является функцией разделения, например
SplitFunction
для неявной-явной интеграции (IMEX), тоnf
— это количество вычислений для первой функции (неявной функции). -
nf2: Если дифференциальное уравнение является функцией разделения, например
SplitFunction
для неявной-явной интеграции (IMEX), тоnf2
— это количество вычислений второй функции, т. е функции, рассматриваемой явным образом. В противном случае оно равно нулю. -
nw: количество матриц W=I-gamma*J (или W=I/gamma-J), построенных в процессе решения.
-
nsolve: количество линейных решений
W
, необходимых для интеграции. -
njacs: количество якобианов, вычисленных при интеграции.
-
nnonliniter: общее количество итераций для нелинейных решателей.
-
nnonlinconvfail: количество сбоев сходимости нелинейного решателя.
-
ncondition: количество вызовов функции условия для обратных вызовов.
-
naccept: количество принятых шагов.
-
nreject: количество отклоненных шагов.
-
maxeig: максимальное собственное значение для решения. Вычисляется, только если метод является алгоритмом автопереключения.
Коды возврата (RetCodes)
Типы решений имеют поле retcode
, которое возвращает символ, обозначающий состояние ошибки решения. Коды возврата приведены ниже.
-
:Default
: решатель не задал коды возврата. -
:Success
: интеграция завершилась без ошибок или решатель устойчивого состояния изSteadyStateDiffEq
нашел устойчивое состояние. -
:Terminated
: интеграция завершается сterminate!(integrator)
. Обратите внимание, что это может произойти при использованииTerminateSteadyState
из библиотеки обратного вызоваDiffEqCallbacks
. -
:MaxIters
: интеграция завершилась досрочно, так как достигла максимального количества итераций. -
:DtLessThanMin
: метод временного шага выбрал размер шага меньший, чем разрешенный минимальный временной шаг, и досрочно выполнил выход. -
:Unstable
: решатель обнаружил, что решение нестабильно, и досрочно выполнил выход. -
:InitialFailure
: решателю DAE не удалось найти согласованные начальные условия. -
:ConvergenceFailure
: внутренним неявным решателям не удалось сойтись. -
:Failure
: общие неклассифицированные сбои и ошибки.