11
$\begingroup$

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?

$\endgroup$
4
  • $\begingroup$ 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. $\endgroup$
    – jVincent
    Commented Aug 16, 2012 at 20:03
  • 2
    $\begingroup$ @jVincent, he doesn't mean that. He wants it for Subscript[f,1][x_] which would be too deep for an UpValue $\endgroup$
    – Rojo
    Commented Aug 16, 2012 at 20:11
  • $\begingroup$ I don't know a neat solution to these things, but workarounds are possible. Check out if symbolising the subscript is good for you $\endgroup$
    – Rojo
    Commented Aug 16, 2012 at 20:14
  • $\begingroup$ Rojo is correct; thank you for clarifying my intentions. $\endgroup$ Commented Aug 29, 2012 at 14:49

4 Answers 4

6
$\begingroup$

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

Mathematica graphics

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

Mathematica graphics

$\endgroup$
5
  • $\begingroup$ +1 I still think symbolising is the best workaround, if you don't need the underscript to be a pattern $\endgroup$
    – Rojo
    Commented Aug 17, 2012 at 12:03
  • $\begingroup$ @Rojo I voted for yours too. (And jVincent's, if anyone's curious.) $\endgroup$
    – Mr.Wizard
    Commented Aug 17, 2012 at 12:06
  • $\begingroup$ @Mr.Wizard 500 th answer ! Seems like you've got enough ideas to write a new (and necessarily concise) Mathematica book. +1 $\endgroup$
    – Artes
    Commented Aug 17, 2012 at 12:07
  • $\begingroup$ @Artes Thanks! I hadn't noticed. I'm no writer; I still haven't made a blog post yet. $\endgroup$
    – Mr.Wizard
    Commented Aug 17, 2012 at 12:11
  • $\begingroup$ 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. $\endgroup$ Commented Aug 29, 2012 at 14:48
10
$\begingroup$

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] 
$\endgroup$
4
  • 1
    $\begingroup$ 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 $\endgroup$
    – Rojo
    Commented Aug 16, 2012 at 20:24
  • $\begingroup$ @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. $\endgroup$
    – jVincent
    Commented Aug 16, 2012 at 20:33
  • $\begingroup$ 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 $\endgroup$
    – Rojo
    Commented Aug 16, 2012 at 20:38
  • $\begingroup$ An ideal solution would remain unevaluated when it doesn't match $\endgroup$
    – Rojo
    Commented Aug 16, 2012 at 20:41
6
$\begingroup$

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`]

$\endgroup$
0
$\begingroup$

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:

Mathematica graphics

$subpat controls the domain:

Mathematica graphics

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.