# How to use pattern matching to assign values to Subscript[f,x_]?

I want to define two subscripted functions Subscript[f,1] and Subscript[f,2]. To keep the assignments local, I would like to associate the definitions with f if possible. My current solution is to write the following.

f/:Subscript[f,1]:=Function[x,g[x]]
f/:Subscript[f,2]:=Function[x,h[x]]


The resulting definition is stored as an UpValue for f, which is acceptable for me. Is it possible to construct a similar definition using pattern matching? I am looking for an analog to the following pair of definitions.

f[x_]:=g[x] (*definition 1*)
f:=Function[x,g[x]] (*definition 2*)


In other words, I am currently using a definition akin to definition 2 above for my subscripted functions. Is it possible to write a definition analogous to definition 1 above?

-
Do you mean f /: Subscript[f[x_], 1] := g[x] ? Seems quite straight forward, so if that's your question you almost answered it yourself. –  jVincent Aug 16 '12 at 20:03
@jVincent, he doesn't mean that. He wants it for Subscript[f,1][x_] which would be too deep for an UpValue –  Rojo Aug 16 '12 at 20:11
I don't know a neat solution to these things, but workarounds are possible. Check out if symbolising the subscript is good for you –  Rojo Aug 16 '12 at 20:14
Rojo is correct; thank you for clarifying my intentions. –  Carl Morris Aug 29 '12 at 14:49

You can do this with the Notation Package and its Symbolize function:

The definition is not attached to Subscript, but to pseudo-Symbol f1:

-
+1 I still think symbolising is the best workaround, if you don't need the underscript to be a pattern –  Rojo Aug 17 '12 at 12:03
@Rojo I voted for yours too. (And jVincent's, if anyone's curious.) –  Mr.Wizard Aug 17 '12 at 12:06
@Mr.Wizard 500 th answer ! Seems like you've got enough ideas to write a new (and necessarily concise) Mathematica book. +1 –  Artes Aug 17 '12 at 12:07
@Artes Thanks! I hadn't noticed. I'm no writer; I still haven't made a blog post yet. –  Mr.Wizard Aug 17 '12 at 12:11
This is probably the best answer for the situations that I can foresee. I admit that the workarounds using wrappers are quite enlightening (hence a +1 for each), but the situations that I would use this subscript notation are mostly in the context of small examples where it seems Symbolize offers the cleanest solution. –  Carl Morris Aug 29 '12 at 14:48

As Rojo notes, defining f/: Subscript[f,1][x_] doesn't work as f is too deep in the expression, however you could define your function in two steps to avoid tying the definition to Subscript.

f /: Subscript[f, n_] := subs[f, n]
subs /: subs[f, n_][x_] := g[x]


This has the problem that Subscript[f,1] for instance will turn up in output as subs[f,1] rather then be nicely formated. You can however simply define that it should be formated like subscript and noone will be the wiser that it's actually a different wrapper:

MakeBoxes[subs[a_, n_], StandardForm] := MakeBoxes[Subscript[a, n], StandardForm]

-
Nice patch +1. Of course the actual value of the output is subs, and it could eventually bite you. I wonder if its possible to work around that too, humm –  Rojo Aug 16 '12 at 20:24
@Rojo I'm not sure how it would come back to bite me since Subscript is mostly just a formatting function, If you had code that acted different depending on the heads you could just define: subs /: Head[subs[__]] = Subscript in which case I think subs becomes a pretty good impostor Subscript. –  jVincent Aug 16 '12 at 20:33
The patch you just suggested will only work for code that explicitly uses Head, which will be the minority. I mean, a reason I see for the OP to want the "pattern version" of the definition is because in a real application his definition many times won't match. This will leave you with some symbolic expression with subs inside that you see and think as Subscript and it will bite you if you ever use Cases or Replace trying to get those expressions –  Rojo Aug 16 '12 at 20:38
An ideal solution would remain unevaluated when it doesn't match –  Rojo Aug 16 '12 at 20:41

Slightly modifying @jVincent's idea so that if there's no match with your definition you go back to the Subscript

Module[{$guard = True, subs}, f /: Subscript[f, n_] /;$guard = subs[f, n];
subs[f, n_][sth_Integer] := g[sth];
subs[f, n_][sth_] := Block[{$guard = False}, Subscript[f, n][sth]] ]  Now Subscript[f, 1][2] Subscript[f, 1][2.5] // FullForm  g[2] Subscript[f,1][2.5] - add comment Here is a different approach to creating a functionality similar to what Rojo does. I attach a single rule to Subscript: Subscript[x_, n_][args__] /; MatchQ[x,$subpat] :=
With[{eval = x[n][args]},
eval /; ! MatchQ[ eval, HoldPattern @ x[n][args] ]
]


Then I define functions that are controlled by this rule:

$subpat = HoldPattern[f | q]; f[1][x_] := x^2 f[2][x_] := Mod[x, 3] q[1][x_] := x + 7  We gain this behavior: $subpat controls the domain:

You can change \$subpat or the definitions for f, q`, etc. to "keep the assignments local" however you see fit.

-