I understand Mathematica can't assign the results of a Solve to the unknowns because there may be more than 1 solution. How can I assign the 4 values of following result to variables?

Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}] You can do this :
s = Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}]; xx = s[[All, 1, 2]]; yy = s[[All, 2, 2]]; Now you can access solutions, this way xx[[1]], yy[[2]].
If you prefer to collect solutions in Array, there is another way :
X = Array[ x, {Length@s}]; Y = Array[ y, {Length@s}]; x[k_] /; MemberQ[ Range[ Length @ s], k] := s[[k, 1, 2]] y[k_] /; MemberQ[ Range[ Length @ s], k] := s[[k, 2, 2]] now X is equivalent to s[[All, 1, 2]], while Y to s[[All, 2, 2]], e.g. :
X[[1]] == x[1] Y == s[[All, 2, 2]] True True
You do not have to use or even to define X and Y arrays, e.g.
{x[1], y[1]} {(-11181 - Sqrt[2242057])/74498, 1/386 (13 - Sqrt[2242057])}
We've used Condition i.e. /; to assure definitions of x[i], y[i] only for i in an appropriate range determined by Length @ s, i.e. number of solutions.
ReplaceAll. This might be a bit too advanced for someone new to Mma. $\endgroup$ assignment tag, so he is rather looking for Set or SetDelayed applications. $\endgroup$ FullForm[s]. $\endgroup$ Part then you'll understand what such a notation as [[i,j,k]] mean. $\endgroup$ Usually you don't want to actually assign values to x and y, and you would use replacement rules instead:
sols = Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}]; {x, y} /. sols[[1]] or for the second solution:
{x, y} /. sols[[2]] If you really want to assign values to x and y globally, you could use:
Set @@@ sols[[1]] but you must clear x and y before using another set:
Clear[x, y] Set @@@ sols[[2]] If you want to assign values to x and y within a Block you could do something like this:
Hold @@ {sols[[2]]} /. Rule -> Set /. _[vars_] :> Block[vars, Sin[x] + Sqrt[y] // N ] This uses what I am calling the injector pattern to get the values into Block in the right syntax without it prematurely evaluating.
Related questions:
Solve will work better if it has this global value instead of trying to remain general for all possible values). I tried the equivalent of Set[sols[[1]]], and when that didn't work. Of course the "help" file is no help because it insists on explaining the symbol = and not the function Set, so I ended up here. What is Set @@@ sols[[1]] doing? $\endgroup$ @@@ is shorthand for Apply at levelspec {1}. So foo @@@ {x -> val1, y -> val2} becomes {foo[x, val1], foo[y, val2]}, or in the code in the question {Set[x, val1], Set[y, val2]}, which then assigns the values with Set. (= is the shorthand for Set.) $\endgroup$ code in HoldForm[FullForm[ code ]] -- for example HoldForm[FullForm[ {x -> val1, y = val2} ]] will reveal List[Rule[x, val1], Set[y, val2]]. This "FullForm" expression is what you need to visualize when you think about Mathematica manipulating code. Virtually all Replace, Map, Apply, Part, etc. operations effectively "see" this structure, not the short form you type in. See e.g. HoldForm[FullForm[ a - b ]] $\endgroup$ Update: Version 10 built-in function Values does value extraction conveniently for rules appearing in lists of arbitrary lengths and depths:
{{x1, y1}, {x2, y2}} = Values[Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}]] (* {{(-11181-Sqrt[2242057])/74498,1/386 (13-Sqrt[2242057])}, {(-11181+Sqrt[2242057])/74498,1/386 (13+Sqrt[2242057])}} *) Another example:
lst={{a->1,b->2},{c->3},{{d->4}},{e->5,{f->6,{g->7}}}}; Values[lst] (* {{1,2},{3},{{4}},{5,{6,{7}}}} *) Original post:
{{x1, y1}, {x2, y2}} = Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}][[All, All, -1]] (* {{(-11181 - Sqrt[2242057])/74498, 1/386 (13 - Sqrt[2242057])}, {(-11181 + Sqrt[2242057])/74498, 1/386 (13 + Sqrt[2242057])}} *) {x1, y2} (* {(-11181- Sqrt[2242057]) / 74498, 1 / 386 (13 + Sqrt[2242057])} *) Last@@@Solve[...]. $\endgroup$ If you really wish to assign solutions to variables, you can do something like this:
In[1]:= ClearAll[Subscript] sols=Solve[y^2==13x+17&&y==193x+29,{x,y}]; i=0; sols/.{r__Rule}:>Set@@@({r}/.var:x|y->Subscript[var,++i]); Subscript//Definition Out[5]=
Subscript[x,1]=(-11181-Sqrt[2242057])/74498
Subscript[x,2]=(-11181+Sqrt[2242057])/74498
Subscript[y,1]=1/386(13-Sqrt[2242057])
Subscript[y,2]=1/386 (13+Sqrt[2242057])
Then you can use the solutions for demonstration purposes:

Here's a painless solution:
s = Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}]; Assign the four results of the solution s above to a variable each, in sequence
{X1, Y1, X2, Y2} = s // Values // Flatten; Verify
{X1, Y1, X2, Y2} {(-11181 - Sqrt[2242057])/74498, 1/386 (13 - Sqrt[2242057]), (-11181 + Sqrt[2242057])/74498, 1/386 (13 + Sqrt[2242057])}
Ah, they finally implemented it in version 10, then! Here's a procedure I've been using since version 5, it might provide similar features in versions prior to the introduction of Value. (I'm not sure, but maybe I posted it on the MathGroup... so forgive me if this is not news)
I had called it "ToValues". I gave it two options:
Options[ToValues] = { Flattening -> Automatic, IndexedFunction -> False};
The help message is hopefully self-explicating:
ToValues::usage = "ToValues[li] suppresses the Rule wrapper in every part of list li.\n ToValues[li,F] \ applies the function F to every rhs of Rule, turning var->value into \ F[value]. If the function F has a parametrized head, then it is possible to \ pass the lhs of Rule to it by setting the option IndexedFunction->True. It will \ turn var->value into F[var][value].\n When the option Flattening is set to \ Automatic, ToValues flattens li to yield a simplified structure (the \ flattening is tuned to get the simplest list of values for the solution of a \ system of several equation in several variables). With Flattening set to None \ the original structure is left intact.";
The code is really short.
ToValues[li_, opts___Rule] := Module[ {newli, vars, sols, fl}, fl = Flattening /. {opts} /. Options[ToValues]; sols = First[Dimensions[li]]; vars = Last[Dimensions[li]]; newli = li /. Rule[_, v_] -> v; If[fl == Automatic && vars == 1, newli = Flatten[newli]]; If[fl == Automatic && sols == 1, First[newli], newli] ] ToValues[li_, fun_, opts___Rule] := Module[ {newli, vars, sols, foo, fl, mi}, mi = IndexedFunction /. {opts} /. Options[ToValues]; fl = Flattening /. {opts} /. Options[ToValues]; If[mi == True, newli = li /. (x_ -> v_) -> foo[x][v], newli = li /. (_ -> v_) -> foo[v] ]; sols = First[Dimensions[li]]; vars = Last[Dimensions[li]]; If[fl == Automatic && vars == 1, newli = Flatten[newli]]; If[fl == Automatic && sols == 1, First[newli], newli] //. foo -> fun ]
Example data:
sols = {{x -> 1}, {y -> 2}, {z -> 3}}; Application of ToValues to lists of rules produces a list of values
ToValues[sols] // InputForm {1, 2, 3}
Of course assignment is immediate, here
{x1,x2,x3} = ToValues[sols] By default, ToValues returns the simplest list of values possible, suppressing nested list. If you want to preserve the original nesting, this is what the Flattening option does:
ToValues[sols, Flattening -> None] // InputForm {{1}, {2}, {3}}
We can specify a function to be applied to the returned values.
ToValues[sols, F] // InputForm {F[1], F[2], F[3]}
We can also use function that make use of the right hand sides of the rules. Just define them as functions with a parametrized Head and set IndexedFunction->True to instruct ToValues to make use of that. In this case we want to return lists in the form {variable name, variable value}:
F[var_][value_] := {var, value} ToValues[sols, F, IndexedFunction -> True] // InputForm {{x, 1}, {y, 2}, {z, 3}}
ToValues[sols, F, IndexedFunction -> True, Flattening -> None] // InputForm {{{x, 1}}, {{y, 2}}, {{z, 3}}}
Real world applications
ToValues is normally used to extract solutions from the lists returned by Solve, NSolve, DSolve, etc. In its default form it can be applied in this way:
Solve[{x + y == 1, x - y == 2}] // ToValues {3/2, 1/2}
This gives a list of the complex solutions
Solve[x^5 == 1] // ToValues This uses the optional function to compute the real and imaginary part of each solution
coords = ToValues[Solve[x^5 == 1, x], {Re[#], Im[#]} &] // N; ListPlot[coords, AspectRatio -> Automatic, Frame -> True, PlotStyle -> PointSize[.018]]; And this pushes the function to create graphics objects (Points) based on those values inside ToValues:
pts = ToValues[Solve[x^9 == 1, x], Point[{Re[#], Im[#]}] &]; Show[Graphics[{PointSize[.018], pts}], AspectRatio -> 1, Frame -> True, Axes -> True]; Someone who has patience enough might want to add the plots.
Here is an easy solution
s = Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}]; x1 = x /. s[[1, 1]]; y1 = y /. s[[1, 2]]; x2 = x /. s[[2, 1]]; y2 = y /. s[[2, 2]]; We can verify with
MatrixForm[{{x1, y1}, {x2, y2}}] The output looks like
For reference, please look at assign.
Solveorders y results before or after x. Here it does though, and that's not good at all. $\endgroup$ Using MapIndexed:
f[s_List] := MapIndexed[Set @@ {Symbol@ StringJoin@(ToString /@ {#1[[1]], #2[[1]]}), #1[[2]]} &, s, {2}] f[Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}]]; {{x1, y1}, {x2, y2}} (*{{(-11181 - Sqrt[2242057])/74498, 1/386 (13 - Sqrt[2242057])}, {(-11181 + Sqrt[2242057])/74498, 1/386 (13 + Sqrt[2242057])}}*) Or using MapIndexed and Subscript:
f[s_List] := MapIndexed[Set[Subscript[#1[[1]], #2[[1]]], #1[[2]]] &, s, {2}] f[Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}]]; {{Subscript[x, 1], Subscript[y, 1]}, {Subscript[x, 2], Subscript[y, 2]}} (*{{(-11181 - Sqrt[2242057])/74498, 1/386 (13 - Sqrt[2242057])}, {(-11181 + Sqrt[2242057])/74498, 1/386 (13 + Sqrt[2242057])}}*) Here is a short one liner.
{{x1,y1},{x2,y2}}= Solve[y^2==13 x+17&&y==193 x+29]/.Rule->Set
The solutions are in x1,y1,x2,y2. x and y will also contain the last solutions, so you might want to Clear[x,y] or Remove[x,y].
In[9051]:= sol = Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y, x, y}] /. Rule -> Set Out[9051]= {{(-11181 - Sqrt[2242057])/74498, 1/386 (13 - Sqrt[2242057])}, {(-11181 + Sqrt[2242057])/74498, 1/386 (13 + Sqrt[2242057])}} In[9055]:= x1 = sol[[1, 1]] Out[9055]= (-11181 - Sqrt[2242057])/74498 In[9056]:= y1 = sol[[1, 2]] Out[9056]= 1/386 (13 - Sqrt[2242057]) In[9057]:= x2 = sol[[2, 1]] Out[9057]= (-11181 + Sqrt[2242057])/74498 In[9058]:= y2 = sol[[2, 2]] Out[9058]= 1/386 (13 + Sqrt[2242057]) S = Solve[x^2 == 1, x] // Values // Flatten S[[1]] S[[2]] Try this:
In[6061]:= {{x1, x2}, {y1, y2}} = Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}] /. Rule -> Set; In[6062]:= {x1, x2, y1, y2} Out[6062]= {(-11181 - Sqrt[2242057])/74498, 1/386 (13 - Sqrt[2242057]), (-11181 + Sqrt[2242057])/74498, 1/386 (13 + Sqrt[2242057])} As you can see, the variables x1,x2,y1,y2 are solved directly in one equation.
Replace(orPart) to assign the values to variables. $\endgroup$