Struct 使用结构内部操纵来帮助管理控制变量,如何初始化
我不知道如何在Mathematica中初始化一个结构,以便与操纵一起使用,以帮助我更好地组织我拥有的许多控制变量 我将举几个例子来说明这个问题 以下是最基本的操作: 方法1Struct 使用结构内部操纵来帮助管理控制变量,如何初始化,struct,wolfram-mathematica,initialization,Struct,Wolfram Mathematica,Initialization,我不知道如何在Mathematica中初始化一个结构,以便与操纵一起使用,以帮助我更好地组织我拥有的许多控制变量 我将举几个例子来说明这个问题 以下是最基本的操作: 方法1 Clear["Global`*"] Manipulate[process[a, b], {{a, 1, "a"}, -10, 10, 1}, {{b, 2, "b"}, -10, 10, 1}, Initialization :> { process[a_, b_] := Module[{}, R
Clear["Global`*"]
Manipulate[process[a, b],
{{a, 1, "a"}, -10, 10, 1},
{{b, 2, "b"}, -10, 10, 1},
Initialization :>
{
process[a_, b_] := Module[{}, Row[{"a=", a, " b=", b}]]
}
]
在我正在编写的演示中,我有更多的控件。有些函数(如上面调用的process[]函数)最终不得不使用15个或更多参数进行调用,这使我很难维护。(对此我别无选择,真的无法考虑)
所以,我尝试使用一个结构来收集这些变量。与此相关的问题是什么
所以,接下来我尝试了下面的方法:(我知道在Mathematica中选择构造结构不是最好的,但我想先看看它是否有效)
方法2
Clear["Global`*"]
Manipulate[process[myData],
{{myData["a"], 1, "a"}, -10, 10, 1},
{{myData["b"], 1, "b"}, -10, 10, 1},
Initialization :>
{
process[myData_] :=
Module[{}, Row[{"a=", myData["a"], " b=", myData["b"]}]]
}
]
但上述措施并不奏效。我明白了
Manipulate::vsform does not have the correct form for a variable specification
所以,我想,好吧,让我自己填写这个结构,在调用process[]函数之前,我这样做了:
方法3
Clear["Global`*"]
Manipulate[
(
myData["a"] = a;
myData["b"] = b;
process[myData]
),
{{a, 1, "a"}, -10, 10, 1},
{{b, 1, "b"}, -10, 10, 1},
Initialization :>
{
process[myData_] :=
Module[{}, Row[{"a=", myData["a"], " b=", myData["b"]}]]
}
]
这是有效的。好的,但是现在,因为我实际上是使用Leonid宏方法来设置我的控件,这里解释
现在我尝试了上面的方法(2),使用宏方法,它现在可以工作了!但仍然存在的问题是如何初始化struct字段。下面是上面的方法(2),使用宏
方法(2)使用Leonid宏方法设置控件
Clear["Global`*"]
Manipulate[process[myData],
(*-- define 2 control variables, using the macro method --*)
Evaluate@With[{s1 = Function[{struct},
Grid[{
{Manipulator[Dynamic[struct["a"]], {-20, 20, 0.1}]},
{Manipulator[Dynamic[struct["b"]], {-2, 2, .5}]}
}],
HoldAll]
},
s1[myData]
],
Initialization :>
{
process[struct_] := Module[{},
Text[Grid[{
{"a=", struct["a"]},
{" b=", struct["b"]}
}]]
]
}
]
上述方法可以工作,但myData没有初始化。这就是我的问题。我需要初始化它,以便屏幕上的初始显示将有一些正确的值
我可以使用Initialization部分来实现这一点,但现在myData将变为全局数据,这可能会在我稍后创建操纵快照时引发问题,因为全局数据将在快照之间共享:
上述方法(2),使用全局部分初始化
Clear["Global`*"]
Manipulate[process[myData],
(*-- define 2 control variables, using the macro method --*)
Evaluate@With[{s1 = Function[{struct},
Grid[{
{Manipulator[Dynamic[struct["a"]], {-20, 20, 0.1}]},
{Manipulator[Dynamic[struct["b"]], {-2, 2, .5}]}
}],
HoldAll]
},
s1[myData]
],
Initialization :>
{
myData["a"] = 1; (* now OK, but mydata is global *)
myData["b"] = 1;
process[struct_] := Module[{},
Text[Grid[{
{"a=", struct["a"]},
{" b=", struct["b"]}
}]]
]
}
]
当我试图在操纵中初始化我的数据时,它不起作用,可能有什么诀窍可以做到这一点
方法(2),尝试使用无控件初始化内部操纵
Clear["Global`*"]
Manipulate[process[myData],
(*-- define 2 control variables, using the macro method --*)
Evaluate@With[{s1 = Function[{struct},
Grid[{
{Manipulator[Dynamic[struct["a"]], {-20, 20, 0.1}]},
{Manipulator[Dynamic[struct["b"]], {-2, 2, .5}]}
}],
HoldAll]
},
s1[myData]
],
{{myData["a"], 1}, None}, (*invalid syntax*)
{{myData["b"], 1}, None},
Initialization :>
{
process[struct_] := Module[{},
Text[Grid[{
{"a=", struct["a"]},
{" b=", struct["b"]}
}]]
]
}
]
所以,我的问题是:如何在上面的方法(2)中初始化myData,但不使其全局化
我只是想补充一点,这是一个演示,所以规则是它必须以操纵[…]开始。外面没有模块。所有东西都必须在里面[…]
谢谢
更新:
我选择了上面(3)中的模式,从一开始我自己填写结构
它似乎工作得很好,并且使对我现在拥有的许多函数的调用变得更容易,因为参数的数量大大减少了(我用20个参数调用了函数!),现在它减少到了5个参数,因为我将相关的控制变量“打包”到一个结构中,现在更容易使用)。这不是一个完美的解决方案,但至少它帮助我更容易使用代码
这就是“模式”现在的样子:
Manipulate[
Module[{myData},
(*fill in the struct *)
myData["a"] = a;
myData["b"] = b;
myData["c"] = c;
process[myData]
],
(*-- define control macro --*)
Evaluate@With[{s1 = Function[{var},
Manipulator[Dynamic[var], {-20, 20, 0.1}], HoldAll]
},
Column[{s1[a], s1[b], s1[c]}]
],
(*initialize fields of the struct, or the control variables*)
{{a, 1}, None},
{{b, 2}, None},
{{c, 3}, None},
Initialization :>
{
process[myData_] := Module[{},
Text[Grid[{
{"a=", myData["a"]},
{" b=", myData["b"]},
{" c=", myData["c"]}
}]]
]
}
]
我认为Mathematica需要一个真正的结构/记录来帮助人们在更大的程序中组织变量 您是否考虑过使用规则来传递参数?解决了丢失数据和排序的问题,而且不会让指定的变量凌乱您的命名空间。