Question on "smart" replacing in mathematica - wolfram-mathematica

How do I tell mathematica to do this replacement smartly? (or how do I get smarter at telling mathematica to do what i want)
expr = b + c d + ec + 2 a;
expr /. a + b :> 1
Out = 2 a + b + c d + ec
I expect the answer to be a + cd + ec + 1. And before someone suggests, I don't want to do a :> 1 - b, because for aesthetic purposes, I'd like to have both a and b in my equation as long as the a+b = 1 simplification cannot be made.
In addition, how do I get it to replace all instances of 1-b, -b+1 or -1+b, b-1 with a or -a respectively and vice versa?
Here's an example for this part:
expr = b + c (1 - a) + (-1 + b)(a - 1) + (1 -a -b) d + 2 a

You can use a customised version of FullSimplify by supplying your own transformations to FullSimplify and let it figure out the details:
In[1]:= MySimplify[expr_,equivs_]:= FullSimplify[expr,
TransformationFunctions ->
Prepend[
Function[x,x-#]&/#Flatten#Map[{#,-#}&,equivs/.Equal->Subtract],
Automatic
]
]
In[2]:= MySimplify[2a+b+c*d+e*c, {a+b==1}]
Out[2]= a + c(d + e) + 1
equivs/.Equal->Subtract turns given equations into expressions equal to zero (e.g. a+b==1 -> a+b-1). Flatten#Map[{#,-#}&, ] then constructs also negated versions and flattens them into a single list. Function[x,x-#]& /# turns the zero expressions into functions, which subtract the zero expressions (the #) from what is later given to them (x) by FullSimplify.
It may be necessary to specify your own ComplexityFunction for FullSimplify, too, if your idea of simple differs from FullSimplify's default ComplexityFunction (which is roughly equivalent to LeafCount), e.g.:
MySimplify[expr_, equivs_] := FullSimplify[expr,
TransformationFunctions ->
Prepend[
Function[x,x-#]&/#Flatten#Map[{#,-#}&,equivs/.Equal->Subtract],
Automatic
],
ComplexityFunction -> (
1000 LeafCount[#] +
Composition[
Total,Flatten,Map[ArrayDepth[#]#&,#]&,CoefficientArrays
][#] &
)
]
In your example case, the default ComplexityFunction works fine, though.

For the first case, you might consider:
expr = b + c d + ec + 2 a
PolynomialReduce[expr, {a + b - 1}, {b, a}][[2]]
For the second case, consider:
expr = b + c (1 - a) + (-1 + b) (a - 1) + (1 - a - b) d + 2 a;
PolynomialReduce[expr, {x + b - 1}][[2]]
(% /. x -> 1 - b) == expr // Simplify
and:
PolynomialReduce[expr, {a + b - 1}][[2]]
Simplify[% == expr /. a -> 1 - b]

Related

How to fix 'Equations may not give solutions for all "solve" variables' error

I am attempting a problem that can be solved with MUC (method of undetermined coefficients).
However, when I use the Solve function, it gives an error.
y[x_] := a x^3 + b x^2 + c x + d
Solve[{y''[x] + 2 y'[x] + y[x] == x^3}, {a, b, c, d}]
[ERROR]:
Solve::svars: Equations may not give solutions for all "solve" variables.
Shouldn't this solve for all variables in the set?
Thank You for your help :)
Looks like some extra methodology is needed for this.
As you stated, a function with the finite family of derivatives for x^3 is
y[x_] := a x^3 + b x^2 + c x + d
Equating coefficients
sol = Solve[Thread[CoefficientList[
y''[x] + 2 y'[x] + y[x], x] == CoefficientList[x^3, x]]]
{{a -> 1, b -> -6, c -> 18, d -> -24}}
Checking the results
FullSimplify[y''[x] + 2 y'[x] + y[x] == x^3 /. sol]
{True}

How to replace implicit subexpressions in Mathematica?

I have this expression in Mathematica:
(a^2 (alpha + beta)^2)/(b^2 + c^2) + (a (alpha + beta))/(b^2 + c^2) + 1
As you can see, the expression has a couple of subexpressions that repeat throughout it.
I want to be able to replace a/(b^2+c^2) with d and alpha+beta with gamma.
The final expression should then be:
1+d*gamma+a*d*gamma^2
I have much more complicated expressions where being able to do this would greatly simplify my work.
I have tried Googling this question, and I only find answers that use FactorTerms and ReplaceRepeated, but do not work consistently and for a more complicated expression like this one. I am hoping that someone here has the answer.
The hard part for the case at hand is the rule for d. Perhaps, there are simpler ways to do it, but one way is to expand the powers to products, to make it work. Let's say this is your expression:
expr = (a^2 (alpha + beta)^2)/(b^2 + c^2) + (a (alpha + beta))/(b^2 + c^2) + 1
and these are the rules one would naively write:
rules = {a/(b^2 + c^2) -> d, alpha + beta -> gamma}
What we would like to do now is to expand powers to products, in both expr and rules. The problem is that even if we do, they will auto-evaluate back to powers. To prevent that, we'll need to wrap them into, for example, Hold. Here is a function which will help us:
Clear[withExpandedPowers];
withExpandedPowers[expr_, f_: Hold] :=
Module[{times},
Apply[f,
Hold[expr] /. x_^(n_Integer?Positive) :>
With[{eval = times ## Table[x, {n}]}, eval /; True] /.
times -> Times //.
HoldPattern[Times[left___, Times[middle__], right___]] :>
Times[left, middle, right]]];
For example:
In[39]:= withExpandedPowers[expr]
Out[39]= Hold[1+(a (alpha+beta))/(b b+c c)+((alpha+beta) (alpha+beta) a a)/(b b+c c)]
The following will then do the job:
In[40]:=
ReleaseHold[
withExpandedPowers[expr] //.
withExpandedPowers[Map[MapAt[HoldPattern, #, 1] &, rules], Identity]]
Out[40]= 1 + d gamma + a d gamma^2
We had to additionally wrap the l.h.s. of rules in HoldPattern, to prevent products from collapsing back to powers there.
This is just one case where we had to fight the auto-simplification mechanism of Mathematica, but for this sort of problems this will be the main obstacle. I can't assess how robust this will be for larger and more complex expressions.
Using ReplaceRepeated:
(a^2 (alpha + beta)^2)/(b^2 + c^2) + (a (alpha + beta))/(b^2 + c^2) +
1 //. {a/(b^2 + c^2) -> d, alpha + beta -> gamma}
Or using TransformationFunctions:
FullSimplify[(a^2 (alpha + beta)^2)/(b^2 +
c^2) + (a (alpha + beta))/(b^2 + c^2) + 1,
TransformationFunctions -> {Automatic, # /.
a/(b^2 + c^2) -> d &, # /. alpha + beta -> gamma &}]
Both give:
1 + gamma (d + (a^2 gamma)/(b^2 + c^2))
I modestly --- I am not a computer scientist --- think this is simpler than all other proposed solutions
1+a(alpha+beta)/(b^2 + c^2) +a^2(alpha+beta)^2/(b^2 + c^2) \\.
{a^2-> a z, a/(b^2 + c^2)-> d,alpha+\beta -> gamma,z-> a}

Difference between definite and indefinite integration in Mathematica?

I have noticed that mathematica chokes out on certain definite integrals, but if I do an indeifinite integration and subtract the limiting values of the resulting function, it would readily give me an answer.
Are there different algorithms to compute the definite and indefinite integrals? Is there some reason the above procedure described isn't done by Mathematica manually?
Examples:
As people in the comment asked for examples, here are two.
Timing[Integrate[(r - c x)/(r^2 + c^2 - (2 r) c x)^(3/2), x]]
Out:={0.010452,(-c+r x)/(r^2 Sqrt[c^2+r^2-2 c r x])}
Gets the output immediately. While,
Integrate[(r - c x)/(r^2 + c^2 - (2 r) c x)^(3/2), {x, -1, 1}]
Keeps computing and slows my old computer down. After a bit of time it returns an unneccesarily long result with a lot of cases. This is Mathematica 7. There are no singularities in this integral or running into complex numbers etc. To get the value, let's abort the computation running for about a minutes now and find the value using the fundamental theorem of calculus manually.
g = (r - c x)/(r^2 + c^2 - (2 r) c x)^(3/2)
l = Integrate[g, x] /. x -> -1;
u = Integrate[g, x] /. x -> 1;
u - l
Out:= (-c+r)/(r^2 Sqrt[c^2-2 c r+r^2])-(-c-r)/(r^2 Sqrt[c^2+2 c r+r^2])
FullSimplify[%]
Out:= ((-c+r)/Sqrt[(c-r)^2]+(c+r)/Sqrt[(c+r)^2])/r^2
Which is actually correct. Finally, for completeness, let's compare the output and the time for the definite integral:
Timing[Integrate[(r - c x)/(r^2 + c^2 - (2 r) c x)^(3/2), {x, -1,
1}]]
Out:= {174.52,If[(Re[c/r+r/c]>=2||2+Re[c/r+r/c]<=0||c/r+r/c\[NotElement]Reals)&&((Im[r] Re[c]+Im[c] Re[r]<=0&&((Im[c]+Im[r]) (Re[c]+Re[r])>=0||Im[c]^3 Re[r]+Im[r] Re[c] (Im[r]^2-Re[c]^2+Re[r]^2)>=Im[c] (Im[c] Im[r] Re[c]+Re[r] (Im[r]^2 ... blah blah half a page
Note the three minutes computation time and the very confused answer.
An actual example from my work, I noticed it and was puzzled but forgot about it after the deadline submission, until today when I faced the same problem again.
f = 1/((-I c + k^2/2 - 1/2 (a + k)^2) (I d + k^2/2 -
1/2 (-b + k)^2)) + 1/((I c + k^2/2 - 1/2 (-a + k)^2) (I c + I d +
k^2/2 - 1/2 (-a - b + k)^2)) + 1/((I d + k^2/2 -
1/2 (-b + k)^2) (I c + I d + k^2/2 -
1/2 (-a - b + k)^2)) + 1/((I c + k^2/2 - 1/2 (-a + k)^2) (-I d +
k^2/2 - 1/2 (b + k)^2)) + 1/((-I c + k^2/2 -
1/2 (a + k)^2) (-I c - I d + k^2/2 -
1/2 (a + b + k)^2)) + 1/((-I d + k^2/2 - 1/2 (b + k)^2) (-I c -
I d + k^2/2 - 1/2 (a + b + k)^2))
When I tried the definite integral, I waited and waited, after several hours (true!) I finally decided to try the workaround that worked in no time:
fl = Integrate[f, k] /. k -> -1 ;
fu = Integrate[f, k] /. k -> 1 ;
F = fu - fl;
F1 = F /. {a -> .01, c -> 0, d -> 1};
Please note that I am not talking about singularities as one comment suggested. Integrate[1/x, {x, -1, 1}] almost immediately returns Integrate::idiv: Integral of 1/x does not converge on {-1,1}. >> which is a perfectly reasonable output.
I think Daniel is right in his comment above: "Most likely is the definite integration code is checking for singularities on the integration path"
Just look:
Timing#Integrate[(r - c x)/(r^2 + c^2 - (2 r) c x)^(3/2), {x, -1, 1}]
Result -> None, I got bored waiting and aborted the calc
While:
Timing#Integrate[(r - c x)/(r^2 + c^2 - (2 r) c x)^(3/2), {x, -1, 1},
          Assumptions -> {r ∈ Reals && c ∈ Reals && c != r && c != -r}]
->{3.688, (-Sign[c - r] + Sign[c + r])/r^2}
So, it is a matter of which conditions you specify for your constants.
Another way is suggested in Simon's comment above:
Timing#Integrate[(r - c x)/(r^2 + c^2 - (2 r) c x)^(3/2), {x, -1, 1},
GenerateConditions -> False]
{10.375, ((-c + r)/Sqrt[(c - r)^2] + (c + r)/Sqrt[(c + r)^2])/r^2}
And finally, you may also do:
Timing#Integrate[(r - c x)/(r^2 + c^2 - (2 r) c x)^(3/2), {x, -1, 1},
GenerateConditions -> True]
{16.45, ConditionalExpression[.. A long expression ...., Re[c^2 + r^2] > 0]}
Belisarius answered this. I just wanted to be a bit specific about what I meant in the comment, and how it applies to this example.
The denominator in the integrand makes it clear that we have a problem if, say, r and c are real, positive, and r
In[1]:= InputForm[Timing[Integrate[(r - c*x)/(r^2 + c^2 - 2*r*c*x)^(3/2),
{x, -1, 1}, Assumptions->r>c>0]]]
Out[1]//InputForm= {2.33, 2/r^2}
Absent useful assumptions, Integrate can take significant time to sort out regions of good vs bad behavior. The technology under the hood is daunting (inequality handling can be that way). And perhaps it is not everywhere applied in the most efficient ways possible.
Further information may be found at
http://library.wolfram.com/infocenter/Conferences/5832/
or
http://dl.acm.org/citation.cfm?doid=2016567.2016569
Daniel Lichtblau

Input list to a pure function

The syntax for a pure function is something like (1+#1+#2)&[a,b], which gives 1+a+b. Now I want to supply the output from some function which looks like {a,b} to the function above, i.e., something like (1+#1+#2)&{a,b}, but with the correct syntax, as that obviously doesn't work. How do I go about doing this?
The easiest approach is to use Apply (##):
In[4]:= (1 + #1 + #2) & ## {a, b}
Out[4]= 1 + a + b
To provide some alternatives, you can also include the Apply within the function if that is more convenient:
f = (1 + # + #2) & ## # &;
f # {a, b}
1 + a + b
Optionally, you can index parts manually:
f = (1 + #[[1]] + #[[2]]) &;
Finally, you may already know this, but for others reading this question:
g[{x_, y_}] := 1 + x + y
g # {a, b}
1 + a + b
Here's a version that is an ordinary function (ie can use square brackets) that will take an arbitrary list. The Apply has been moved inside the function and the ## means SlotSequence (c.f. _ and __ in pattern matching)
In[1]:= (1 + ##&## #) &[{a, b}]
(1 + ##&## #) &[{a, b, c, d, e}]
Out[1]= 1 + a + b
Out[2]= 1 + a + b + c + d + e

How to get rid of denominator in numerator and denominator in mathematica

I have the following expression
(-1 + 1/p)^B/(-1 + (-1 + 1/p)^(A + B))
How can I multiply both the denominator and numberator by p^(A+B), i.e. to get rid of the denominators in both numerator and denominator? I tried varous Expand, Factor, Simplify etc. but none of them worked.
Thanks!
I must say I did not understand the original question. However, while trying to understand the intriguing solution given by belisarius I came up with the following:
expr = (-1 + 1/p)^B/(-1 + (-1 + 1/p)^(A + B));
Together#(PowerExpand#FunctionExpand#Numerator#expr/
PowerExpand#FunctionExpand#Denominator#expr)
Output (as given by belisarius):
Alternatively:
PowerExpand#FunctionExpand#Numerator#expr/PowerExpand#
FunctionExpand#Denominator#expr
gives
or
FunctionExpand#Numerator#expr/FunctionExpand#Denominator#expr
Thanks to belisarius for another nice lesson in the power of Mma.
If I understand you question, you may teach Mma some algebra:
r = {(k__ + Power[a_, b_]) Power[c_, b_] -> (k Power[c, b] + Power[a c, b]),
p_^(a_ + b_) q_^a_ -> p^b ( q p)^(a),
(a_ + b_) c_ -> (a c + b c)
}
and then define
s1 = ((-1 + 1/p)^B/(-1 + (-1 + 1/p)^(A + B)))
f[a_, c_] := (Numerator[a ] c //. r)/(Denominator[a ] c //. r)
So that
f[s1, p^(A + B)]
is
((1 - p)^B*p^A)/((1 - p)^(A + B) - p^(A + B))
Simplify should work, but in your case it doesn't make sense to multiply numerator and denominator by p^(A+B), it doesn't cancel denominators

Resources