Skip to content
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

Merged
merged 10 commits into from
Dec 26, 2023

Conversation

RuchitJagodara
Copy link
Contributor

@RuchitJagodara RuchitJagodara commented Dec 9, 2023

  • 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,

        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,

        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 #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

  • The title is concise, informative, and self-explanatory.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.

⌛ Dependencies

None

@RuchitJagodara RuchitJagodara changed the title Fix wrong answer on symbolic power of nilpotent matrix Fix answer on symbolic power of nilpotent matrix Dec 9, 2023
@RuchitJagodara RuchitJagodara changed the title Fix answer on symbolic power of nilpotent matrix Give more precise answer on symbolic power of nilpotent matrix Dec 9, 2023
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))
Copy link

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

n
sage: An = A^n; An
[ 0^n 0^(n - 1)*n]
[ 0 0^n]
Copy link

@phul-ste phul-ste Dec 10, 2023

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]

Copy link

@phul-ste phul-ste left a 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:

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.

Copy link
Contributor Author

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 ?

Copy link
Contributor Author

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.

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.

Copy link

@phul-ste phul-ste Dec 12, 2023

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 of 0^{n-i}for 0<i <=nshould be understood as kronecker_delta(i,n) in this special case (assuming that n is a *non-negative integer)

Copy link
Contributor Author

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.

@RuchitJagodara
Copy link
Contributor Author

RuchitJagodara commented Dec 13, 2023

    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.

@phul-ste
Copy link

@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 n=0 where we should get an indentity matrix but the answer given in doctest is false as it will not give identity matrix for n=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)

@RuchitJagodara
Copy link
Contributor Author

Ohh, ya that's right, thank you for pointing out.

@RuchitJagodara RuchitJagodara changed the title Give more precise answer on symbolic power of nilpotent matrix Give more precise answer on symbolic power of a matrix Dec 13, 2023
@dimpase
Copy link
Member

dimpase commented Dec 14, 2023

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

# Return mk^(n-i) instead of mk**(n-i) if mk=0

Do you mean ^ as in Python? That's confusing. Better use a maths way to explain what you mean.

@RuchitJagodara
Copy link
Contributor Author

RuchitJagodara commented Dec 14, 2023

@dimpase I have updated the results of doctest and also updated the comment. Can you please review this? And I have modified code style for this file according to sage's developer guide which can be found in #36877. After merging that PR, I think Lint check for this PR will be passed.

@RuchitJagodara
Copy link
Contributor Author

In Build & Test / build (pull_request) it is showing that doctests are failing on some files. But when I checked it in my machine was working fine and passing all doctests for all files. Like for below it is showing that 130 doctests are failed but when I ran the same command in my machine it is showing that all doctests are passes.

sage -t --long --random-seed=286735480429121101562228604801325644303 sage/libs/coxeter3/coxeter_group.py  # 130 doctests failed

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.
@dimpase
Copy link
Member

dimpase commented Dec 17, 2023

Please fix the linting errors

/sage/matrix/matrix2.pyx:3185:30: W291 trailing whitespace
./sage/matrix/matrix2.pyx:3191:29: W291 trailing whitespace
./sage/matrix/matrix2.pyx:3199:44: W291 trailing whitespace
./sage/matrix/matrix2.pyx:18665:106: W291 trailing whitespace
./sage/matrix/matrix2.pyx:18666:106: W291 trailing whitespace

Copy link

Documentation preview for this PR (built with commit ed4e712; changes) is ready! 🎉

Copy link
Member

@dimpase dimpase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, thanks

vbraun pushed a commit to vbraun/sage that referenced this pull request Dec 21, 2023
    
- 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
vbraun pushed a commit to vbraun/sage that referenced this pull request Dec 22, 2023
    
- 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
vbraun pushed a commit to vbraun/sage that referenced this pull request Dec 23, 2023
    
- 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
vbraun pushed a commit to vbraun/sage that referenced this pull request Dec 24, 2023
    
- 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
vbraun pushed a commit to vbraun/sage that referenced this pull request Dec 25, 2023
- 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
@vbraun vbraun merged commit 58e899c into sagemath:develop Dec 26, 2023
1 check passed
@mkoeppe mkoeppe added this to the sage-10.3 milestone Dec 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Symbolic power of a nilpotent matrix is zero
5 participants