Suppose you have the following expression:
expr = f[p^(3) * q^(5) * m] * f[p^(-2) * q^(-5) * m] * f[p^(1/2) * q^(1) * m] + 5 * f[p^(1) * q^(2) * n] * f[q^(-2) * n] + s * f[p^(h) * q^(r) * j] * f[p^(1-h) * q^(-r) * j].
Moreover, suppose that the function f is such that
f[p^(a) * q^(b) * x] * f[p^(1-a) * q^(-b) * x] == 1
for any value (numerical or symbolic) of the exponents a,b and for any x.
This means that
expr == f[p^(1/2) * q^(1) * m] + 5 + s.
How can I teach Mathematica to recognise this property of f and then simplify expr according to it?
I tried to implement it as the following rule
/.f[p^(a_)*q^(b_)*x_]f[p^(1-a_)*q^(-b_)*x_]->1
but it doesn't work. It only works if you specify the numerical value of the exponents a and b, but not if you want them to be generic.
What is the right way to write such a rule?
The answer here may provide a solution : How to insert a subexpression into a larger expression in Mathematica? c/o Rojo
For example, using your expression expr and a larger expression A
expr = f[p^(a)*q^(b)*x] f[p^(1 - a)*q^(-b)*x];
A = 3 expr + z (f[p^(a)*q^(b)*x]) + y expr
doThat[expr_, vars_List] := Expand[Simplify[expr /. Flatten[
Solve[# == ToString##, First#Variables##] & /# vars]],
Alternatives ## ToString /# vars] /.
Thread[ToString /# vars -> vars];
done = doThat[A, {expr}];
ans = Simplify[done //. expr -> 1]
3 + y + z f[p^a q^b x]
The expected answer.
For general cases as per the comment, a pattern can be used, e.g.
expr = f[p^(a)*q^(b)*x] f[p^(1 - a)*q^(-b)*x];
A = 3 expr + z (f[p^(a)*q^(b)*x]) +
y f[p^(h)*q^(l)*x] f[p^(1 - h)*q^(-l)*x];
done = doThat[A, {expr}];
ans = Simplify[done //.
f[p^(a_)*q^(b_)*x] f[p^(1 - a_)*q^(-b_)*x] -> 1]
3 + y + z f[p^a q^b x]
But in the end it can simply be done by
A /. f[p^(a_)*q^(b_)*x] f[p^(1 - a_)*q^(-b_)*x] -> 1
3 + y + z f[p^a q^b x]
2nd edit
A = (3 f[p^(a)*q^(b)*x] f[p^(1 - a)*q^(-b)*x] +
z (f[p^(a)*q^(b)*x]) +
y f[p^(h)*q^(l)*x] f[p^(1 - h)*q^(-l)*x] f[p m])
A /. h -> 2 /. f[p^(a_)*q^(b_)*x_] f[p^(1 - a_)*q^(-b_)*x_] -> 1
3 + z f[p^a q^b x] + y f[m p] f[(q^-l x)/p] f[p^2 q^l x]
When h is 2 the second replacement no longer applies to the expression containing p^(1 - h) because the form has become p^(-1).
On the other hand, keeping the variables symbolic by using Z instead of 2
A /. h -> Z /. f[p^(a_)*q^(b_)*x_] f[p^(1 - a_)*q^(-b_)*x_] -> 1
3 + y f[m p] + z f[p^a q^b x]
I'm trying this code
g2[x_] = 1/(2 a (a^2 - b^2)) (-a b^2 ϕ1[x] - b^2 ϕ2[x] + a ϕ3[x] + ϕ4[x]) + c2[x];
g4[x_] = 1/(2 a (a^2 - b^2)) (-a^2 b ϕ1[x] - a^2 ϕ2[x] + b ϕ3[x] + ϕ4[x]) + c4[x];
DSolve[{h1[t] + g2[a t] + h3[t] + g4[b t] == μ1[t],
h1'[t] + g2'[a t] + h3'[t] + g4'[b t] == μ2[t]}, {h1[t], h3[t]},t]
But Mathematica's response is DSolve duplicate
DSolve[{c2[a t] + c4[b t] + h1[t] +
h3[t] + (-a b^2 [Phi]1[a t] - b^2 [Phi]2[a t] +
a [Phi]3[a t] + [Phi]4[a t])/(
2 a (a^2 - b^2)) + (-a^2 b [Phi]1[b t] - a^2 [Phi]2[b t] +
b [Phi]3[b t] + [Phi]4[b t])/(2 a (a^2 - b^2)) == [Mu]1[t],
Derivative[1][c2][a t] + Derivative[1][c4][b t] +
Derivative[1][h1][t] +
Derivative[1][h3][t] + (-a b^2 Derivative[1][[Phi]1][a t] -
b^2 Derivative[1][[Phi]2][a t] + a Derivative[1][[Phi]3][a t] +
Derivative[1][[Phi]4][a t])/(
2 a (a^2 - b^2)) + (-a^2 b Derivative[1][[Phi]1][b t] -
a^2 Derivative[1][[Phi]2][b t] + b Derivative[1][[Phi]3][b t] +
Derivative[1][[Phi]4][b t])/(2 a (a^2 - b^2)) == [Mu]2[
t]}, {h1[t], h3[t]}, t]
What am I doing wrong?
By combining your responses to people's questions when you posted this yesterday and again today on mathematica.stackexchange.com, by inspection the solution to your system is
{h1[t] + g2[a t] + h3[t] + g4[b t] == μ1[t], μ2[t] == μ1'[t]}
because your second equation inside DSolve is simply the derivative of your first, as long as μ2[t] == μ1'[t]. That uses all the available information to "solve" your system and without more information I don't believe anything more can be done. At the moment I don't see a way to coax DSolve into seeing this is the solution.
I have Mathematica expressions involving the special functions Erf[x] and Erfc[x], but I'd like to express them in terms of the scaled and translated version
F[x_] := CDF[NormalDistribution[0,1]][x]
throughout the notebook. This is because F[x] has an easy interpretation in the context of my problem.
Not sure whether I understand your problem, but I'm trying to answer my interpretation of what your saying.
So you have an expression in erf and erfc, like this
expr = Erf[x] + 1/Erfc[x] + Sin[Erf[x]] + Cos[Erfc[x]]
All it takes to replace erf and erfc with F is this:
expr //. {Erfc[x_] -> 2 F[-(x) Sqrt[2]], Erf[x_] -> 1 - Erfc[x]}
(* ==> 1 + Cos[2 F[-Sqrt[2] x]] + 1/(2 F[-Sqrt[2] x]) -
2 F[-Sqrt[2] x] + Sin[1 - 2 F[-Sqrt[2] x]]
*)
which with your definition of F[x] is indeed the same:
1 + Cos[2 F[-Sqrt[2] x]] + 1/(2 F[-Sqrt[2] x]) - 2 F[-Sqrt[2] x] +
Sin[1 - 2 F[-Sqrt[2] x]] /. F[x_] -> CDF[NormalDistribution[0, 1]][x]
(* ==> 1 + Cos[Erfc[x]] + 1/Erfc[x] - Erfc[x] + Sin[1 - Erfc[x]] *)
Evaluating the following integral should be non-zero, and mathematica correctly gives a non-zero result
Integrate[ Cos[ (Pi * x)/2 ]^2 * Cos[ (3*Pi*x)/2 ]^2, {x, -1, 1}]
However, attempting a more general integral:
FullSimplify[
Integrate[Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/2],
{x, -1, 1}],
Element[{m, n}, Integers]]
yields zero, which is definitely not true for m = n = 1
I'd expect a conditional expression. Is it possible to "tell" mathematica about my constraints on m and n before the integral is evaluated so that it handles the special cases properly?
While I'm late to the party, no one has given a complete solution, thus far.
Sometimes, it pays to understand the integrand better before you integrate. Consider,
ef = TrigReduce[
Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/2]]/.
Cos[a_] :> Cos[ Simplify[a, Element[{m,n}, Integers] ] ]
which returns
(2 Cos[(m - n) Pi x] + Cos[(1 + m - n) Pi x] + Cos[(1 - m + n) Pi x] +
Cos[(m + n) Pi x] + 2 Cos[(1 + m + n) Pi x] + Cos[(2 + m + n) Pi x] )/8
where each term has the form Cos[q Pi x] with integral q. Now, there are two cases to consider when integrating Cos[q Pi x] over -1 to 1 (where q is integral): q == 0 and q != 0.
Case q = 0: This is a special case that Mathematica misses in the general result, as it implies a constant integrand. (I'll often miss it, also, when doing this by hand, so Mathematica isn't entirely to blame.) So, the integral is 2, in this case.
Strictly speaking, this isn't true. When told to integrate Cos[ q Pi x ] over -1 < x < 1, Mathematica returns
2 Sin[ Pi q ]/( Pi q )
which is 0 except when q == 0. At that point, the function is undefined in the strict sense, but Limit[Sin[x]/x, q -> 0] == 1. As the singularity at q == 0 is removable, the integral is 2 when q -> 0. So, Mathematica does not miss it, it is just in a form not immediately recognized.
Case q != 0: Since Cos[Pi x] is periodic with period 2, an integral of Cos[q Pi x] from x == -1 to x == 1 will always be over q periods. In other words,
Integrate[ Cos[q Pi x], {x, -1, 1},
Assumptions -> (Element[ q, Integers ] && q != 0) ] == 0
Taken together, this means
Integrate[ Cos[q Pi x], {x, -1, 1}, Assumptions -> Element[ q, Integers ] ] ==
Piecewise[{{ q == 0, 2 }, { 0, q!=0 }}]
Using this, we can integrate the expanded form of the integrand via
intef = ef /. Cos[q_ Pi x] :> Piecewise[{{2, q == 0}, {0, q != 0}}] //
PiecewiseExpand
which admits non-integral solutions. To clean that up, we need to reduce the conditions to only those that have integral solutions, and we might as well simplify as we go:
(Piecewise[{#1,
LogicalExpand[Reduce[#2 , {m, n}, Integers]] //
Simplify[#] &} & ### #1, #2] & ## intef) /. C[1] -> m
\begin{Edit}
To limit confusion, internally Piecewise has the structure
{ { { value, condition } .. }, default }
In using Apply (##), the condition list is the first parameter and the default is the second. To process this, I need to simplify the condition for each value, so then I use the second short form of Apply (###) on the condition list so that for each value-condition pair I get
{ value, simplified condition }
The simplification process uses Reduce to restrict the conditions to integers, LogicalExpand to help eliminate redundancy, and Simplify to limit the number of terms. Reduce internally uses the arbitrary constant, C[1], which it sets as C[1] == m, so we set C[1] back to m to complete the simplification
\end{Edit}
which gives
Piecewise[{
{3/4, (1 + n == 0 || n == 0) && (1 + m == 0 || m == 0)},
{1/2, Element[m, Integers] &&
(n == m || (1 + m + n == 0 && (m <= -2 || m >= 1)))},
{1/4, (n == 1 + m || (1 + n == m && (m <= -1 || m >= 1)) ||
(m + n == 0 && (m >= 1 || m <= 0)) ||
(2 + m + n == 0 && (m <= -1 || m >= 0))) &&
Element[m, Integers]},
{0, True}
}
as the complete solution.
Another Edit: I should point out that both the 1/2 and 1/4 cases include the values for m and n in the 3/4 case. It appears that the 3/4 case may be the intersection of the other two, and, hence, their sum. (I have not done the calc out, but I strongly suspect it is true.) Piecewise evaluates the conditions in order (I think), so there is no chance of getting this incorrect.
Edit, again: The simplification of the Piecewise object is not as efficient as it could be. At issue is the placement of the replacement rule C[1] -> m. It happens to late in the process for Simplify to make use of it. But, if it is brought inside the LogicalExpand and assumptions are added to Simplify
(Piecewise[{#1,
LogicalExpand[Reduce[#2 , {m, n}, Integers] /. C[1] -> m] //
Simplify[#, {m, n} \[Element] Integers] &} & ### #1, #2] & ## intef)
then a much cleaner result is produce
Piecewise[{
{3/4, -2 < m < 1 && -2 < n < 1},
{1/2, (1 + m + n == 0 && (m >= 1 || m <= -2)) || m == n},
{1/4, 2 + m + n == 0 || (m == 1 + n && m != 0) || m + n == 0 || 1 + m == n},
{0, True}
}]
Not always zero ...
k = Integrate[
Cos[(Pi x)/2]^2 Cos[((2 (n) + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/ 2],
{x, -1, 1}, Assumptions -> Element[{m, n}, Integers]];
(*Let's find the zeroes of the denominator *)
d = Denominator[k];
s = Solve[d == 0, {m, n}]
(*The above integral is indeterminate at those zeroes, so let's compute
the integral again there (a Limit[] could also do the work) *)
denZ = Integrate[
Cos[(Pi x)/2]^2 Cos[((2 (n) + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/ 2] /.s,
{x, -1, 1}, Assumptions -> Element[{m, n}, Integers]];
(* All possible results are generated with m=1 *)
denZ /. m -> 1
(*
{1/4, 1/2, 1/4, 1/4, 1/2, 1/4}
*)
Visualizing those cases:
Plot[Cos[(Pi x)/2]^2 Cos[((2 (n) + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/2]
/. s /. m -> 1, {x, -1, 1}]
Compare with a zero result integral one:
Plot[Cos[(Pi x)/2]^2 Cos[((2 (n) + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/ 2]
/. {m -> 1, n -> 4}, {x, -1, 1}]
If you just drop the whole FullSimplify part, mathematica does the integration neatly for you.
Integrate[
Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/
2], {x, -1, 1}]
To include the condition that m and n are integers, it's better to use the Assumptions option in Integrate.
Integrate[
Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/
2], {x, -1, 1}, Assumptions -> Element[{m, n}, Integers]]
Lets use some conclusive conditions about the two integers m=n||m!=n.
Assuming[{(n \[Element] Integers && m \[Element] Integers && m == n)},
Integrate[Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/2],
{x, -1, 1}]]
The answer for this case is 1/2. For the other case it is
Assuming[{(n \[Element] Integers && m \[Element] Integers && m != n)},
Integrate[
Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/
2], {x, -1, 1}]]
and the answer is 0.
However I am amazed to see that if we add this two conditions as an "either or stuff", Mathematica returns one zero after integration. I mean in case of the following I am getting only zero but not ``1/2||0`.
Assuming[{(n \[Element] Integers && m \[Element] Integers &&
m == n) || (n \[Element] Integers && m \[Element] Integers &&
m != n)},
Integrate[
Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/
2], {x, -1, 1}]]
By the way we can see the conditions exclusively where this integral becomes Indeterminate.
res = Integrate[
Cos[(Pi x)/2]^2 Cos[((2 n + 1) Pi x)/2] Cos[((2 m + 1) Pi x)/
2], {x, -1, 1}] // Simplify
The output is here.
Now lets see all the relations m and n can have to make the Integral bad!
BadPart = (res*4 Pi);
Flatten#(Solve[(Denominator[#] == 0), m] & /#
Table[BadPart[[i]], {i, 1, Length#BadPart}] /.
Rule -> Equal) // TableForm
So these are the special cases which as Sjoerd mentioned are having infinite instances.
BR
Is there a way to assign a random value to p1, p2, p3 and p4 for the following equation?
p1 y1 + p2 y2 + p3 y3 = p4
given that y1, y2 and y3 are variables to be solved.
The easiest(?) way is to Thread a list of random values over a replacement rule:
For example:
p1 y1 + p2 y2 + p3 y3 == p4 /. Thread[{p1, p2, p3, p4} -> RandomReal[{0, 1}, 4]]
(* 0.345963 y1 + 0.333069 y2 + 0.565556 y3 == 0.643419 *)
Or, inspired by Leonid, you can use Alternatives and pattern matching:
p1 y1 + p2 y2 + p3 y3 == p4 /. p1 | p2 | p3 | p4 :> RandomReal[]
Just for fun, here's one more, similar solution:
p1 y1 + p2 y2 + p3 y3 == p4 /. s_Symbol :>
RandomReal[]/;StringMatchQ[SymbolName[s], "p"~~DigitCharacter]
Where you could replace DigitCharacter with NumberString if you want it to match more than just p0, p1, ..., p9. Of course, for large expressions, the above won't be particularly efficient...
The other answers are good, but if you do a lot of this sort of thing, I recommend naming your variables and coefficients in a more systematic way. This will not only allow you to write a much simpler rule, it will also make for much simpler changes when it's time to go from 3 equations to 4. For example:
In[1]:= vars = Array[y, 3]
Out[1]= {y[1], y[2], y[3]}
In[2]:= coeffs = Array[p, 4]
Out[2]= {p[1], p[2], p[3], p[4]}
You can be a little fancy when you make your equation:
In[3]:= vars . Most[coeffs] == Last[coeffs]
Out[3]= p[1] y[1] + p[2] y[2] + p[3] y[3] == p[4]
Substituting random numbers for the coefficients is now one one very basic rule:
In[4]:= sub = eqn /. p[_] :> RandomReal[]
Out[4]= 0.281517 y[1] + 0.089162 y[2] + 0.0860836 y[3] == 0.915208
The rule at the end could also be written _p :> RandomReal[], if you prefer. You don't have to type much to solve it, either.
In[5]:= Reduce[sub]
Out[5]= y[1] == 3.25099 - 0.31672 y[2] - 0.305785 y[3]
As Andrew Walker said, you use Reduce to find all the solutions, instead of just some of them. You can wrap this up in a function which paramerizes the number of variables like so:
In[6]:= reduceRandomEquation[n_Integer] :=
With[{vars = Array[y, n], coeffs = Array[p, n+1]},
Reduce[vars . Most[coeffs]]
In[7]:= reduceRandomEquation[4]
Out[7]= y[1] == 2.13547 - 0.532422 y[2] - 0.124029 y[3] - 2.48944 y[4]
If you need solutions with values substituted in, one possible way to do this is:
f[y1_, y2_, y3_] := p1 y1 + p2 y2 + p3 y3 - p4
g = f[y1, y2, y3] /. p1 -> RandomReal[] /. p2 -> RandomReal[] /.
p3 -> RandomReal[] /. p4 -> RandomReal[]
Reduce[g == 0, {y1}]
Reduce[g == 0, {y2}]
Reduce[g == 0, {y3}]
If all you need is the solution to the equations:
f[y1_, y2_, y3_] := p1 y1 + p2 y2 + p3 y3 - p4
g = f[y1, y2, y3]
Solve[g == 0, {y1}]
Solve[g == 0, {y2}]
Solve[g == 0, {y3}]
If you can live without the symbolic coefficient names p1 et al, then you might generate as below. We take a variable list, and number of equations, and a range for the coefficients and rhs vector.
In[80]:= randomLinearEquations[vars_, n_, crange_] :=
Thread[RandomReal[crange, {n, Length[vars]}].vars ==
RandomReal[crange, n]]
In[81]:= randomLinearEquations[{x, y, z}, 2, {-10, 10}]
Out[81]= {7.72377 x - 4.18397 y - 4.58168 z == -7.78991, -1.13697 x +
5.67126 y + 7.47534 z == -6.11561}
It is straightforward to obtain variants such as integer coefficients, different ranges for matrix and rhs, etc.
Daniel Lichtblau
Another way:
dim = 3;
eq = Array[p, dim].Array[y, dim] == p[dim + 1];
Evaluate#Array[p, dim + 1] = RandomInteger[10, dim + 1]
Solve[eq, Array[y, dim]]