Using Subscripts and 
the SubscriptSymbols Package
By Ted Ersek   ted.ersek@navy.mil

Preface

Ted Ersek (ted.ersek@navy.mil) wrote the SubscriptSymbols package after David Park (djmp@earthlink.net) suggested such a package was needed.  David Park influenced the package design and content of this notebook.

Version 1.0

Version 1.0 was completed and posted on MathSource on 10 April 2002.

Version 1.1

Version 1.1 was completed and posted on MathSource on about 25 April 2002.
The following changes were made for Version 1.1.

•  Version 1.0 would fail when one tried to do the following.
	Clear[x];
	SubscriptSymbols[Off]
	x=4.3;
	SubscriptSymbols[On]
	Head[(Subscript[x, 2])]
   This was a bug and has been fixed.

•  The section of this notebook for Installing and Loading the Package now discusses 
    an error message that is often displayed and can generally be ignored.

•  The package has a new function  NotationPalette[] which is used to open the Notation palette.

Version 1.2

Version 1.2 was posted on MathSource on about 18 Nov 2002.

•  Version 1.2 has new installation instuctions in this notebook to ensure the file (SubscriptSymbols.m) is made with the user's computer.  This is needed to ensure a successful installation on any platform..

•  With earlier versions I had the file (SubscriptSymbols.m) posted on MathSource.  Instead I now have (SubscriptSymbols.nb) posted on MathSource.

Installing and Loading the Package

If you do not automatically turn off spelling similarity error messages in one of your init file, do so now for this notebook.

Off[General::spell, General::spell1];

I found that the following procedure is needed to ensure a successful installation on any platform. First you should save the notebook (SubscriptSymbols.nb) to the folder/directory returned when the the next cell is evaluated.

\(ToFileName[{$TopDirectory, "AddOns", "ExtraPackages", "Utilities"}]\)

Next open the (SubscriptSymbols.nb) file that you saved in the folder/directory shown above.  It's imperitive that you open the copy that was saved to the above folder/directory.  Save the notebook immediately after opening it and a dialog box will pop-up.  When the dialog box comes up click the button to "Create Auto Save Package".  Mathematica will then make a file called (SubscriptSymbols.m) and put it in the same directory as (SubscriptSymbols.nb).  You can then load the package by evaluating the Needs statement in the next cell. However, if this is your first time through the notebook, you shouldn't load the package now.  First you should read Section 1 (Introduction) where Mathematica's normal handling of Subscript expressions is demonstrated.

Needs["Utilities`SubscriptSymbols`"];

When the SubscriptSymbols package, or for that matter the Notation package, is loaded in a notebook that didn't previously make use of either of these packages the following message is displayed.  This is actually not a message, but a cell created in the message notebook via NotbookWrite.

Jason Harris of Wolfram Research is the author of the Utilities`Notation` package.  Jason explains that when you are using a legacy notebook containing notation statements created with the a notation package that was shipped with Mathematica 3.0 evaluating  UpdateNotationsInNotebook[] is required. For most users this is rarely or never the case and the message can normally be ignored.  If you like I can show you how to modify the Notation package source code to prevent this "message". 
 
The following statement gives access to all the usage messages for the routines in SubscriptSymbols once the package is loaded. The principal routine is SubscriptSymbols. If you have Mathematica Version 4.1 you can simply click on the names to obtain a usage message for the routine. If you have a previous version, you will only obtain a list of the package routines.

?Utilities`SubscriptSymbols`*

1. Introduction

Many Mathematica users like to use subscripted variables in their code and expressions because that is the way expressions are written in textbooks and technical papers, and it looks nice. In many cases Mathematica's default handling of subscripts does just what one would expect and there is no problem. But there are other cases where little effects happen to confuse the issue. A subscript such as (Subscript[x, 1]) is useless as a symbol if x has a value. An integer subscript gets turned into a real number if N is used on such expressions. Also, you cannot simply Clear a subscripted variable as you do other variables, because Clear demands a symbol. And if you ask the Mathematica pattern matcher to do something with all Integers in an expression the integers in your subscripts will be affected.

If we want to use subscripted variables in the definition of a function or as a scoped variable in a Module, With, Function or Block construct, we will be foiled because these statements demand symbols. Similarly, if we want to treat a subscripted variable as a Symbol for purposes of pattern matching we are foiled.

The SubscriptSymbols package makes it much easier to use subscripted variables. First, it adds attributes to Subscript that fix some of the problems with normal use. Secondly, it provides a symbolization function for those cases where a subscripted symbol must be treated as a Symbol. It is very easy to use the package to turn the symbolization of specified symbols on and off as needed. The package automatically performs routines from the Utilities`Notation`  package and adds code behind the scene to smooth the way. Hence the notation package that comes with Mathematica works invisibly in the background.

Summary:
1) Just by loading the package you will obtain a more consistent use of subscript expressions.
2) To use subscripts in definitions and declarations of local variables, use SubscriptSymbols.

If you have already loaded the SubscriptSymbols package, quit the kernel and start over by evaluating the following cells. This allows us to see the default behavior of Mathematica with Subscript expressions.

Quit[];

Off[General::spell, General::spell1];

1.1  Cases When the Default Handling of Subscripts Works Well

In many cases Mathematica works with Subscript expressions, such as (Subscript[x, 1]) as if they were symbols.  So, for example, we can use subscripted variables in the examples below.

Clear[x];
Solve[2  (Subscript[x, 1]) + a == (1/((Subscript[x, 1]) - 3)), {(Subscript[x, 1])}]

2  (Subscript[x, 1]) + a - (1/((Subscript[x, 1]) - 3)) /. (Subscript[x, 1]) -> h + xx

Plot[Sin[(Subscript[x, 1])] + ((Subscript[x, 1])/8), {(Subscript[x, 1]), 0, 4  π}];

1.2  Cases When the Default Handling of Subscripts Doesn't Work Well

However, the examples above don't work as well when x evaluates to a number.  This point is demonstrated below where the subscript expression from the next input is probably not what you would want when x evaluates to 2.5.

x = 2.5;
(Subscript[x, 1])

The next input solves the equation but gives a strange looking rule.

Solve[2  (Subscript[x, 1]) + a == (1/((Subscript[x, 1]) - 3)), {(Subscript[x, 1])}]

The next few examples also fail to give us what we expect when x has an assigned value.

Table[(Subscript[x, i]), {i, 1, 4}]

∫\[DifferentialD]((Subscript[x, 1])/(Subscript[x, 1]))

Next we can use subscripts to make a table of Bernoulli polynomials and it seems to work even though B has an assigned value.

Clear[x];
B = 3;
(Subscript[B, n])_[x_] := BernoulliB[n, x]
Table[(Subscript[B, i])[x], {i, 0, 6}] // TableForm

(Subscript[B, 2])'[x]

However (Subscript[B, n])[x] is actually stored as a definition for  (Subscript[3, n])[x_].

?? Subscript

Also if the value of B is changed or cleared the above definition of (Subscript[B, n])[x] no longer works as demonstrated with the next input.

Clear[B];
(Subscript[B, 2])'[x]

The next input can be used to remove the subscripted convention for Bernoulli polynomials that was made above.  This is hardly an intuitive way to remove the above definition.

(Subscript[3, n])_[x_] =.

By default arguments of Subscript are affected by use of N as we see with the next input where the terms (Subscript[t, 1]) don't add together because N changed the subscript of (Subscript[t, 1])  to an approximate number.

Clear[t];
expr = (Subscript[t, 1]) + π/4;
N[expr] + (Subscript[t, 1])

In the next subsection I show that the above examples work much better after making some simple changes.

1.3  Consider -  SetAttributes[Subscript, {HoldFirst, NHoldRest}]

Carl Woll once mentioned in the MathGroup that a lot of things involving subscripts work better if Subscript has the HoldFirst attribute.  However, it also helps if Subscript has the NHoldRest attribute.  Evaluating the next input will give Subscript these attributes. When the SubscriptSymbols package is loaded, these attributes are automatically added.

SetAttributes[Subscript, {HoldFirst, NHoldRest}];

Now the examples below give better results.

x = 2.5;
(Subscript[x, 1])

Solve[2  (Subscript[x, 1]) + a == (1/((Subscript[x, 1]) - 3)), {(Subscript[x, 1])}]

Table[(Subscript[x, i]), {i, 1, 4}]

∫\[DifferentialD]((Subscript[x, 1])/(Subscript[x, 1]))

Next we can use subscripts to make a table of Bernoulli polynomials and  B in the definition doesn't evaluate.

Clear[x];
B = 3;
(Subscript[B, n])_[x_] := BernoulliB[n, x]

?? Subscript

This time clearing the definition for Bernoulli polynomials is straight forward.

(Subscript[B, n])_[x_] =.

?? Subscript

Now the subscript 1 isn't affected by N.

Clear[t];
expr = (Subscript[t, 1]) + π/4;
N[expr] + (Subscript[t, 1])

1.4  Improve the Format of  Power[(Subscript[x, 1]), n]

By default Mathematica doesn't format the result of  Power[(Subscript[x, 1]), n] the way I think it should.

Power[(Subscript[x, 1]), n]

Evaluating the following little statement changes the formatting of such expressions.

MakeBoxes[HoldPattern[Power[x_Subscript, n_]], 
        form_] := 
SuperscriptBox[MakeBoxes[x, form], 
        MakeBoxes[n, form]]

I think that after evaluating the above input a subscript to a power is formatted better.  The above MakeBoxes expression is near the beginning of the (SubscriptSymbols.m) package.  If you prefer the default format of  Power[(Subscript[x, 1]), n] you can comment out that line in the package.

Power[(Subscript[x, 1]), n]

2. Symbolizing Subscripted Variables

You can use the Utilities`Notation`  package to symbolize subscripts such as ((Subscript[x, 3]), (Subscript[x, 4])), but the SubscriptSymbols package allows you do this more easily. Instructions for installing the SubscriptSymbols package were provided above.  Once the package is copied to the right folder, evaluating the next input will load the package and display the usage message for the SubscriptSymbols function.  This input also turns off some messages about similar variables.

Needs["Utilities`SubscriptSymbols`"];
Off[General::spell, General::spell1];
?SubscriptSymbols

Loading the package improves the way Mathematica handles Subscript expressions and allows you to Clear them. However, it does not automatically turn Subscript expressions into symbols as illustrated by the next cell. You have to explicitly issue commands to symbolize subscripts.

Head /@ {(Subscript[θ, 2]), (Subscript[x, 1]), (Subscript[y, 4]), (Subscript[w, 0]), (Subscript[x, a]), (Subscript[y, b]), (Subscript[z, c])}

2.1  Universal Subscript Symbolization - Highest Level

The next input makes it so any variable with a non-negative integer subscript is considered a symbol.

SubscriptSymbols[On]
Head /@ {(Subscript[θ, 2]), (Subscript[x, 1]), (Subscript[y, 4]), (Subscript[w, 0]), (Subscript[x, a]), (Subscript[y, b]), (Subscript[z, c])}

The next input restores the default behavior for all subscripts.

SubscriptSymbols[Off]
Head /@ {(Subscript[θ, 2]), (Subscript[x, 1]), (Subscript[y, 4]), (Subscript[w, 0]), (Subscript[x, a]), (Subscript[y, b]), (Subscript[z, c])}

2.2  Subscript Symbolization of Specific Variables - Middle Level

The next input makes it so θ with a non-negative integer subscript is a symbol.  Notice it doesn't matter that  θ  has the value 2.5.

θ = 2.5;
SubscriptSymbols[θ, On]

In the next input (Subscript[θ, n]) is considered a Subscript expression because the subscript isn't an integer. However, the list returned ((Subscript[θ, 1]), (Subscript[θ, 2]), (Subscript[θ, 3]), (Subscript[θ, 4])) is considered a list of symbols.  Notice ((Subscript[θ, 1]), (Subscript[θ, 2]), (Subscript[θ, 3]), (Subscript[θ, 4])) doesn't evaluate to ((Subscript[2.5, 1]), (Subscript[2.5, 2]), (Subscript[2.5, 3]), (Subscript[2.5, 4])) because the SubscriptSymbols package gives Subscript the HoldFirst attribute.

lst = Table[(Subscript[θ, n]), {n, 4}]
Head /@ lst

After evaluating the next input  x  or  y  with a non-negative integer subscript is considered a symbol, in addition to θ with a non-negative subscript due to the input above.  Subscript symbols is designed to have the same effect whether the second argument is On or True, and the second argument is True in the next cell to demonstrate this point.

SubscriptSymbols[{x, y}, True]
Head /@ {(Subscript[θ, 2]), (Subscript[x, 1]), (Subscript[y, 4]), (Subscript[w, 0]), (Subscript[x, a]), (Subscript[y, b]), (Subscript[z, c])}

After evaluating the next input no  θ  or  x  subscripts are considered symbols, but  y  with a non-negative subscript is still a symbol.

SubscriptSymbols[{θ, x}, Off]
Head /@ {(Subscript[θ, 2]), (Subscript[x, 1]), (Subscript[y, 4]), (Subscript[w, 0]), (Subscript[x, a]), (Subscript[y, b]), (Subscript[z, c])}

The next input ensures no  y  subscripts are considered symbols.  SubscriptSymbols has the same effect whether the second argument is Off or False.  In the next example the second argument is False to demonstrate this point.

SubscriptSymbols[y, False]
Head /@ {(Subscript[θ, 2]), (Subscript[x, 1]), (Subscript[y, 4]), (Subscript[w, 0]), (Subscript[x, a]), (Subscript[y, b]), (Subscript[z, c])}

2.3  Subscript Symbolization of Specific Subscript Expressions - Lowest Level

The next input ensures only (Subscript[x, 1]) is considered a symbol.

SubscriptSymbols[Off]
SubscriptSymbols[(Subscript[x, 1]), On]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[x, 3]), (Subscript[y, a]), (Subscript[y, b]), (Subscript[y, 1])}

The next input ensures ((Subscript[y, a]), (Subscript[y, b]))are considered subscripts in addition to (Subscript[x, 1]) due to the line above.  Notice we can symbolize specific subscript expressions where the subscript is not an integer.

SubscriptSymbols[{(Subscript[y, a]), (Subscript[y, b])}, On]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[x, 3]), (Subscript[y, a]), (Subscript[y, b]), (Subscript[y, 1])}

The next input turns off symbolization of (Subscript[x, 1]).

SubscriptSymbols[(Subscript[x, 1]), Off]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[x, 3]), (Subscript[y, a]), (Subscript[y, b]), (Subscript[y, 1])}

The next input turns off symbolization of ((Subscript[y, a]), (Subscript[y, b])).

SubscriptSymbols[{(Subscript[y, a]), (Subscript[y, b])}, Off]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[x, 3]), (Subscript[y, a]), (Subscript[y, b]), (Subscript[y, 1])}

2.4  Relation Between Turning Subscripts On and Off

The relation between turning on symbolization and turning off symbolization is a little subtle.  To demonstrate this point consider the next input which symbolizes  x  or  y  with a non-negative integer subscript.

SubscriptSymbols[Off]
SubscriptSymbols[x, On]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[x, a]), (Subscript[x, b]), (Subscript[y, 1]), (Subscript[y, 2]), (Subscript[y, a]), (Subscript[y, b])}

If we also want (Subscript[x, a]) symbolized we need to explicitly symbolize it using the following.

SubscriptSymbols[(Subscript[x, a]), On]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[x, a]), (Subscript[x, b]), (Subscript[y, 1]), (Subscript[y, 2]), (Subscript[y, a]), (Subscript[y, b])}

SubscriptSymbols[x,Off]  isn't simply the opposite of  SubscriptSymbols[x,On]  because it turns off symbolizing of all  x subscripts including  (Subscript[x, a]), which wasn't symbolized using SubscriptSymbols[x,On].  Likewise SubscriptSymbols[Off] turns off symbolizing of subscripts such as ((Subscript[x, a]), (Subscript[y, a,   ... ])) which aren't symbolized using SubscriptSymbols[On].

SubscriptSymbols[x, Off]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[x, a]), (Subscript[x, b]), (Subscript[y, 1]), (Subscript[y, 2]), (Subscript[y, a]), (Subscript[y, b])}

To demonstrate another point the next input symbolizes all variables with a non-negative integer subscript.

SubscriptSymbols[On]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[x, a]), (Subscript[x, b]), (Subscript[y, 1]), (Subscript[y, 2]), (Subscript[y, a]), (Subscript[y, b])}

SubscriptSymbols allows you to turn off symbolization at an equal or higher level, but not at a lower level.  In the next input we try to turn off symbolization at a lower level and get a error messages.

SubscriptSymbols[x, Off]

SubscriptSymbols[(Subscript[x, 1]), Off]

Summary:
1)  SubscriptSymbols[On] and SubscriptSymbols[x, On] will not symbolize ((Subscript[x, a]), (Subscript[x, b]),  ... )since the subscripts are not integers.

2)  SubscriptSymbols[Off] and SubscriptSymbols[x, Off] turns off symbolizing of  ((Subscript[x, 1]), (Subscript[x, 2]),  ... )and ((Subscript[x, a]), (Subscript[x, b]),  ... ).

3)  You can turn off subscript symbols created at a given level by using SubscriptSymbols[equal or higher level, Off] .

4)  You cannot use a SubscriptSymbols[lower level, Off] on symbols created at a higher level.

2.5  Giving SubscriptSymbols A Specification List

SubscriptSymbols has the HoldFirst attribute.  So in the next two examples we have to use Evaluate on the first argument to get the same result as evaluating  SubscriptSymbols[{i, j, k}, On].

SubscriptSymbols[Off]
list = {i, j, k};
SubscriptSymbols[Evaluate[list], On]
Head /@ {(Subscript[i, 1]), (Subscript[j, 2]), (Subscript[k, 3])}

SubscriptSymbols[Evaluate[list], Off]
Head /@ {(Subscript[i, 1]), (Subscript[j, 2]), (Subscript[k, 3])}

If the first argument of SubscriptSymbols is a list it can be a list of regular symbols or a list of subscripts, but it can't be a mix of the two.  If you try to violate this rule a message is posted as in the next two examples.

SubscriptSymbols[{x, y, (Subscript[a, 1]), (Subscript[b, 1])}, On]

SubscriptSymbols[{x, y, (Subscript[a, 1]), (Subscript[b, 1])}, Off]

2.6  Internal Representation of Subscripted Symbols

How are subscript symbols actually stored? In StandardForm and TraditionalForm you will not see the internal representation because the package routines automatically display the subscripted form. However, if you use InputForm or FullForm on an expression containing subscript symbols, you will see the internal representation. The Notation package automatically parses a two dimensional subscript such as  (Subscript[w, 2]) into the symbol  w⎵Subscript⎵2.  The convention of using this long form is a feature of the Notation package which is inherited in the SubscriptSymbols package. This is illustrated below.

SubscriptSymbols[w, On]
lst = {(Subscript[w, 1]), (Subscript[w, 2]), (Subscript[w, 3])};
StandardForm[lst]

TraditionalForm[lst]

InputForm[lst]

FullForm[lst]

In fact, you could  type the symbol "w⎵Subscript⎵2"  as  "w\[UnderBracket]Subscript\[UnderBracket]2" and get the same result as if you typed (Subscript[w, 2]). Once the w subscripts are symbolized the StandardForm for displaying  w⎵Subscript⎵2  is the more readable form (Subscript[w, 2]) and the TraditionalForm is very similar.  This is demonstrated in the next input.  You should never need to type an expression using the long form of a symbolized expression as below, but this shows how the Notation package is able to treat Subscripts as symbols.

Log[w⎵Subscript⎵2]

3. Application Examples

3.1  Addition of Relativistic Velocities

Suppose we want to write a definition for the addition of relativistic velocities (expressed as a percentage of the velocity of light). Our textbook uses subscripted symbols and we would like to make our definition look like the textbook definition.

To use subscripted variables in definitions, it is necessary to use the longer colon form for a pattern. The expression (x : _) is the same as (x_), but with subscripted variables the colon is necessary, because the Mathematica parser gets to the expression before the symbolization code does. We will use the CirclePlus operator to represent relativistic addition of velocities. (CirclePlus can be entered by Esc c + Esc.)

Clear[CirclePlus];
SubscriptSymbols[Off]
SubscriptSymbols[v, On]
CirclePlus[(Subscript[v, 1]) : _, (Subscript[v, 2]) : __] := ((Subscript[v, 1]) + 
            CirclePlus[(Subscript[v, 2])])/(1 + (Subscript[v, 1]) 
              CirclePlus[(Subscript[v, 2])])
CirclePlus[(Subscript[v, 1]) : _] := (Subscript[v, 1])

The velocity never exceeds 1, the velocity of light.

3/4⊕3/4

0.9⊕0.9⊕0.9

The next input displays the definition of CirclePlus.

?? CirclePlus

The definition still works, even after v is turned off.

SubscriptSymbols[v, Off]

0.99⊕0.99

This is because the subscripted variables are still in the definition of CirclePlus.  However, when symbolization of  v subscripts was turned off the rules for displaying  v⎵Subscript⎵1  and  v⎵Subscript⎵2  as subscripts were removed and that is why the definition now looks different than it did above.

?? CirclePlus

Clear[CirclePlus]
SubscriptSymbols[v, Off]

3.2  Resistance Ladder

Suppose we want to write a routine for evaluating the resistance of a resistance ladder. The ladder can have n legs with each leg consisting of a parallel and series resistor. The parallel resistor is parallel with what came before and the series resistor is added. The first parallel resistor is parallel with an infinite resistance. We would like to write the equations in the same form as our textbook equations using subscripted R's.

These are the subscripted variables we will use.

RList = Table[(Subscript[R, i]), {i, 3}]

The following statement turns them into subscript symbols.

SubscriptSymbols[Evaluate[RList], On]

The following are our rules for combining parallel and series resistors. Notice that in the definition we must use the long, colon form for the pattern to ensure correct parsing as explained above. We wouldn't be able to use subscripts to name the patterns if  (Subscript[R, 1]), (Subscript[R, 2]) weren't treated as symbols.

parallel[(Subscript[R, 1]) : _, (Subscript[R, 2]) : _] := 
      1/((1/(Subscript[R, 1])) + (1/(Subscript[R, 2])))
series[(Subscript[R, 1]) : _, (Subscript[R, 2]) : _] := (Subscript[R, 1]) + (Subscript[R, 2])

The ResistanceLadder routine will show the resistance after each leg is added to the ladder.

ResistanceLadder[
        legs : {{_, _} .. }] := 
FoldList[
With[
{(Subscript[R, 1]) = #1, 
(Subscript[R, 2]) = First[#2], 
(Subscript[R, 3]) = 
                Last[#2]}, 
series[parallel[(Subscript[R, 1]), (Subscript[R, 2])], 
              (Subscript[R, 3])]] &, ∞, legs]

Again, we could not have used (Subscript[R, 1]), (Subscript[R, 2]) and (Subscript[R, 3]) in the With statement if  (Subscript[R, 1]), (Subscript[R, 2]) and (Subscript[R, 3]) weren't treated as symbols.  You might have other applications where you would like to use subscripts as local variables in Module, Function or give subscripts local values using Block as in 
Module[{(Subscript[v, 1]), (Subscript[v, 2])},  expr],
Function[{(Subscript[v, 1]), (Subscript[v, 2])},  expr],
Block[{(Subscript[v, 1]) = value1, (Subscript[v, 2]) = value2},  expr].
These are also cases where  (Subscript[v, 1]), (Subscript[v, 2])  would have to be symbolized.

This calculates the resistance at each stage of a 25 leg ladder with each leg having resistances 1 and 1.

tabl = ResistanceLadder[Table[{1, 1}, {25}]]
N[tabl, 20] // TableForm

In the limit the resistance approaches the GoldenRatio.

N[Last[tabl] - GoldenRatio, 22]

3.3  Make Subscripts Match (_Symbol)

Consider the following case where we are working with lists of subscripted symbols.

SubscriptSymbols[Off]
lst1 = {(Subscript[x, 1]), (Subscript[x, 4]), (Subscript[x, 7]), (Subscript[x, 10]), (Subscript[x, 15])};
lst2 = lst1 /. n_Integer :> n - 1

lst3 = a + (lst2 - lst1)/20

Now suppose we want a concise way to make the replacements 
{a -> f[a], (Subscript[x, n]) -> f[(Subscript[x, n])]} where  n  is an Integer.  The following is a concise attempt that doesn't work.

Replace[lst3, s_Symbol :> f[s], -1]

The following input is the most concise solution I can find without changing the way subscripts are handled.

Replace[
      lst3, 
{a -> f[a], 
        Subscript[x, n_] :> 
          f[Subscript[x, n]]}, -1]

Next I show how the SubscriptSymbols package allows a simpler solution to the problem above.  Here SubscriptSymbols[x, On] is used to ensure the rule (s_Symbol:>f[s]) applies to  (Subscript[x, 0]),  (Subscript[x, 1]), …

SubscriptSymbols[x, On];
Replace[lst3, s_Symbol :> f[s], -1]

4.  Values Assigned to Subscripts

In the next input I assign values to some subscripts when the subscripts aren't symbolized.

SubscriptSymbols[Off];
{(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[y, 1]), (Subscript[y, 2])} = {11, 12, 13, 14};

Next I demonstrate that I can use the value assigned to (Subscript[x, 1]) above.  This is part of Mathematica's default handling of subscripts.

5*(Subscript[x, 1])

In the next input I ensure that  x  with a non-negative integer subscript and (Subscript[y, 1]) are symbols.  Notice the values assigned to the affected subscripts are gone.  However, the value assigned to (Subscript[y, 2]) wasn't erased because it wasn't symbolized.

SubscriptSymbols[x, On];
SubscriptSymbols[(Subscript[y, 1]), On];
{(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[y, 1]), (Subscript[y, 2])}

In the next input I turn off symbolizing that was enabled above, and we see that the values that were assigned to (Subscript[x, 1]),  (Subscript[x, 2]),  (Subscript[y, 1]) are still gone.  The lesson here is that you must not assign a value to a subscript if you will be switching between treating it as a subscript expression and a symbol.

SubscriptSymbols[x, Off];
SubscriptSymbols[(Subscript[y, 1]), Off];
{(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[y, 1]), (Subscript[y, 2])}

Next I symbolize the subscripts (Subscript[x, 1]), (Subscript[x, 2]).

SubscriptSymbols[{(Subscript[x, 1]), (Subscript[x, 2])}, On]
Head /@ {(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[y, 1]), (Subscript[y, 2])}

Next I assign values to ((Subscript[x, 1]),  (Subscript[x, 2]),  (Subscript[y, 1]),  (Subscript[y, 2])) and show that we can use the value assigned to (Subscript[x, 1]).

{(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[y, 1]), (Subscript[y, 2])} = {6, 7, 8, 9};
5*(Subscript[x, 1])

In the next input I disable symbolization of all  x  subscripts, and the definitions of affected subscripts are erased.

SubscriptSymbols[x, Off]
{(Subscript[x, 1]), (Subscript[x, 2]), (Subscript[y, 1]), (Subscript[y, 2])}

Summary:
1)  Values assigned to Subscript expressions are lost if you symbolize the expression.
2)  Values assigned to subscript symbols are lost if you turn the symbolization off.

5.  Clearing Subscripts

The SubscriptSymbols package automatically extends the Clear function so that subscript expressions and subscript symbols can be cleared of values just by listing them in the Clear statement. Without the package, subscript expressions can only be cleared by clearing Subscript (which may clear more than you want) or by using specific Unset statements.

The next input assigns a values to (Subscript[x, 1]),  t  and defines a function (Subscript[f, 1]) when no subscripts are considered Symbols.

SubscriptSymbols[Off]
(Subscript[x, 1]) = 43;
t = 4.5;
(Subscript[f, 1])[x_] := x + 5

The next input makes use of these definitions, and this is part of Mathematica's default handling of subscripts.

{(Subscript[x, 1]), (Subscript[f, 1])[6], t}

By default the built-in function Clear will not clear the above definitions for (Subscript[x, 1]) and (Subscript[f, 1]), but The SubscriptSymbols package enhances Clear so it can clear the definitions made above.  This is done with the next input.

Clear[(Subscript[x, 1]), (Subscript[f, 1]), t]
{(Subscript[x, 1]), (Subscript[f, 1])[6], t}

Next I look at the previous example when  (Subscript[x, 1]) and (Subscript[f, 1]) are considered Symbols.

SubscriptSymbols[{x, f}, On]
Head /@ {(Subscript[x, 1]), (Subscript[f, 1])}

The next input assigns values to (Subscript[x, 1]), (Subscript[f, 1]),  t and makes use of these values.

(Subscript[x, 1]) = 65;
(Subscript[f, 1])[x_] := x + 7;
t = 9.3;
{(Subscript[x, 1]), (Subscript[f, 1])[6], t}

Next I Clear the above definitions and it simply does what we expect.

Clear[(Subscript[x, 1]), (Subscript[f, 1]), t]
{(Subscript[x, 1]), (Subscript[f, 1])[6], t}

In the next input ClearAll can take  (Subscript[x, 1]), (Subscript[f, 1])  as arguments when the subscripts are symbolized.

Head /@ {(Subscript[x, 1]), (Subscript[f, 1])}
ClearAll[(Subscript[x, 1]), (Subscript[f, 1]), t]

However, in the next input  (Subscript[x, 1]), (Subscript[f, 1])  have the head Subscript, and can't be used as arguments for ClearAll, but there is no reason to do this because you can't assign attributes to a subscript expression.

SubscriptSymbols[Off]
ClearAll[(Subscript[x, 1]), (Subscript[f, 1]), t]

6.  GetSubscript

It isn't easy to get the subscript from  (Subscript[x, 1]) when it's considered a symbol.  The SubscriptSymbols package provides a function GetSubscript to perform such a task and its usage message is shown below.

?GetSubscript

In the next cell I demonstrate GetSubscript with symbolized subscripts (Subscript[x, 2]), (Subscript[x, 6]), (Subscript[x, 7])and subscript expressions (Subscript[y, 10]), (Subscript[y, 12]).

SubscriptSymbols[Off]
SubscriptSymbols[x, On]

    
symbs = {(Subscript[x, 2]), (Subscript[x, 6]), (Subscript[x, 7]), (Subscript[y, 10]), 
          (Subscript[y, 12])};
GetSubscript /@ symbs

7.  MapSubscript

The SubscriptSymbols package defines MapSubscript so you can systematically change the subscript of (Subscript[x, 1]) whether it's symbolized or not. The MapSubscript usage message is shown below.

?MapSubscript

The next cell generates a list where the first two elements are symbolized subscripts and the last two elements are subscript expressions.

SubscriptSymbols[Off]
SubscriptSymbols[x, On]

    
list = {(Subscript[x, 2]), (Subscript[x, 6]), (Subscript[y, 10]), (Subscript[y, 12])};
Head /@ list

MapSubscript is used in the next input to increase each subscript by 50. Notice that it works with Subscript expressions and symbolized subscripts.

FiftyMore[n_] := n + 50
MapSubscript[FiftyMore, #] & /@ list

8.  ApplySubscript

When (Subscript[x, 1])is a subscript expression it's easy to get the parts {x,1}, but this isn't simple when (Subscript[x, 1]) is symbolized.  The SubscriptSymbols package defines ApplySubscript to solve this problem and its usage message is displayed below.

?ApplySubscript

The next input ensures that only  x  with a non-negative integer subscript is symbolized.  Then ApplySubscript is used to change the symbolized subscript (Subscript[x, 12]) to the list {x,12}, and the subscript expression (Subscript[y, 14]) to the list {y,14}.  Note that it works on both symbolized subscripts and on subscript expressions.

Clear[x, y];
SubscriptSymbols[Off]
\(\(\(SubscriptSymbols[x, On]\)\(
\)
    \)\)
ApplySubscript[List, (Subscript[x, 12])]
ApplySubscript[List, (Subscript[y, 14])]

Next ApplySubscript is used to change the symbolized subscript (Subscript[x, 16]) to the Hold[x,16].  In this case Hold prevents  x  from evaluating to 3.24.

x = 3.24;
ApplySubscript[Hold, (Subscript[x, 16])]

9.  SymbolizedSubscriptQ

Normally it wouldn't be easy to tell the difference between a regular symbol and a symbolized subscript. The SubscriptSymbols package defines SymbolizedSubscriptQ to address this problem and its usage message is displayed below.

?SymbolizedSubscriptQ

The next input ensures that only  x  with a non-negative integer subscript is symbolized.  Here SymbolizedSubscriptQ tells us that  (Subscript[x, 2]), (Subscript[x, 6]) are the only symbolized subscripts in list.

SubscriptSymbols[Off]
SubscriptSymbols[x, On]

    
list = {(Subscript[x, 2]), (Subscript[x, 6]), (Subscript[y, 10]), (Subscript[y, 12]), a, b, 
          4, (Sqrt[3])};
SymbolizedSubscriptQ /@ list

10.  NotationPalette

When the SubscriptSymbols package is loaded the Utilities`Notation` package is also loaded without the associated palette. If you need the Notation palette after loading SubscriptSymbols  NotationPalette[] should be evaluated.  The NotationPalette usage message is displayed below.

?NotationPalette

Evaluating the next input opens to Notation palette.

NotationPalette[]