在Engee中使用变量
要创建新变量,请在 命令提示符 / 脚本编辑器
和赋值运算符 = (等号)分配所需的值。
*Engee*中的变量可以以不同的方式设置。 让我们考虑基于以下代码和三个变量的主要赋值方法’a'’b','c`:
a = 1 # 简单分配
a::Float64 = 1.0 # 具有显式数据类型指示的分配
b = 1 + 2 # 通过计算表达式进行赋值
c = b = 5 # 多重赋值
a,b,c = (10,20,30) # 解包元组
作为执行代码的结果,我们可以得到以下内容:
-
变量’a’被赋值'1'。 这是对变量的最简单的值赋值。;
-
变量’a’被赋值为`1`,但具有Float64(浮点)数据类型的显式指示;现在它的实际值是`1.0`;
-
变量b被赋值表达式'1+2’的结果,即'3`;
-
值'5’被分配给变量b和c;
-
来自元组`(10,20,30)`的值被解压缩并分别分配给变量a、b和c。;
请注意,*Engee*中的变量可以是标量,矢量和矩阵。:
-
标量-具有单个数据值。 它使用整数和实数,逻辑值和字符串形式的变量进行设置。 例如:
v = 1 # 整数,Int64数据类型 v = 1.0 # 实数,Float64数据类型 v = true # 布尔值,数据类型Bool v = "a" # 字符串,数据类型字符串
-
向量是可以表示为一维数组的元素的有序集合。 它使用包含整数或实数、布尔值或字符串的变量进行设置。 例如:
v = [1, 2, 3] # 整数的向量,数据类型向量{Int64} v = [1.0, 2.0, 3.0] # 实数向量,数据类型向量{Float64} v = [true, false] # 逻辑值的向量,数据类型向量{Bool} v = ["a", "b", "与"] # 字符串的向量,数据类型向量{String}
-
*矩阵*是由行和列组成的二维数据数组。 矩阵可用于同时表示多个变量。 矩阵的每个元素都可以是标量值,例如整数、实数、布尔值或字符串。 例如:
v = [1 2 3] # 整数矩阵,数据类型矩阵{Int64} v = [1.0 2.0 3.0] # 实数矩阵,数据类型矩阵{Float64} v = [true false] # 逻辑值矩阵,数据类型矩阵{Bool} v = ["a" "b" "与"] # 字符串的矩阵,数据类型矩阵{String} v = ([1 2 3; 4 5 6; 7 8 9]) # 多行矩阵,数据类型矩阵{Int64}
要创建维度大于3的数组,可以使用值’undef',表示数组尚未初始化。 这种数组的元素可以包含任意数据。 让我们选择两个结构中的一个来创建一个数组。:
Array{T}(undef, dims)
Array{T,N}(undef, dims)
哪里:
-
'T’是数组的数据类型。
-
'N’是数组的维数。 它可以明确设置,也可以由"dims"的长度和数量确定。 如果明确指定,它必须匹配`dims’的长度和数量。
-
'dims’是一个元组或一系列整数参数,对应于每个维度中的长度。
例如:
A = Array{Float64, 3}(undef, 2, 3, 4)
# 或
A = Array{Float64}(undef, 2, 3, 4) # 我们得到一个三维数组,其维数2*3*4 ,数据类型为Float64,维度自动设置
数组创建结果的输出
2×3×4 Array{Float64, 3}:
[:, :, 1] =
6.94241e-310 6.94267e-310 6.94267e-310
6.94272e-310 6.94267e-310 6.94267e-310
[:, :, 2] =
6.94267e-310 6.94267e-310 6.94267e-310
6.94267e-310 6.94267e-310 6.94267e-310
[:, :, 3] =
6.94267e-310 6.94267e-310 6.94267e-310
6.94267e-310 6.94267e-310 6.94267e-310
[:, :, 4] =
6.94267e-310 6.94267e-310 6.94267e-310
6.94267e-310 6.94267e-310 6.94267e-310
键入变量
*Engee*支持显式和隐式变量类型,这意味着变量的数据类型可以显式指定(强制分配)或根据程序执行期间的内容确定。 数据的主要类型包括:
-
Integer-表示整数,例如`1`,
100
,-1
. -
Float-表示实数(浮点),例如'1.0'’-3.14'。
-
String-表示用引号括起来的文本,例如'"Hello,world!"`.
-
Array-表示一组有序的元素,例如,
[1, 2, 3]
.
请考虑在以下示例中显式指定变量的数据类型:
在这里,Int64数据类型被明确地设置为变量`z`,它只包含整数。 试图将实数`3.14’分配给变量’z`(对应于数据类型Float64')导致错误(InexactError:Int64)。
尝试将不适当的数据类型分配给变量会导致错误并在 可变窗口 err=没什么 |
元组
Engee中的元组是一种有序且不可变的数据结构。 元组是使用括号`()`和逗号创建的。
元组使用参数化数据类型`MyType’来描述。{ParamType1,ParamType2,ParamType3,。..}'并以直序列表示元素的数据类型。 在这种情况下,元组元素可以具有不同的数据类型。 例如,元组可以包含整数、实数和带引号的文本。 考虑这样的元组:
tuple=(1,3.14,"你好,世界!")
在这种情况下,元组具有数据类型Tuple(Int64,Float64,String)。
元组可以是常规的,也可以是命名的:
-
常规元组是一种有序且不可变的数据结构。 常规元组的每个元素都可以是任何数据类型。 其元素按一定顺序排列。 元素通过它们的索引进行访问。 使用示例考虑这样的元组:
x=(1,3.14,"你好,世界!") x[3]
在示例中,变量’x’包含三个值-
1','3.14’和’Hello,world!'. 序数索引对应于这些值。 `[1]
,[2]
和`[3]'分别。 使用变量’x',其中包含常规元组的值和索引`[3],我们得到了变量的具体值—`Hello,World!
,而不是整个元组。图片:变量-article/special-variables-article-2-3_cn.png[]
-
命名元组是一种特殊类型的元组,类似于常规元组,但其中每个元素都有自己的名称。 命名元组也可以通过元素的名称访问元素,而不是像常规元组那样通过索引访问元素。 命名元组的示例:
x=(a=1,b=3.14,c="你好,世界!") 打印(x.a) 打印(x.b) 打印(x.c) 打印(x[1]) 打印(x[2]) 打印(x[3])
图片:变量-article/special-variables-article-2-4_cn.png[]
这个例子不仅支持通过索引访问元组元素(如通常的元组`[1],。..,[n]`),而且还通过变量名—'x.a`’x.b',`x.c’等。
由于元组是一个不可变的结构,其元素的顺序很重要并被保留。 元组的不变性允许您处理多个赋值。
*多重赋值*是一项功能,允许您使用元组同时为多个变量赋值。 此功能避免了临时变量并提高了代码的可读性。 例如:
tuple=(1,3.14,"你好,世界!") a,b,c=元组
这里创建了一个包含三个元素的元组。:
-
整数为'1'。
-
实数是`3.14'。
-
字符串`"你好,世界!"`.
接下来,元组值分别并行分配给三个变量’a`’b’和’c'。 执行代码后,变量’a’将包含值'1`,变量`b`将包含`3.14`,变量`c`将包含字符串'"Hello,world!"`. 这样,您可以在同一时间分配多个变量,而无需使用字符串插值显式指定元组值。:
info = ("Ilya", 25, "Engineer")
name, age, occupation = info
println("Name: $name, Age: $age, Occupation: $occupation")
在这段代码中,元组用于存储信息,并行赋值用于将元组值解压缩到单独的变量中。 然后使用文字`$'进行字符串插值以输出有关此人的信息。:
-
'info=("Ilya",25,"Engineer")
—创建一个包含三个元素的`info`元组:字符串`"Ilya"
(名称),整数`25`(年龄)和字符串`"Engineer"`(职业)。 -
'name,age,occupation=info'—使用并行赋值,元组值被解压缩为三个变量:
name
,age`和`occupation'。 现在name变量包含值'"Ilya"
,age包含整数`25`,occupation包含职业`"Engineer"`。 -
释放("Name:$姓名、年龄:$年龄、职业:$占领")'—一串出采用字符串插入(使用
$name`,$年龄
,并`$占领`插入变量的数值进入串)。 作为执行这行代码的结果,它将被输出:
Name: Ilya, Age: 25, Occupation: Engineer
因此,代码创建一个包含有关人员信息的元组,然后将此元组解压缩为单独的变量,以便更轻松地访问数据,并将信息输出到脚本编辑器或命令行。
视野范围
我们所说的代码块是指包含在句法结构"函数"或"let"中的一段代码。.. 结束'。 在这样的代码块中,您可以声明局部变量,这些变量仅在该块中可见,并且不会与代码其他部分的变量(例如,全局变量)冲突。 *Scope*定义代码中可以使用变量的位置。 所以,有局部变量和全局变量。: |
-
*局部(内部)变量—-如果变量在其父元素中声明并定义,例如函数,对象,代码块(在其中定义)等,则将其视为局部变量。 局部变量仅在定义它们的范围内可见,并且在其外部不可访问。 我们以一个局部变量为例:
function example_function() x = 10 println(x) end
这里,'function example_function()`定义了一个名为`example_function`的函数,该函数在局部作用域中包含一个局部变量`x'。
使用命令`example_function()对函数的进一步调用输出变量`x`的值等于'10
:
example_function()
代码执行还在*Engee*变量窗口中创建了一个具有函数数据类型的`example-function`变量。 |
函数执行后,局部变量’x`超出作用域,在函数之外变得不可访问。 这意味着变量只存在于定义它的块中。
让我们尝试使用以下代码调用局部作用域之外的变量:
println(x)
作为执行代码的结果,我们收到一个错误,即变量`x`未定义。 我们得出结论,局部变量仅限于代码块内部的范围(在其中定义它),并且不是从外部确定的。
外部代码无权访问局部变量,并返回未定义局部变量的错误。 |
全局(外部)变量-如果变量在具有局部作用域的函数、循环和代码块之外定义,则将其视为全局变量。 全局变量可以从代码的任何部分访问,并且位于全局作用域中,默认情况下,全局作用域是主模块。 在主模块内部,您可以定义将具有自己的全局变量的子模块。 我们以一个全局变量为例:
global_var = 20
function example_function()
println(global_var)
end
此代码设置全局变量’global_var’并定义函数’example_function(’。 'example_function()'输出全局变量的值。 要输出函数的结果,请输入以下代码:
example_function()
println(global_var)# 您可以在函数之外使用全局变量。
调用’example_function()后,全局变量`global_var`的值设置为`20
。 Println函数在同一时间输出两个变量值,一次来自函数,另一次来自函数外部。
当局部作用域中存在具有相同名称的变量时,由于阴影问题,使用这样的变量可能会很困难。 |
*阴影变量*是在特定范围内(例如,在函数或代码块内)使用与全局范围中同名的变量的情况。 结果,作用域内的变量"遮蔽"(复盖)外部作用域同名的变量。
指定具有相同名称的变量时要小心。 由于阴影,在有限范围内的变量可能具有与在程序的其他部分中具有相同名称的变量不同的值或类型。 |
例如,考虑创建两个具有相同名称和值且没有阴影的变量的代码:
global_var = 10 # 创建全局变量
function example_function()
global_var = 20 # 创建一个与全局变量同名的局部变量(在函数内部)
println(global_var) # 将使用函数内部的局部变量。
end
example_function() # 函数调用
println(global_var) # 全局变量在函数内部没有被改变,所以它的值是输出的。
在函数内部创建一个局部变量,其名称与全局变量相同。 这不会改变全局变量,而是创建一个新的局部变量,仅在函数内部可见。 结果,显示两个变量的值,分别等于`20`(全局)和`10`(局部)。 因此,在不同的作用域中创建变量有助于避免复盖具有相同名称的变量的问题。
仿真环境中的变量
变量作为模型参数
在*Engee*中,变量可以设置为模型参数。 考虑以下示例:
engee.create("model")
使用方法 创建已在*Engee*命名模型中创建模型。 接下来,分配变量:
m = engee.gcm()
通过方法 gcm我们访问创建的模型并返回表示此模型的对象(在我们的例子中,GCM,获取当前模型,获取当前模型)。 生成的对象被分配给变量’m'。
接下来,我们将建模参数替换为 set_param!:
engee.set_param!(m, "name" => "Tsit5", "type" => "variable-step")
求解器的参数及其步长在代码中从常量变为变量。
使用该方法查看模型参数是否已更改 gcm:
engee.get_param("model")
由于`m`变量,模型参数已更改为新参数:
接下来,使用方法 运行让我们通过一个变量来运行模型的模拟:
engee.run("m")
模拟成功后,将具有对象属性(变量`m`)的*Engee*模型保存到文件浏览器中的指定路径。 在我们的例子中:
engee.save(m,"/user/start/examples/base_simulation/command_control/model.engee"; force=true)
如果具有该名称的文件已经存在(在我们的例子中,model。engee),`force=true’选项将用`m`变量的数据复盖模型,而无需请求确认。 如果在保存模型时需要复盖现有文件,这很有用。
*Engee*模型只有在保存后才会出现在文件浏览器中。 保存模型将允许您将来使用它并应用所有功能。 文件浏览器 ![]() |
本文还介绍了在建模环境中使用变量的更多可能性。 软件控制建模.
变量作为块参数
您可以在没有编程方法的情况下控制块参数,只需将单个参数值设置为变量即可。 让我们来看一个例子与文章中提出的模型。 Engee中仿真结果的软件处理. 该模型由块 正弦波 和 终结者,对它们之间的信号使能记录:
座 正弦波 -模型中唯一可以调整参数的块。 左键单击该块,并根据绘图设置每个参数的变量。:
设置块值的变量名称后,我们将为每个变量赋值。:
a_var = 1 # 幅度变为等于1
b_var = 2 # 偏置变为等于2
f_var = 3 # 频率变为3
p_var = 1 # 相位变为等于1
s_var = 1 # 采样时间变为1
让我们通过将模型名称设置为一个单独的变量(在文章"m"前面)并使用"engee"来运行模型的模拟。运行’方法,或通过按钮手动 运行模型 . 该图将显示该块 正弦波 我改变了我的参数,模拟进行正确。:
如果块具有影响特定参数的依赖关系,则将变量设置为块参数非常有用。:
a_var = (2*f_var) # 振幅变为6
b_var = (6/f_var) # 偏置变为等于2
f_var = 3 # 频率等于3
p_var = (1 + f_var) # 相变为4
s_var = 1 # 采样时间为1
代数表达式,包括那些带有变量的表达式,可以用作块参数。:
输出
变量’a_var’等于'6`,那么乘以`3`后的幅度将等于`18',让我们在仿真结果的曲线图上看到这一点。:
使用不同的变量值集(存储在不同的脚本中)允许您对具有相同结构但不同参数的对象进行建模。 |
保存模拟结果
您可以使用"simout"变量将模型的仿真结果保存到*Engee*RAM中。 该变量是在模型仿真完成后,当记录模型信号被启用时自动创建的。 让我们看一下上一段中的模型示例,但使用之前创建的变量’m'。
模型仿真完成后,文件浏览器中会出现`simout’变量,存储仿真结果。 将数据从"simout"卸载到"m"变量:
m = collect(simout["newmodel_1/Sine Wave.1"])
我们使用绘图库和变量可视化仿真结果:
using Plots # 连接绘图模块
plot(m.time, m.value) # 从变量m输出时间和值
代码完成后,我们会看到如下图:
有关保存模拟结果的过程的信息在关于 Engee中仿真结果的软件处理.