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$
  • 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$ – Wojciech Artichowicz Dec 3 '15 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$ – Shou Ya Dec 3 '15 at 11:47
  • $\begingroup$ Could you provide an actual simple example of such expression? $\endgroup$ – Wojciech Artichowicz Dec 3 '15 at 11:52
  • 2
    $\begingroup$ First@Differences[expr /. {{x->a}, {x->b}}]? Or (expr /. x->b) - (expr /. x->a}? $\endgroup$ – Michael E2 Dec 3 '15 at 12:08
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 *)
| improve this answer | |
$\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];
| improve this answer | |
$\endgroup$
  • $\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 '15 at 14:44
2
$\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}]
        ]&
    )
];
| improve this answer | |
$\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.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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