# Raising a tensor to a fractional power

**URL:** <https://discuss.pytorch.org/t/raising-a-tensor-to-a-fractional-power/93655>\
**Category:** Uncategorized\
**Created:** [August 21, 2020, 5:51pm UTC](https://discuss.pytorch.org/t/raising-a-tensor-to-a-fractional-power/93655 "2020-08-21T17:51:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mmutic](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mmutic](https://discuss.pytorch.org/u/mmutic)\
**Post date:** [August 21, 2020, 5:51pm UTC](https://discuss.pytorch.org/t/raising-a-tensor-to-a-fractional-power/93655/1 "2020-08-21T17:51:09Z")

</div>

Hi, I need to raise a matrix to the power of -1/2, but I believe doing so using just \*\*(-1/2) makes the computation element-wise.

For example, if I do

```auto
m = torch.tensor([[.5,.5],[.7,.9]])
print(m**(-1/2))

```

I get

```auto
tensor([[1.4142, 1.4142],
        [1.1952, 1.0541]])

```

But what I want is

```auto
tensor([[2.6978, -1.1091],
   [-1.5527,1.8105]])

```

which is what Matlab provides when I run m^(-1/2). Unfortunately torch.matrix\_power() seems to only take integers, and torch.pow() also seems to do the computation element-wise.

Thanks!

---

<div class="post-metadata">

**Author:** ![mathematics](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/mathematics/32/40082_2.png) [@mathematics](https://discuss.pytorch.org/u/mathematics)\
**Post date:** [August 21, 2020, 6:20pm UTC](https://discuss.pytorch.org/t/raising-a-tensor-to-a-fractional-power/93655/2 "2020-08-21T18:20:46Z")

</div>

Although it is not best solution, but it will work.  
`scipy` will work without changing torch tensor to numpy as eg.

```auto
import scipy.linalg
m = torch.tensor([[.5,.5],[.7,.9]])
print(scipy.linalg.fractional_matrix_power(m, (-1/2)))

array([[2.69776664, -1.10907208],
       [-1.55270001, 1.81051025]])

```

---

<div class="post-metadata">

**Author:** ![KFrank](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/k/ecb155/32.png) [@KFrank](https://discuss.pytorch.org/u/KFrank)\
**Post date:** [August 21, 2020, 8:13pm UTC](https://discuss.pytorch.org/t/raising-a-tensor-to-a-fractional-power/93655/3 "2020-08-21T20:13:41Z")

</div>

Hi mmutic!

> [@mmutic](#):
>
> I need to raise a matrix to the power of -1/2, but I believe doing so using just \*\*(-1/2) makes the computation element-wise.

A standard approach to exponentiating a matrix is to calculate its  
eigendecomposition and then exponentiate the eigenvalues.

Here is a pytorch version 0.3.0 script that illustrates this:

```python
import torch
print (torch. __version__ )

m = torch.FloatTensor([[.5,.5],[.7,.9]]) # original matrix

# desired result
mres = torch.FloatTensor ([[2.69776664, -1.10907208], [-1.55270001, 1.81051025]])

evals, evecs = torch.eig (m, eigenvectors = True) # get eigendecomposition
evals = evals[:, 0] # get real part of (real) eigenvalues

# rebuild original matrix
mchk = torch.matmul (evecs, torch.matmul (torch.diag (evals), torch.inverse (evecs)))

mchk - m # check decomposition

evpow = evals**(-1/2) # raise eigenvalues to fractional power

# build exponentiated matrix from exponentiated eigenvalues
mpow = torch.matmul (evecs, torch.matmul (torch.diag (evpow), torch.inverse (evecs)))

mpow - mres # check result

```

Here is the output:

```plaintext
>>> import torch
>>> print (torch. __version__ )
0.3.0b0+591e73e
>>>
>>> m = torch.FloatTensor([[.5,.5],[.7,.9]]) # original matrix
>>>
>>> # desired result
... mres = torch.FloatTensor ([[2.69776664, -1.10907208], [-1.55270001, 1.81051025]])
>>>
>>> evals, evecs = torch.eig (m, eigenvectors = True) # get eigendecomposition
>>> evals = evals[:, 0] # get real part of (real) eigenvalues
>>>
>>> # rebuild original matrix
... mchk = torch.matmul (evecs, torch.matmul (torch.diag (evals), torch.inverse (evecs)))
>>>
>>> mchk - m # check decomposition

1.00000e-07 *
 -0.5960 0.0000
 -0.5960 1.1921
[torch.FloatTensor of size 2x2]

>>>
>>> evpow = evals**(-1/2) # raise eigenvalues to fractional power
>>>
>>> # build exponentiated matrix from exponentiated eigenvalues
... mpow = torch.matmul (evecs, torch.matmul (torch.diag (evpow), torch.inverse (evecs)))
>>>
>>> mpow - mres # check result

1.00000e-07 *
  4.7684 7.1526
 -2.3842 -7.1526
[torch.FloatTensor of size 2x2]

```

You can see that this scheme recovers your Matlab result (actually  
Mr. mathematics’s scipy result, because he printed it out with greater  
precision).

This will work mathematically for positive semi-definite (square)  
matrices (although numerically you will probably want your smallest  
eigenvalue to be enough larger than zero that its computation doesn’t  
yield a negative value due to numerical error).

> [@mathematics](#):
>
> `scipy` will work without changing torch tensor to numpy

However, if you want to use autograd to calculate gradients (for, e.g.,  
backpropagation), performing the calculation in scipy won’t work  
(unless you write your own `.backward()` function).

Because the `torch.eig()` approach works entirely with pytorch tensor  
functions, you get autograd / gradients “for free.”

Good luck.

K. Frank

---

<div class="post-metadata">

**Author:** ![byteSamurai](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/bytesamurai/32/38897_2.png) [@byteSamurai](https://discuss.pytorch.org/u/byteSamurai)\
**Post date:** [May 30, 2021, 3:20pm UTC](https://discuss.pytorch.org/t/raising-a-tensor-to-a-fractional-power/93655/4 "2021-05-30T15:20:45Z")

</div>

This is an old one, so sorry, if my question might be naive, but isn’t this valid for matrix calculation as well?

![image](https://discuss.pytorch.org/uploads/default/original/3X/3/3/3350645909c4c700c4293e79e0fd13868fc83584.png)

So, if I run this, I get the same result as with scipy:

```auto
X.inverse().sqrt()

```

I assume, this also maintains the gradients?

---

<div class="post-metadata">

**Author:** ![KFrank](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/k/ecb155/32.png) [@KFrank](https://discuss.pytorch.org/u/KFrank)\
**Post date:** [May 31, 2021, 2:09am UTC](https://discuss.pytorch.org/t/raising-a-tensor-to-a-fractional-power/93655/5 "2021-05-31T02:09:06Z")

</div>

Hi Alfred!

> [@byteSamurai](#):
>
> ```auto
> X.inverse().sqrt()
> 
> ```

This is incorrect. [torch.sqrt()](https://pytorch.org/docs/1.8.1/generated/torch.sqrt.html#torch.sqrt) computes the square-roots of the  
individual elements of the tensor (not the matrix square-root).

(`torch.inverse()`, however, does compute the matrix inverse,  
rather than the reciprocals of the individual elements.)

Best.

K. Frank

---

<div class="post-metadata">

**Author:** ![byteSamurai](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/bytesamurai/32/38897_2.png) [@byteSamurai](https://discuss.pytorch.org/u/byteSamurai)\
**Post date:** [May 31, 2021, 3:47am UTC](https://discuss.pytorch.org/t/raising-a-tensor-to-a-fractional-power/93655/6 "2021-05-31T03:47:17Z")

</div>

Oh sorry, I see. Thanks for the hint 🙂
