使用Genie可视化线性算子的动作
本文致力于应用GenieFramework开发一个交互式web应用程序,演示线性算子的动作。 作为一个例子,我们考虑使用2x2矩阵表示圆的一组点的变换。 Stipple和PlotlyBase包用于实现。 文本详细描述了代码的关键元素,并在相关片段之后进行了解释。 特别注意使用响应式宏的理由 @in 和 @out 控制矩阵的元素(m11, m12, m21, m22),以及使用自定义类型的可能性,例如 mutable struct,基于点画文档。
应用概念
附录说明了2x2矩阵作为线性算子对二维点集的影响。 最初,这些点形成半径为1的圆,用户可以使用滑块更改矩阵的元素,观察拉伸,压缩或旋转等变换的影响。 这种方法通过提供学习线性代数的交互式工具具有教育潜力。
从一组点创建一个圆
``'茱莉亚
使用GenieFramework,点画,点画。ReactiveTools,StippleUI,PlotlyBase
const circ_range=-1:0.05:1
const circle=[[i,j]for i in circ_range for j in circ_range if i2+j2<=1]
const x_axis_points=findall(x->x[1]==0&&x[2]>=0,圆)
const y_axis_points=findall(x->x[2]==0&&x[1]>=0,圆)
const circle_matrix=Base。堆叠(圆形)
此片段形成可视化的源数据。 范围被定义 `circ_range` -1到1,x和y坐标以0.05为增量。 使用列表包含生成坐标对。 `[i, j]` 由圆方程过滤 `i^2 + j^2 <= 1`,这给出了一组近似半径为1的圆的点。 变量 `x_axis_points` 和 `y_axis_points` 它们分别包含位于Y轴和X轴正部分上的点的索引,以突出显示基向量。 功能 `Base.stack` 将坐标列表转换为矩阵,其中第一行是x坐标,第二行是y坐标。 常量(`const`)用于不可变的数据。 离散步骤导致圆的一些逐步轮廓,但该方法实现简单。
### 开发图形转换函数
``'茱莉亚
函数create_plot_data(m11::Float64,m12::Float64,m21::Float64,m22::Float64)
变换=[m11m12;m21m22]*circle_matrix
[
散点(x=变换[1,:],y=变换[2,:],模式="标记",名称="圆点"),
scatter(x=transformed[1,x_axis_points],y=transformed[2,x_axis_points],name="Y轴"),
scatter(x=transformed[1,y_axis_points],y=transformed[2,y_axis_points],name="X轴",aspect_ratio=:equal)
]
结束
const initial_plot_data=create_plot_data(1.0,0.0,0.0,1.0)
功能 create_plot_data 负责转换点并为图形准备数据。 接受四个参数-2x2矩阵的元素(m11, m12, m21, m22). 执行矩阵乘法 circle_matrix,获取点的新坐标 transformed. 返回三个对象的数组 scatter:圆的所有点,Y轴上的点和X轴上的点。 参数 aspect_ratio=:equal 提供轴的均匀比例。 常数 initial_plot_data 用不改变圆的单位矩阵设置图形的初始状态。
配置图形布局
``'茱莉亚
const plot_layout=PlotlyBase。设计图(
title="线性圆变换",
xaxis=attr(title="X轴",showgrid=true,range=[-2,2]),
yaxis=attr(title="Y轴",showgrid=true,range=[-2,2]),
宽度=600,高度=550
)
该片段使用以下方法定义图形布局 `PlotlyBase.Layout`. 设置了标题、轴标签、网格和值范围从-2到2。 图形尺寸是固定的:宽600像素,高550像素。 布局声明为常量,因为它在应用程序运行期间不会更改。
### 确保反应性
``'茱莉亚
@应用程序开始
@在m11=1.0
@在m12=0.0
@在m21=0.0
@在m22=1.0
@out plot_data=initial_plot_data
@out plot_layout=plot_layout
@onchange m11,m12,m21,m22开始
plot_data=create_plot_data(m11,m12,m21,m22)
结束
结束
座 @app 定义响应式应用程序模型。 宏 @in 将矩阵元素声明为具有对应于单位矩阵的初始值的输入变量。 宏 @out 设置输出数据: plot_data 对于时间表和 plot_layout 为布局。 宏 @onchange 跟踪值的变化 m11, m12, m21, m22 和原因 create_plot_data 要更新 plot_data.
自定义用户界面
``'茱莉亚
功能ui()
滑块=[row([column([h6("m(j)={m(j)}}"),滑块(-2:0.1:2,符号("m(j)"),color="purple")],size=3)for j in1:2])for i in1:2]
[
行([
列(滑块,大小=4),
列(plot(:plot_data,layout=:plot_layout))
],尺寸=3)
]
结束
@页("/",ui)
功能 `ui` 形成接口。 变量 `sliders` 创建一个由两行组成的数组,每行包含两个带有标题的滑块(`m11`, `m12`, `m21`, `m22`). 滑块的范围从-2到2,增量为0.1。 接口由行(`row`)有两列:左边的滑块,右边的图形,通过 `plot`. 宏 `@page` 将接口绑定到根路由"/"。
### 申请的需要 `@in` 和 `@out`
#### 点画中的反应性
Stipple实现了响应式模型,确保数据和接口的同步。 宏 `@in` 和 `@out` 将元素集成到此模型中。 `@in` 将数据绑定到界面元素(滑块),允许用户更改它们。 `@out` 状态改变时更新输出数据(图形)。 使用标准广告时,例如 `m11 = 1.0` 接口元素失去与值的连接,不包括它们的修改; `@onchange` 它没有响应,因为点画不跟踪这些数据;交互性被破坏,因为值没有传递给JavaScript。
#### 自定义类型的替代方案
根据Stipple文档([Types of variables in Stipple](https://engee.com/helpcenter/stable/ru/julia/Stipple/reference/reactivity.html#типы-переменных)),有可能使用 `mutable struct` 作为反应变量:
``'茱莉亚
可变结构MatrixState
m11::浮64
m12::浮64
m21::浮64
m22::浮64
结束
@应用程序开始
@在状态=MatrixState(1.0,0.0,0.0,1.0)
@out plot_data=initial_plot_data
@out plot_layout=plot_layout
@交换状态开始
plot_data=create_plot_data(状态。m11,州。m12,州。m21,州。m22)
结束
结束
结构 MatrixState 通过 @in,这允许Stipple跟踪其字段的变化。 但是,在此应用中,优先考虑单个变量(@in m11 等。),因为这通过单独的滑块简化了矩阵元素的管理。
没有 @in 和 @out 矩阵元素在Julia中保持隔离,而不与界面交互。 响应式宏或 mutable struct 与 @in/@out 它们提供必要的通信,方法的选择取决于数据结构和接口要求。
要启动应用程序,我们将使用[以前的статьям]中已经熟悉的应用程序(https://engee.com/community/ru/catalogs/projects/tablo-aeroporta-s-dinamicheskoi-tablitsei-v-genieframework )由建筑:
using Markdown
cd(@__DIR__)
app_url = string(engee.genie.start(string(@__DIR__,"/app.jl")))
Markdown.parse(match(r"'(https?://[^']+)'",app_url)[1])
结论
本文演示了如何使用GenieFramework创建一个可视化线性算子动作的交互式应用程序。 响应式宏 @in 和 @out 我们提供了接口和逻辑之间的链接,以及使用的可能性 mutable struct 为复杂场景提供灵活性。 该应用程序突出了Genie开发教育工具的能力。---