Engee 文档

处理不同维度的信号

矢量化和广播是使用*Engee*中的模型时的重要技术,可以有效地处理不同维度的信号。 使用矢量化,您可以完全对数组执行计算,避免显式元素循环,从而加快计算速度并简化代码。 反过来,Broadcast在执行操作时提供了数组之间的自动维度匹配,使您可以方便地使用不同格式的数据。

在建模中使用矢量化和广播可以有效地处理和分析多维数据。 矢量化通过处理整个数组来减少操作数量,广播消除了手动维度匹配的需要。

建模中的矢量化

建模中的矢量化允许您针对各种参数值立即评估模型的行为,这在灵敏度分析和测试中特别有用。 这意味着,您可以设置参数矩阵并在同一时间获取所有值的结果,而不是为每个值运行单独的运行。

例如,如果设置块的*Amplitude*参数 Sine Wave 值的矩阵 [[1, 2]; [3, 4]],这将意味着该块产生具有矩阵中指定的幅度的几个信号。 下图显示了*正弦波*块如何生成具有给定幅度的多个信号,这使您可以立即看到*幅度参数的不同值的结果。*:

vectorization x 1

广播

广播允许您协调数组的维度以对其执行操作。 在*Engee*中,这种机制会自动扩展数组的维度,允许在看似不兼容的数组上执行操作。 例如,如果一个数组具有大小 2x2 而另一个 — 1x2,然后添加时,数组将减少到兼容的尺寸。

考虑具有两个*Constant*块和一个*Add*块的示例。 带有参数的*Constant*块 [3, 4; 5, 6] 被添加到*常量*块与参数 [2, 3]. 与此同时,broadcast会自动将数组调整为兼容的大小并执行元素添加。:

broadcast 1

broadcast 2

块的输出结果将是 [5, 7; 7, 9],因为线条是自动匹配的。 这种方法可以轻松地在不同大小的阵列之间执行操作,并大大简化了建模中多维信号的工作。

定制轮胎类型

在学习关于自定义轮胎类型的部分之前,建议您首先熟悉块 Bus CreatorBus Selector.

在*Engee*中,支持由类型表示的总线的自定义数据类型 N.公共标志. 此类型允许您为处理类似数据的块设置总线结构。 命名元组在*Engee*(命名的,命名的),例如:

bus = (s1 = 4, s2 = 5.5, s3 = [1, 2, 3])

类型 N.公共标志 它由信号的名称参数化(姓名),基本类型(基本类型),尺寸(暗淡无光),以及总线的名称(总线名称). 例如,具有三个信号的总线可以被描述为:

bus_type = BusSignal{(:s1, :s2, :s3), Tuple{Int, Float64, Float64}, ((), (), (3,)), :MyBus}
基本类型 仅指定基本类型(例如, Int型, 漂浮64),而不是容器(例如, 向量{Int}). 数组的维度分别设置在 暗淡无光.

这里:

  • :s1, :s2, :s3 -信号名称;

  • 元组{Int,Float64,Float64} -信号数据的类型;

  • (), (), (3,) -信号的尺寸(例如, s3 -长度数组 3).

  • 我的巴士 --轮胎的名字。

    信号和总线的名称中允许使用引号以外的任何字符(").

使用总线有两种方法:创建总线对象(具有特定数据)或设置总线类型(仅结构,没有数据),以便在块设置中使用它。 这两种方法在语法上有所不同—使用卷曲的方法。 {} 和圆 () 斯台普斯。

何时使用大括号和圆括号

语法 何时使用 例子:

BusSignal{…​}

描述参数化总线类型或使用数据创建总线对象

bus_obj=BusSignal{(:x,:y),元组{Int,Int}, ), (, :Coords}(x=10,y=20)

BusSignal(。..)

创建总线类型值(没有数据的结构)—在块设置中使用它

bus_type=BusSignal:x,:y),(Int,Int), ((), (, :Coords)

BusSignal{…​} 您直接设置类型参数,可以立即创建总线对象。

BusSignal(。..) 无需指定数据即可创建总线类型值。

下面显示了调用这些构造函数的签名和示例。

创建总线对象

以下结构构造函数用于创建总线对象 N.公共标志:

BusSignal{Names, Types, Dimensions, BusName}(x::NamedTuple{TupleNames, TupleTypes}) where {Names, Types, Dimensions, BusName, TupleNames, TupleTypes}

BusSignal{Names, Types, Dimensions, BusName}(; kwargs...) where {Names, Types, Dimensions, BusName}

BusSignal{Names, Types, Dimensions, BusName}(x::Tuple) where {Names, Types, Dimensions, BusName}

BusSignal{Names, Types, Dimensions, BusName}(varargs...) where {Names, Types, Dimensions, BusName}

例子::

# 通过NamedTuple
bus_obj = BusSignal{(:a, :b), Tuple{Int, Float64}, ((), (3,)), :MyBus}((a=1, b=[1.0, 2.0, 3.0]))

# 使用关键参数
bus_obj = BusSignal{(:x, :y), Tuple{Int, Int}, ((), ()), :Coords}(x=10, y=20)

# 通过元组
bus_obj = BusSignal{(:p, :q), Tuple{Float64, Float64}, ((), ()), :Pair}((1.5, 2.5))

# 通过varargs
bus_obj = BusSignal{(:m, :n), Tuple{Int, Int}, ((), ()), :Nums}(5, 6)

创建总线类型

以下方法用于创建总线类型(不带数据的结构):

BusSignal(names::Vector{Symbol}, types::Vector{DataType}, dims::Vector{<:Dims}, bus_name::Symbol=:CustomBusSignal)

BusSignal(names::NTuple{N, Symbol}, types::NTuple{N, DataType}, dims::NTuple{N, Dims}, bus_name::Symbol=:CustomBusSignal) where N

例子::

# 通过5磅
bus_type = BusSignal([:a, :b], [Int, Float64], [(), (3,)], :MyBus)

# 通过元组
bus_type=BusSignal((:x,:y),(Int,Int), ((), ()), :Coords)

# 嵌入式总线
bus_type=BusSignal((:a,:b,:c),(Int,Float64,NamedTuple{(:x, :y), Tuple{Int, Int}}), ((), (2,), ()))

获取有关巴士的信息

要提取有关总线参数的信息,可以使用以下函数:

get_names_types_dims(::Type{BusSignal{Names, Types, Dimensions, BusName}}) where {Names, Types, Dimensions, BusName}

get_bus_names(::Type{BusSignal{Names, Types, Dimensions, BusName}}) where {Names, Types, Dimensions, BusName}

get_bus_types(::Type{BusSignal{Names, Types, Dimensions, BusName}}) where {Names, Types, Dimensions, BusName}

get_bus_dimensions(::Type{BusSignal{Names, Types, Dimensions, BusName}}) where {Names, Types, Dimensions, BusName}

get_bus_name(::Type{BusSignal{Names, Types, Dimensions, BusName}}) where {Names, Types, Dimensions, BusName}

第一个函数(get_names_types_dims)一次返回所有总线参数,其余的允许您分别获取名称,类型,维度和总线名称。

使用函数的示例
bus_type = BusSignal{(:s1, :s2, :s3), Tuple{Int64, Float64, Int8}, ((), (2,), (2, 2))}
# 此类总线的实例可能如下所示:(s1=5,s2=[4.3,5.4],s3=Int8[1 2;3 4])

get_names_types_dims(but_type)
# 结果:((:s1,:s2,:s3),(Int64,Float64,Int8), ((), (2,), (2, 2))) - 一个由三个元组组成的元组,每个元组描述自己的总线类型参数

get_names(but_type)
# 结果:(:s1,:s2,:s3)

get_types(but_type)
# 结果:Tuple{Int64,Float64,Int8},即参数仍然以原始形式返回,有些不方便。 在下一个任务中,它将被修复,结果将是一个元组(Int64,Float64,Int8)

get_dimensions(but_type)
# 结果如何?: ((), (2,), (2, 2))

例如,方法 get_bus_signal_type 将命名元组转换为适当的总线类型。:

bus = (s1 = 5, s2 = [4.3, 5.4], s3 = (a = 4, b = 5.5))
bus_type = get_bus_signal_type(bus)
# bus_type等于BusSignal{(:s1,:s2,:s3),Tuple{Int64,Float64,BusSignal{(:a,:b),Tuple{Int64,Float64}, ((), ())}}, ((), (2,), ())}

还支持嵌套结构,其中一个总线的元素可以是另一个总线(上面的示例)。 要指定嵌入式总线的类型,必须在其元素的类型中指定嵌入式总线的完整类型。

尽管*Engee*中的总线对象被命名为元组,但为它们的创建提供了特殊的构造函数。 这些函数确保正在创建的对象与其总线类型声明匹配。

以下结构构造函数可用于创建总线对象 N.公共标志:

BusSignal{Names, Types, Dimensions, BusName}(x::NamedTuple{TupleNames, TupleTypes}) where {Names, Types, Dimensions, BusName, TupleNames, TupleTypes}
BusSignal{Names, Types, Dimensions, BusName}(; kwargs...) where {Names, Types, Dimensions, BusName}
BusSignal{Names, Types, Dimensions, BusName}(x::Tuple) where {Names, Types, Dimensions, BusName}
BusSignal{Names, Types, Dimensions, BusName}(varargs...) where {Names, Types, Dimensions, BusName}
创建总线对象的示例

首先,让我们创建数据应该对应的总线类型。:

bus_type = BusSignal((:s1, :s2), (Int64, Float64), ((), ()), :MyBus)

现在,您可以通过不同的方式创建此类型的总线对象。:

  • 具有命名元组:

    bus1 = BusSignal{(:s1, :s2), Tuple{Int64, Float64}, ((), ()), :MyBus}((s1 = 5, s2 = 6.4))

    传送来的 命名的,命名的,其结构完全对应于类型 bus_类型.

  • 带有命名参数:

    bus2 = BusSignal{(:s1, :s2), Tuple{Int64, Float64}, ((), ()), :MyBus}(s1 = 5, s2 = 6.4)

    总线结构是由命名参数创建的。 信号的名称和类型(中一, 中二)必须匹配参数 bus_类型.

  • 用一个常规元组:

    bus3 = BusSignal{(:s1, :s2), Tuple{Int64, Float64}, ((), ()), :MyBus}((5, 6.4))

    参数按类型指定的顺序传递。 bus_类型. 数量、类型和尺寸必须与总线参数匹配。

  • 通过varargs:

    bus4 = BusSignal{(:s1, :s2), Tuple{Int64, Float64}, ((), ()), :MyBus}(5, 6.4)

    值作为位置参数传递,而不打包成元组。

因此,在所有示例中创建了相同总线的对象。 :MyBus. 与此同时:

  • 巴士1巴士2 信号的名称、类型和大小必须严格匹配总线参数。

  • 巴士3巴士4 传递的参数的数量、类型和大小必须满足总线类型的要求。


对于块,如 Constant,可以通过参数*输出数据类型*指定总线类型的值,然后在*输出总线类型*中设置其结构。

user bus signal

例如,假设总线值(参数*常量值*, bus_值)等于 (a=10,b=[2.5,3.5],c=(x=1,y=2)),则其类型(输出总线类型)设置为:

BusSignal((:a,:b,:c),(Int,Float64,BusSignal((:x,:y),(Int,Int),((),()),:InnerBus)),((),(2,),()),:MyBus)

这里:

  • BusSignal((:a,:b,:c),…​) -总线信号的枚举: :a, :b, :c.

  • 第二个论点 (Int,Float64,BusSignal:x,:y),(Int,Int),((),(,:InnerBus)) -基本类型的字段:

    • A::Int -一个标量整数。

    • B::浮64 -基本元素类型;矢量不是在这里设置的,而是在Dims中设置的。

    • c -带有名称的嵌套总线 (:x,:y)、类别 (Int,Int) 和尺寸 ),(;她自己的名字 — :因内布斯.

  • 第三个论点 ), (2,), ( -尺寸(Dims):

    • a -标量 ().

    • b -长度为2的向量 (2,),因此,值应该是形式 [2.5, 3.5].

    • c -标量嵌入式总线 (). 其内部尺寸在描述中设置 :因内布斯.

  • 第四个论点 :MyBus -轮胎的象征性名称。