MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Trouble with coupled quadratic

  • To: mathgroup at smc.vnet.net
  • Subject: [mg108305] Re: [mg108256] Re: [mg106476] Trouble with coupled quadratic
  • From: DrMajorBob <btreat1 at austin.rr.com>
  • Date: Sat, 13 Mar 2010 07:56:19 -0500 (EST)
  • References: <201001141046.FAA19729@smc.vnet.net>
  • Reply-to: drmajorbob at yahoo.com

If you have 3n variables, I don't see why you'd think you're in 3-space.

Bobby

On Fri, 12 Mar 2010 06:07:48 -0600, Robert Hoy <robert.hoy at yale.edu> wrote:

> Hello - sorry for the extremely belated reply.  Daniel, your method
> worked, of course - thanks.
>
> What I ended up going with was a numerical solver that makes initial
> guesses (with some randomnness) as to the values of the {x, y, z}, and
> then uses Newton iterations to try and solve them.  If it doesn't work
> after a number of iterations (which I set), it makes another initial
> guess.  The code uses LU decomposition and a number of standard
> tricks.  One thing I thought worth mentioning is, the method does not
> employ complex numbers, and I don't see why complex numbers would be
> needed.  So, bringing things back to Mathematica, three questions:
>
> 1) Is there a way to restrict the Mathematica solver to work only in
> real space?
>
> 2) A problem with solving these sets of equations in Mathematica is
> its use of Grobner bases; solutions slow drastically as the number of
> variables (3N) exceeds 21 (N = 7).  Does Mathematica have a special
> solver for quadratic forms (my equations are all quadratic forms)
> which uses something other than Grobner bases?
>
> 3) To be clear, though I am solving equations in 3N variables, the
> solutions 'live in' 3-dimensional Cartesian space (R^3).  Is there
> some command to tell Mathematica to look for solutions only in R^3?
>
> The reason I ask is, the numerical solver I'm using also starts to
> break as N becomes 'large' (how large 'large' is can be increased by
> using tricks, but only up to a point), but I guess Mathematica might
> include some special routines for dealing with this problem (which is,
> after all, just solving real quadratic forms).
>
> Thanks,
> Robert Hoy
>
>
> On Jan 14, 2010, at 11:46 AM, Daniel Lichtblau wrote:
>
>> Robert Hoy wrote:
>>> Hi, all!  I am trying to solve for the structures of small atomic
>>> clusters using Mathematica.  Using adjacency (contact) matrices as
>>> input, my the desired output is 3-D Cartesian coordinates.   I
>>> formulate the problem as coupled quadratic equations and
>>> inequalities.  For example, for clusters of M = 6 atoms I
>>> introduce  the variables
>>> xvec = {{x1, y1, z1}, {x2, y2, z2}, {x3, y3, z3}, {x4, y4, z4},
>>> {x5, y5,
>>>    z5}, {x6, y6, z6}}
>>> Then, for an adjacency matrix A
>>> {
>>>   {0, 1, 0, 1, 1, 1},
>>>   {1, 0, 1, 1, 0, 1},
>>>   {0, 1, 0, 1, 1, 1},
>>>   {1, 1, 1, 0, 1, 0},
>>>   {1, 0, 1, 1, 0, 1},
>>>   {1, 1, 1, 0, 1, 0}
>>>  }
>>> there are M(M-1)/2 coupled equations and inequalities:
>>> EqnTab = {(x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2 ==
>>>   1, (x1 - x3)^2 + (y1 - y3)^2 + (z1 - z3)^2 >
>>>   1, (x1 - x4)^2 + (y1 - y4)^2 + (z1 - z4)^2 ==
>>>   1, (x1 - x5)^2 + (y1 - y5)^2 + (z1 - z5)^2 ==
>>>   1, (x1 - x6)^2 + (y1 - y6)^2 + (z1 - z6)^2 ==
>>>   1, (x2 - x3)^2 + (y2 - y3)^2 + (z2 - z3)^2 ==
>>>   1, (x2 - x4)^2 + (y2 - y4)^2 + (z2 - z4)^2 ==
>>>   1, (x2 - x5)^2 + (y2 - y5)^2 + (z2 - z5)^2 >
>>>   1, (x2 - x6)^2 + (y2 - y6)^2 + (z2 - z6)^2 ==
>>>   1, (x3 - x4)^2 + (y3 - y4)^2 + (z3 - z4)^2 ==
>>>   1, (x3 - x5)^2 + (y3 - y5)^2 + (z3 - z5)^2 ==
>>>   1, (x3 - x6)^2 + (y3 - y6)^2 + (z3 - z6)^2 ==
>>>   1, (x4 - x5)^2 + (y4 - y5)^2 + (z4 - z5)^2 ==
>>>   1, (x4 - x6)^2 + (y4 - y6)^2 + (z4 - z6)^2 >
>>>   1, (x5 - x6)^2 + (y5 - y6)^2 + (z5 - z6)^2 == 1}
>>> In these equations and inequalities, the left hand sides are
>>> Dot[xvec[[m]] - xvec[[n]], xvec[[m]] - xvec[[n]] (i. e. the
>>> squared  Euclidean distance between xvec[[m]] and xvec[[n]] and the
>>> 'right hand  sides'  are '==1' if A[[m,n]]==1 and '> 1' if
>>> A[[m,n]]=0.  Only terms  above the diagonal of the adjacency matrix
>>> (n > m) are necessary since  A is symmetric.
>>> I know the solution to these equations; the six elements of xvec
>>> form  the vertices of an octahedron.
>>> Mathematica hangs when I try to solve this set.  This isn't
>>> surprising, because the above equations alone are invariant under
>>> translations and rotations, so the solutions are continuously
>>> degenerate.  To eliminate the continuous degeneracies I add
>>> equations  constraining the first three 'atoms' to a plane (I can
>>> do this because  they are noncollinear).  There is another discrete
>>> mirror degeneracy  (the other atoms can lie on either side of the
>>> defined plane), so I  add another inequality saying the fourth atom
>>> is on one side.  This  adds ten equations/inequalities and gives
>>> the system
>>> CompleteEqnTab = {x1 == 0, y1 == 0, z1 > 0, x2 == 0, z2 == 0, y2 >
>>> 0,  y3 == 0, z3 == 0, x3 > 0,
>>>   x4/x3 + y4/y2 + z4/z1 > 1, [the 15 terms of EqnTab]}
>>> Now, the problem is, I have been unable (after a considerable
>>> amount  of effort) to solve this system with Mathematica.
>>> Reduce[CompleteEqnTab, Flatten[xvec], Reals] fails.  So does
>>> FindInstance[CompleteEqnTab, Flatten[xvec], Reals].  The memory
>>> used  by the kernel just increases (well past 1GB) until the
>>> program hangs.
>>> I think the problem is that the solution for xvec (i. e. the
>>> vertices  of an octahedron) has many rotational symmetries - its
>>> point group is  O_h.  Perhaps these symmetries give Mathematica's
>>> solver trouble?
>>> In contrast, the exact same approach for a less symmetric cluster
>>> with  adjacency matrix
>>> (
>>>   {0, 1, 1, 1, 1, 1},
>>>   {1, 0, 1, 1, 1, 1},
>>>   {1, 1, 0, 1, 0, 0},
>>>   {1, 1, 1, 0, 1, 0},
>>>   {1, 1, 0, 1, 0, 1},
>>>   {1, 1, 0, 0, 1, 0}
>>>  )
>>> and equation/inequality set
>>> CompleteEqnTab2 = {x1 == 0, y1 == 0, z1 > 0, x2 == 0, z2 == 0, y2 >
>>> 0,  y3 == 0, z3 == 0, x3 > 0,
>>>   x4/x3 + y4/y2 + z4/z1 > 1, (x1 - x2)^2 + (y1 - y2)^2 + (z1 -
>>> z2)^2 ==
>>>   1, (x1 - x3)^2 + (y1 - y3)^2 + (z1 - z3)^2 ==
>>>   1, (x1 - x4)^2 + (y1 - y4)^2 + (z1 - z4)^2 ==
>>>   1, (x1 - x5)^2 + (y1 - y5)^2 + (z1 - z5)^2 ==
>>>   1, (x1 - x6)^2 + (y1 - y6)^2 + (z1 - z6)^2 ==
>>>   1, (x2 - x3)^2 + (y2 - y3)^2 + (z2 - z3)^2 ==
>>>   1, (x2 - x4)^2 + (y2 - y4)^2 + (z2 - z4)^2 ==
>>>   1, (x2 - x5)^2 + (y2 - y5)^2 + (z2 - z5)^2 ==
>>>   1, (x2 - x6)^2 + (y2 - y6)^2 + (z2 - z6)^2 ==
>>>   1, (x3 - x4)^2 + (y3 - y4)^2 + (z3 - z4)^2 ==
>>>   1, (x3 - x5)^2 + (y3 - y5)^2 + (z3 - z5)^2 >
>>>   1, (x3 - x6)^2 + (y3 - y6)^2 + (z3 - z6)^2 >
>>>   1, (x4 - x5)^2 + (y4 - y5)^2 + (z4 - z5)^2 ==
>>>   1, (x4 - x6)^2 + (y4 - y6)^2 + (z4 - z6)^2 >
>>>   1, (x5 - x6)^2 + (y5 - y6)^2 + (z5 - z6)^2 == 1}
>>> gives a quick solution
>>> In[32]:= Timing[Reduce[CompleteEqnTab2, Flatten[xvec], Reals]]
>>> Out[32]= {18.527, x1 == 0 && y1 == 0 && z1 == 1/Sqrt[2] && x2 == 0
>>> &&  y2 == 1/Sqrt[2] &&
>>>    z2 == 0 && x3 == 1/Sqrt[2] && y3 == 0 && z3 == 0 && x4 == 1/
>>> Sqrt[2] &&
>>>   y4 == 1/Sqrt[2] && z4 == 1/Sqrt[2] && x5 == -(1/(3 Sqrt[2])) &&
>>>   y5 == (2 Sqrt[2])/3 && z5 == (2 Sqrt[2])/3 && x6 == -(11/(9
>>> Sqrt[2])) &&
>>>   y6 == 5/(9 Sqrt[2]) && z6 == 5/(9 Sqrt[2])}
>>> Similar issues hold for larger clusters; Mathematica solves the
>>> less- symmetric systems and hangs on the more-symmetric ones.  Is
>>> there  anything I can do about this?  I thought FindInstance was
>>> designed for  this sort of thing but it doesn't seem to help.
>>> As you can see from the above, the form of the equations and
>>> inequalities is simple.  I assume Mathematica can handle the
>>> symmetric  cases and I'm just unaware of the necessary
>>> functionality.  Any help  would be greatly appreciated.  I am using
>>> Mathematica 7.0.1.0 on Mac  OS 10.5.8.
>>> Thanks,
>>> Robert Hoy
>>
>> I'm not sure what I am trying is quite what you need. Might give a
>> start though. The idea is this.
>>
>> (1) Start with the equations (that is, ignore the inequalities)
>> (2) Reduce by the variables that are set to zero,
>> (3) Perturb numerically
>> (4) Solve numerically
>> (5) Discard complex solutions
>> (6) Put back the zero-valued variables
>> (7) Apply the inequalities
>> (8) Inspect what remains as solution, if anything. If it gives some
>> insight into the exact solutions, use that to further simplify
>> matters.
>>
>> I show this below.
>>
>> In[53]:= CompleteEqnTab =
>>  Join[{x1 == 0, y1 == 0, z1 > 0, x2 == 0, z2 == 0, y2 > 0, y3 == 0,
>>    z3 == 0, x3 > 0, x4/x3 + y4/y2 + z4/z1 > 1}, EqnTab];
>>
>> In[54]:= eqns = Cases[CompleteEqnTab, _Equal];
>>
>> In[55]:= polys = Apply[Subtract, eqns, 1];
>>
>> In[56]:= rules = Thread[{x1, y1, x2, z2, y3, z3} -> 0];
>>
>> In[57]:= p2 = DeleteCases[polys /. rules, 0]
>>
>> Out[57]= {-1 + y2^2 + z1^2, -1 + x4^2 + y4^2 + (z1 - z4)^2, -1 +
>>  x5^2 + y5^2 + (z1 - z5)^2, -1 + x6^2 + y6^2 + (z1 - z6)^2, -1 +
>>  x3^2 + y2^2, -1 + x4^2 + (y2 - y4)^2 + z4^2, -1 +
>>  x6^2 + (y2 - y6)^2 + z6^2, -1 + (x3 - x4)^2 + y4^2 +
>>  z4^2, -1 + (x3 - x5)^2 + y5^2 + z5^2, -1 + (x3 - x6)^2 + y6^2 +
>>  z6^2, -1 + (x4 - x5)^2 + (y4 - y5)^2 + (z4 - z5)^2, -1 + (x5 -
>>    x6)^2 + (y5 - y6)^2 + (z5 - z6)^2}
>>
>> In[58]:= vars2 = Variables[p2];
>>
>> In[59]:= p3 = p2 + 1/10000*RandomReal[{0, 1}, Length[p2]]
>>
>> Out[59]= {-0.999914 + y2^2 + z1^2, -0.999904 + x4^2 +
>>  y4^2 + (z1 - z4)^2, -0.999945 + x5^2 +
>>  y5^2 + (z1 - z5)^2, -0.999912 + x6^2 +
>>  y6^2 + (z1 - z6)^2, -0.999905 + x3^2 + y2^2, -0.999958 +
>>  x4^2 + (y2 - y4)^2 + z4^2, -0.999909 + x6^2 + (y2 - y6)^2 +
>>  z6^2, -0.999983 + (x3 - x4)^2 + y4^2 +
>>  z4^2, -0.999903 + (x3 - x5)^2 + y5^2 +
>>  z5^2, -0.999948 + (x3 - x6)^2 + y6^2 +
>>  z6^2, -0.999968 + (x4 - x5)^2 + (y4 - y5)^2 + (z4 -
>>    z5)^2, -0.999984 + (x5 - x6)^2 + (y5 - y6)^2 + (z5 - z6)^2}
>>
>> In[60]:= Timing[solns = NSolve[p3];]
>>
>> Out[60]= {29.8675, Null}
>>
>> In[61]:= s2 = vars2 /. solns;
>>
>> In[62]:= keep = Map[Apply[And, Map[Head[#] =!= Complex &, #]] &, s2];
>>
>> In[63]:= realsols = Pick[solns, keep, True];
>>
>> In[64]:= realsols = Map[Join[rules, #] &, realsols];
>>
>> ineqs = DeleteCases[CompleteEqnTab, _Equal];
>>
>> In[66]:= keep2 = Apply[And, ineqs /. realsols, 1]
>>
>> Out[66]= {False, True, False, False, False, False, False, False, \
>> False, False, False, False, False, False, False, False, False,
>> False, \
>> False, False, False, False, False, False, False, False, False,
>> False, \
>> False, False, False, False, False, False, False, False, False,
>> False, \
>> False, False, False, False, False, False, False, False, False, False}
>>
>> In[67]:= Pick[realsols, keep2, True]
>>
>> Out[67]= {{x1 -> 0, y1 -> 0, x2 -> 0, z2 -> 0, y3 -> 0, z3 -> 0,
>>  y2 -> 0.00324073, x4 -> 0.502247, x6 -> 0.497657, z4 -> 0.502289,
>>  y5 -> -0.00324273, z6 -> 0.497678, y4 -> 0.707095, y6 -> -0.707086,
>>  z1 -> 0.999952, z5 -> 0.999946, x3 -> 0.999947, x5 -> 0.999967}}
>>
>> That finishes steps (1)-(7). For (8), I would surmise that you want
>> to impose the following equations: {z1==1, z5==1, x3==1, x5==1,
>> x4==z4, y4==-y6, x6==z6, y2==-y5}.
>>
>> In[75]:= moreeqns = {z1 == 1, z5 == 1, x3 == 1, x5 == 1, x4 == z4,
>>   y4 == -y6, x6 == z6, y2 == -y5};
>>
>> In[80]:= fulleqns = Join[eqns, moreeqns];
>>
>> In[77]:= fullpolys = Apply[Subtract, fulleqns, 1];
>>
>> In[78]:= Timing[solns2 = NSolve[fullpolys];]
>>
>> Out[78]= {0.110983, Null}
>>
>> Let's have a look.
>>
>> In[79]:= solns2
>>
>> Out[79]= {{x1 -> 0., x3 -> 1., y1 -> 0., y3 -> 0., z1 -> 1., z3 -> 0.,
>>   z2 -> 0., z5 -> 1., z4 -> 0.5, z6 -> 0.5, y4 -> -0.707107,
>>  y6 -> 0.707107, y2 -> 0., y5 -> 0., x4 -> 0.5, x6 -> 0.5, x2 -> 0.,
>>  x5 -> 1.}, {x1 -> 0., x3 -> 1., y1 -> 0., y3 -> 0., z1 -> 1.,
>>  z3 -> 0., z2 -> 0., z5 -> 1., z4 -> 0.5, z6 -> 0.5, y4 -> -0.707107,
>>   y6 -> 0.707107, y2 -> 0., y5 -> 0., x4 -> 0.5, x6 -> 0.5, x2 -> 0.,
>>   x5 -> 1.}, {x1 -> 0., x3 -> 1., y1 -> 0., y3 -> 0., z1 -> 1.,
>>  z3 -> 0., z2 -> 0., z5 -> 1., z4 -> 0.5, z6 -> 0.5, y4 -> 0.707107,
>>  y6 -> -0.707107, y2 -> 0., y5 -> 0., x4 -> 0.5, x6 -> 0.5, x2 -> 0.,
>>   x5 -> 1.}, {x1 -> 0., x3 -> 1., y1 -> 0., y3 -> 0., z1 -> 1.,
>>  z3 -> 0., z2 -> 0., z5 -> 1., z4 -> 0.5, z6 -> 0.5, y4 -> 0.707107,
>>  y6 -> -0.707107, y2 -> 0., y5 -> 0., x4 -> 0.5, x6 -> 0.5, x2 -> 0.,
>>   x5 -> 1.}}
>>
>> Not hard to deduce the algebraic values (all are in the set +-
>> {0,1/2,Sqrt[2]/2,1}). But they all seem to violate the inequality
>> that y2>0.
>>
>> Notice that the enforcement of real solutions might also be overly
>> restrictive. Since we do a perturbation, there might be complex
>> solutions with small imaginary parts that would be zero in the
>> unperturbed case. So one might want to allow them, modifying some of
>> the subsequent code as needed to check inequalities, etc. When I
>> tried that I still seem to run afoul of the y2>0 requirement. You
>> might have better luck.
>>
>> Daniel Lichtblau
>> Wolfram Research
>
>


-- 
DrMajorBob at yahoo.com


  • Prev by Date: Re: Re: locally changing Options
  • Next by Date: Re: Re: locally changing Options
  • Previous by thread: Re: Trouble with coupled quadratic equations where the solutions are
  • Next by thread: character repeat