expression = 2 - (1 + E^x)/(1 + x);
TL;DR : Try automatically mapping Asymptotic to sub expressions until one of the results fits your criteria.
Code
(code explanation after discussion below)
Note : …=\[Ellipsis]
sub…expressions =
DeleteDuplicates@Cases[expression, _, All];
(sub…expressions
// Map[(expression /. # -> Asymptotic[#, x -> Infinity]) &]
// DeleteDuplicates
// DeleteCases[expression]
// Select[Limit[# - expression, x -> Infinity] == 0 &]
)
$$ \left\{2-\frac{e^x}{x+1}\right\} $$
EDIT : The following code might be faster and might handle better expressions that depend on multiple variables. This modification is not included in the explanation section below.
sub…expressions =
DeleteDuplicates@
DeleteCases[x]@Cases[expression, _?(Not@*FreeQ[x]), {1, Infinity}]
asymptotic[expression_, sub…expression_, var_, limit_] :=
expression /.
sub…expression :>
Asymptotic[sub…expression, x -> limit]
j=1;
While[approximation=
asymptotic[expression
,
sub…expressions[[j]]
,
x
,
Infinity
]
;
j++
;
approximation===expression ∨
Not[Limit[approximation-expression,x->Infinity]===0]
]
approximation
Discussion
(code section below)
It seems that Asymptotic replaces every part of the expression with it's approximation which is similar to the behavior of ReplaceAll. The problem is then controlling how the replacements occur. Such a problem may occur with ReplaceAll as well.
There are different techniques to gain control on how replacements occur and they may be applied to this problem. For example, using ReplaceAt or MapAt and Asymptotic to control where the transformations occur depending on their position or using pattern matching on sub expressions.
If the expression is not too large we can just try everything and select the ones that give the result we want. An alternative would require some sort of smart algorithm that is aware of the expression as a whole and that applies Asymptotic at the right parts based on a criteria from the user. That seems rather complicated (albeit an artificial neural network might find a pattern) so for now it might be significantly easier to just try everything and select the results that satisfy the criteria. A simplified version of that is what the code below does.
Code explanation
Find sub expressions:
Note : …=\[Ellipsis]
sub…expressions =
DeleteDuplicates@Cases[2 - (1 + E^x)/(1 + x), _, All];
$$\left\{2,-1,1,e,x,e^x,e^x+1,x+1,\frac{1}{x+1},-\frac{e^x+1}{x+1},2-\frac{e^x+1}{x+1}\right\}$$
To visualize what will follow, consider applying a function h with no definition:
formal…list = (expression /. # -> h[#]) & /@
sub…expressions
$$ \left\{h(2)-\frac{e^x+1}{x+1},h(-1) \left(e^x+1\right) (x+1)^{h(-1)}+2,2-\frac{h(1)+e^x}{h(1)+x},2-\frac{h(e)^x+1}{x+1},2-\frac{e^{h(x)}+1}{h(x)+1},2-\frac{h\left(e^x\right)+1}{x+1},2-\frac{h\left(e^x+1\right)}{x+1},2-\frac{e^x+1}{h(x+1)},2-\left(e^x+1\right) h\left(\frac{1}{x+1}\right),h\left(-\frac{e^x+1}{x+1}\right)+2\right\} $$
Note that not all combinations of applications of h are present. For every element in sub…expressions, every occurrence of that element in the original expression is replaced by h[element] at the same time via the replacement rule. This makes the computation a bit faster than trying all possible combinations but it might discard combinations that were the right combinations to consider. In the following, the above subset will be sufficient however if more combinations are needed we could use:
ReplaceAt[expression, b_ :> h[b], #] & /@
Position[expression, _, Heads -> False]
Below h is replaced with Asymptotic using the desired limit :
asymptotic…list =
formal…list /. h -> (Asymptotic[#, x -> Infinity] &) //
DeleteDuplicates // DeleteCases[expression]
$$\left\{2-\frac{e^x}{x+1},2-\frac{e^x+1}{x},2-\frac{e^x}{x}\right\}$$
Now choose the approximation such that expression-approximation goes to zero in the desired limit:
Select[asymptotic…list,
Limit[# - expression, x -> Infinity] == 0 &]
$$ \left\{2-\frac{e^x}{x+1}\right\} $$
Note: I used Limit but in my experience Limit is rather slow.Series[# - expression,{x,Infinity,0}]//Normal does not seem to be sufficient with the exponential term.
limitHold[direction_][expr_]:=Module[{lim=Limit[expr,direction]},If[lim==Infinity,Unevaluated@expr,lim]], thenlimitHold[x->Infinity]/@Expand[(Exp@x+1)/(x+1)+2]gives the desired result. – Lacia Aug 12 '22 at 00:45Log[x + 1]/Log[x]and got zero (expected one) – Anixx Aug 12 '22 at 00:50Log[x + 1]/Log[x]has only one term, and you need replace/@by@. The original example contains three terms, so I useMap/@so thatlimitHoldacts on each single term and then they get added together. – Lacia Aug 12 '22 at 00:541 + E^x (-1 + x), it returns-Infinitybut I want infinite terms left unevaluated. Moreover, the desired result should be positive infinite. – Anixx Aug 12 '22 at 01:02lim==Infinitybylim==Infinity||lim==-Infinity. Let me explain a bit more about my trick. The functionlimitHoldevaluateLimitas usual, and if the result isInfinityit will return the orginial expression.Mapbasically doesa+b+ctof[a]+f[b]+f[c]. Maybe confused you,Unevaluateddoes nothing and you can delete it. This trick applies only for some simple expressions and I don't know how to deal with the original question you put on MO systematically. – Lacia Aug 12 '22 at 01:11f = 2 - (E^x + 1)/(x + 1); f2 = List @@ Map[Apart, f, Infinity]; (* {2,-(1/(1+x)),-(E^x/(1+x))} *) Total@Select[f2, (Limit[#, x -> Infinity] != 0 &)] (* 2-E^x/(1+x) *)– Akku14 Aug 12 '22 at 11:05