2011-03-30 64 views
10

有什麼辦法可以強制Mathematica獨立處理下標變量嗎?進一步來說。我說,我有以下定義:下標變量

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

現在,當我使用

Subscript[b, 1] 

數學將與

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

時,我想這是三個獨立的值代替它,因此改變b不會影響下標[b,..]。可能嗎?

回答

13

在回答前一個SO問題,Mathematica Notation and syntax modstelefunkenvf14提到,他是

希望用不縮強制MMA 治療下標變量符號

這基本上就是這個問題。

WReach指出,Notation package可以做到這一點很簡單地使用Symbolize

Needs["Notation`"]; 
Symbolize[ParsedBoxWrapper[SubscriptBox["_", "_"]]] 

哪裏(如在丹尼爾的回答)不擔心Box結構過於上面,你可以使用Notation調色板更簡單地輸入這個東西。

檢查所有作品想:

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

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

In[6]:= Subscript[b, 1] = {{1, 2}} 
     Subscript[b, 2] = {{3, 4}} 
     b = Join[Subscript[b, 1], Subscript[b, 2]] 
Out[6]= {{1, 2}} 
Out[7]= {{3, 4}} 
Out[8]= {{1, 2}, {3, 4}} 

注:所有上面的代碼已經copied as Input Text,所以排版SubscriptBox■找了轉換爲輸入格式Subscript s。然而,Symbolize在箱子級別工作,所以測試需要轉換回他們的2D表格。爲此,請使用Cell菜單或shortcutCtrl-Shift-N來選擇代碼(或單元格)並選擇convert it to standard form。所有上面的代碼筆記本看起來應該像 screenshot

1

符號是b,而不是Subscript[b, _]

當你定義:

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] 

正如預期的那樣。

所以,我想簡短的回答是否定的。至少不是直截了當的方式。

編輯

雖然上面是真實的(我認爲),我不知道該符號包有辦法避免默認行爲。其他答案包含細節。

+0

當然,我不知道Notation包實際使用什麼內在魔法來實現它的功能?例如'Symbolize'實際上做了什麼? – Simon 2011-03-30 07:20:31

+0

@Simon ha!我發佈了,然後刪除了對你的答案的類似評論。這種事情讓我不寒而慄:) – 2011-03-30 07:24:14

+0

它不會那麼糟糕 - 除了'Symbol'是'Locked' - 這會阻止你給它額外的'MakeBoxes'定義。請參閱下面的[社區維基「答案」](http://stackoverflow.com/questions/5481216/subscripted-variables/5481897#5481897)。 – Simon 2011-03-30 07:31:53

1

可以使用相同名稱包裝中的表示法。

不介意下面的代碼,你不知道RowBox結構。只需使用調色板模板並在右側輸入Subscript [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]] 

缺貨[3] = {{1,2}}

缺貨[4] = {{3,4}}

缺貨[5] = {{1,2} ,{3,4}}

Subscript[b, 1] 

出[6] = {{1,2}}

你可能會得到更準確的答覆,這是第一次我曾經與樂譜包打亂。

丹尼爾Lichtblau 沃爾夫勒姆研究

+0

@丹尼爾從我的回答中應該可以看出,我從來沒有這樣做過。 :) – 2011-03-30 03:22:56

+0

嗨丹尼爾:符號包有一個名爲'Symbolize'的命令,它被設計用來做Max想要的。完整的'Notation'命令不是必需的。 – Simon 2011-03-30 04:02:05

+4

自定義符號的潛在問題是.nb和.m文件的解析機制不同。它肯定會導致InfixNotation(https://groups.google.com/forum/#!msg/comp.soft-sys.math.mathematica/wABDm0h1EHg/CHHrGkdfbcIJ)的問題,不確定Symbolize – 2011-03-30 06:16:03

2

如果你不想使用Notation包(見Daniel'smy答案),但要複製的Symbolize的行爲,那麼它變得有點棘手。

我在閱讀SO answer之後就這樣做了,但遇到了麻煩而放棄了。我將把代碼放在這裏作爲社區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)該代碼不會拿起寫在FullForm中的下標。
2)如果下標的兩個部分都是「簡單的」,那麼這個定義只會被觸發 - 沒有空格,括號,操作符等等。

其次,因爲這個符號的名字是如此的醜陋,這裏是一個可選的東西,使之更好時,它的要求(這可能需要改變)

Protect[$inSymbolName]; 
Unprotect[SymbolName]; 
SymbolName[symb_Symbol] := 
Block[{$inSymbolName = True, result, s}, 
    result = If[StringMatchQ[s = SymbolName[symb], "$sUbsCript$" ~~ __], 
    [email protected][StringDrop[s, 11], "$SPLIT$"], 
    s]] /; ! TrueQ[$inSymbolName] 
Protect[SymbolName]; 

最後,我們希望這個下標符號打印出來很好。通常我們會使用MakeBoxes定義來做到這一點 - 但我們不能在這種情況下,因爲Symbol的屬性爲Locked :(
)相反,我們將在$PrePrint中找到這些瘋狂命名的符號,並將它們寫回標:

$PrePrint = (# /. s_Symbol :> 
    Block[{$inSymbolName = True}, 
    If[StringMatchQ[SymbolName[s], "$sUbsCript$" ~~ __], 
     [email protected]@StringSplit[StringDrop[SymbolName[s], 11], "$SPLIT$"], s]] 
    )&; 

最後,所有的這倒下的,如果你嘗試的東西分配給下標符號我還沒有嘗試過解決這個工作還沒有地方

一些測試 - 注意你!必須將Subscript s轉換爲代碼才能工作的實際框。通過轉換來完成此操作到StandardForm: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"}} 

它不與SetSetDelayed工作,如果它們產生OwnValues,它不與Information

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. >> 
2

定義工作這是我用來做這個的一些代碼。它應該爲你工作了:

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]:= [email protected][f] 

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

但他們顯示爲下標。

從一個快速的看,我認爲這可能是西蒙的目標。

如果您的應用程序允許,您可能希望考慮採用類似Mathematica的命名約定,例如FullyDescriptiveCamelCase變量名稱而不是下標變量。它最終會使你的代碼更具可移植性,並最終成爲第二性質。

+0

嗨安德魯 - 剛看到這個。它工作得很好,比我的方法更健全。 +1 – Simon 2011-08-15 11:38:05

0

我通過將各種答覆粘貼到Mathematica筆記本中(並試用版本7和8)詳細研究了下標變量的線程。但是,我發現在某些情況下,下標變量的明確表示形式爲Subscript[a,b]並未給出這些答案中包含的正確答案。但是,當我明確使用下標(a_b)的二維表示法時,答案與預期的一樣。是否可以將下標符號粘貼到電子郵件中時表示爲 Subscript[a,b]。 (當然,我應該補充說,對於每個人的貢獻,我使用Quit[ ]後開始使用Mathematica)。

+1

嗨,羅伯特,歡迎來到Stack Overflow。發表一個新的答案並不是真正的評論地點,但由於你沒有足夠的[聲譽評論](http://stackoverflow.com/privileges/comment),我想你沒有什麼可以做的提出這個有效的觀點。當複製爲輸入文本時,Mathematica會自動將下標框轉換爲完整形式,我認爲每個人在測試時自動將完整形式轉換回框,並且沒有人想到提及這一事實。我會更新我的答案以反映這種擔憂。 – Simon 2011-08-15 11:50:27