penny
penny

Reputation: 121

Creating random coefficients for linear equations in mathematica

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.

Upvotes: 5

Views: 511

Answers (5)

Dr. belisarius
Dr. belisarius

Reputation: 61056

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

Upvotes: 2

Daniel Lichtblau
Daniel Lichtblau

Reputation: 6894

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

Upvotes: 3

Simon
Simon

Reputation: 14731

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...

Upvotes: 9

Pillsy
Pillsy

Reputation: 9901

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]

Upvotes: 7

Andrew Walker
Andrew Walker

Reputation: 42500

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

Upvotes: 4

Related Questions