Engee documentation
Notebook

Code placement in Engee Function blocks

Using blocks Engee Function, you can create model elements that behave according to an algorithm you specify. It makes sense to use these blocks in the following cases:

  • If you already have the required, tested algorithm in the form of Julia code or if it is easy for you to write it yourself;
  • If it is easier to write the algorithm in Julia than to create it from graphical components;
  • If the behaviour of the block you need is not defined by any of the existing Engee blocks, or it cannot be defined using graphical blocks.

Blocks Engee Function can store calculate state variables, unlike blocks MATLAB Function of MATLAB/Simulink environment. So they can also replace the blocks S Function.

Let's calculate the mathematical expectation and variance of the vector using the Engee Function block

Let's show how to calculate statistical characteristics of a vector of arbitrary length fed to the block input using the model Engee Function.

Proceeding from the fact that connection of additional libraries inside Engee Function blocks (for example, Statistics.jl) is not supported, we realise in the block calculations according to the formulas:

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

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

where $\mu$ is the mathematical expectation of the sample $x$, $\sigma$ is the variance, $N$ is the number of elements in the sample.

The following code (placed inside the block Engee Function) allows to realise these calculations:

struct Block <: AbstractCausalComponent; end

# Calculation of block output signals
# The first argument of `t` is time, the rest are values of input signals
function (c::Block)(t::Real, x)
    N = length(x);
    μ = sum(x)/N;
    σ = sqrt( sum( (x .- μ).^2 ) / (N-1) )
    return (μ, σ)
end

We will calculate the variance with the Bessel correction (from here N-1).

This code can be entered or edited by opening the editor by clicking the "Edit Source Code" button in the Engee Function block settings (accessible by double-clicking this block or by clicking when the block is selected).

It is worth paying attention to the setting of inputs and outputs of this block.

image.png

The three panels that are illustrated show the properties of the block, the configuration of its input and output ports, and the configuration of the parameters that are passed to the code.

  • in the block properties (tab Main) you should pay attention to the number of inputs and outputs - our example has one input and two output signals;
  • in the port properties (tab Ports) we specify that the input port named x will have dimension -1 (inherited from the previous block when compiling the model), the dimension of the two output signals named μ and σ is specified as () - this is the scalar dimension;
  • on the "parameters" tab (Parameters) we only indicate that the block has no additional parameters passed to the code (the number is equal to 0).

You can find out the dimension of the signal using the command size. The terminal will prompt what dimensionality should be specified when passing a scalar, vector or matrix to the Engee Function block.

image.png

We can specify the specific length of the input vector (5,), following the syntax for describing one-dimensional tuples (Tuple), or we can rely on the compiler and define the input dimension as inherited (equal to -1).

Let's place our block in the following environment (model engee_function_basics.engee):

image.png

Let's run the model using Programming commands and plot the graph:

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

The graph shows us that the mathematical expectation and variance of the sequence [2,3,4,5,6] are equal to the values 4.0 and 1.58.

Conclusion

Applications of the block Engee Function, which we have not covered in this example, include:

  • adding external code stored in *.jl files via directives include
  • setting block parameters taken from the Engee global variable space,
  • changing block parameters, i.e. creating a block Engee Function with time-varying parameters.

You will find them in other demos.

Blocks used in example