Документация Engee
Notebook

Размещение кода в блоках Engee Function

Используя блоки Engee Function, вы можете создавать элементы модели, которые ведут себя согласно заданному вами алгоритму. Эти блоки имеет смысл использовать в следующих случаях:

  • Если у вас уже есть нужный, протестированный алгоритм в виде кода на Julia или если вам легко его написать самостоятельно;
  • Если алгоритм на Julia написать легче, чем создать его из графических компонентов;
  • Если поведение нужного вам блока не задано ни одним из существующих блоков Engee, или его невозможно задать при помощи графических блоков.

Блоки Engee Function могут храните вычислять переменные состояния, в отличие от блоков MATLAB Function среды MATLAB/Simulink. Так что ими можно заменить также и блоки S Function.

Рассчитаем математическое ожидание и дисперсию вектора при помощи блока Engee Function

Покажем, как с помощью модели Engee Function рассчитать статистические характеристики вектора произвольной длины, поданного на вход блока.

Исходя из того, что подключение дополнительных библиотек внутри блоков Engee Function (например, Statistics.jl) не поддерживается, мы реализуем в блоке вычисления согласно формулам:

$$\mu = \frac{1}{N}\sum_i^N {x_i}$$

$$\sigma = \sqrt{\frac{1}{N-1} \sum_i^N {(x_i - \mu)^2}}$$

где $\mu$ – математическое ожидание выборки $x$, $\sigma$ – дисперсия, $N$ – количество элементов в выборке.

Реализовать эти вычисления позволяет следующий код (помещенный внутрь блока Engee Function):

struct Block <: AbstractCausalComponent; end

# Вычисление выходных сигналов блока
# Первый аргумент `t` - время, остальные - значения входных сигналов
function (c::Block)(t::Real, x)
    N = length(x);
    μ = sum(x)/N;
    σ = sqrt( sum( (x .- μ).^2 ) / (N-1) )
    return (μ, σ)
end

Дисперсию мы будем рассчитывать с поправкой Бесселя (отсюда N-1).

Этот код можно ввести или отредактировать, если открыть редактор, нажав кнопку "Редактировать исходный код" в настройках блока Engee Function (доступных при двойном щелчке на этот блок или по нажатию кнопки при выбранном блоке).

Стоит обратить внимание на настройку входов и выходов этого блока.

image.png

На трех панелях, которые изображены на иллюстрации, показаны свойства блока, настройка его входных и выходных портов и настройка параметров, которые передаются в код.

  • в свойствах блока (вкладка Main) нужно обратить внимание на количество входов и выходов – наш пример имеет один входной и два выходных сигнала;
  • в свойствах портов (вкладка Ports) мы указываем, что входной порт под названием x будет иметь размерность -1 (унаследованную от предшествующего блока при компиляции модели), размерность двух выходных сигналов с именами μ и σ указывается как () – это размерность скаляра;
  • на вкладке параметры" (Parameters) мы лишь указываем, что дополнительных параметров, передаваемых в код, блок не имеет (количество равно 0).

Размерность сигнала можно узнать при помощи команды size. Терминал подскажет, какую размерность нужно указать при передаче в блок Engee Function скаляра, вектора или матрицы.

image.png

Мы можем задать конкретную длину входного вектора (5,), соблюдая синтаксис описания одномерных кортежей (Tuple), или можем положиться на компилятор и определить размерность входного сигнала как наследуемую (равную -1).

Поместим наш блок в следующее окружение (модель engee_function_basics.engee):

image.png

Запустим модель при помощи команд Программного управления и построим график:

In [ ]:
mName = "engee_function_basics"
model = mName in [m.name for m in engee.get_all_models()] ? engee.open( mName ) : engee.load( "$(@__DIR__)/$(mName).engee" );
data = engee.run( mName )

print( "μ = $(data["μ"].value[1]), σ = $(data["σ"].value[1])" )
μ = 4.0, σ = 1.5811388300841898

График нам показывает, что математическое ожидание и дисперсия последовательности [2,3,4,5,6] равны значениям 4.0 и 1.58.

Заключение

К применениям блока Engee Function, которые мы не рассмотрели в этом примере, относятся:

  • добавление внешнего кода, сохраненного в файлах *.jl, через директивы include
  • задание параметров блока, принимаемых из глобального пространства переменных Engee,
  • изменение параметров блока, т.е. создание блока Engee Function с изменяемыми во времени параметрами.

Вы найдете их в других демонстрационных примерах.

Блоки, использованные в примере