Struct 使用结构内部操纵来帮助管理控制变量,如何初始化

Struct 使用结构内部操纵来帮助管理控制变量,如何初始化,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

我不知道如何在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[{}, 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需要一个真正的结构/记录来帮助人们在更大的程序中组织变量

您是否考虑过使用规则来传递参数?解决了丢失数据和排序的问题,而且不会让指定的变量凌乱您的命名空间。