I have the following inequalities on 21 variables:
http://pastebin.com/raw.php?i=FTU970Em
When I run "Reduce[ineq,Integers]" on this, Mathematica hangs for a
long time.
That makes sense: there are MANY sets of values for x[1]..x[21] that
satisfy the inequalities.
All I really want is bounds for each variable (eg, "2 <= x[i] <= 7"
for each i).
How can I get this efficiently w/ Mathematica? Is there a better
program for this?
Note: this is part of the larger project:
Partially re-create Risk-like game based on incomplete log files
The entire hideous list of inequalities: http://pastebin.com/CyX9f70J
Running "Reduce[ineq,Integers]" on the above yields "false", so I've
probably incorrectly translated:
http://conquerclub.barrycarter.info/ONEOFF/7460216.html
I second the CLP(FD) suggestion given in the other thread. Using SWI-Prolog 5.10:
:- use_module(library(clpfd)).
vars([X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13,X14,X15,X16,X17,X18,
X19,X20,X21]) :-
X0 #= 3, X1 #>= 1, X1 #=< X0, X2 #>= 1, X2 #=< X1,
X3 #>= 1, X3 #=< X2, X4 #>= 1, X4 #=< X3, X5 #=< X4 + 3,
X5 #>= 1, X6 #>= 1, X6 #=< X5, X7 #>= 1, X7 #=< X6,
X8 #>= 1, X8 #=< X7, X9 #>= 1, X9 #=< X8, X10 #>= 1,
X10 #=< X9, X11 #>= 1, X11 #=< X10, X12 #>= 1, X12 #=< X11,
X13 #>= 1, X13 #=< X12, X14 #=< X13 + 4, X14 #>= 1, X15 #>= 1,
X15 #=< X14, X16 #>= 1, X16 #=< X15, X17 #=< X16 + 6, X17 #>= 1,
X18 #>= 1, X18 #=< X17, X19 #>= 1, X19 #=< X18, X20 #>= 1,
X20 #=< X19, X21 #>= 1, X21 #=< X20, X21 #= 1.
Example queries:
?- vars(Vs), maplist(fd_dom, Vs, Ds).
Ds = [3..3, 1..3, 1..3, 1..3, 1..3, 1..6, 1..6, 1..6, ... .. ...|...]
?- vars(Vs), label(Vs).
Vs = [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ;
Vs = [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1] ;
Vs = [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1] ;
etc.
It's late enough that there are probably a number of slick reductions, but this works...
ineq={...};
pivotAt[set_, j_] := Select[set, And[
Not[FreeQ[#, x[u_] /; u <= j]],
FreeQ[#, x[u_] /; u > j]
] &]
triangularize[set_] := Module[{left, i, new},
left = set;
Reap[
For[i = 0, i <= 21, i++,
new = pivotAt[left, i];
Sow[new];
left = Complement[left, new];
]][[2, 1]]
]
Module[{
tri,
workingIntervals,
partials, increment, i
},
tri = triangularize[ineq];
workingIntervals[set_] := set /. {
t_ <= c_ :> {t, Interval[{-\[Infinity], Max[c]}]},
t_ == c_ :> {t, Interval[{Min[c], Max[c]}]},
t_ >= c_ :> {t, Interval[{Max[c], \[Infinity]}]}};
partials = {};
increment[slice_] :=
Rule[#[[1, 1]], IntervalIntersection ## #[[All, 2]]] &[
workingIntervals[slice /. partials ] ];
For[i = 1, i <= Length[tri], i++,
partials = Join[partials, {increment[tri[[i]]]}];
];
partials
]
It's permissive in that correlations between variables ("this high means that low") are not accounted.
-- EDIT --
The result of the above is, of course
{x[0] -> Interval[{3, 3}], x[1] -> Interval[{1, 3}],
x[2] -> Interval[{1, 3}], x[3] -> Interval[{1, 3}],
x[4] -> Interval[{1, 3}], x[5] -> Interval[{1, 6}],
x[6] -> Interval[{1, 6}], x[7] -> Interval[{1, 6}],
x[8] -> Interval[{1, 6}], x[9] -> Interval[{1, 6}],
x[10] -> Interval[{1, 6}], x[11] -> Interval[{1, 6}],
x[12] -> Interval[{1, 6}], x[13] -> Interval[{1, 6}],
x[14] -> Interval[{1, 10}], x[15] -> Interval[{1, 10}],
x[16] -> Interval[{1, 10}], x[17] -> Interval[{1, 16}],
x[18] -> Interval[{1, 16}], x[19] -> Interval[{1, 16}],
x[20] -> Interval[{1, 16}], x[21] -> Interval[{1, 1}]}
Are there many sets of values which satisfy the inequalities ?
I ran the following commands through Mathematica:
In[14]:= ineqs = {x0 == 3, x1 >= 1, x1 <= x0, x2 >= 1, x2 <= x1,
x3 >= 1, x3 <= x2, x4 >= 1, x4 <= x3, x5 <= x4 + 3, x5 >= 1,
x6 >= 1, x6 <= x5, x7 >= 1, x7 <= x6, x8 >= 1, x8 <= x7, x9 >= 1,
x9 <= x8, x10 >= 1, x10 <= x9, x11 >= 1, x11 <= x10, x12 >= 1,
x12 <= x11, x13 >= 1, x13 <= x12, x14 <= x13 + 4, x14 >= 1,
x15 >= 1, x15 <= x14, x16 >= 1, x16 <= x15, x17 <= x16 + 6,
x17 >= 1, x18 >= 1, x18 <= x17, x19 >= 1, x19 <= x18, x20 >= 1,
x20 <= x19, x21 >= 1, x21 <= x20, x21 == 1};
In[15]:= vars =
Union[{x0, x1, x1, x2, x2, x3, x3, x4, x4, x5, x5, x6, x6, x7, x7,
x8, x8, x9, x9, x10, x10, x11, x11, x12, x12, x13, x13, x14, x14,
x15, x15, x16, x16, x17, x17, x18, x18, x19, x19, x20, x20, x21,
x21, x21}];
In[16]:= FindInstance[ineqs, vars]
and got the result:
Out[16]= {{x0 -> 3, x1 -> 1, x10 -> 1, x11 -> 1, x12 -> 1, x13 -> 1,
x14 -> 1, x15 -> 1, x16 -> 1, x17 -> 1, x18 -> 1, x19 -> 1, x2 -> 1,
x20 -> 1, x21 -> 1, x3 -> 1, x4 -> 1, x5 -> 1, x6 -> 1, x7 -> 1,
x8 -> 1, x9 -> 1}}
I haven't been able to persuade Mathematica to provide another set of assignments and a little work with pencil and paper doesn't point me towards other sets of assignments. But it's late here, I may have missed something obvious.
OK, it turns out that solving this particular set of equations is
easy, once you rewrite some of them slightly:
x5 <= x4 + 3 becomes x5 - 3 <= x4
x6 <= x5 becomes x6 - 3 <= x5 - 3
and so on until:
x13 <= x12 becomes x13 - 3 <= x12 - 3
x14 <= x13 + 4 becomes x14 - 7 <= x13 -3
By doing this, {x0, x1, x2, x3, x4, x5-3, x6-3, ..., x13-3, x14-7, ..., x21}
becomes a strictly decreasing sequence of integers starting at 3
and ending at 1.
In fact, any sequence w/ that property works, since xi>=1 is trivally
satisfied.
However, while this works to solve this particular set of
inequalities, it doesn't work in general, so I don't consider it a
complete solution.
Related
I am writing a program to find all of the squares that a Knight can move to in a game of chess.
For example: validKnightMove(X1/Y1, X2/Y2). where each argument is a co-ordinate pair.
What I've done:
Written the predicate.
Made it deterministic using cuts.
Unit-tested it with PL-Unit.
The predicate works, but I cannot query it in a desirable way from the Prolog shell.
What I'd like to do:
I would like to make a query that will find all of the valid squares I can move to from a given location. For example, ?- validKnightMove(4/4, X/Y), then the shell would search for X and Y values which satisfy the predicate.
However, when I make the query, it simply returns false., despite having valid solutions.
Here is some output from the shell to demonstrate the issue:
1 ?- validKnightMove(4/4, 6/3).
true.
2 ?- validKnightMove(4/4, X/Y).
false.
Here is my code:
This code is admittedly verbose, but should be easy to read.
validKnightMove(X1/Y1, X2/Y2) :- % Right 1, Down 2
onBoard(X2/Y2),
X2 =:= X1 + 1,
Y2 =:= Y1 + 2,
!.
validKnightMove(X1/Y1, X2/Y2) :- % Right 2, Down 1
onBoard(X2/Y2),
X2 =:= X1 + 2,
Y2 =:= Y1 + 1,
!.
validKnightMove(X1/Y1, X2/Y2) :- % Left 2, Down 1
onBoard(X2/Y2),
X2 =:= X1 - 2,
Y2 =:= Y1 + 1,
!.
validKnightMove(X1/Y1, X2/Y2) :- % Left 1, Down 2
onBoard(X2/Y2),
X2 =:= X1 - 1,
Y2 =:= Y1 + 2,
!.
validKnightMove(X1/Y1, X2/Y2) :- % Right 1, Up 2
onBoard(X2/Y2),
X2 =:= X1 + 1,
Y2 =:= Y1 - 2,
!.
validKnightMove(X1/Y1, X2/Y2) :- % Right 2, Up 1
onBoard(X2/Y2),
X2 =:= X1 + 2,
Y2 =:= Y1 - 1,
!.
validKnightMove(X1/Y1, X2/Y2) :- % Left 2, Up 1
onBoard(X2/Y2),
X2 =:= X1 - 2,
Y2 =:= Y1 - 1,
!.
validKnightMove(X1/Y1, X2/Y2) :- % Left 1, Up 2
onBoard(X2/Y2),
X2 =:= X1 - 1,
Y2 =:= Y1 - 2,
!.
onBoard(X/Y) :-
between(1, 8, X),
between(1, 8, Y),
!.
My question is: Why can't prolog find all the solutions for a deterministic predicate?
Note: My prolog version is SWI-Prolog (Multi-threaded, 32 bits, Version 6.2.2)
I am trying to numerically solve the below system of six equations (g0-g5) for a0-a5 in Mathematica. I am no expert in Mathematica and am not entirely sure how to do this.
f[x_, y_] := Exp[a0 - 1 + a1*x + a2*y + a3*x*x + a4*y*y + a5*x*y]
g0[x_, y_] := Integrate[f[x, y],{y,-Infinity,Infinity},{x,-Infinity,Infinity}] - 1
g1[x_, y_] := Integrate[x*f[x, y],{y,-Infinity,Infinity},{x,-Infinity,Infinity}]
g2[x_, y_] := Integrate[y*f[x, y],{y,-Infinity,Infinity},{x,-Infinity,Infinity}]
g3[x_, y_] := Integrate[x*x*f[x, y],{y,-Infinity,Infinity},{x,-Infinity,Infinity}] - 1
g4[x_, y_] := Integrate[y*y*f[x, y],{y,-Infinity,Infinity},{x,-Infinity,Infinity}] - 1
g5[x_, y_] := Integrate[x*y*f[x, y],{y,-Infinity,Infinity},{x,-Infinity,Infinity}]
I have, however, spent considerable time trying to get NSolve and FindRoot to yield a solution. Here is that code:
NSolve[{g0[x, y]==0, g1[x, y]==0, g2[x, y]==0, g3[x, y]==0, g4[x, y]==0,
g5[x, y]==0}, {a0, a1, a2, a3, a4, a5}, Reals]
FindRoot[{g0[x, y]==0, g1[x, y]==0, g2[x, y]==0, g3[x, y]==0, g4[x, y]==0,
g5[x, y]==0}, {{a0,1}, {a1,1}, {a2,1}, {a3,1}, {a4,1}, {a5,1}}]
One additional piece of information I can offer is that the resulting solution for f(x,y) should be equivalent to the bivariate standard normal density. Any help would be much appreciated. This is my first post on SO, so please let me know if any additional information is necessary.
I am astonished. I never expected it to finish. But if you subtract off all the time for it to do the integrals then Reduce finishes in the blink of an eye.
f[x_, y_] := Exp[a0 - 1 + a1*x + a2*y + a3*x*x + a4*y*y + a5*x*y];
g0[x_, y_] := Integrate[f[x, y], {y, -Infinity, Infinity}, {x, -Infinity, Infinity}]-1;
g1[x_, y_] := Integrate[x*f[x, y], {y, -Infinity, Infinity}, {x, -Infinity, Infinity}];
g2[x_, y_] := Integrate[y*f[x, y], {y, -Infinity, Infinity}, {x, -Infinity, Infinity}];
g3[x_, y_] := Integrate[x*x*f[x, y], {y, -Infinity, Infinity}, {x, -Infinity, Infinity}]-1;
g4[x_, y_] := Integrate[y*y*f[x, y], {y, -Infinity, Infinity}, {x, -Infinity, Infinity}]-1;
g5[x_, y_] := Integrate[x*y*f[x, y], {y, -Infinity, Infinity}, {x, -Infinity, Infinity}];
Reduce[Simplify[{g0[x,y]==0, g1[x,y]==0, g2[x,y]==0, g3[x,y]==0, g4[x,y]==0, g5[x,y]==0},
Re[4 a4-a5^2/a3]<0], {a0,a1,a2,a3,a4,a5}]
gives you
C[1] \[Element] Integers && a0==1+2I\[Pi] C[1]-Log[2]-Log[\[Pi]] &&
a1==0 && a2==0 && a3== -(1/2) && a4== -(1/2) && a5==0
Note: That gives Simplify one assumption which you should verify is justified. That assumption allows it to turn all your ConditionalExpression into presumably valid expressions for your problem. I got that assumption by looking at each of the results returned from Integrate and seeing that they all depended on that for the result to be valid.
Here is how to formulate this numerically:
f[x_, y_, a0_, a1_, a2_, a3_, a4_, a5_] :=
Exp[a0 - 1 + a1*x + a2*y + a3*x*x + a4*y*y + a5*x*y]
g0[a0_?NumericQ, a1_, a2_, a3_, a4_, a5_] :=
Integrate[
f[x, y, a0, a1, a2, a3, a4, a5], {y, -Infinity, Infinity},
{x, -Infinity, Infinity}] - 1
g1[a0_?NumericQ, a1_, a2_, a3_, a4_, a5_] :=
Integrate[
x*f[x, y, a0, a1, a2, a3, a4, a5], {y, -Infinity, Infinity},
{x, -Infinity, Infinity}]
g2[a0_?NumericQ, a1_, a2_, a3_, a4_, a5_] :=
Integrate[
y*f[x, y, a0, a1, a2, a3, a4, a5], {y, -Infinity, Infinity},
{x, -Infinity, Infinity}]
g3[a0_?NumericQ, a1_, a2_, a3_, a4_, a5_] :=
Integrate[
x*x*f[x, y, a0, a1, a2, a3, a4, a5], {y, -Infinity,
Infinity}, {x, -Infinity, Infinity}] - 1
g4[a0_?NumericQ, a1_, a2_, a3_, a4_, a5_] :=
Integrate[
y*y*f[x, y, a0, a1, a2, a3, a4, a5], {y, -Infinity,
Infinity}, {x, -Infinity, Infinity}] - 1
g5[a0_?NumericQ, a1_, a2_, a3_, a4_, a5_] :=
Integrate[
x*y*f[x, y, a0, a1, a2, a3, a4, a5], {y, -Infinity,
Infinity}, {x, -Infinity, Infinity}]
FindRoot[ {
g0[a0, a1, a2, a3, a4, a5] == 0,
g1[a0, a1, a2, a3, a4, a5] == 0,
g2[a0, a1, a2, a3, a4, a5] == 0,
g3[a0, a1, a2, a3, a4, a5] == 0,
g4[a0, a1, a2, a3, a4, a5] == 0,
g5[a0, a1, a2, a3, a4, a5] == 0} ,
{{a0, -.8379}, {a1, 0}, {a2, 0}, {a3, -.501},
{a4, -.499}, {a5, 0}}]
Note I've put in an initial guess very close to the known solution (thanks #Bill) and it still takes a very long time to find the answer.
{a0 -> -0.837388 - 1.4099*10^-29 I,
a1 -> -6.35273*10^-22 + 7.19577*10^-46 I,
a2 -> -1.27815*10^-20 + 6.00264*10^-38 I,
a3 -> -0.500489 + 1.41128*10^-29 I, a4 -> -0.5 - 7.13595*10^-44 I,
a5 -> -5.55356*10^-28 - 9.23563*10^-47 I}
Chop#%
{a0 -> -0.837388, a1 -> 0, a2 -> 0, a3 -> -0.500489, a4 -> -0.5,
a5 -> 0}
So guys, I'm learning constraints with prolog, and trying to implement a little puzzle using this new knowledge.
The goal of the puzzle is simple: I have a square grid with some numbers on top/below each column and on the right/left of each row.
The domain of values goes from 0 to Gridsize -1, wich means, a grid 7x7 can have numbers from 0 to 6.
The constraints are as follow:
Each number can only apear once each row and once each column
The number on top/right are the sum of the First and Last digits on the column/row respectively
The number on bottom/left are the sum of the Second and SecondLast digits on the column/row respectively
Zeros don't count as digits, are only on the program to represent blank spaces
For an example:
TopConstraint = [7, 6, 4, 7, 3]
RightConstraint = [5, 5, 5, 5, 5]
BottomConstraint = [3, 4, 6, 3, 7]
LeftConstraint = [5, 5, 5, 5, 5]
This constraints can have a 0 too, wich make the program simple ignore (the sum can be any number, if it goes accordingly with the other restrictions).
One solution to the above lists would be the matrix:
3 | 4 | 1 | | 2
1 | 3 | 2 | 4 |
2 | | 4 | 1 | 3
| 1 | 3 | 2 | 4
4 | 2 | | 3 | 1
Now the problem is: my constraints somehow aren't applying, and the program isn't giving me the solution.
After puting the right domain and putting all column/row cells different(wich without any other restrictions it gives me the expected solution), I have this code to apply to each cell, the sum restrictions:
put_restrictions(Sol, Gridsize, SumT, SumR, SumB, SumL):-
put_restrictions_row(Sol, Gridsize, SumR, SumL, 1),
put_restrictions_col(Sol, Gridsize, SumT, SumB, 1).
Where Gridsize is the Gridsize to make iterations upon it, SumT, SumR, SumB, SumL, are the above constraint lists respectively, and 1 to start the iteration counter.
So this predicates are where my problem resides
put_restrictions_col(_, Gridsize, _, _, X):- X > Gridsize, write('end put_restrictions_col'),nl.
put_restrictions_col(Grid, Gridsize, [SumTH|SumTT], [SumBH|SumBT], X):-
get_cell(Grid, FirstInCol, X, 1, Gridsize),
get_cell(Grid, LastInCol, X, Gridsize, Gridsize),
get_cell(Grid, SecondInCol, X, 2, Gridsize),
SecondLastIndex is Gridsize-1,
get_cell(Grid, SecondLastInCol, X, SecondLastIndex, Gridsize),
get_cell(Grid, ThirdInCol, X, 3, Gridsize),
ThirdLastIndex is Gridsize-2,
get_cell(Grid, ThirdLastInCol, X, ThirdLastIndex, Gridsize),
(SumTH #> 0) #=>
(
(((FirstInCol #> 0) #/\ (LastInCol #> 0)) #=> (SumTH #= FirstInCol + LastInCol))
#\/
((FirstInCol #= 0) #=> (SumTH #= SecondInCol + LastInCol))
#\/
((LastInCol #= 0) #=> (SumTH #= FirstInCol + SecondLastInCol))
),
(SumBH #> 0) #=>
(
(((SecondInCol #> 0) #/\ (SecondLastInCol #> 0)) #=> (SumBH #= SecondInCol + SecondLastInCol))
#\/
((SecondInCol #= 0) #=> (SumBH #= ThirdInCol + SecondLastInCol))
#\/
((SecondLastInCol #= 0) #=> (SumBH #= SecondInCol + ThirdLastInCol))
),
X1 is X+1,
put_restrictions_col(Grid, Gridsize, SumTT, SumBT, X1).
put_restrictions_row([], _, _,_,_):- write('end put_restrictions_row'),nl.
put_restrictions_row([H|T], Gridsize, [SumRH|SumRT],[SumLH|SumLT], N):-
element(1, H, FirstInRow),
element(Gridsize, H, LastInRow),
element(2, H, SecondInRow),
SecondLastIndex is Gridsize -1,
element(SecondLastIndex, H, SecondLastInRow),
element(3, H, ThirdInRow),
ThirdLastIndex is Gridsize -2,
element(ThirdLastIndex, H, ThirdLastInRow),
(SumRH #> 0) #=>
(
(((FirstInRow #> 0) #/\ (LastInRow #> 0)) #/\ (FirstInRow + LastInRow #= SumRH))
#\/
((FirstInRow #= 0) #/\ (SecondInRow + LastInRow #= SumRH))
#\/
((LastInRow #= 0) #/\ (FirstInRow + SecondLastInRow #= SumRH))
),
(SumLH #> 0) #=>
(
(((SecondInRow #> 0) #/\ (SecondLastInRow #> 0)) #/\ (SumLH #= SecondInRow + SecondLastInRow))
#\/
((SecondInRow #= 0) #/\ (SumLH #= ThirdInRow + SecondLastInRow))
#\/
((SecondLastInRow #= 0) #/\ (SumLH #= SecondInRow + ThirdLastInRow))
),
N1 is N+1,
put_restrictions_row(T, Gridsize, SumRT, SumLT, N1).
I think the code is pretty self explanatory, if not, what I'm trying to do:
If there is a constraint on the right side:
If the 1st and last cells of the row aren't 0, then their sum is = to the restriction
If the 1st cell on the row is 0, then the sum of 2nd cell of the row and the last = to the restriction -> makes the left restriction being the sum of the 3rd cell from the left and the secondlast
And so on...
I'm not getting any solution on the problem.
What am I doing wrong associating the constraints?
Any help is welcome. Thanks in advance for helping the prologNoob here :P
I tried to solve, with simpler code...
restrictions :-
T = [7, 6, 4, 7, 3], % TopRestriction
R = [5, 5, 5, 5, 5], % RightRestriction
B = [3, 4, 6, 3, 7], % BottomRestriction
L = [5, 5, 5, 5, 5], % LeftRestriction
restrictions(T, R, B, L, Sol),
maplist(writeln, Sol).
restrictions(T, R, B, L, Rows) :-
% check all restrictions are properly sized
maplist(length_(N), [T, R, B, L]),
% solution is a square
length_(N, Rows),
maplist(length_(N), Rows),
transpose(Rows, Cols),
% main constraints
append(Rows, Vs),
N1 is N-1,
Vs ins 0..N1,
maplist(all_different, Rows),
%maplist(all_different, Cols),
% apply restrictions
maplist(restriction, Rows, L, R),
maplist(restriction, Cols, T, B),
% if constraints are not enough strong for an unique solution
label(Vs).
restriction(Tile, S1, S2) :-
append([A,B], R, Tile),
append(_, [C,D], R),
S1 #= 0 #\/ A #= 0 #\/ D #= 0 #\/ S1 #= A + D,
S2 #= 0 #\/ B #= 0 #\/ C #= 0 #\/ S2 #= B + C.
length_(N, L) :- length(L, N).
Note the second all_different constraint is commented out, since when I post it, no solution is found. Removing constraints (so, 'weakening' solutions), it's the only 'real' debugging tool that I've been able to find so far by myself.
Solutions sample:
?- restrictions.
[3,0,1,4,2]
[1,0,2,3,4]
[0,1,2,4,3]
[2,1,4,0,3]
[4,2,0,3,1]
true ;
[3,0,1,4,2]
[1,0,2,3,4]
[0,1,2,4,3]
[2,1,4,0,3]
[4,2,3,0,1]
...
I run into the "No more memory available" error message in Mathematica. I understand that "Parallelize[]" isn't (obviously) going to help me. Neither has "ClearSystemCache[]".
What gives? Do I just need more RAM?
My Code
Needs["VectorAnalysis`"]
Needs["DifferentialEquations`InterpolatingFunctionAnatomy`"];
Clear[Eq4, EvapThickFilm, h, S, G, E1, K1, D1, VR, M, R]
Eq4[h_, {S_, G_, E1_, K1_, D1_, VR_, M_, R_}] := \!\(
\*SubscriptBox[\(\[PartialD]\), \(t\)]h\) +
Div[-h^3 G Grad[h] +
h^3 S Grad[Laplacian[h]] + (VR E1^2 h^3)/(D1 (h + K1)^3)
Grad[h] + M (h/(1 + h))^2 Grad[h]] + E1/(
h + K1) + (R/6) D[D[(h^2/(1 + h)), x] h^3, x] == 0;
SetCoordinates[Cartesian[x, y, z]];
EvapThickFilm[S_, G_, E1_, K1_, D1_, VR_, M_, R_] :=
Eq4[h[x, y, t], {S, G, E1, K1, D1, VR, M, R}];
TraditionalForm[EvapThickFilm[S, G, E1, K1, D1, VR, M, R]];
L = 318; TMax = 10;
Off[NDSolve::mxsst];
Clear[Kvar];
Kvar[t_] := Piecewise[{{1, t <= 1}, {2, t > 1}}]
(*Ktemp = Array[0.001+0.001#^2&,13]*)
hSol = h /. NDSolve[{
(*S,G,E,K,D,VR,M*)
EvapThickFilm[1, 3, 0.1, 7, 0.01, 0.1, 0, 160],
h[0, y, t] == h[L, y, t],
h[x, 0, t] == h[x, L, t],
(*h[x,y,0] == 1.1+Cos[x] Sin[2y] *)
h[x, y, 0] ==
1 + (-0.25 Cos[2 \[Pi] x/L] - 0.25 Sin[2 \[Pi] x/L]) Cos[
2 \[Pi] y/L]
},
h,
{x, 0, L},
{y, 0, L},
{t, 0, TMax},
MaxStepSize -> 0.1
][[1]]
hGrid = InterpolatingFunctionGrid[hSol];
Error message
No more memory available.
Mathematica kernel has shut down.
Try quitting other applications and then retry.
My OS specs
Intel Core 2 Duo with 4.00 GB ram, 64 bit OS (Windows 7)
Here you may get a taste of what is happening:
Replace
MaxStepSize -> 0.1
by
MaxStepFraction -> 1/30
And run your code.
Then:
p = Join[#,Reverse##]&#
Table[Plot3D[hSol[x, y, i], {x, 0, L}, {y, 0, L},
PlotRange -> {All, All, {0, 4}}],
{i, 7, 8, .1}]
Export["c:\\plot.gif", p]
So, Mma is trying to refine the solution at those peaks, to no avail.
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]]