56

29

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}]
```

56

29

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}]
```

34

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.

4I think the OP is a complete beginner, and all he's looking for is `ReplaceAll`

. This might be a bit too advanced for someone new to Mma. – Szabolcs – 2012-06-11T13:57:47.110

@Szabolcs Literally there is the `assignment`

tag, so he is rather looking for `Set`

or `SetDelayed`

applications. – Artes – 2012-06-11T16:07:27.077

I think I'll use your first solution for now, until I get the hang of ReplaceAll. @Szabolcs: Yes, Mma virgin. Thanks, all. – stevenvh – 2012-06-12T07:09:25.413

@stevenvh I think this answer can be also interesting for you : http://mathematica.stackexchange.com/questions/1819/arithmetic-operation-on-the-value-returned-by-solve/8223#8223

– Artes – 2012-07-12T11:17:59.100@Artes: could you tell me how can I find more information about the function s[[All, 1, 2]]? – anhnha – 2017-09-21T03:13:35.610

1@anhnha That's all information you can get, unless you've defined s in a different way, however one can use `FullForm[s]`

. – Artes – 2017-09-21T05:06:08.200

@Artes: What is the meaning of "All, 1, 2" in that function? – anhnha – 2017-09-21T05:42:02.700

1@anhnha Read the doccumentation pages of `Part`

then you'll understand what such a notation as `[[i,j,k]]`

mean. – Artes – 2017-09-21T06:55:18.390

40

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:

1

+1.Something related to your last comment and the injector pattern.

– Leonid Shifrin – 2012-06-11T14:05:04.137I agree that often you just want to use rules, but in my case I'm trying to set a global variable before going on to solve for other things (where `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? – Travis Bemrose – 2016-02-21T22:39:48.590

@Travis Assuming you want this in my own words please reference (46248). `@@@`

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`

.)

I understand that `Set`

and `=`

are equivalent, but it's the `Set[x, val]`

that the help file wouldn't tell me. I'm not sure what *levelspec* is, but I see that `@@@`

is grabbing stuff from either side of `->`

. I'm guessing there's some `Func[x, val]`

equivalent to `x -> val`

so that `@@@`

replaces `Func`

with `Set`

? – Travis Bemrose – 2016-02-22T11:05:19.410

1@Travis Okay. You need to become familiar with the long form of all these "shorthand" operators. You can see the long form by wrapping `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 ]]`

– Mr.Wizard – 2016-02-22T16:45:06.853

@Mr.Wizard Your comments have been very helpful, and I keep coming back here to relearn "what function was that, that showed me the structure?" I've been searching **levelspec**, but I only find references *to* it, and to tutorials *on* it directly. I have questions such as "Does the index start counting at 0 or 1? Does it count up or down? Is it relative or absolute?" --- Do you know a good tutorial or reference you can point me and others to? – Travis Bemrose – 2016-03-08T06:27:28.683

21

**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])} *)
```

I'm sorry you've deleted your previous answer nevertheless suppresing duplicates we reduce increasing overall entropy of this site, +1. – Artes – 2014-09-19T21:07:05.020

@artes, thank you for the upvote. I agree with your concern over excessive duplicates. The other Q/A is indeed a special case of this one. However, because of its special structure, some tricks that work there do not work here, e.g `Last@@@Solve[...]`

. – kglr – 2014-09-19T21:16:29.187

10

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:

7

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])}`

5

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.

1

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.

1Correct but seems to duplicate parts of earlier answers. – bbgodfrey – 2018-06-08T21:44:46.647

Also requires knowing the structure of the solution set. The outcome should not depend on whether `Solve`

orders `y`

results before or after `x`

. Here it does though, and that's not good at all. – Daniel Lichtblau – 2018-06-08T23:26:14.030

It is different, I used replacement with variables instead of direct assignment. – zyy – 2018-06-09T17:03:21.717

As for requirement of knowing the structure, you have to know the structure before you do the assignment, as Mathematica is not showing the solutions in a particular order, which is a pain for me as well. – zyy – 2018-06-09T17:05:59.690

Could you elaborate on what you are trying to achieve? In principle you can use

`Replace`

(or`Part`

) to assign the values to variables. – sebhofer – 2012-06-11T13:36:35.390@sebhofer - I want to assign the first x value to a variable X1, then the y value to Y1, the other two to X2 and Y2. I just don't seem to get the hang of references yet. – stevenvh – 2012-06-11T13:40:56.700