Engee documentation
Notebook

Calculating the approximate value of some function

In this demonstration we will look at the possibilities of calculating approximate values of a function using Engee and study the basic blocks used to solve this problem.

Block analysis

The Prelookup block calculates the number and fraction of the interval that determines how its input value u relates to a set of reference points.

image_3.png

The Interpolation Using Prelookup block is most effective when the Prelookup block is used. The Prelookup block calculates an index and an interval fraction that determine how its input value u relates to the dataset of breakpoints. The resulting index and fraction values are fed into the Interpolation Using Prelookup block to interpolate an n-dimensional table. Both blocks have integrated algorithms.

image_4.png

The n-D Lookup Table block calculates the approximate value of some function. This block and its variants match the input data with a table of output values using interpolation and extrapolation methods.

image_2.png

The Direct Lookup Table (n-D) block indexes an n-dimensional table to extract a scalar, vector, or two-dimensional matrix. The first index of the selection corresponds to the top (or left) input port. You can specify the table data as block input data or define the table data in the block dialogue box. The number of input ports and the output size depend on the number of table dimensions and the selected output slice.

image.png

Realisation of the model

Next, let's consider the model with the application of all the blocks listed above.

image_2.png

Now let's add initialisation of tables and lookup points for the model. Let's start with Direct Lookup Table (n-D) and 2-D Lookup Table blocks, and connect libraries necessary for data processing and visualisation.

In [ ]:
Pkg.add(["CSV"])
In [ ]:
# Подключение библиотек
using CSV
using DataFrames
using Plots
In [ ]:
Points2D = [1, 2, 3]; # Точки индексации
Matrix2D = [4 50 6; 16 19 20; 10 18 23] # Таблица
Out[0]:
3×3 Matrix{Int64}:
  4  50   6
 16  19  20
 10  18  23
In [ ]:
# Точки для чтения 
X = 1;
Y = 2;
idx = [X,Y];
In [ ]:
# Точки для чтения 
X = 1;
Y = 2;
idx = [X,Y];

Now initialise Prelookup and Interpolation Using Prelookup, and plot the relation of points to the table.

In [ ]:
Value1 = 10:10:110; # Точки
Value2 = sqrt.(collect(1:11) * collect(1:11)'); # Таблица
plot(Value1, Value2)
Out[0]:

The last block that has no initialisation parameters declared is 1-D Lookup Table.

In [ ]:
Points1D = 1:1:100; # Точки индексации
Matrix1D = sin.(1:2:200); # Таблица
A = 50; # Амплитуда генератора сигналов
plot(Points1D,Matrix1D)
Out[0]:

Let's run the model with the given parameters.

In [ ]:
function run_model( name_model, path_to_folder )
    
    Path = path_to_folder * "/" * name_model * ".engee"
    
    if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
        model = engee.open( name_model ) # Открыть модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
    else
        model = engee.load( Path, force=true ) # Загрузить модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
        engee.close( name_model, force=true ); # Закрыть модель
    end

    return model_output
end
Out[0]:
run_model (generic function with 1 method)
In [ ]:
run_model("Lookup_Table","/user/start/examples/base_simulation/lookup_table")
Building...
Progress 100%
Out[0]:
Dict{String, DataFrame}()

Let's consider the results of the modelling. First, we count all the recorded data. The matrix file must be unparseeded, so we use a custom function to read such CSV.

In [ ]:
function parse_csv_engee(filename :: String)
    file = open(filename)
    line = readline(file)
    name_idx = vcat(0,findall(',', line), length(line)+1)
    names = collect([line[(name_idx[it-1]+1):(name_idx[it]-1)] for it  2:length(name_idx)])
    data = collect([it for it  (line -> eval(Meta.parse(line)))(readline(file))])
    while !eof(file)
        data = ((a, b) -> [a;;;b]).(data, collect([it for it  (line -> eval(Meta.parse(line)))(readline(file))]))
    end
    close(file)
    return Dict(names .=> data)
end
Out[0]:
parse_csv_engee (generic function with 1 method)

In the first case we read a column from Matrix2D.

In [ ]:
Direct_Lookup_Table = parse_csv_engee("/user/start/examples/base_simulation/lookup_table/out1.csv");
Direct_Lookup_Table = Direct_Lookup_Table["1"];
Direct_Lookup_Table[:,:,1]
Out[0]:
3×1 Matrix{Int64}:
 50
 19
 18

In the second case we read values from Matrix2D into [X,Y] cells.

In [ ]:
Lookup_Table_2D = Matrix(CSV.read("/user/start/examples/base_simulation/lookup_table/out2.csv", DataFrame)); #загрузка данных
arr = Lookup_Table_2D[:,2]
arr[1]
Out[0]:
50.0

In the third case, we read from Interpolation Using Prelookup using data from Prelookup.

In [ ]:
Interpolation_Using_Prelookup = Matrix(CSV.read("/user/start/examples/base_simulation/lookup_table/out3.csv", DataFrame)); #загрузка данных
plot(Interpolation_Using_Prelookup[:,2])
Out[0]:

And in the last case we read the sinusoid from 1-D Lookup Table.

In [ ]:
Lookup_Table_1D = Matrix(CSV.read("/user/start/examples/base_simulation/lookup_table/out4.csv", DataFrame)); #загрузка данных
plot(Lookup_Table_1D[:,2])
Out[0]:

Conclusion

As a result of this demonstration, we have shown how to use different blocks to calculate the approximate value of some function. And we also implemented two functions:

  1. running the model;
  2. parsing CSV with a matrix written into it.