-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update SymPy chapter for 2023. #122
Conversation
- Improved wording in various places. - Added more hyperlinks to connect to mentioned topics. - Added an exercise to almost all sections. - Expanded some examples.
sympy.rst
Outdated
|
||
A.inv() @ b | ||
|
||
But it is best to use the ``.LUsolve()`` method to perform Gaussian-Elimination |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be nice to link to something like this: https://gregorygundersen.com/blog/2020/12/09/matrix-inversion/. Not sure how permanent this explanation is or if there is a better one.
I have used .LUsolve(..), where each solution had 100,000 operations or
more.
It finds the solution in split seconds, while linsolve(..., .) seems to
take forever, say, after 10 minutes still no solution and I abort it.
My applications are limited to solving the speed constraints resulting from
a configuration constraint.
I assume, the theory of Gaussian elimination is in any textbook of linear
algebra, unsure whether such an attachment is needed.
|
I recall that a long time ago you explained to me how to lambdify a
function which exists in numpy, but not in sympy. (At that time,
*heaviside()* did not exist in sympy)
Would this be something to be incorporated here?
|
If you can report a simple example that demonstrates this to SymPy, that would help. linsolve just isn't battle tested and it chokes on steps that it shouldn't. |
I don't want to explain it here, because they should have learned it in prior courses, but linking to a good reference can give them a pointer to refresh their memory. |
My examples are always solving speed constraints, based on a configuration
constraint.
Would a program, up to solving the linear equations, be adequate?
I wold delete all the Kane'd formalism.
|
The homework problem I give them is exactly that: solve nonholonomic constraint for the speeds. I just give them the expressions. So it would be better if the book add a different example, so they can't just copy and paste to solve the homework. |
Understood!
Let me see if I can contrive some example, and revert.
|
This is a fairly contrieved example to solve a systen of linerar equations.
1.
I set up a system of linear equations, where the size, N, may be selected.
2.
I use
*- LUsolve*
*- sm.linsolve*
*- sm.solve*
to get the solutions.
3.
This example shows, that *LUsolve is far better than the other two:*
While all methods produce the same solution, LUsolve runs MUCH faster, and
has far fewer operations in the solution.
My code is attached below.
```
.. code:: ipython3
import sympy as sm
import numpy as np
import random
import time
random.seed(105)
N = 2 # dimension of the problem
q_list = [sm.symbols('q' + str(i)) for i in range(N)] # variables
to be solved for
param_list = [sm.symbols('a' + str(i)) for i in range(5)] # list of
parameters, '5' is arbitary
pL_vals = [i for i in range(5)]
# set up arbitrary linear equations
gleichung = []
for _ in range(N): # number of equations
summe1 = 0
for q in q_list:
summe = random.choice(param_list)
for _ in range(len(param_list)):
wert = random.choice(param_list)
c1 = random.choice(param_list)
c2 = random.choice([sm.sin(c1), sm.cos(c1), sm.exp(c1)])
summe += wert * c2
summe1 += summe * q + random.choice(param_list)
gleichung.append(summe1)
# convert the list to an sm.Matrix, so operation may be done
equation = sm.Matrix(gleichung) # equation = 0 to be solved for q_list
# lambdification to check the accuracy of the solutions later
equation_lam = sm.lambdify(q_list + param_list, equation, cse=True)
# LU decomposition
start = time.time()
matrix_A = equation.jacobian(q_list)
vector_b = equation.subs({i: 0 for i in q_list})
solution = matrix_A.LUsolve(-vector_b)
print('it took {:.5f} sec to solve with LU.solve'.format(time.time() -
start))
op_zahl = sum([solution[l].count_ops(visual=False) for l in range(N)])
print('solution contains {} operations'.format(op_zahl))
solution_lam = sm.lambdify(param_list, solution, cse=True )
loesung = [solution_lam(*pL_vals)[i][0] for i in range(N)]
print('the solution with ULsolve is:', loesung)
print('The closer these values are to zero, the better the solution',
equation_lam(*loesung, *pL_vals),'\n')
# using sm.linsolve
if N < 3:
start = time.time()
solution, = sm.linsolve(equation, q_list)
print('it took {:.5f} sec to solve with
sm.linsolve'.format(time.time() - start))
op_zahl = sum([solution[l].count_ops(visual=False) for l in
range(N)])
print('solution contains {} operations'.format(op_zahl))
solution_lam = sm.lambdify(param_list, solution, cse=True)
loesung = [solution_lam(*pL_vals)[i] for i in range(N)]
print('the solution with linsolve is:', loesung, '\n')
# using sm.solve
if N < 3:
start = time.time()
solution = sm.solve(equation, q_list)
print('it took {:.5f} sec to solve with
sm.solve'.format(time.time() - start))
op_zahl = sum([solution[l].count_ops(visual=False) for l in q_list])
print('solution contains {} operations'.format(op_zahl))
solution = [solution[i] for i in q_list]
solution_lam = sm.lambdify(param_list, solution, cse=True)
loesung = solution_lam(*pL_vals)
print('the solution with sm.sove is:', loesung)
```
|
If N is equal or larger than 3, linsolve and solve seem to run forever, I
aborted the run after maybe 5 min.
|
Dear Jason,
would this example be useful, to start an issue in sympy about linsolve?
Thanks!
Peter
|
Yes, I think this is good to point out to the sympy devs. solve and linsolve should run faster. |
This one is complete now, ready for review. I added an exercise to see how cse affects lambdify. |
My usual dumb question: how do I see it?
|
What a CLEVER and NEAT example!!
|
… out the solution to last exercise.
Merging. Raise issues if anything is noticed in the published version. |
TODO:
Fixes #121