6
$\begingroup$

I want to define a function that takes, several, let's say two arguments, both of which have several sub- and suberscripts. For example a function might have the signature $$ f(x_i,q_{j,k}) = \mathrm{function\ of\ } x_i, q_{j,k} $$ Now I want the notebook to be so flexible as to allow for $f$ to take arbitrary arguments with abitrary values of indices, e.g: $$ f(a,b) = \mathrm{function\ of\ } a,b $$ $$ f(x_{i+5},q_{j+1,k}) = \mathrm{function\ of\ } x_{i+5}, q_{j+1,k} $$ that is, I want the value of f to change whether I change the values passed or the indices. Of course, in the former case, if the value of f depends explicitly on the value of one of the indices of one of the parameters, say $$f(x_i)=x_i*i$$ then $$f(a)$$ would not necessarily a properly defined expression, unless $a$ can be written as some $x_j$.

Is there a way to define such functions?

$\endgroup$
8
  • 1
    $\begingroup$ Yes, you should just place the blank pattern in the sub or superscript. $\endgroup$ Commented Mar 12, 2020 at 16:06
  • 4
    $\begingroup$ I would not recommend superscripts. Instead use the single bracket notation. Thus f[i, j]. See here for why this is not such a good idea. All you have asked to do is absolutely standard in Mathematica. $\endgroup$
    – Hugh
    Commented Mar 12, 2020 at 17:02
  • 1
    $\begingroup$ Yes you can use as many arguments to the brackets as you wish and they can be superscripts or subscripts. The advantage of using the bracket for superscripts is that they will not cause confusion with raising to a power. Note that when you wish to have a pretty, mathematical looking form for your equations or results you can put in a replacement rule to change the bracket form to a superscript or subscript form. $\endgroup$
    – Hugh
    Commented Mar 12, 2020 at 18:36
  • 1
    $\begingroup$ Mathematica has pattern recognition when looking at arguments of functions. You can have the same function name but have it operate differently when supplied with different types of arguments. Thus you could define f[a,b] and f[x[i], q[j,k]]. You can make a function respond differently if it is supplied with a number or a symbol. The pattern recognition will spot this and take the correct action. I always find it easier to work with a bracket notation. Working with subscripts has got me lost in the past. $\endgroup$
    – Hugh
    Commented Mar 12, 2020 at 18:55
  • 1
    $\begingroup$ I have given an answer with an example. $\endgroup$
    – Hugh
    Commented Mar 12, 2020 at 19:13

2 Answers 2

9
$\begingroup$

Following the comments I am encouraging the use of brackets rather than subscripts or superscripts. Here is an example where a function may take a variable with a subscript or a variable without a subscript. The function will use pattern recognition to sort out how to behave. First we define the function. Note I start with a ClearAll[f] so that previous versions of f are deleted

ClearAll[f];
f[x_[i_]] := 5 x[i] + i;
f[a_] := 2 a 

Now we can try this out.

f[z[3]]

gives

3 + 5 z[3]

while

f[c]

gives

2 c

Is this along the lines of what you are seeking?

Edit

At the request of a comment here is an example where one function has several different outputs which depend on the type of input.

ClearAll[f];
f[x_[i_]] := { 5 x[i] + i, "Indexed Variables"};
f[a_Symbol] := { 10 a , "Symbol"};
f[a_Integer] := { 20 a, "Integer"};
f[a_Real] := {30 a, "Real"};
f[a_] := {40 a , "Anything Else"};

Here is a list of different inputs that we feed into the function

tests = {y[i], z[3], s, 3, 4., a + b^2};
results = f[#] & /@ tests;
TableForm[results]

With output

i+5 y[i]    Indexed Variables
3+5 z[3]    Indexed Variables
10 s    Symbol
60  Integer
120.    Real
40 (a+b^2)  Anything Else

This approach is standard in Mathematica. I am sure there are good examples elsewhere but I could not find them. If you know one please add the link to this answer.

$\endgroup$
4
  • 3
    $\begingroup$ I very much agree with Hugh: SubScript should be thought of as a typographical construct not indexing. It leads to all kinds of issues once you do replacements using /. $\endgroup$
    – SHuisman
    Commented Mar 12, 2020 at 19:34
  • $\begingroup$ Hugh, can you clarify if this still works when you reverse the order in which you define f? $\endgroup$ Commented Mar 12, 2020 at 21:55
  • 1
    $\begingroup$ @CATrevillian The order in which you give the function definitions is important. Mathematica examines each pattern in order and moves on to the next if the pattern is not satisfied. Tests may be applied to the patterns see PatternTest for details. Thus one can make a function that can be widely applied to various circumstances and types of input. This is the basis of a general approach to defining functions. $\endgroup$
    – Hugh
    Commented Mar 13, 2020 at 8:45
  • $\begingroup$ Yeah most definitely, Hugh! Great explanation. Can you add it to your answer? I know this is a tricky part of defining expressions, so i think it would be helpful if you showed what happens when you don’t do the right order? $\endgroup$ Commented Mar 13, 2020 at 19:18
3
$\begingroup$

Below I have defined a few different forms which will do exactly as you asked. While I, too, agree with the sentiments iterated by user @Hugh regarding the use of sub- and superscripts, that this is possible with the Wolfram Language must be noted and demonstrated. Regardless, please see the following:

ClearAll[f]; f[Subscript[x_, i_]] := Subscript[x, i] i; f[x_^i__] := x^i/i; f[x_] := x; f[Subscript[x_, i__], Subscript[y_, j__]] := g[Subscript[x, i], Subscript[y, j]]; f[x_, y_] := x + y;

Where g is a function of your definition. Now, we can test this out:

f[Subscript[x, i], Subscript[q, j, k]]
(* g[Subscript[x, i], Subscript[q, j, k]] *)
f[a, b]
(* a + b *)
f[Subscript[x, i + 5], Subscript[q, j + 1, k]]
(* g[Subscript[x, 5 + i], Subscript[q, 1 + j, k]] *)
f[Subscript[x, i]]
(* i Subscript[x, i] *)
f[n^j]
(* n^j/j *)
$\endgroup$
6
  • $\begingroup$ If the right hand side of $f$ does not depend on $i$, can use the first line and then call f with a single argument, for example f[1]? $\endgroup$ Commented Mar 12, 2020 at 17:30
  • 1
    $\begingroup$ @HerpDerpington If you defined your expression like this, sure! But as you stated you did not want this? For more advanced functionality you may find benefit in using the Notations package. This is just a basic example to show that this is possible. $\endgroup$ Commented Mar 12, 2020 at 17:53
  • 1
    $\begingroup$ @HerpDerpington I’ll update in a short bit with all of your requests showing that this can work, it’ll require a slight update to how you define these things. I did the above on my mobile Mathematica so I was limited with their keyboard $\endgroup$ Commented Mar 12, 2020 at 17:57
  • 1
    $\begingroup$ @HerpDerpington I have updated the answer $\endgroup$ Commented Mar 12, 2020 at 20:30
  • 1
    $\begingroup$ Incidentally have you considered Indexed? $\endgroup$
    – Mr.Wizard
    Commented Mar 14, 2020 at 19:59

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.