-
-
Notifications
You must be signed in to change notification settings - Fork 482
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
Give more precise answer on symbolic power of a matrix #36845
Give more precise answer on symbolic power of a matrix #36845
Conversation
src/sage/matrix/matrix2.pyx
Outdated
vk = [(binomial(n, i) * mk._pow_(n-i)).simplify_full() | ||
for i in range(nk)] | ||
else: | ||
vk = [(binomial(n, i).simplify_full() * mk._pow_(n-i)) |
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.
In fact, a more suitable result would be given by
vk = [(binomial(n, i).simplify_full() * kronecker_delta(n,i)) for i in range(nk)]
This even allows to evaluate with small values of n
src/sage/matrix/matrix2.pyx
Outdated
n | ||
sage: An = A^n; An | ||
[ 0^n 0^(n - 1)*n] | ||
[ 0 0^n] |
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.
According to the comment on line 18678,
We would then have something like
[ kronecker_delta(0, n) n*kronecker_delta(1, n)]
[ 0 kronecker_delta(0, n)]
that can then be evaluated
sage: An({n:0})
[1 0]
[0 1]
4757770
to
3042d2a
Compare
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.
I checked and it works perfectly to me.
sage: An = _matrix_power_symbolic(A,n); An
[ kronecker_delta(0, n) n*kronecker_delta(1, n)]
[ 0 kronecker_delta(0, n)]
sage: print(all(A^k == An.subs({n: k}) for k in range(8)))
#True
if mk: | ||
vk = [(binomial(n, i) * mk._pow_(n-i)).simplify_full() | ||
for i in range(nk)] | ||
else: |
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.
In fact, I realize that after the computation, we can get a value even for negative n (or even also for non-integer n).
I think that, somehow, the system should raise an error if mk=0 but the evaluation is made at bad values of n. I have no idea on how to do that properly.
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.
This can be done by declaring variable with domain="integer", here when you do not give any domain to a variable it will consider it in complex plane by default.
But we can check whether the variable have an integer value of not at the time of evaluation.
I think that, somehow, the system should raise an error if mk=0 but the evaluation is made at bad values of n.
I didn't get that, why system should give an error if mk=0 ?
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.
I'll implement this in a new PR as this topic is not concentrated on nilpotent matrices.
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.
This can be done by declaring variable with domain="integer", here when you do not give any domain to a variable it will consider it in complex plane by default.
great!
But we can check whether the variable have an integer value of not at the time of evaluation.
I think that, somehow, the system should raise an error if mk=0 but the evaluation is made at bad values of n.
I didn't get that, why system should give an error if mk=0 ?
It should raise an error if mk=0 and n negative since the matrix is then non-invertible. For n positive non-integer, I don't know if it makes sense either.
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.
I'll implement this in a new PR as this topic is not concentrated on nilpotent matrices.
By the way, I already opened an other issue #36863 for general simplification of 0^n
.
But the problem for matrices is somehow different since:
- the exponent is generally assumed to be an integer
- the general formula for the power of a Jordan block with eigenvalue 0 involves some expression of the form
P(n)*0^{n-i}
(P polynomial) where the meaning of0^{n-i}
for0<i <=n
should be understood askronecker_delta(i,n)
in this special case (assuming that n is a *non-negative integer)
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.
In fact, I realize that after the computation, we can get a value even for negative n (or even also for non-integer n).
I think that, somehow, the system should raise an error if mk=0 but the evaluation is made at bad values of n. I have no idea on how to do that properly.
I checked what I can do to determine whether we are evaluating an integer power or not. I found that when evaluating the matrix, we only replace the variables with their values, and we cannot impose a condition that the variable should be an integer for obvious reasons because we are not sure that the variable is the symbolic power only. The only place where we can make a change is when calculating the power of the matrix (i.e., A^n). However, if we do so, it will not be ideal because we can define a real power of a matrix, and imposing a condition would not be appropriate. So, I think implementing a system for this is not practical. So it is better to use domain=integer while defining a variable.
ab1ec91
to
fc7526d
Compare
Testing exponentiation in the integer ring::
sage: A = matrix(ZZ, [[1,-1], [-1,1]])
sage: A^(2*n+1) # needs sage.symbolic
[ 1/2*2^(2*n + 1) -1/2*2^(2*n + 1)]
[-1/2*2^(2*n + 1) 1/2*2^(2*n + 1)] @dimpase, Can I change the above doctest which was there before my changes, because here, according to my change, I think the answer should be [ 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) -1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)]
[-1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] But the answer given in doctest is different. And to support my answer, I'll say that this is working for 2n+1=0 where we should get an indentity matrix but the answer given in doctest is false as it will not give identity matrix for 2n+1=0. And becuase of this my PR is failing that doctest check. |
A precision (in case your argument is misunderstood by others), you mean 0 as the power of the matrix (and not for n=0 when we consider the power 2n+1) |
Ohh, ya that's right, thank you for pointing out. |
It makes sense to talk about changing the doctest result to match the output of the changed function. By the way, I don't quite understand the comment
Do you mean |
fc7526d
to
700f425
Compare
In
|
This fixes sagemath#36838. Here, I have added a condition to check whether mk=0 or not. Because whenever mk=0 we should give mk^(n-i) (i.e. 0^(n-i)) instead of only 0 considering (n-i) can be equal to zero and in this case 0^(n-i) will be more accurate than only 0.
This change handles all the errors which were occuring in previous commit and this commit handles the case of mx=0 very effectively.
Created tests covering the changes and checking whether the trac:`36838` is fixed or not.
Instead of returning 0^(n-i), it would be more precise if we reutrn value of kroncker_delta function, it will be helpful when we try to evaluate the final matrix using the value of n.
Changed the final answer given by test of this PR.
Changed the answer of doctest according to new changes.
Corrected the doctest and improved some code styles, which were not correct according to guidelines for python coding for sage.
Updated the old doctests which were failing before and updated the comment to make it more readable.
700f425
to
7955a51
Compare
Please fix the linting errors
|
Documentation preview for this PR (built with commit ed4e712; changes) is ready! 🎉 |
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.
looks good, thanks
- Changed _matrix_power_symbolic function to consider mk=0 case - Changed the _matrix_power_symbolic function to handle all the cases - Created tests covering the changes This PR improves the answer given by _matrix_power_symbolic() function, which involves finding the symbolic power of a matrix, and also gives more precise answer on evalution. eg, before, when we were evaluating the zeroth power of a matrix sometimes it was giving wrong answer like below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^n -1/2*2^n] [-1/2*2^n 1/2*2^n] sage: An({n:0}) [ 1/2 -1/2] [-1/2 1/2] ``` Here, for n=0, it is not giving an identity matrix which is wrong, but after the change it will give answer as below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) -1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] [-1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] sage: An({n:0}) [1 0] [0 1] ``` Also, This patch fixes sagemath#36838 . The function, _matrix_power_symbolic() was giving symbolic power of a nilpotent matrix as a null matrix but the correct answer should be represented in the form of kronecker_delta() function. In the case of mk=0, simplifying only binomial term should work because afterall the form 0^(n-i) should be simplifed to kronecker_delta() function and no further simplification is needed. And in every other case it is simplifying whole term so it will handle all other cases. <!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes sagemath#1234" use "Introduce new method to calculate 1+1" --> <!-- Describe your changes here in detail --> <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes sagemath#12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - sagemath#12345: short description why this is a dependency - sagemath#34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> None URL: sagemath#36845 Reported by: Ruchit Jagodara Reviewer(s): Dima Pasechnik, phul-ste, Ruchit Jagodara
- Changed _matrix_power_symbolic function to consider mk=0 case - Changed the _matrix_power_symbolic function to handle all the cases - Created tests covering the changes This PR improves the answer given by _matrix_power_symbolic() function, which involves finding the symbolic power of a matrix, and also gives more precise answer on evalution. eg, before, when we were evaluating the zeroth power of a matrix sometimes it was giving wrong answer like below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^n -1/2*2^n] [-1/2*2^n 1/2*2^n] sage: An({n:0}) [ 1/2 -1/2] [-1/2 1/2] ``` Here, for n=0, it is not giving an identity matrix which is wrong, but after the change it will give answer as below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) -1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] [-1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] sage: An({n:0}) [1 0] [0 1] ``` Also, This patch fixes sagemath#36838 . The function, _matrix_power_symbolic() was giving symbolic power of a nilpotent matrix as a null matrix but the correct answer should be represented in the form of kronecker_delta() function. In the case of mk=0, simplifying only binomial term should work because afterall the form 0^(n-i) should be simplifed to kronecker_delta() function and no further simplification is needed. And in every other case it is simplifying whole term so it will handle all other cases. <!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes sagemath#1234" use "Introduce new method to calculate 1+1" --> <!-- Describe your changes here in detail --> <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes sagemath#12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - sagemath#12345: short description why this is a dependency - sagemath#34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> None URL: sagemath#36845 Reported by: Ruchit Jagodara Reviewer(s): Dima Pasechnik, phul-ste, Ruchit Jagodara
- Changed _matrix_power_symbolic function to consider mk=0 case - Changed the _matrix_power_symbolic function to handle all the cases - Created tests covering the changes This PR improves the answer given by _matrix_power_symbolic() function, which involves finding the symbolic power of a matrix, and also gives more precise answer on evalution. eg, before, when we were evaluating the zeroth power of a matrix sometimes it was giving wrong answer like below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^n -1/2*2^n] [-1/2*2^n 1/2*2^n] sage: An({n:0}) [ 1/2 -1/2] [-1/2 1/2] ``` Here, for n=0, it is not giving an identity matrix which is wrong, but after the change it will give answer as below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) -1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] [-1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] sage: An({n:0}) [1 0] [0 1] ``` Also, This patch fixes sagemath#36838 . The function, _matrix_power_symbolic() was giving symbolic power of a nilpotent matrix as a null matrix but the correct answer should be represented in the form of kronecker_delta() function. In the case of mk=0, simplifying only binomial term should work because afterall the form 0^(n-i) should be simplifed to kronecker_delta() function and no further simplification is needed. And in every other case it is simplifying whole term so it will handle all other cases. <!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes sagemath#1234" use "Introduce new method to calculate 1+1" --> <!-- Describe your changes here in detail --> <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes sagemath#12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - sagemath#12345: short description why this is a dependency - sagemath#34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> None URL: sagemath#36845 Reported by: Ruchit Jagodara Reviewer(s): Dima Pasechnik, phul-ste, Ruchit Jagodara
- Changed _matrix_power_symbolic function to consider mk=0 case - Changed the _matrix_power_symbolic function to handle all the cases - Created tests covering the changes This PR improves the answer given by _matrix_power_symbolic() function, which involves finding the symbolic power of a matrix, and also gives more precise answer on evalution. eg, before, when we were evaluating the zeroth power of a matrix sometimes it was giving wrong answer like below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^n -1/2*2^n] [-1/2*2^n 1/2*2^n] sage: An({n:0}) [ 1/2 -1/2] [-1/2 1/2] ``` Here, for n=0, it is not giving an identity matrix which is wrong, but after the change it will give answer as below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) -1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] [-1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] sage: An({n:0}) [1 0] [0 1] ``` Also, This patch fixes sagemath#36838 . The function, _matrix_power_symbolic() was giving symbolic power of a nilpotent matrix as a null matrix but the correct answer should be represented in the form of kronecker_delta() function. In the case of mk=0, simplifying only binomial term should work because afterall the form 0^(n-i) should be simplifed to kronecker_delta() function and no further simplification is needed. And in every other case it is simplifying whole term so it will handle all other cases. <!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes sagemath#1234" use "Introduce new method to calculate 1+1" --> <!-- Describe your changes here in detail --> <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes sagemath#12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - sagemath#12345: short description why this is a dependency - sagemath#34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> None URL: sagemath#36845 Reported by: Ruchit Jagodara Reviewer(s): Dima Pasechnik, phul-ste, Ruchit Jagodara
- Changed _matrix_power_symbolic function to consider mk=0 case - Changed the _matrix_power_symbolic function to handle all the cases - Created tests covering the changes This PR improves the answer given by _matrix_power_symbolic() function, which involves finding the symbolic power of a matrix, and also gives more precise answer on evalution. eg, before, when we were evaluating the zeroth power of a matrix sometimes it was giving wrong answer like below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^n -1/2*2^n] [-1/2*2^n 1/2*2^n] sage: An({n:0}) [ 1/2 -1/2] [-1/2 1/2] ``` Here, for n=0, it is not giving an identity matrix which is wrong, but after the change it will give answer as below, ```python sage: n = var("n") sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: An = A^(n) [ 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) -1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] [-1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] sage: An({n:0}) [1 0] [0 1] ``` Also, This patch fixes sagemath#36838 . The function, _matrix_power_symbolic() was giving symbolic power of a nilpotent matrix as a null matrix but the correct answer should be represented in the form of kronecker_delta() function. In the case of mk=0, simplifying only binomial term should work because afterall the form 0^(n-i) should be simplifed to kronecker_delta() function and no further simplification is needed. And in every other case it is simplifying whole term so it will handle all other cases. <!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes sagemath#1234" use "Introduce new method to calculate 1+1" --> <!-- Describe your changes here in detail --> <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes sagemath#12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - sagemath#12345: short description why this is a dependency - sagemath#34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> None URL: sagemath#36845 Reported by: Ruchit Jagodara Reviewer(s): Dima Pasechnik, phul-ste, Ruchit Jagodara
This PR improves the answer given by _matrix_power_symbolic() function, which involves finding the symbolic power of a matrix, and also gives more precise answer on evalution. eg, before, when we were evaluating the zeroth power of a matrix sometimes it was giving wrong answer like below,
Here, for n=0, it is not giving an identity matrix which is wrong, but after the change it will give answer as below,
Also, This patch fixes #36838 . The function, _matrix_power_symbolic() was giving symbolic power
of a nilpotent matrix as a null matrix but the correct answer should be represented
in the form of kronecker_delta() function. In the case of mk=0, simplifying only binomial
term should work because afterall the form 0^(n-i) should be simplifed to kronecker_delta() function and no further simplification is needed.
And in every other case it is simplifying whole term so it will handle all other cases.
📝 Checklist
⌛ Dependencies
None