Создание случайных коэффициентов для линейных уравнений в mathematica

Есть ли способ присвоить случайное значение p1, p2, p3 и p4 для следующего уравнения?

p1 y1 + p2 y2 + p3 y3 = p4

учитывая, что y1, y2 и y3 - переменные, которые необходимо решить.


person penny    schedule 16.09.2011    source источник
comment
должны ли коэффициенты иметь определенное распределение? Обычный? Униформа?   -  person Andrew Walker    schedule 16.09.2011
comment
нет, просто случайные действительные или случайные целые числа   -  person penny    schedule 16.09.2011
comment
@penny: что, вероятно, означает, что вам нужно равномерное распределение ...   -  person Simon    schedule 16.09.2011


Ответы (5)


Самый простой (?) Способ - это Thread список случайных значений поверх правила замены:

Например:

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 *)

Или, вдохновленный Леонидом, вы можете использовать Alternatives и сопоставление с образцом:

p1 y1 + p2 y2 + p3 y3 == p4 /. p1 | p2 | p3 | p4 :> RandomReal[]

Ради интереса вот еще одно похожее решение:

p1 y1 + p2 y2 + p3 y3 == p4 /. s_Symbol :> 
     RandomReal[]/;StringMatchQ[SymbolName[s], "p"~~DigitCharacter]

Где вы можете заменить DigitCharacter на NumberString, если хотите, чтобы он соответствовал не только p0, p1, ..., p9. Конечно, для больших выражений приведенное выше не будет особенно эффективным ...

person Simon    schedule 16.09.2011
comment
+1. Если вы используете Alternatives, как я предлагал, вы должны использовать правило отложенного запроса, иначе все числа будут одинаковыми. - person Leonid Shifrin; 16.09.2011
comment
@Leonid: ой ... думал, что да! - person Simon; 16.09.2011

Другие ответы хороши, но если вы много занимаетесь подобными вещами, я рекомендую называть ваши переменные и коэффициенты более систематическим образом. Это не только позволит вам написать гораздо более простое правило, но и внесет гораздо более простые изменения, когда придет время перейти от 3 уравнений к 4. Например:

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

Вы можете немного фантазировать, когда составляете свое уравнение:

In[3]:= vars . Most[coeffs] == Last[coeffs]
Out[3]= p[1] y[1] + p[2] y[2] + p[3] y[3] == p[4]

Подстановка коэффициентов случайными числами теперь является одним из очень простых правил:

In[4]:= sub = eqn /. p[_] :> RandomReal[] 
Out[4]= 0.281517 y[1] + 0.089162 y[2] + 0.0860836 y[3] == 0.915208

Правило в конце можно также записать _p :> RandomReal[], если хотите. Вам также не нужно много печатать, чтобы решить эту проблему.

In[5]:= Reduce[sub]
Out[5]= y[1] == 3.25099 - 0.31672 y[2] - 0.305785 y[3]

Как сказал Эндрю Уокер, вы используете Reduce найти все решения, а не только некоторые из них. Вы можете заключить это в функцию, которая параметризует количество переменных следующим образом:

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]
person Pillsy    schedule 16.09.2011

Если вам нужны решения с замененными значениями, один из возможных способов сделать это:

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

Если все, что вам нужно, это решение уравнений:

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}]
person Andrew Walker    schedule 16.09.2011
comment
для чего нужна функция уменьшения? это необходимо? - person penny; 16.09.2011
comment
Reduce похож на Solve, но найдет все решения. В этом случае решения было бы достаточно - person Andrew Walker; 16.09.2011
comment
@ Андрей +1. Ваше решение можно было бы несколько упростить: f[y1, y2, y3] /. p1 | p2 | p3 | p4 :> RandomReal[]. - person Leonid Shifrin; 16.09.2011
comment
о, вообще-то, я еще не хочу решать эту проблему. мне просто нужно вывести уравнения. - person penny; 16.09.2011
comment
@Leonid - спасибо за упрощение, новые возможности попробовать! :) - person Andrew Walker; 16.09.2011

Если вы можете жить без символических имен коэффициентов p1 и др., Вы можете сгенерировать, как показано ниже. Мы берем список переменных, количество уравнений и диапазон для коэффициентов и вектора rhs.

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}

Легко получить такие варианты, как целочисленные коэффициенты, различные диапазоны для матрицы и правых сторон и т. Д.

Даниэль Лихтблау

person Daniel Lichtblau    schedule 16.09.2011

Другой путь:

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]]
person Dr. belisarius    schedule 16.09.2011