If I have two symbolic expressions and the algebra can tell which one is the largest, how can I get Mathematica to find that out? Example:
A = s1/z1 + s2/z2 + Sqrt[(s1/z1 + s2/z2)^2 + 4 (z1^2 z2^2 - s1 s2)/(z1 z2)];
B = s1/z1 + s2/z2 - Sqrt[(s1/z1 + s2/z2)^2 + 4 (z1^2 z2^2 - s1 s2)/(z1 z2)];
Assuming[s1 > 0 && s2 > 0 && z1 > 0 && z2 > 0, Max[A, B]]
This gives
Max[s1/z1 + s2/z2 - Sqrt[(s1/z1 + s2/z2)^2 + (4 (-s1 s2 + z1^2 z2^2))/(z1 z2)],
s1/z1 + s2/z2 + Sqrt[(s1/z1 + s2/z2)^2 + (4 (-s1 s2 + z1^2 z2^2))/(z1 z2)]]
which not much of use.
However, one can see that it's always A < B, because A is a difference between two positive numbers, while B is the sum. I'd like Mathematica to tell me that the Max is always B. Can it be done?
had a chance to check ..
Assuming[ {z1 > 0, z2 > 0, s1 > 0, s2 > 0} , Simplify[Reduce[A > B]]]
-> True
note by removing the Simplify and looking at the conditional expression produced by Reduce you can see how to relax the assumptions a bit:
Assuming[ {z1 > 0, z2 > 0, Element[{s1, s2}, Reals]} , Simplify[Reduce[A > B]]]
-> True
Note also Reduce[A < B] returns False with no assumptions. That expression can not be true even with complex expressions.
I suppose if you want to implement something like Max you could do this:
Assuming[ {z1 > 0, z2 > 0, s1 > 0, s2 > 0} ,
Which[ Simplify[Reduce[A > B]] , A ,
Simplify[Reduce[B > A ]] , B ,
True , Indeterminate ]]
The answer by agentp can be also made iterative, so one can generalize this to more than two expressions:
v = {A, B};
max = B;
Assuming[{z1 > 0, z2 > 0, s1 > 0, s2 > 0},
For[i = 1, i <= 2, i++,
If[Simplify[Reduce[v[[i]] > max]], max = v[[i]]]
]
]
Print[max];
-> s1/z1+s2/z2+Sqrt[(s1/z1+s2/z2)^2+(4 (-s1 s2+z1^2 z2^2))/(z1 z2)]
Related
I use MiniZinc compute a problem of optimization of shortest path problem based on hakank's model in http://www.hakank.org/minizinc
I input the distance matrix to a symmetric one such that the graph is bidirectional.
int: start = 2; % start node
int: end = 1; % end node
int: M = 999; % large number
array[1..n, 1..n] of 0..M: d = array2d(1..n,1..n,
[ M, 11, 8, 3, 8, 10, 2, 4, % 1-X
11, M, 3, 5, 1, 4, 8, 3, % 2-X
8, 3, M, 5, 7, 7, 11, 4, % 3-X
3, 5, 5, M, 9, 3, 10, 15, % 4-X
8, 6, 7, 9, M, 7, 12, 1, % 5-X
10, 4, 7, 3, 7, M, 6, 9, % 6-X
2, 8, 8, 10, 12, 9, M, 14, % 7-X
4, 3, 4, 15, 1, 9, 14, M % 8-X
]
);
% objective to minimize
var int: total_cost = sum(i in 1..n, j in 1..n where d[i,j] < M) ( d[i,j]*x[i,j] );
array[1..n] of var -1..1: rhs; % indicating start/end nodes
array[1..n, 1..n] of var 0..1: x; % the resulting connection matrix
array[1..n, 1..n] of var 0..n*n: y; % output node matrix
array[1..n] of var 0..1: outFlow; % out flow array
array[1..n] of var 0..1: inFlow; % in flow array
constraint
% set rhs for start/end nodes
forall(i in 1..n) (
if i = start then
rhs[i] = 1
elseif i = end then
rhs[i] = -1
else
rhs[i] = 0
endif
)
/\ % assert that all x values is >= 0
forall(i in 1..n, j in 1..n where d[i,j] < M) (
x[i,j] >= 0 /\ y[i,j] >= 0
)
/\ % calculate out flow
forall(i in 1..n) (
outFlow[i] = sum(j in 1..n where d[i,j] < M) (x[i,j])
)
/\ % calculate in flow
forall(j in 1..n) (
inFlow[j] = sum(i in 1..n where d[i,j] < M) (x[i,j])
)
/\ % outflow = inflow
forall(i in 1..n) (outFlow[i] - inFlow[i] = rhs[i])
/\ % do not loops
forall(i in 1..n) (
x[i,i] = 0
)
/\ % sanity: there can be no connection in x if there is not
% connection in d
forall(i,j in 1..n) (
if d[i,j] = M then
x[i,j] = 0
else
true
endif
)
;
solve minimize total_cost;
output [
if i = 1 /\ j = 1 then
"total_cost: " ++ show(total_cost) ++ "\n" ++
"inFlow: " ++ show(inFlow) ++ "\n" ++ "outFlow: " ++ show(outFlow) ++ "\n" ++
" 1 2 3 4 5 6 7 8\n"
else "" endif ++
if j = 1 then show(i) ++ " : " else "" endif ++
show_int(4,x[i,j]) ++ if j = n then "\n" else " " endif
| i in 1..n, j in 1..n
];
The solution gives an output matrix that indicates which edge of a graph is participating in the solution; however, the solution is directionless. I cannot tell the order of edge to take on a particular solution. In the above example, the shortest path from node 2 to node 1 gives the following solution
total_cost: 6
inFlow: [1, 0, 0, 0, 1, 0, 0, 1]
outFlow: [0, 1, 0, 0, 1, 0, 0, 1]
1 2 3 4 5 6 7 8
1 : 0 0 0 0 0 0 0 0
2 : 0 0 0 0 1 0 0 0
3 : 0 0 0 0 0 0 0 0
4 : 0 0 0 0 0 0 0 0
5 : 0 0 0 0 0 0 0 1
6 : 0 0 0 0 0 0 0 0
7 : 0 0 0 0 0 0 0 0
8 : 1 0 0 0 0 0 0 0
which suggests to the edge 8->1, 2->5, 5->8 are taken but I won't be able to order all edges as 2->5, 5->8, and 8->1.
I was thinking to find the index at where the start node is (here it is 2,5) and search the matrix until x[i,j]>0 and x[j,k]>0 where inFlow[j]=outFlow[j]=1, but it does not work since there may have more than one k satisfying the problem (the output graph is directionless). I wonder if there is any idea how to save the order of edges in solution. Thanks.
One way would be over a variable representing the path:
array[1..n] of var 0..n: path;
Define the path through constraints:
constraint
% start point
path[1] = start
/\ % end point
path[sum(inFlow) + 1] = end
/\ % interior points
forall(p in 2..sum(inFlow))
(path[p] = sum(i in 1..n)(i * x[path[p-1], i]));
Then show the path as part of the output statement:
"path: " ++ show([path[i] | i in 1..sum(inFlow) + 1]) ++ "\n" ++
I am solving a project in Mathematica 10 and I think that the best way to do it is using a loop like For or Do. After build it I obtain the results I looking for but with a to much big multiplicity. Here is the isolated part of the code:
(*Initializing variables*)
epot[0] = 1; p[0] = 1; \[Psi][0] = HermiteH[0, x] E^(-(x^2/2));
e[n_] := e[n] = epot[n];
(*Defining function*)
\[Psi][n_] := \[Psi][n] = (Sum[p[k]*x^k,{k,0,4*n}]) [Psi][0];
(*Differential equation*)
S = - D[D[\[Psi][n], x], x] + x^2 \[Psi][n] + x^4 \[Psi][n - 1] - Sum[e[n-k]*\[Psi][k],{k,0,n}];
(*Construction of the loop*)
S1 = Collect[E^(x^2/2) S, x, Simplify];
c = Coefficient[S1, x, 0];
sol = Solve[c == 0, epot[n]]; e[n] = epot[n] /. sol;
For[j = 1, j <= 4 n, j++,
c = Coefficient[S1, x, j];
sol = Solve[c == 0, p[j]];
p[j] = p[j] /. sol;];
(*Results*)
Print[Subscript[e, n], "= ", e[n] // InputForm];
Subscript[e, 1]= {{{3/4}}}
Print[ArrayDepth[e[n]]];
3 (*Multiplicity, it should be 1*)
Print[Subscript[\[Psi], n], "= ", \[Psi][n]];
Subscript[\[Psi], 1]= {{E^(-(x^2/2)) (1-(3 x^2)/8-x^4/8)}}
Print[ArrayDepth[\[Psi][n]]];
2 (*Multiplicity, it should be 1*)
After this calculation, the question remaining is how do i substitute this results in the original functions. Thank you very much.
I'm learning about dynamic programming via the 0-1 knapsack problem.
I'm getting some weird Nulls out from the function part1. Like 3Null, 5Null etc. Why is this?
The code is an implementation of:
http://www.youtube.com/watch?v=EH6h7WA7sDw
I use a matrix to store all the values and keeps, dont know how efficient this is since it is a list of lists(indexing O(1)?).
This is my code:
(* 0-1 Knapsack problem
item = {value, weight}
Constraint is maxweight. Objective is to max value.
Input on the form:
Matrix[{value,weight},
{value,weight},
...
]
*)
lookup[x_, y_, m_] := m[[x, y]];
part1[items_, maxweight_] := {
nbrofitems = Dimensions[items][[1]];
keep = values = Table[0, {j, 0, nbrofitems}, {i, 1, maxweight}];
For[j = 2, j <= nbrofitems + 1, j++,
itemweight = items[[j - 1, 2]];
itemvalue = items[[j - 1, 1]];
For[i = 1, i <= maxweight, i++,
{
x = lookup[j - 1, i, values];
diff = i - itemweight;
If[diff > 0, y = lookup[j - 1, diff, values], y = 0];
If[itemweight <= i ,
{If[x < itemvalue + y,
{values[[j, i]] = itemvalue + y; keep[[j, i]] = 1;},
{values[[j, i]] = x; keep[[j, i]] = 0;}]
},
y(*y eller x?*)]
}
]
]
{values, keep}
}
solvek[keep_, items_, maxweight_] :=
{
(*w=remaining weight in knapsack*)
(*i=current item*)
w = maxweight;
knapsack = {};
nbrofitems = Dimensions[items][[1]];
For[i = nbrofitems, i > 0, i--,
If[keep[[i, w]] == 1, {Append[knapsack, i]; w -= items[[i, 2]];
i -= 1;}, i - 1]];
knapsack
}
Clear[keep, v, a, b, c]
maxweight = 5;
nbrofitems = 3;
a = {5, 3};
b = {3, 2};
c = {4, 1};
items = {a, b, c};
MatrixForm[items]
Print["Results:"]
results = part1[items, 5];
keep = results[[1]];
Print["keep:"];
Print[keep];
Print["------"];
results2 = solvek[keep, items, 5];
MatrixForm[results2]
(*MatrixForm[results[[1]]]
MatrixForm[results[[2]]]*)
{{{0,0,0,0,0},{0,0,5 Null,5 Null,5 Null},{0,3 Null,5 Null,5 Null,8 Null},{4 Null,4 Null,7 Null,9 Null,9 Null}},{{0,0,0,0,0},{0,0,Null,Null,Null},{0,Null,0,0,Null},{Null,Null,Null,Null,Null}}}
While your code gives errors here, the Null problem occurs because For[] returns Null. So add a ; at the end of the outermost For statement in part1 (ie, just before {values,keep}.
As I said though, the code snippet gives errors when I run it.
In case my answer isn't clear, here is how the problem occurs:
(
Do[i, {i, 1, 10}]
3
)
(*3 Null*)
while
(
Do[i, {i, 1, 10}];
3
)
(*3*)
The Null error has been reported by acl. There are more errors though.
Your keep matrix actually contains two matrices. You need to call solvek with the second one: solvek[keep[[2]], items, 5]
Various errors in solvek:
i -= 1 and i - 1 are more than superfluous (the latter one is a coding error anyway). The i-- in the beginning of the For is sufficient. As it is now you're decreasing i twice per iteration.
Append must be AppendTo
keep[[i, w]] == 1 must be keep[[i + 1, w]] == 1 as the keep matrix has one more row than there are items.
Not wrong but superfluous: nbrofitems = Dimensions[items][[1]]; nbrofitems is already globally defined
The code of your second part could look like:
solvek[keep_, items_, maxweight_] :=
Module[{w = maxweight, knapsack = {}, nbrofitems = Dimensions[items][[1]]},
For[i = nbrofitems, i > 0, i--,
If[keep[[i + 1, w]] == 1, AppendTo[knapsack, i]; w -= items[[i, 2]]]
];
knapsack
]
I'm working with chaotic attractors, and testing some continuous-> discrete equivalences. I've made a continuous simulation of the Rossler system this way
a = 0.432; b = 2; c = 4;
Rossler = {
x'[t] == -y[t] - z[t],
y'[t] == x[t] + a*y[t],
z'[t] == b + x[t]*z[t]-c*z[t]};
sol = NDSolve[
{Rossler, x[0] == y[0] == z[0] == 0.5},
{x, y, z}, {t,500}, MaxStepSize -> 0.001, MaxSteps -> Infinity]
Now, when trying to evaluate a discrete equivalent system with RSolve, Mma doesn't do anything, not even an error, it just can't solve it.
RosslerDiscreto = {
x[n + 1] == x[n] - const1*(y[n] + z[n]),
y[n + 1] == 1 - a*const2)*y[n] + const2*x[n],
z[n + 1] == (z[n]*(1 - const3) + b*const3)/(1 - const3*x[n])}
I want to know if there is a numerical function for RSolve, analogous as the NDSolve is for DSolve.
I know i can make the computation with some For[] cycles, just want to know if it exists such function.
RecurrenceTable is the numeric analogue to RSolve:
rosslerDiscreto = {
x[n+1] == x[n] - C[1]*(y[n] + z[n]),
y[n+1] == (1 - a*C[2])*y[n] + C[2]*x[n],
z[n+1] == (z[n]*(1 - C[3]) + b*C[3]) / (1 - C[3]*x[n]),
x[0] == y[0] == z[0] == 0.5
} /. {a->0.432, b->2, c->4, C[1]->0.1, C[2]->0.1, C[3]->0.1};
coords = RecurrenceTable[rosslerDiscreto, {x,y,z}, {n,0,1000}];
Graphics3D#Point[coords]
I have a set of inequalities, for example,
2 x1 >=3 x2 && 0<=x1<=1 && 0<=x2<=1
which can be solved with Reduce. Then I want to do an integration for the function f(x1,x2)=1/x1 in the area defined by the inequalities above. In this case, Reduce gives a result
(x1 == 0 && x2 == 0) || (0 < x1 <= 1 && 0 <= x2 <= (2 x1)/3)
Then I can do integration by using
Integrate[Integrate[1/x1, {x2, 0, 2 x1/3}], {x1, 0, 1}]
But these all need my manual intervention. How do I do this in a streamline fashion? Many thanks!
Integrate[1/x1 Boole[2 x1 >= 3 x2 && 0 <= x1 <= 1 &&0 <= x2 <= 1], {x1, -\[Infinity], \[Infinity]}, {x2, -\[Infinity], \[Infinity]}]