3
$\begingroup$

Sometimes I need to evaluate an expression at the end points. e.g. the right hand side of $\int_a^bf(x)\textrm{d}x=F(x)\big|_a^b$. $F(x)$ could be complicated so I can't just substitute the values by hand. I currently do it this way:

(m[a]-m[b] /. m[x_] -> u)

But this introduces a new variable m and doesn't look very elegant. I'm looking for a built-in notation and/or a function for this purpose.

$\endgroup$
4
  • 1
    $\begingroup$ How about defining a function r[u_, a_, b_] := u[b] - u[a] and applying it to replace rule u[x] /. u[x] -> r[u, a, b]. It will yield: -u[a] + u[b] or for different function u[x] /. u[x] -> r[F, a, b] it will yield -F[a] + F[b] $\endgroup$ Dec 3, 2015 at 11:18
  • $\begingroup$ @WojciechArtichowicz: Actually I don't have FUNCTION F[x], it's just an EXPRESSION u. I would want some function like diff[u,{x,a,b}] more. $\endgroup$
    – shouya
    Dec 3, 2015 at 11:47
  • $\begingroup$ Could you provide an actual simple example of such expression? $\endgroup$ Dec 3, 2015 at 11:52
  • 2
    $\begingroup$ First@Differences[expr /. {{x->a}, {x->b}}]? Or (expr /. x->b) - (expr /. x->a}? $\endgroup$
    – Michael E2
    Dec 3, 2015 at 12:08

4 Answers 4

3
$\begingroup$
diff = Function[{expr}, 
   Subtract @@ (expr /. {{#1 -> #3}, {#1 -> #2}})] &

longComplexExpr[x] // diff[x, 1, 3]
(* - longComplexExpr[1] + longComplexExpr[3] *)

So for integrals:

Integrate[x^2, x] // diff[x, 1, 3]
(* 26/3 *)

Integrate[x^2, {x, 1, 3}]
(* 26/3 *)
$\endgroup$
8
$\begingroup$

I've had a play to try and get a slightly more stylistic solution by creating a new template for the form you want and then assigning it an InputAlias, following closely the work here.

The code below will allow you to access the template enter image description here by simply typing escbarEvalesc.

It will then evaluate the function at the limits and take the difference, as defined in the BarEvaluate function:

enter image description here

Some limitations are:

  1. I've been a little hacky in trying to get a longer vertical bar, maybe someone can come up with a better way of producing it? (On my system I can get a proper LaTex one through the MaTeX package).
  2. You might need to adapt it for cases when your function F takes more than just the single parameter.

Code:

SetAttributes[BarEvaluate, HoldAll]

BarEvaluate[f_, limits_] := f[limits[[1]]] - f[limits[[2]]]

BarEvaluate /: MakeBoxes[BarEvaluate[f_, {a_, b_}], TraditionalForm] :=
  TemplateBox[{ToBoxes[f], ToBoxes[a], ToBoxes[b]}, 
  "conditionalProduct", 
  DisplayFunction :> (RowBox[{#, 
   SubsuperscriptBox[
    StyleBox["\[VerticalSeparator]", "Subsubtitle"], 
    AdjustmentBox[#2, BoxBaselineShift -> 1], 
    AdjustmentBox[#3, BoxBaselineShift -> -1]]}] &), 
  InterpretationFunction :> (RowBox[{"BarEvaluate", "[", 
   RowBox[{#, ",", "{", #2, ",", #3, "}"}], "]"}] &)]

aliases = Options[EvaluationNotebook[], InputAliases];
newAliases = 
  Join[InputAliases /. 
aliases, {"barEval" -> 
 TemplateBox[{"\[SelectionPlaceholder]", "\[Placeholder]", 
   "\[Placeholder]"}, "barEvaluate", 
  DisplayFunction :> (RowBox[{#, 
       SubsuperscriptBox[
        StyleBox["\[VerticalSeparator]", "Subsubtitle"], 
        AdjustmentBox[#2, BoxBaselineShift -> 1], 
        AdjustmentBox[#3, BoxBaselineShift -> -1]]}] &), 
  InterpretationFunction :> (RowBox[{"BarEvaluate", "[", 
       RowBox[{#, ",", "{", #2, ",", #3, "}"}], "]"}] &)]}];
SetOptions[EvaluationNotebook[], InputAliases -> newAliases];
$\endgroup$
1
  • $\begingroup$ Very useful answer for much broader cases than here. I wish I knew how to search for stuff like that without knowing the keyword InputAliases +1 ofc $\endgroup$
    – LLlAMnYP
    Dec 3, 2015 at 14:44
3
$\begingroup$

Here is another version that should typeset and evaluate the way you want. The first step is to use a symbol that supports vertical spanning, and looks like a bar. There are several such symbols, |, \[VerticalSeparator], \[VerticalLine], \[VerticalLine], \[RightBracketingBar] and perhaps some others. I think \[VerticalLine] works best, so I will use that symbol. Next, one needs to restrict the spanning, so that only the selected portion influences the spanning. So, the basic plan is to use the boxes:

RawBoxes @ SubsuperscriptBox[
    RowBox[{"\[SelectionPlaceholder]", "\[VerticalLine]"}],
    "\[Placeholder]",
    "\[Placeholder]"
]

enter image description here

An example:

RawBoxes @ SubsuperscriptBox[
    RowBox[{FractionBox[SuperscriptBox["x","2"],"3"],"\[VerticalLine]"}],
    "1",
    "2"
]

enter image description here

By including the bar inside of a SubsuperscriptBox, the spanning will only consider whatever is placed inside \[SelectionPlaceholder]. For example:

RawBoxes @ RowBox[{
    FractionBox[SuperscriptBox["x","3"],"4"],
    "+",
    SubsuperscriptBox[RowBox[{"x","\[VerticalLine]"}],"1","2"]
}]

enter image description here

You will notice that the min size of the bar and the spacing is a bit off, so the following version should look better (I also turned off the SpanSymmetric option):

CellPrint @ Cell[
    BoxData @ SubsuperscriptBox[
        RowBox[{
            FractionBox[SuperscriptBox["x","2"],"3"],
            StyleBox["\[VerticalLine]",
                SpanSymmetric->False,
                SpanMinSize->1.5
            ]
        }],
        RowBox[{"\[MediumSpace]", "1"}],
        RowBox[{"\[MediumSpace]", "2"}]
    ],
    "Input"
]

enter image description here

This produces a box structure that should look the way you want. Now, to make it evaluatable, let's define an EvaluatedAt function:

EvaluatedAt[expr_, Automatic, min_, max_] := EvaluatedAt[
    expr,
    Replace[Reduce`FreeVariables[expr], {{v_,___}->v, _->None}],
    min,
    max
]

EvaluatedAt[expr_, x_, min_, max_] := (expr /. x->max) - (expr /. x->min)

A couple examples:

EvaluatedAt[1/x^2, x, 1, 2]
EvaluatedAt[1/x, Automatic, 1, 2]

-3/4

-1/2

In the second example with Automatic, EvaluatedAt looks for the first free variable in expr and then does the desired arithmetic.

Now, we are ready to create an input alias that both typesets as desired, and evaluates as desired:

CurrentValue[EvaluationNotebook[], {InputAliases,"at"}] = TemplateBox[
    {"\[SelectionPlaceholder]", "Automatic", "\[Placeholder]", "\[Placeholder]"},
    "EvaluatedAt",
    DisplayFunction->(
        SubsuperscriptBox[
            RowBox[{
                #1,
                StyleBox[
                    "\[VerticalLine]",
                    SpanMinSize->1.5,
                    SpanSymmetric->False
                ]
            }],
            RowBox[{"\[MediumSpace]", #3}],
            RowBox[{"\[MediumSpace]", #4}]
        ]&
    )
];

And, here's another version where you specify the variable to be replaced:

CurrentValue[EvaluationNotebook[], {InputAliases,"at2"}] = TemplateBox[
    {"\[SelectionPlaceholder]", "\[Placeholder]", "\[Placeholder]", "\[Placeholder]"},
    "EvaluatedAt",
    DisplayFunction->(
        SubsuperscriptBox[
            RowBox[{
                #1,
                StyleBox[
                    "\[VerticalLine]",
                    SpanMinSize->1.5,
                    SpanSymmetric->False
                ]
            }],
            RowBox[{"\[MediumSpace]", #2, "=", #3}],
            RowBox[{"\[MediumSpace]", #4}]
        ]&
    )
];

And here is an animation showing both in action:

enter image description here

Finally, all the necessary code in one code block:

EvaluatedAt[expr_, Automatic, min_, max_] := EvaluatedAt[
    expr,
    Replace[Reduce`FreeVariables[expr], {{v_,___}->v, _->None}],
    min,
    max
]

EvaluatedAt[expr_, x_, min_, max_] := (expr /. x->max) - (expr /. x->min)

CurrentValue[EvaluationNotebook[], {InputAliases,"at"}] = TemplateBox[
    {"\[SelectionPlaceholder]", "Automatic", "\[Placeholder]", "\[Placeholder]"},
    "EvaluatedAt",
    DisplayFunction->(
        SubsuperscriptBox[
            RowBox[{
                #1,
                StyleBox[
                    "\[VerticalLine]",
                    SpanMinSize->1.5,
                    SpanSymmetric->False
                ]
            }],
            RowBox[{"\[MediumSpace]", #3}],
            RowBox[{"\[MediumSpace]", #4}]
        ]&
    )
];

CurrentValue[EvaluationNotebook[], {InputAliases,"at2"}] = TemplateBox[
    {"\[SelectionPlaceholder]", "\[Placeholder]", "\[Placeholder]", "\[Placeholder]"},
    "EvaluatedAt",
    DisplayFunction->(
        SubsuperscriptBox[
            RowBox[{
                #1,
                StyleBox[
                    "\[VerticalLine]",
                    SpanMinSize->1.5,
                    SpanSymmetric->False
                ]
            }],
            RowBox[{"\[MediumSpace]", #2, "=", #3}],
            RowBox[{"\[MediumSpace]", #4}]
        ]&
    )
];
$\endgroup$
1
$\begingroup$
diff = {x, a, b} \[Function] expr \[Function] #2 - # & @@ (Function @@ {x, expr}) /@ {a, b}

The usage of diff is the same as that in LLlAMnYP's answer.

$\endgroup$

Your Answer

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

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