DMUG-Archiv 1998

Frühere

 

Chronologischer Index

 

Spätere

Vorherige

 

Thematischer Index

 

Nächste

Re: Solve (einfaches Problem, hoher Zeit- und Speicherbedarf)

Michael hat natuerlich das Thema eigentlich schon erschoepfend behandelt,
aber hier eine kleine Anmerkung, dass man (fuer lineare Systeme) auch recht
einfach ein simples Programm schreiben kann (kein Anspruch auf perfekte Programmierung
hier ;-)), dass solche Probleme (meistens) erfolgreich und schnell loest:

In[1]:= <<LSolve`

In[2]:= eqn = Flatten[{
        { C12+C13*C23/(C13+C23) == C10*C20/(C10+C20) },
        { C13+C12*C23/(C12+C23) == C10*C30/(C10+C30) },
        { C23+C12*C13/(C12+C23) == C20*C30/(C20+C30) } }];

In[3]:= LSolve[eqn, {C10, C20, C30}]//Timing//InputForm

Out[3]//InputForm= 
  {0.5*Second, {C10 -> 
     (2*(C12*C13 + C12*C23 + C13*C23)*(C12*C13 + C12*C23 + C23^2))/
      (C12*C13^2 + C12*C13*C23 + 2*C12*C23^2 + 2*C23^3), 
    C20 -> (2*(C12*C13 + C12*C23 + C13*C23)*(C12*C13 + C12*C23 + C23^2))/
      (C13*(C12*C13 + 3*C12*C23 + 2*C23^2)), 
    C30 -> (2*(C12*C13 + C12*C23 + C13*C23)*(C12*C13 + C12*C23 + C23^2))/
      (C12*(C13 + C23)*(2*C12 - C13 + 2*C23))}}

In[4]:= !!LSolve.m
(* :Title: LSolve *)
(* :Summary:  LSolve is like Solve, but only for linear equations *)
BeginPackage["LSolve`"];
LSolve::usage=
"LSolve is equivalent to Solve, except that it works only for 
linear equations (and returns just a list) 
and uses the High-school algorithm and is sometimes better than
Solve for rational polynomial systems.";
$VeryVerbose::usage=
"$VeryVerbose is a global variable with default value 0.
Setting it to 1 or 2 displays intermediate informations 
during the calculation.";
Begin["`Public`"]; $VeryVerbose=0;
LSolve[a_ /; Head[a] =!= List, b__] := LSolve[{a}, b];
LSolve[eqq_List, cli_List, ops___Rule] := Block[
{newel,lneq,neqh,neq,newneq,col,coll,new,res = {},leq=Length[eqq]},
col[x_] := Collect[x, cli, Cancel[Factor[#]]&];
specsimp[{}, b_Rule] := {b}; specsimp[a_List, b_Rule] :=
Map[(#[[1]] -> (coll[#[[2]] /. b]))&, a] /. coll -> col;
neq = eqq /. Equal[a_, b_] :> (a-b);
For[i = 1, i <= leq, i++, 
If[!FreeQ[neq, cli[[i]]],
    While[FreeQ[neq1 = col[neq[[1]] /. res], cli[[i]]],
          If[$VeryVerbose > 1, Print["rotating ", i]];
          neq = RotateLeft[neq = Prepend[Rest[neq],neq1]] ];
    new = Solve[neq1==0, cli[[i]]][[1,1]];
    If[$VeryVerbose > 0, Print["solved ",new//InputForm]];
    new = new[[1]] -> Collect[new[[2]], cli, Cancel[Factor[#]]&];
    neq = Rest[neq];
If[i>1, res = Append[specsimp[res, new], new], res = {new}];
  If[i < leq, If[ $VeryVerbose > 1, Print["UPDATING"] ];
     newneq = {}; neqh = Hold@@{neq}; lneq = Length[neq];
     For[iij = 1, iij <= lneq, iij++,
         If[$VeryVerbose > 1,Print["updating ", iij, " out of ",lneq]];
         newel = neqh[[1, iij]] /. res;
         If[newel === neqh[[1, iij]], AppendTo[newneq, newel],
            AppendTo[newneq, col[newel]]
           ];    Clear[newel]; ];
     neq = newneq]]]; res];
End[]; EndPackage[];

In[4]:= Simplify/@(eqn/.Last[%])

Out[4]= {True, True, True}


Rolf Mertig



Verweise:
Solve (einfaches Problem, hoher Zeit- und Speicherbedarf)
Harald von Aschen, 15.12.1996

Frühere

 

Chronologischer Index

 

Spätere

Vorherige

 

Thematischer Index

 

Nächste

DMUG-Archiv, http://www.mathematica.ch/dmug-liste.html; Letzte Änderung: 08.09.2003 20:44