Как можно анимировать изменяющуюся во времени функцию с помощью стримплота Маки?

Я пытался построить простую функцию:

v(x, y) = (y*t, 2*x*t)

(фактическая реализация: v(x::Point2{T}, t) where T = Point2{T}(one(T) * x[2] * t, 4 * x[1]))

с использованием функции 2D-стримплота Маки.

Хотя я могу построить каждый временной шаг индивидуально, создав анонимную функцию f = x -> v(x, 5e0) (например) и построение f, когда я пытаюсь обернуть его в Observable (используя Node(f)), то я больше не могу обновить этот Observable, чтобы он указывал на другую функцию, поэтому мой цикл записи завершается неудачно.

Я пробовал сделать тип узла более абстрактным (Node{Function}). К сожалению, этот абстрактный тип, кажется, теряется где-то во внутренностях Маки и, таким образом, теряется.

Могу ли я как-нибудь обернуть свой тип, чтобы не столкнуться с конфликтами типов, но по-прежнему оставаться функцией?

1 ответ

Решение

Оказывается, есть прекрасный метод Base Fix2(function, argument), который в основном решает мою проблему (поскольку возвращает завернутый тип).

Рассмотрим этот пример функции:

v(x::Point2{T}, t) where T = Point2{T}(one(T) * x[2] * t, 4 * x[1])

Можно создать вызываемую функцию со временем, равным 1.0:

fixedfunc = Base.Fix2(v, 1.0)

который затем можно загрузить в Observable и без проблем обновить для получения нового значения времени.

Вот последний код для справки:

v(x::Point2{T}, t) where T = Point2{T}(one(T) * x[2] * t, 4 * x[1])
sf = Node(Base.Fix2(v, 0e0))

title_str = Node("t = 0.00")

sp = streamplot(
        sf,
        -2..2, -2..2;
        linewidth = 2,
        padding = (0, 0),
        arrow_size = 0.09,
        colormap =:magma
    )

sc = title(sp, title_str)

record(sc, "test.mp4", LinRange(0, 20, 5*30)) do i
  sf[] = Base.Fix2(v, i)
  title_str[] = "t = $(round(i; sigdigits = 2))"
end

видео

Другие вопросы по тегам