Wolfram mathematica 下标变量

Wolfram mathematica 下标变量,wolfram-mathematica,Wolfram Mathematica,有没有办法强迫Mathematica独立于未订阅变量来处理订阅变量?更具体地说。比如,我有以下定义: Subscript[b, 1] = {{1, 2}} Subscript[b, 2] = {{3, 4}} b = Join[Subscript[b, 1], Subscript[b, 2]] 现在当我使用 Subscript[b, 1] Mathematica将用 Subscript[{{1, 2}, {3, 4}},1] 当我希望它们是三个独立的值时,更改b不会影响下标[b,…]。有

有没有办法强迫Mathematica独立于未订阅变量来处理订阅变量?更具体地说。比如,我有以下定义:

Subscript[b, 1] = {{1, 2}}
Subscript[b, 2] = {{3, 4}}
b = Join[Subscript[b, 1], Subscript[b, 2]]
现在当我使用

Subscript[b, 1] 
Mathematica将用

Subscript[{{1, 2}, {3, 4}},1]

当我希望它们是三个独立的值时,更改b不会影响下标[b,…]。有可能吗?

符号是
b
,而不是
下标[b,u]

定义时:

Subscript[b, 1] = {{1, 2}}
类似于为任何函数f定义一个downvalue。喜欢做:

f[b, 2] = {{1, 2}} 
那么,你正在做的是

f[b, 1] = {{1, 2}} 
f[b, 2] = {{3, 4}} 
b = Join[f[b, 1], f[b, 2]]
这当然会给符号b赋值

现在呢

f[b, 1]
->f[{{1, 2}, {3, 4}}, 1]
正如所料

所以,我想简短的答案是否定的。至少不是直截了当的

编辑


虽然上述情况是正确的(我相信),但我不知道Notation包有一种绕过默认行为的方法。其他答案包含详细信息。

可以使用来自同名包的符号

不要介意下面的代码,您不知道行框结构。只需使用调色板模板,在左侧键入下标[b,j],在右侧键入bb[j]。所以“实际”变量现在是bb[1]等,您可以安全地分配给b

Needs["Notation`"]

Notation[ParsedBoxWrapper[
  RowBox[{"Subscript", "[", 
   RowBox[{"b", ",", "j_"}], "]"}]] \[DoubleLongRightArrow] 
   ParsedBoxWrapper[
  RowBox[{"bb", "[", "j_", "]"}]]]

Subscript[b, 1] = {{1, 2}}
Subscript[b, 2] = {{3, 4}}
b = Join[Subscript[b, 1], Subscript[b, 2]]
Out[3]={{1,2}

Out[4]={3,4}

Out[5]={1,2},{3,4}

Subscript[b, 1]
Out[6]={{1,2}

你可能会得到更准确的回复,这是我第一次弄乱了这个符号包

丹尼尔·利奇布劳
Wolfram Research在回答之前的SO问题时提到他

希望用符号来强制MMA 将下标变量视为符号的步骤

这就是这个问题的本质所在

指出使用
符号

Needs["Notation`"];
Symbolize[ParsedBoxWrapper[SubscriptBox["_", "_"]]]
其中(如Daniel的回答中所示)不要太担心上面的
结构,因为您可以使用
表示法
调色板更简单地输入这些内容

检查所有功能是否正常工作:

In[3]:= Subscript[a, b]//Head
        a = 1
        Subscript[a, b]

Out[3]= Symbol
Out[4]= 1
Out[5]= Subscript[a, b]


注意:上述所有代码都已被删除,因此排版
下标框
s已转换为输入格式
下标
s。但是,
符号
在框级别工作,因此测试需要转换回其二维形式。要执行此操作,请选择代码(或单元格),然后使用
单元格
菜单或
Ctrl-Shift-N
。包含上述所有代码的笔记本应该如下所示

如果您不想使用
符号
包(请参阅和答案),而是想复制
符号
的行为,那么它会变得有点棘手

读了这篇文章后,我曾尝试过这样做,但遇到了麻烦,于是放弃了。我将把代码放在这里作为社区wiki,这样其他人就可以尝试完成它

首先,您希望截取输入的下标框结构,并将其解释为“唯一”符号。下面的代码

MakeExpression[SubscriptBox[x_String, i_String], form_] := 
 With[{name = StringJoin[{"$sUbsCript$", x, "$SPLIT$", i}]}, 
  Hold[Symbol[name]]]
使输入的
x_i
成为名为
的符号“$sUbsCript$x$SPLIT$i”
。不保证是唯一的符号名称。。。但这将是一个相当不寻常的! 注:
1) 此代码不会拾取以
完整格式编写的下标

2) 只有当下标的两个部分都是“简单的”时,这个定义才会触发-没有空格、括号、运算符等

接下来,因为这个符号名称太难看了,所以这里有一个可选的东西,可以让它在被要求时变得更好(这可能应该更改)

最后,我们希望这个下标符号能够很好地打印出来。通常我们会使用
makebox
定义来实现这一点,但在这种情况下我们不能,因为
Symbol
具有属性
Locked
:(
相反,我们将侵入一个
$PrePrint
,找到这些疯狂命名的符号,并将它们写回下标:

$PrePrint = (# /. s_Symbol :> 
  Block[{$inSymbolName = True}, 
    If[StringMatchQ[SymbolName[s], "$sUbsCript$" ~~ __], 
       Subscript@@StringSplit[StringDrop[SymbolName[s], 11], "$SPLIT$"], s]]
   )&;
最后,所有这些都会失败的地方是,如果你试图给一个下标符号分配一些东西。我还没有尝试过解决这个问题

一些测试-请注意,您必须将
下标
s转换为实际框,代码才能正常工作。请通过转换为标准格式来完成此操作:Ctrl-Shift-N

symbs = {x, yy, Subscript[a, 3], Subscript[long, name]};

In[10]:= Head/@symbs
Out[10]= {Symbol, Symbol, Symbol, Symbol}

In[11]:= SymbolName/@symbs
Out[11]= {x, yy, a3, longname}

In[12]:= Block[{$inSymbolName=True},SymbolName/@symbs]
Out[12]= {x, yy, $sUbsCript$a$SPLIT$3, $sUbsCript$long$SPLIT$name}

In[13]:= f[x_Symbol] := Characters[SymbolName[x]]
In[14]:= {f["acb"], f[abc], f[Subscript[xx, 2]]}
Out[14]= {f["acb"], {"a", "b", "c"}, {"x", "x", "2"}}
如果
Set
SetDelayed
生成
OwnValues
,则它不适用于
设置
SetDelayed
,也不适用于
信息

In[15]:= Subscript[x, y] = 5
         ??Subscript[x, y]
During evaluation of In[4]:= Set::write: Tag Symbol in Symbol[$sUbsCript$x$SPLIT$y] is Protected. >>
Out[15]= 5
During evaluation of In[4]:= Information::nomatch: No symbol matching Symbol["$sUbsCript$x$SPLIT$y"] found. >>
它与产生
DownValues

In[17]:= Subscript[x, z][z_]:=z^2
In[18]:= Subscript[x, z][2]
Out[18]= 4

In[19]:= ?Subscript[x, z]
Information::nomatch: No symbol matching Symbol["$sUbsCript$x$SPLIT$z"] found. >>

下面是我用来做这件事的一些代码。它应该也适用于您:

SubscriptToProxySymbol[_] = Null;
MakeExpression[SubscriptBox[a_, b_], StandardForm] := 
 Module[{proxy, boxes = SubscriptBox[a, b]}, 
  proxy = SubscriptToProxySymbol[boxes];
  If[proxy === Null, proxy = ToString[Unique[ProxySymbol]];
   SubscriptToProxySymbol[boxes] = proxy;
   With[{n = Symbol[proxy]}, MakeBoxes[n, StandardForm] := boxes];];
  MakeExpression[RowBox[{proxy}], StandardForm]]
有了这个,定义如下

f[Subscript[a, b] : _] := Sin[Subscript[a, b]]
内部存储方式如下:

In[11]:= InputForm@DownValues[f]

Out[11]//InputForm=
{HoldPattern[f[ProxySymbol$99_]] :> Sin[ProxySymbol$99]}
但它们显示为下标

快速看一眼,我想这可能就是西蒙的目标


如果您的应用程序允许,您可能希望考虑采用Mathematica,例如命名为FulyDeavigyVCAMELCALE变量名,而不是下标变量。这将使您的代码最终变得更便携,最终成为第二性质。将各种回答输入Mathematica笔记本(并在版本7和版本8中进行了尝试)。然而,我发现,在某些情况下,下标变量的显式表示为

Subscript[a,b]
并不能给出这些答案中所包含的正确答案。然而,当我显式使用下标的2d表示法时(a_b)答案与预期的一样。可能是在将订阅的符号粘贴到电子邮件中时,它们被表示为
Subscript[a,b]
(当然,我应该在使用
Quit[]
)后,为我重新开始Mathematica的每一个个人贡献添加这一点。

@Daniel从我的回答中可以明显看出,我从来没有这样做过。:)嗨,Daniel:Notation包有一个名为
symbol
的命令,该命令是为满足Max的要求而设计的。不需要完整的
Notation
命令。自定义Notation的潜在问题是
f[Subscript[a, b] : _] := Sin[Subscript[a, b]]
In[11]:= InputForm@DownValues[f]

Out[11]//InputForm=
{HoldPattern[f[ProxySymbol$99_]] :> Sin[ProxySymbol$99]}