Home > Mobile >  Create random systems of linear equations - Python
Create random systems of linear equations - Python

Time:10-13

Edit: more details

Hello I found this problem through one of my teachers but I still don't understand how to approach to it, and I would like to know if anyone had any ideas for it:

Create a program capable of generating systems of equations (randomly) that contain between 2 and 8 variables. The program will ask the user for a number of variables in the system of equations using the input function. The range of the coefficients must be between [-10,10], however, no coefficient should be 0. Both the coefficients and the solutions must be integers.

The goal is to print the system and show the solution to the variables (x,y,z,...). NumPy is allowed.

As far as I understand it should work this way:

Enter the number of variables: 2

x   y = 7 
4x - y =3

x = 2
y = 5

I'm still learning arrays in python, but do they work the same as in matlab?

Thank you in advance :)!

CodePudding user response:

For k variables, the lhs of the equations will be k number of unknowns and a kxk matrix for the coefficients. The dot product of those two should give you the rhs. Then it's a simple case of printing that however you want.

import numpy as np

def generate_linear_equations(k):
    coeffs = [*range(-10, 0), *range(1, 11)]
    rng = np.random.default_rng()
    return rng.choice(coeffs, size=(k, k)), rng.integers(-10, 11, k)

k = int(input('Enter the number of variables: '))
if not 2 <= k <= 8:
    raise ValueError('The number of variables must be between 2 and 8.')
coeffs, variables = generate_linear_equations(k)
solution = coeffs.dot(variables)

symbols = 'abcdefgh'[:k]
for row, sol in zip(coeffs, solution):
    lhs = ' '.join(f'{r: }{s}' for r, s in zip(row, symbols)).lstrip(' ')
    print(f'{lhs} = {sol}')
print()
for s, v in zip(symbols, variables):
    print(f'{s} = {v}')

Which for example can give

Enter the number of variables: 3
8a  6b -4c = -108
9a -9b -4c = 3
10a  10b  9c = -197

a = -9
b = -8
c = -3

If you specifically want the formatting of the lhs to have a space between the sign and to not show a coefficient if it has a value of 1, then you need something more complex. Substitute lhs for the following:

def sign(n):
    return ' ' if n > 0 else '-'

lhs = ' '.join(f'{sign(r)} {abs(r)}{s}' if r not in (-1, 1) else f'{sign(r)} {s}' for r, s in zip(row, symbols))
lhs = lhs[2:] if lhs.startswith(' ') else f'-{lhs[2:]}'

CodePudding user response:

I did this by randomly generating the left hand side and the solution within your constraints, then plugging the solutions into the equations to generate the right hand side. Feel free to ask for clarification about any part of the code.

import numpy as np

num_variables = int(input('Number of variables:'))
valid_integers = np.asarray([x for x in range(-10,11) if x != 0])

lhs = np.random.choice(valid_integers, lhs_shape)
solution = np.random.randint(-10, 11, num_variables)
rhs = lhs.dot(solution)

for i in range(num_variables):
  for j in range(num_variables):
    symbol = '=' if j == num_variables-1 else ' '
    print(f'{lhs[i, j]:3d}*x{j 1} {symbol} ', end='')
  print(rhs[i])

for i in range(num_variables):
  print(f'x{i 1} = {solution[i]}'

Example output:

Number of variables:2
  2*x1    -7*x2 = -84
 -4*x1     1*x2 = 38
x1 = -7
x2 = 10
  • Related