## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
• 01:24
oscarbenjamin labeled #21653
• 01:24
oscarbenjamin labeled #21654
• 01:23
oscarbenjamin labeled #21658
• 01:23
oscarbenjamin labeled #21658
• 01:23
oscarbenjamin commented #21658
• 01:08
oscarbenjamin synchronize #21626
• Jun 24 23:49
oscarbenjamin commented on c111fb7
• Jun 24 23:47
oscarbenjamin commented on c111fb7
• Jun 24 23:45
oscarbenjamin commented on c111fb7
• Jun 24 22:53
pyr-kaboosh edited #21658
• Jun 24 22:51
pyr-kaboosh edited #21658
• Jun 24 22:50
pyr-kaboosh edited #21658
• Jun 24 22:48
pyr-kaboosh opened #21658
• Jun 24 20:06
sympy-bot commented #21619
• Jun 24 20:06
smichr edited #21619
• Jun 24 20:06
smichr synchronize #21619
• Jun 24 20:05
smichr synchronize #21619
• Jun 24 19:49
smichr synchronize #21619
• Jun 24 19:40
EelcoHoogendoorn commented #21652
• Jun 24 19:07
rathmann commented #6662
I'm using sympy to solve some linear systems in my finite difference model (since I need nullspaces, I cannot use numpy least square directly).
Also since I don't know beforehand the size of my linear system (not big for now, not bigger than 10 variavles). I'm solving it without specify the "symbols" because I really don't care.
the line to solve is simpleand looks like linsolve(Matrix(np.c_[V,o])).
in this specific case (i think 6 variables involved), I got a free variable as response {(-1.0*tau0 - 0.916666666666667, 5.0*tau0 + 0.708333333333333, -10.0*tau0 + 0.375, 10.0*tau0 - 0.208333333333333, -5.0*tau0 + 0.0416666666666667, tau0)}, seems is autonamed tau0
I want to eval tau0 = 0, but without know the variable name before hand.
something like lin(Matrix(np.c_[V, o])) | all_free_variables = 0
where | all_free_variables = 0 is a poetry freedom on python language, since I don't know how to do that
r.evalf(subs={tau0: 0}) doesn't works, and also ) don't want to specify the variable name, since I will not know beforehand
neither r.subs(tau0, 0), both complain about tau0 not being defined

doing:
tau0 = symbols('tau0'); r.subs(tau0,0)

works. But I must know before hand each symbol. That I don't. =/

I solved the issue with

r_tmp = linsolve(Matrix(np.c_[V[j], o]))
for symbol in list(r_tmp.free_symbols):
r_tmp = r_tmp.subs(symbol,0)
mysolution = np.array(list(r_tmp)).ravel().astype(float)

Any smarter solution?

the mysolution is a numpy array as you could notice.
Kalevi Suominen
@jksuom
@igormorgado The docstring of linsolve says:
This message was deleted
If no symbols are given, internally generated symbols will be used.
It seems that you can give the names that you would like to use instead of the generated names like tau0.
@jksuom But I cannot specify the names,since I don't know how many free vars will exist.
@jksuom in fact, I don't even know the size of the matrix beforehand. It will depend on size of the grid loaded. can have 500 variables.

@igormorgado That seems like a good enough solution, though I would do the substitution like:

zeros = [(s, 0) for s in r_tmp.free_symbols]
solution_as_list = r_tmp.subs(zeros)

Not sure what you are trying to do with the numpy array part though

@valglad The solution_as_list, didn't returns a list per se, but a set with a tuple, as in: {(-0.916666666666667, 0.708333333333333, 0.375, -0.208333333333333, 0.0416666666666667, 0)} of type sympy.sets.sets.FiniteSet.
@valglad Regarding to the numpy line. I'm very sticky to numpy, since I oftern work with it. Maybe I will keep everything inside sympy, until get the final solution.

I see, so you need to turn it into a list, flatten it and make everything a float. You could use a comprehension again like

solution = np.array([e for e in r_tmp]).astype(float)

It may or may not be slightly faster but it looks shorter

Ah, wait, that doesn't flatten it. So you'll have to do what you did or use SymPy's flatten anyway... Never mind then

Actually,

solution = np.array(*[e for e in r_tmp]).astype(float)

should flatten it as well

wow. :-( Given the matrix PI

array([[ -0.917,   0.042,   0.   ,   0.   ,  -1.   ],
[  0.708,  -1.125,   0.042,   0.   ,   5.   ],
[  0.375,   1.125,  -1.125,   0.042, -10.   ],
[ -0.208,  -0.042,   1.125,  -1.125,  10.   ],
[  0.042,   0.   ,  -0.042,   1.125,  -5.   ],
[  0.   ,   0.   ,   0.   ,  -0.042,   1.   ]])

and the vector c

array([-1.   ,  0.   ,  0.   , -0.042,  1.083, -0.042])

the solution given by

linsolve(Matrix(np.c_[PI,c]))

returns an EmptySet()

while the same operation in Maple 16 returns non empty, and exactly

np.array([649/576, 143/192, 75/64, 551/576, -25/13824])

that in float is around

array([ 1.127,  0.745,  1.172,  0.957, -0.002])

Any ideas?

the example in maple is shown above
just to make clear, the float points in my PI matrix are not exactly 3 digits precision, I'm just showing the first 3 most significant digits using: np.set_printoptions(precision=3)
for sake of this test it was created using the ratios, as in
PI = np.array([
[-11/12, 1/24, 0, 0, -1],
[ 17/24, -9/8, 1/24, 0 ,5],
[3/8, 9/8, -9/8, 1/24, -10],
[-5/24, -1/24, 9/8, -9/8, 10],
[1/24, 0, -1/24, 9/8, -5],
[0, 0, 0, -1/24, 1]
])
Ideas, are very likely welcome.
Using np.linalg.lstsq(PI, c, rcond=-1)[0] returned the expected answer as: array([ 1.127, 0.745, 1.172, 0.957, -0.002])
but still, I would like to know what I'm doing wrong on Sympy side.
Kalevi Suominen
@jksuom

It seems that your system is over-determined. It has 6 equations in 5 variables. It can have solutions only if the determinant of the extended system is 0.

>>> P = Matrix([[ -0.917,   0.042,   0.   ,   0.   ,  -1.   ],
...        [  0.708,  -1.125,   0.042,   0.   ,   5.   ],
...        [  0.375,   1.125,  -1.125,   0.042, -10.   ],
...        [ -0.208,  -0.042,   1.125,  -1.125,  10.   ],
...        [  0.042,   0.   ,  -0.042,   1.125,  -5.   ],
...        [  0.   ,   0.   ,   0.   ,  -0.042,   1.   ]])
>>> c = Matrix([-1.   ,  0.   ,  0.   , -0.042,  1.083, -0.042])
>>> Pc = P.row_join(c)
>>> Pc.det()
0.000998125750125132

In this example, the determinant not 0 because of the inaccuracy of floating point numbers. Hence there is no solution.

Kalevi Suominen
@jksuom
You can probably find a solution if you remove one of the equations.
Het Patel
@hetp111
is NumPy related to sympy?
i am learning python megacourse on udemy and it is also teaching numpy, so i was wondering if it might be useful
@hetp111 not related but can work together.
The lack of solutions is definitely a precision issue - if you input all entries as Rational (e.g. Rational(1,2) instead of 1/2), then linsolve returns the same as Maple (though obviously that's awkward)

A potential solution could be to define

rationalize = lambda x: [nsimplify(e) for e in x]

(this will turn numbers from a list into rationals). And then do

PI = Matrix(map(rationalize, [
[-11/12, 1/24, 0, 0, -1],
[ 17/24, -9/8, 1/24, 0 ,5],
[3/8, 9/8, -9/8, 1/24, -10],
[-5/24, -1/24, 9/8, -9/8, 10],
[1/24, 0, -1/24, 9/8, -5],
[0, 0, 0, -1/24, 1]
]))

and similarly for c. I've just checked and this returns the right solutions

@jksuom I cant remove any variable unfortunately.
Kalevi Suominen
@jksuom
Do not remove any variables. There are too few already. Remove one of the equations.
There are 6 rows and only 5 columns. One row could be omitted.
@jksuom I can't either, they are strict contraints in my solution space.
Kalevi Suominen
@jksuom
If there is a solution, then the same solution is obtained after one equation is omitted.
Kalevi Suominen
@jksuom
In [7]: linsolve(Pc[:5, :])
Out[7]:
{(1.12549831271091, 0.749071392102014, 1.16564957508439, 0.96140585029474, -0.
000620954287620833)}
I have created mrationalize = lambda x: [nsimplify(e) for e in [r for r in x]] that I do not like much the fell.