Glinting Orc
Glinting Orc

Reputation: 23

Create random systems of linear equations - Python

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 :)!

Upvotes: 1

Views: 1166

Answers (2)

Kosaro
Kosaro

Reputation: 395

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

Upvotes: 1

Reti43
Reti43

Reputation: 9797

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

Upvotes: 2

Related Questions