我的问题(在 Mathematica 中)指的是特定数组中给出的变量并以下列方式操作它们(作为示例):
输入:vars = {x,y,z},system =某些ODE,如x ^ 2 + 3 * x * y + ...等 (请注意,我实际上并没有创建变量x y和z)
目标:
为列表“var”中的变量赋值,目的是将这些值输入到ODE系统中。然后,一旦完成,清除数组变量中变量的值,使其处于原始形式{x,y,z}(而不是{x,1,3},其中y = 1和z = 3)。我想通过引用变量的位置元素来做到这一点(我的目的是不知道x,y和z是实际的变量)。
原因:我正在尝试编写一个程序,该程序可以包含用户定义的任意数量的变量和ODE。由于变量的数量和用于它们的实际字母是未知的,因此有必要对数组本身进行操作。
尝试:
固定数量的变量很容易。对于任意情况,我尝试过模块和块,但没有成功。请考虑以下代码:
Clear[x,y,z,vars,svars]
vars={x,y,z}
svars=Map[ToString,vars]
Module[{vars=vars,svars=svars},
Symbol[svars[[1]]]//Evaluate=1
]
然后vars = {1,y,z}而不是{x,y,z}。我已经使用列表,原子等进行了函数式编程。因此,对我来说,变量之后会发生变化,因为我已经改变了x而不是变量。但是,我不能让变量列表中的“x”保持为本地。当然我可以放入“x”本身,但这对于这个具体案例来说是特别的。我更喜欢这样的东西:
Clear[x,y,z,vars,svars]
vars={x,y,z}
svars=Map[ToString,vars]
Module[{vars=vars,svars=svars, vars[[1]]},
Symbol[svars[[1]]]//Evaluate=1
]
当然不起作用,因为vars [[1]]不是符号或符号的赋值。
其他可能性: 我找到了一个功能
assignToName[name_String, value_] :=
ToExpression[name, InputForm, Function[var, var = value, HoldAll]]
看起来很有希望。基本上name_String是变量的名称,value是它的新值。我试图这样做:
vars={x,y,z}
svars=Map[ToString,vars]
vars[[1]]=//Evaluate=1
assignToName[svars[[1]],svars[[1]]]
但是D[x^2, vars[[1]]]
之类的东西不起作用(x不是有效的变量)。
如果我遗失了某些东西,或者我可能会走错路,我愿意尝试其他事情。
感谢。
答案 0 :(得分:1)
我不能说我很好地跟踪了你的思路,所以这些碎片可能会帮助你回答你自己的问题,而不是一个连贯而完整的答案。但是为了回答你最后的“问题”,我认为你可能会走错路。
顺便说一句,请注意评估表达式
vars = {x,y,z}
实际上确实定义了这三个变量,尽管它没有为它们定义任何重写规则(例如值)。
给定多项式poly
,您可以使用函数Variables[poly]
提取其中的变量,所以类似
Variables[x^2+3*x*y]
应该返回
{x,y}
请注意,我写'应该'而不是因为我在这台机器上没有Mathematica所以我的语法可能有点不稳定。另请注意,您的示例ODE不是那种类型,但令我印象深刻的是,您可以编写一个包装器来将ODE操作为Variables
可以从中提取变量的形式。 Mathematica提供了很多其他功能,可以选择表达式并重新组合它们,遵循Variables
的路径。它通常允许在Lists
上使用在其他头部的表达式上定义的函数,所以它总是值得尝试一下。
有几种广泛适用的方法可以避免在Mathematica中设置变量值。例如,你可以写
x^2+3*x*y/.{x->2,y->3}
将评估为
22
但未设置x
和y
的值。这是使用(组)替换规则临时将值赋值给变量
避免为变量设置值的另一种方法是使用Modules
或Blocks
来定义函数,这两个函数都定义了自己的上下文。文档将告诉您关于这两者的所有信息以及它们之间的差异。
我不禁想到使用Symbol
,ToExpression
和ToString
的所有聪明技巧都有点不合时宜。花一些时间熟悉Mathematica的内置功能,然后再往下走,你可能会发现你不需要。
最后,用任何语言写作
等表达式vars=vars,svars=svars
会导致疯狂。它可能在语法上是正确的,你甚至可以在你第一次编写这样的代码时解密语义,但是在一个星期的时间里你会诅咒你年轻的自己写这个。