Is it possible to declare Unknowns in Python to calculate constants of a Mathematical function?

Asked

Viewed 2,682 times

14

I need to assemble a quadratic function Y = Ax² + bx + c from values of X and Y acquaintances.
In this case, I’m trying to H(Q) = aq² + Bq + c (Gauge height as a function of flow rate).

Where:
H1 = 3; Q1 = 3.4
H2 = 8; Q2 = 2.6
H3 = 15; Q3 = 0.8

... or ...

H(3.4)=3
H(2.6)=8
H(0.8)=15

Mathematically, I need to make the deductions of the constants "a", "b", "c", where:
c = H1 - a*((Q1) 2) - b*(Q1)
b = (H2 - a*((Q2) 2) - c) / (Q2)
a = (H3 - b*(Q3) - c) / ((Q3) 2)

Knowing that in the end I would have the value of "a", replacing in the equations of "b" and "c" consequently, how could I automate this in a code in Python?

I learned in programming that when declaring a variable without value it returns value equal to 1 (I don’t even know if in Python it is like this).

Therefore, how to declare "a", "b", "c" so that the program iterates until it finds the real values of these constants?

  • 2

    My previous comment was largely nonsense, so I removed it. I confused things. What you need is to solve a linear system of equations.

  • 3

    @Luizvieira Jefferson’s answer is certainly worth receiving the reward. I wanted to have given it myself and I forgot. I’ll be happy to give it to him - or any other answer that might still appear.

2 answers

17


What you’re looking for is something that solves linear system.

This answer will be written in a generic way, it can be applied in any function whose thick form is known. In this case, the examples will be polynomials of degree 2, according to your doubt, or of degree 1 to facilitate the explanation of something not critical but necessary.

The answer is language independent. Possibly I will initially take a pure algorithmic approach, but in future versions the code will eventually be pythonized

Shall we divide the answer into two parts? The first is: assembling the linear system. In practice it does not answer anything, but leaves everything ready and normalized for the second part (not to mention that it is basically independent): solving a linear system.

The second part I will create a subdivision: and when there is no answer?

Ready? Buckle up, come on.

Assembling the linear system

How about defining what a "linear system" is before?

First, the full name is "system of linear equations". So, term by term:

  • equation: something given as a ruma arithmetic operation between variables and constants that arrives at an exact value.
  • linear equation: an equation with only linear operations. A linear operation is one between two constants or between a variable in its base value and a constant.

    15 x A is linear, already To 2 is quadratic, and sqrt(A) belongs to grade 0.5 and is also non-linear

  • system of equations: when we have a single equation, we have a system of an equation; when we have 2 equations that share variables, we have a system of 2 equations; the same goes for 3, 4 or n equations

When we know the form of the equation and wish to find its parameters, and we have also provided some pairs of "input/result", then we can replace the X in their values and equal to the Y supplied.

For example, suppose we have an unknown line. Only this gives me its structure: Y = a*X+ b. If we know she’s through the dots (0, 0) and (2, 2), then we have the following system of equations:

a*X + b = Y  (forma geral)
a*0 + b = 0 (ponto (0,0))
a*2 + b = 2 (ponto (2,2))

We could have a parable (therefore, formula Y = a*X**2 + b*X + c) with the following known points:

(0, 10)
(2, 14)
(10, 110)

That I could assemble the system as follows:

a*X**2 + b*X +c = Y (forma geral)
a*0**2 + b*0 + c = 10 (ponto (0,0))
a*2**2 + b*2 + c = 14 (ponto (2,14))
a*10**2 + b*10 + c = 110 (ponto (10,110))

Formally, how can I represent my linear system? Well, through a single matrix that contains in itself the following formula:

A x b = c

Where:

  • A is the parameter matrix
  • b is the vector (column) of unknowns; and
  • c is the vector (column) with the results

The representation is a unique matrix with the information of A is an extra column for c. The value of b is already encoded implicitly. The two linear systems described above would be so represented:

consider the vertical bar only a stylistic feature to separate the content of A vector c

0 1 | 0
2 1 | 2
  0  0  1 |  10
  4  2  1 |  14
100 10  1 | 110

Solving a linear system

My favorite method of solving linear systems is through Gaussian elimination. How does it happen? Through 2 or 3 steps that repeat to the end:

  1. normalization for the first non-zero term to be 1
  2. annul this term in the columns below
  3. possibly reorder the lines so that steps 1 and 2 can be done again

You can only perform 3 types of operations with matrices:

  1. multiply a line by a number
  2. match lines
  3. change position lines

Let’s take the first linear system:

0 1 0
2 1 2

The first thing here is to reorder it, as the first line does not allow the required normalization. It would look like this after reordering:

2 1 2
0 1 0

Then we normalize by the first nonzero term. In this case, it implies multiplying the first line by 1/2; the second line requires no change:

1 0.5 1
0   1 0

Okay, we’re at the end of the matrix. No more operations. Now that we have reached the value of a variable, then let’s calculate the value of the other variables. This last line can be read this way, why we reached the value of the variable:

1*b = 0

After this first step of Gaussian elimination, let’s get out of something that was like this:

a00 a01 a02 a03 c0
a10 a11 a12 a13 c1
a20 a21 a22 a23 c2
a30 a31 a32 a33 c3

We get something like this:

1 a'01 a'02 a'03 c'0
0    1 a'12 a'13 c'1
0    0    1 a'23 c'2
0    0    0    1 c'3

So, from there, if you do the Gaussian elimination operation by going up we have a diagonal matrix. It would look something like this:

1 0 0 0 c*0
0 1 0 0 c*1
0 0 1 0 c*2
0 0 0 1 c'3

This means that we get the desired result for the linear system. So, going back to the previous linear system:

1 0.5 1
0   1 0

We can remove the 0.5 of the first line adding it with 0.5 * l2. That would be:

1 0 1
0 1 0

Therefore, we can conclude that (a, b) = (1, 0), which is the same thing as saying that the formula is y = 1*x + 0, or else y = x

For the other case, from the parable, let’s solve?

  0  0  1  10
  4  2  1  14
100 10  1 110

Let’s first change the position of lines 1 and 3, so we can continue the Gaussian elimination:

100 10  1 110
  4  2  1  14
  0  0  1  10

Normalizing the first line:

1 0.1 0.01 1.10
4   2    1   14
0   0    1   10

Making l2 = l2 - 4*l1:

1 0.1 0.01 1.10
0 1.6 0.96 9.60
0   0    1   10

Normalizing l2:

1 0.1 0.01 1.10
0   1  0.6    6
0   0    1   10

Now, going from bottom to top. Doing l2 = l2 - 0.6*l3:

1 0.1 0.01 1.10
0   1    0    0
0   0    1   10

Now, going from bottom to top. Doing l1 = l1 - 0.0.1*l3:

1 0.1 0  1
0   1 0  0
0   0 1 10

Making l1 = l1 - 0.1*l2:

1 0 0  1
0 1 0  0
0 0 1 10

Therefore, we conclude that (a, b, c) = (1, 0, 10). The formula is y = x**2 + 10.

For your case

The linear system of your question is:

11.56 3.4 1  3 # H(3.4) = 3
 6.76 2.6 1  8 # H(2.6) = 8
 0.64 0.8 1 15 # H(0.8) = 15

Only solve the linear system now, simple as that. Be happy =D

And when there’s no answer?

There are cases where it is impossible to find an answer from a linear system. The two possibilities are:

  1. there is a freedom of degree > 0; you only get answer when freedom is of degree = 0
  2. there is an inconsistency in the data, but for this it is necessary to provide more equations than variables

There are two possibilities to fall in the case where there are degrees of freedom:

  1. fewer equations than variables
  2. an equation is a linear combination of the other equations

The second case (for second-degree polynomials) does not occur when providing input/output pairs. But hypothetically it can occur with degree 3+.

With a polynomial of degree 3, we have four parameters:

  1. a, related to X**3
  2. b, related to X**2
  3. c, related to X
  4. d, independent of X

Let’s take l1, l2 and l3 as follows:

a00 a01 a02 1 c1 #l1
a10 a11 a12 1 c2 #l2
a20 a21 a22 1 c3 #l3

So let’s do l4 = l3 - l2 + l1:

a30 = a20 - a10 + a00
a31 = a21 - a11 + a01
a32 = a32 - a22 + a02
a33 = 1 - 1 + 1 = 1
c3 = c2 - c1 + c0

With that, we have:

a00           a01           a02           1 c0         #l1
a10           a11           a12           1 c1         #l2
a20           a21           a22           1 c2         #l3
(a20-a10+a00) (a21-a11+a01) (a32-a22+a02) 1 (c2-c1+c0) #l4

Any attempt to do diagonalization operation will result in having a null line. If the order of the lines is not changed, l4 certainly will be null.

What does that mean? What the value of (a,b,c) are linearly dependent on d. There is a degree of freedom, and it is the variable d.

  • Thank you very much, Mr. Jefferson. I’ll stick with Anderson’s answer below because it gives me directly the class or library of the mathematical function in Python. But your explanation ta ta show ball, I’ll just have to study it more deeply to understand later.

  • 2

    @h1k3r, Anderson’s solution is actually more idiomatic. I have a deficiency of not knowing in depth the standard libraries of languages, but usually I deal with problems with own algorithms =) and, yes, often a solution Homebrew It’s worse than coming from libraries, but it’s always good to know the base and be able to manage in limited environments, not to mention it’s language-independent

12

Yes, it is possible.

Python has its own library for working with symbolic mathematics: sympy. You can create symbols using the function symbols, or the class Symbol:

from sympy import Symbol

x = Symbol('x')
y = x + 1

print(y)  # x + 1

And it is possible to solve the symbols by replacing them with numerical values:

print(y.subs(x, 41))  # 42

As well as Sympy already has functions for solving linear systems:

from sympy import symbols
from sympy.solvers.solveset import linsolve

a, b, c = symbols('a, b, c')

system = [
    a*3.4**2 + b*3.4 + c - 3,
    a*2.6**2 + b*2.6 + c - 8,
    a*0.8**2 + b*0.8 + c - 15
]

result = linsolve(system, (a, b, c))

The system defined in system is exactly as described in the question. Note only that the library expects equations that are zero, so if you have something like x - a = 5, you need to define how x - a - 5 = 0, which are equivalent.

The function linsolve will solve the system based on symbols a, b and c, returning their values, if the system has a solution.

For details of the mathematics that underlies this whole process, please see reply by Jefferson Quesado - highly recommended read, even if you will not apply it directly.

  • 5

    The feeling I had with his reply was import antigravity

Browser other questions tagged

You are not signed in. Login or sign up in order to post.